Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to upload files? #463

Closed
SmithChart opened this issue Aug 7, 2023 · 5 comments · Fixed by #503
Closed

Question: How to upload files? #463

SmithChart opened this issue Aug 7, 2023 · 5 comments · Fixed by #503
Labels
enhancement New feature or request

Comments

@SmithChart
Copy link
Contributor

I've been looking into uploading files to a Lona server.

Last time I had this problem I solved it using an non-interactive view that handled the actual upload. That was OK for the toy-project at the time (See View and routing ). But now I want to find a solution that integrates a little nicer into an interactive Lona view.

When using a <form> with an <input type="file"> this fails, since Lona does not send the files content to the server when intercepting (and faking) the POST-request. So this example does not work at the moment:

class File(Node):
    TAG_NAME = "input"
    SELF_CLOSING_TAG = True

    ATTRIBUTES = {
        "type": "file",
    }


@app.route("/")
class Index(View):
    def handle_request(self, request):
        if request.method == "POST":
            print(request.POST)

        return HTML(
            H1("Enter your name"),
            Form(
                File(name="file"),
                TextInput(name="name"),
                Submit("Submit"),
                action=".",
                method="post",
            ),
        )

This will print ({'file': {}, 'name': 'abc'}) when typing "abc" into the text field.

I could try to implement a custom JavaScript based solution for this. But before doing so I wanted to know if anyone already has an Opinion on how we want to go forward here. I guess uploading files is not a very common problem, but still is needed from time to time.

@fscherf
Copy link
Member

fscherf commented Aug 8, 2023

Hi @SmithChart,

That's a feature Lona is missing since the begin of this project. Basically, you can just use aiohttp file upload in an non-interactive, http-pass-through view as you did, but I want to add a more user-friendly feature to the library.

I was working on this: master...fscherf/topic/file-upload

It is pretty much what you are doing, but using a generic middleware, instead of a view. That way is easier to configure and you don't have to add a custom file upload view to the routing table of every project that wants to use it.

My idea was to provide an python API like this:

from lona_dropzone import DropZone            
                                              
bucket = server.get_file_bucket(              
    max_files=3,                              
    max_size=1024,                            
    list_files=True,                          
)

bucket.list_files() # -> ['/tmp/euhaeu12/file-1.png', ]                                            
                                              
HTML(                                         
    H1('Drag & Drop your files here'),        
    DropZone(                                 
        bucket=bucket,                        
        handle_file_upload=lambda e: print(e),
    ),                                        
)                                             

As you mentioned, we will need something that does the actual upload, using a POST request, and I was looking at a project like https://www.dropzone.dev/

btw: The name bucket was my first idea, because in my head its like an area where you can dump things and list and remove them afterwards. I am open to better names :D

@fscherf fscherf added the enhancement New feature or request label Aug 8, 2023
@SmithChart
Copy link
Contributor Author

This sounds like the API that i want to use :-) Also I like the idea of using a well-tested project. Especially the chunked upload method sounds promising. Especially when planning on uploads for larger files.

bucket sounds fine. Stuff like store sounds too permanent.

Do you have a plan on cleaning up unused files from the buckets? I initially thought about a context manager. But that would be too limiting when using event handlers.
It would be nice to have a way to tidy up uploaded files once the view (or lona) ends.

@fscherf
Copy link
Member

fscherf commented Sep 6, 2023

Valid point. Then it should be View.get_file_bucket() instead of Server.get_file_bucket(). Then the buckets are linked to a view, and the server can cleanup all buckets when the view gets removed from the server.

@SmithChart
Copy link
Contributor Author

view.get_file_bucket() sounds like the right place for that. Thx!

@fscherf
Copy link
Member

fscherf commented Nov 12, 2023

Hi @SmithChart,

I am sorry it took me so long, but I have the buckets API ready now (it was not easy to come up with something that is safe, easy to use, and is easy to implement)

I made a few changes to the design:

  • I renamed the class FileBucket to Bucket. I can't come up with another type of buckets that should be part of the standard library, so buckets are always for files now.
  • I wanted buckets to be self-contained like Channel objects, so they shouldn't be part of the view API. Now, buckets get initialized with a Request object so Lona can correlate which bucket belongs to which server and view.

I also realized that the server-side is pretty useless without a frontend-component to use it. So I integrated Dropzone.js (https://github.com/lona-web-org/lona-dropzone) and added a demo to the documentation. There are also tests and documentation.

PR: #503

Let me know what you think

@fscherf fscherf linked a pull request Nov 12, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants