AnswerDotAI / fasthtml

The fastest way to create an HTML app
https://fastht.ml/
Apache License 2.0
5.66k stars 237 forks source link

[BUG] Incorrect hx-post Value Breaks File Upload in Example #584

Open plops opened 5 days ago

plops commented 5 days ago

In the example code 'Single File Uploads' and 'Multiple File Uploads' is not working for me.

The hx-post attribute in the file upload form is incorrectly populated with the Python function object representation instead of the function name string "upload", causing htmx to fail processing the form submission.

Minimal Reproducible Example

# This is a copy of the non-working code from here https://docs.fastht.ml/tutorials/quickstart_for_web_devs.html
from fasthtml.common import *
from pathlib import Path

app, rt = fast_app()

upload_dir = Path("filez")
upload_dir.mkdir(exist_ok=True)

@rt('/')
def get():
    return Titled("File Upload Demo",
        Article(
# The following line should contain hx_post="upload" 
            Form(hx_post=upload, hx_target="#result-one")(
                Input(type="file", name="file"),
                Button("Upload", type="submit", cls='secondary'),
            ),
            Div(id="result-one")
        )
    )

def FileMetaDataCard(file):
    return Article(
        Header(H3(file.filename)),
        Ul(
            Li('Size: ', file.size),            
            Li('Content Type: ', file.content_type),
            Li('Headers: ', file.headers),
        )
    )    

@rt
async def upload(file: UploadFile):
    card = FileMetaDataCard(file)
    filebuffer = await file.read()
    (upload_dir / file.filename).write_bytes(filebuffer)
    return card

serve()

Expected behavior The generated HTML should contain hx-post="upload", allowing htmx to correctly submit the form to the /upload route.

Actual Behavior: hx-post="<function upload at 0x...>"

Environment Information Please provide the following version information:

Confirmation Please confirm the following:

Additional context

Affected File: nbs/tutorials/quickstart_for_web_devs.ipynb (likely the only file needing changes, though nbs/llms-ctx-full.txt and nbs/llms-ctx.txt contain the related function).

I think two code examples 'Single File Uploads' and 'Multiple File Uploads' have this issue.

TransparentIA commented 4 days ago

Hi plops, I can reproduce the issue with FastHTML version '0.9.1'. Odd enough, it works in a Jupyter notebook. So, I found that specifying the host in the python script works again: serve(host='localhost') It might be that '0.0.0.0' is not converted to 'localhost' ?

On Thu, Nov 21, 2024 at 2:16 PM plops @.***> wrote:

In the example code 'Single File Uploads' and 'Multiple File Uploads' is not working for me.

The hx-post attribute in the file upload form is incorrectly populated with the Python function object representation instead of the function name string "upload", causing htmx to fail processing the form submission.

Minimal Reproducible Example Provide a minimal code snippet that reproduces the issue. This is crucial for us to understand and fix the bug quickly.

This is a copy of the non-working code from here https://docs.fastht.ml/tutorials/quickstart_for_web_devs.htmlfrom fasthtml.common import *from pathlib import Path

app, rt = fast_app() upload_dir = Path("filez")upload_dir.mkdir(exist_ok=True) @rt('/')def get(): return Titled("File Upload Demo", Article(# The following line should contain hx_post="upload" 1 Form(hx_post=upload, hx_target="#result-one")(2 Input(type="file", name="file"), Button("Upload", type="submit", cls='secondary'), ), Div(id="result-one") ) ) def FileMetaDataCard(file): return Article( Header(H3(file.filename)), Ul( Li('Size: ', file.size), Li('Content Type: ', file.content_type), Li('Headers: ', file.headers), ) ) @rt3async def upload(file: UploadFile):4 card = FileMetaDataCard(file)5 filebuffer = await file.read()6 (upload_dir / file.filename).write_bytes(filebuffer) return card serve()

Expected behavior The generated HTML should contain hx-post="upload", allowing htmx to correctly submit the form to the /upload route.

Actual Behavior: hx-post="<function upload at 0x...>"

Environment Information Please provide the following version information:

Confirmation Please confirm the following:

  • I have read the FAQ (https://docs.fastht.ml/explains/faq.html)
  • I have provided a minimal reproducible example
  • I have included the versions of fastlite, fastcore, and fasthtml
  • I understand that this is a volunteer open source project with no commercial support.

Additional context

Affected File: nbs/tutorials/quickstart_for_web_devs.ipynb (likely the only file needing changes, though nbs/llms-ctx-full.txt and nbs/llms-ctx.txt contain the related function).

I think two code examples 'Single File Uploads' and 'Multiple File Uploads' have this issue.

— Reply to this email directly, view it on GitHub https://github.com/AnswerDotAI/fasthtml/issues/584, or unsubscribe https://github.com/notifications/unsubscribe-auth/BMRMPJTDSYW4UIKLTHVZACT2BXMLTAVCNFSM6AAAAABSG7H5ZOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGY3TSNBQGY3TMOI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

plops commented 4 days ago

@TransparentIA your observation intrigued me, so I tried the extra option for the serve call myself.

For me adding the option host='localhost' to the serve() call doesn't fix the issue.

serve()
# => INFO:     127.0.0.1:58928 - "POST /%3Cfunction%20upload%20at%200x7f24d96ccea0%3E HTTP/1.1" 404 Not Found

serve(host='localhost')
# => INFO:     127.0.0.1:53432 - "POST /%3Cfunction%20upload%20at%200x7fe87a4c8f40%3E HTTP/1.1" 404 Not Found

# The proper fix:
Form(hx_post="upload", hx_target="#result-one") ... 
serve()
# => INFO:     127.0.0.1:49164 - "POST /upload HTTP/1.1" 200 OK

Note that I added the relevant lines from the log output after # =>