What is the maximum size of upload file we can receive in FastAPI?
Asked Answered
K

1

11

I am trying to figure out the maximum file size, my client can upload , so that my python fastapi server can handle it without any problem.

Kuehn answered 23/6, 2021 at 7:34 Comment(4)
As far as I can tell, there is no actual limit: github.com/encode/starlette/issues/890 - see github.com/tiangolo/fastapi/issues/362 for how to implement a limit based on the Content-Length headerPotted
thanks for answering, aren't there any http payload size limitations also?Kuehn
If you're thinking of POST size, that's discussed in those tickets - but it would depend on whether you're serving requests through FastAPI/Starlette directly on the web, or if it goes through nginx or similar first. Any part of the chain may introduce limitations on the size allowed.Potted
Please have a look at this answer on how to read the request body in chunks using .stream(), and hence, enforce body/file size limits in your application.Undersexed
S
17

Your request doesn't reach the ASGI app directly. It goes through reverse proxy (Nginx, Apache), ASGI server (uvicorn, hypercorn, gunicorn) before handled by an ASGI app.

Reverse Proxy

For Nginx, the body size is controlled by client_max_body_size, which defaults to 1MB.

For Apache, the body size could be controlled by LimitRequestBody, which defaults to 0.

ASGI Server

The ASGI servers don't have a limit of the body size. At least it's the case for gunicorn, uvicorn, hypercorn.

Quote from Hypercorn doc.

Large request body

This attack is of the second type and aims to exhaust the server’s memory by inviting it to receive a large request body (and hence write the body to memory). A poorly configured server would have no limit on the request body size and potentially allow a single request to exhaust the server.

It is up to the framework to guard against this attack. This is to allow the framework to consume the request body if desired.

Note: Gunicorn doesn't limit the size of request body, but sizes of the request line and request header.

  • --limit-request-line, size limit on each req line, default 4096
  • --limit-request-fields, number of header fields, default 100
  • --limit-request-field_size, size of headef fields, default 8190

ASGI App/Framework

Since FastAPI is based upon Starlette. How to reading the body is handled by Starlette. Reading from the source (0.14.3), there seems no limit on request body either.

class Request(HTTPConnection):
    ...
    async def stream(self) -> typing.AsyncGenerator[bytes, None]:
        if hasattr(self, "_body"):
            yield self._body
            yield b""
            return

        if self._stream_consumed:
            raise RuntimeError("Stream consumed")

        self._stream_consumed = True
        while True:
            message = await self._receive()
            if message["type"] == "http.request":
                body = message.get("body", b"")
                if body:
                    yield body
                if not message.get("more_body", False):
                    break
            elif message["type"] == "http.disconnect":
                self._is_disconnected = True
                raise ClientDisconnect()
        yield b""

    async def body(self) -> bytes:
        if not hasattr(self, "_body"):
            chunks = []
            async for chunk in self.stream():
                chunks.append(chunk)
            self._body = b"".join(chunks)
        return self._body

Conclusion: If you get 413 Payload Too Large error, check the reverse proxy.

Selfexplanatory answered 23/6, 2021 at 10:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.