wmnnd

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.

Most Liked

wmnnd

wmnnd

Upload in-memory data with Belt 0.4.0!

Thanks to @jayjun’s fantastic work, a brand-new feature is now available in Belt: Uploading iodata directly to all Providers without the need to go through a file first.
Belt.store_data/3 works just like Belt.store/3, except that it takes iodata instead of a file path as the second argument and the :key option is mandatory.
Of course, it’s also accompanied by Belt.store_data_async/3 :slight_smile:

I’ve also updated the ex_aws dependency to the 2.x branch.
I originally wasn’t sure if this is the right thing to do, since it’s a major version update for this (optional) dependency and just a minor version update for Belt.
But since there is a bug in ExAws 1.x which breaks it on Elixir 16/OTP 21 and @benwilson512 pointed out that ExAws 2.x is “plug and play compatible” with 1.x, I decided this was the way to go :crystal_ball:

As always, Feedback is very welcome.

wmnnd

wmnnd

#New version 0.1.8
Since DBLSQD is finally up and running, there is at least one instance of Belt out in the wild now :smile:

More features will come as DBLSQD and Belt evolve. For now, these are the changes of the most recent release:

Changelog

  • Improvement: When storing files on SFTP, hashes are now calculated locally. Retrieving hashes when none were requested is now a noop.
  • Improvement: Better compatibility with SFTP servers with small maximum package sizes. Thanks to the obscure and undocumented (yet public) functions :ssh_sftp.send_window/2 and :ssh_sftp.recv_window/2, package size is now determined dynamically.
  • Fixed bug causing infinite loops when listing files on some SFTP servers
  • Fixed connecting to SFTP servers with verify_host set to false

##roadmap

  • Make jobs more flexible
  • Explore the possibility of using ETS directly or ConCache as a backend for jobs

Feedback and suggestions are welcome as always!

wmnnd

wmnnd

Small SFTP update 0.2.0

Version 0.2.0 of Belt brings improved SFTP transfer performance (as much as 10 times faster transfer speed) thanks to asynchronous writing as well as better support for different SFTP servers.

What’s next?

Belt 0.x will continue to receive updates and soon I’ll add a feature to test configurations without the need to upload something or use one of the other commands first.
A rewrite is coming for version 1.x which will bring new Ecto-style configuration and direct uploads - both for S3 and by proxy for SFTP as well.

Where Next?

Popular in Announcing Top

sasajuric
I’d like to announce a small library called boundaries. This is an experimental project which explores the idea of enforcing boundaries ...
New
tmbb
PhoenixWS - Websockets over Phoenix Channels Source code on Github here: GitHub - tmbb/phoenix_ws: Websockets implemented over Phoenix Ch...
New
josevalim
Yes, yet another parser combinator library! Most of the parser combinators in the ecosystem are either compile-time, often using AST tra...
159 19417 141
New
dominicletz
Hi, I thought I had posted my library before but seems I hadn’t. The project is still in early stages but it’s growing and so I think it...
New
kip
ex_cldr provides localisation and internationalisation support based upon the data from the Unicode CLDR project. Unicode released CLDR ...
407 13014 120
New
kip
Image is an image processing library for Elixir. It is based upon the fabulous vix library that provides a libvips wrapper for Elixir. I...
622 18934 194
New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
michalmuskala
Hello everybody. I have just released Jason - a new JSON library. You might be wondering, why do we need a new library? The primary foc...
New
benlime
LiveMotion enables high performance animations declared on the server and run on the client. As a follow up to my previous thread A libr...
New
trisolaran
Hi! :waving_hand: I would like to present LiveSelect, a little library that I wrote to easily add a dynamic selection input to your LV f...
198 10954 107
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39467 209
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

We're in Beta

About us Mission Statement