Search code examples
python-3.xfastapipython-3.9

FastAPI Raises Missing Positional Argument Error


The following code raises the following exception.

I'm not sure I fully understand how FastAPI works. Could someone help me understand?

from fastapi import FastAPI
from fastapi import BackgroundTasks
from fastapi import Request

app = FastAPI()

async def parse_request(req: Request):
    print(req)
    print(req.client.host)

@app.route("/endpoint")
async def endpoint(request: Request, background_tasks: BackgroundTasks):
    background_tasks.add_task(parse_request, request)
    return {"msg": "ok"}

Exception:

Traceback (most recent call last):
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
    await super().__call__(scope, receive, send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/routing.py", line 580, in __call__
    await route.handle(scope, receive, send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/routing.py", line 241, in handle
    await self.app(scope, receive, send)
  File "/home/user/repos/fastapi_pg/env_39/lib/python3.9/site-packages/starlette/routing.py", line 52, in app
    response = await func(request)
TypeError: endpoint() missing 1 required positional argument: 'background_tasks'

I've gotten this to work without the Request param when I pass in my own variable in the route path:

@app.get("/test/{input_str}")
async def test(input_str: str, background_tasks: BackgroundTasks):
    background_tasks.add_task(do_stuff, input_str)
    return {"Hello": "World"}

Seems like Starlette doesn't know how to handle multiple of these params being passed so you can't mix and match. Ideal I'd be able to take the Request and Header objects and pass them to a background task for processing.


Solution

  • The decorator @app.route seems to be the problem. (see: https://github.com/tiangolo/fastapi/issues/912) Use @app.api_route instead or even better @app.get or @app.post.