wmnnd
Belt - A Flexible File-Storage Library
Hi there,
for my project DBLSQD, I needed a file storage solution that is a bit more flexible than Arc. Because I thought others might find it useful as well, I decided to share it with everyone and release it as free software. You can install version 0.1.1 from hex.pm.
What can it do?
Belt allows you to store files on remote or local systems. Currently, SFTP, S3 and the local filesystem are supported as targets. Belt is especially useful if you want to target multiple storage systems that are configured at runtime (e. g. because they are user-provided).
Belt is built on top of GenStage and also supports asynchronous uploads.
Belt also offers some convenience functions such as retrieving hashes of a file.
How does it work?
Here is a little example on how to use Belt:
#Simple file upload
{:ok, config} = Belt.Provider.SFTP.new(host: "example.com", directory: "/var/files",
user: "…", password: "…")
Belt.store(config, "/path/to/local/file.ext")
#=> {:ok, %Belt.FileInfo{…}}
#Asynchronous file upload
{:ok, config} = Belt.Provider.S3.new(access_key_id: "…", secret_access_key: "…",
bucket: "belt-file-bucket")
{:ok, job} = Belt.store_async(config, "/path/to/local/file.ext")
#Do other things while Belt is uploading in the background
Belt.await(job)
#=> {:ok, %Belt.FileInfo{…}}
You can read more on how to install and configure Belt in the Getting Started guide.
Roadmap
Belt is definitely usable the way it is right now but I have planned several additional features such as an Ecto integration.
Feedback welcome!
Suggestions for useful new features are more than welcome.
Also, if you discover bugs or find the documentation lacking in any way, please file a bug report.
Trending in Announcing
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 10 of 51 Posts!
Eiji
@wmnnd: nice!
I have some questions:
supports asynchronous uploads- is it support add upload file to queue, so we can send onlyxfiles at one time andyfiles on one storage type at one timexproviders and then download/sync that folder to another machine automatically.wmnnd
@Eiji: Thank you for your questions!
Jobsthat work similar toTasksin Elixir. You can easily use that mechanism for creating callbacks already. But I suppose it’s a feature worth exploring. How would you like to see it implemented? Would you want to be able to execute arbitrary code when aJobhas been completed? Is this considered good practice in Elixir? So far I haven’t seen many examples of this kind of callback being used.hassan
Cool, I’m working a lot with AWS right now, so this response may be
colored by spending a lot of time with the AWS CLI, but
It seems wrong to have to specify a bucket as an option to config;
aws s3 lsalone will give me a list of buckets, which is useful forfurther processing
I may have missed it, but most aws-related tools support pulling
secret keys from the standard ~/.aws/credentials file (and reading
an AWS_PROFILE env var if present). Is that supported? And if
not would you entertain a PR?
Regardless, thanks for publishing this.
wmnnd
@hassan: Thank you for your feedback!
ExAws.S3.list_buckets/1toBelt.Provider.S3. Do you think that would be worth it in order to avoid having to work directly with ExAws?ExAwswhich is used by Belt already has support for reading AWS CLI files. How do you imagine using Belt with defaults read from the CLI file? My current approach would be something like this:You could then configure defaults in your config file. A provider could also automatically try to pull common environment variables. What do you think about this idea?
Eiji
@wmnnd:
1, 3 - nice
2. I think that GenStage will be really good here, so I can listen on what you will produce, so in async mode background job could catch errors and apply callbacks on specified producer events.
4. If we are talking about
Producer -> Consumersscenario then it could be good to have a stand alone process that checks differences between shared files/folders, so after example app will got event that something was changed it could call callback to (ask) sync data.hassan
Put that way, probably not a high priority
Good point, let me look at how ExAws handles config first before
offering any more useless suggestions
LostKobrakai
I’m sure you did your research, but I want to share it anyways: there’s https://flysystem.thephpleague.com/, which does what you created in php. This might be interesting in terms of kick-starting other cloud providers.
wmnnd
@LostKobrakai: Cool, thank you for pointing this out!
Is there something in particular that you like about Flysystem?
I’ll see if I can’t get some good ideas from there
wmnnd
New version 0.1.2
I have just released a small update, version 0.1.2.
It comes with the following changes:
Changelog
Belt.delete_all/2andBelt.delete_scope/3Belt.Provider.default/1You can now configure your own defaults with
Mix.Config.Belt.Provider.S3can also make use of the AWS environment variables and AWS CLI config (read more). Thanks to @hassan for suggesting this.Roadmap
Next up will be:
Feedback and suggestions regarding functionality, code quality and/or documentation are always welcome!
wmnnd
New version 0.1.4
I have just released a little update, version 0.1.4.
Changelog
You can now directly store config structs in your database and Belt will take care of serializing and deserializing those structs so that no manual conversion is necessary. This is what it looks like:
Roadmap
Next up will be:
I’m looking forward to your feedback
Last Post!
cvkmohan
Thanks for the new release and update.
One example repo with Ecto Integration would go a great deal for adoption.
How to add a cover image for a post with - a. Regular View. b. LiveView - that will help newbies like me.
My confusions are -
a. Where to add transformations - producing thumbnails etc.
b. Ecto Changeset Integration.
Thanks in advance.
PS: I am from the Ruby world and Shrine has been the goto solution. So, still a bit lost on the path here.