Using UploadFile for direct file upload without a multipart/form-data request

Question:

I have an FastAPI endpoint for handling file uploads that looks something like this:

@app.post('/upload')
async def accept_some_file(f: UploadFile):
    content = await f.read()
    # ... do stuff with content and generate a response

but this appears to only work with multipart/form-data encoded payloads.

I’d like to be able to send file bytes directly through a request that looks like this:

POST /upload HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.79.1
Accept: */*
Content-Type: image/jpeg
Content-Length: 11044

... image bytes

Is there a FastAPI setting I can use to allow this? Or is there another request type that makes more sense for this use case?

Asked By: kingkupps

||

Answers:

You can get the request body as bytes using await request.body(). If you would like to do that in the synchronous way (i.e., using def endpoint instead, see here for def vs async def), please have a look at this answer.

from fastapi import Request

@app.post('/upload')
async def accept_some_file(request: Request):
    body = await request.body()

or, you can also access the request body as a stream, as described in this answer (under "Update" section). In this way, the byte chunks are provided without storing the entire body to memory—see Starlette documentation. Example:

@app.post('/upload')
async def accept_some_file(request: Request):
    body = b''
    async for chunk in request.stream():
        body += chunk
Answered By: Chris
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.