Josh Bello
Josh Bello

Reputation: 371

__call__() missing 1 required positional argument: 'send' FastAPI on App Engine

When trying to host an API on App Engine, the following error keeps coming up. The program used to run on Flask which was working but very slow.

Error:

"Traceback (most recent call last):
  File "/env/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 134, in handle
    self.handle_request(listener, req, client, addr)
  File "/env/lib/python3.7/site-packages/gunicorn/workers/sync.py", line 175, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
TypeError: __call__() missing 1 required positional argument: 'send'
"

Docker File:

FROM gcr.io/google_appengine/python

RUN apt-get update && apt-get install -y ffmpeg

# Create a virtualenv for dependencies. This isolates these packages from
# system-level packages.

RUN virtualenv /env -p python3.7

# Setting these environment variables are the same as running
# source /env/bin/activate.

ENV VIRTUAL_ENV /env
ENV PATH /env/bin:$PATH

ADD requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt

# Add the application source code.

ADD . /app

CMD gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

app.yaml

runtime: custom
env: flex
entrypoint: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
service: encoder

runtime_config:
  python_version: 3

handlers:

- url: /.*
  script: auto

Upvotes: 35

Views: 62388

Answers (5)

Francois Lemaitre
Francois Lemaitre

Reputation: 511

In the Starlette code, I found a reference to a2wsgi. And it looks like it is going in both directions (wsgi<>asgi).

I gave it a try and it worked well for me:

from a2wsgi import ASGIMiddleware
wsgi_app = ASGIMiddleware(app)
# use this wsgi instead of your app

Upvotes: 2

capitalistlion
capitalistlion

Reputation: 26

I solved it by putting python main.py as the build command and setting my uvicorn command in the main.py as uvicorn.run("main:app", host="0.0.0.0", port=8080)

Upvotes: 0

Antoine Krajnc
Antoine Krajnc

Reputation: 1323

I ran into the same issue when I want to deploy a FastAPI app to Heroku. Indeed, you can't use uvicorn (which is the ASGI framework that FastAPI is using) with Heroku that uses gunicorn.

However, by adding a uvicorn worker to gunicorn then it works!:

gunicorn api:app --bind 0.0.0.0:$PORT --worker-class uvicorn.workers.UvicornWorker

Upvotes: 7

Akshith
Akshith

Reputation: 553

As Dustin said I found out that worker class need to be changed. Try the below one.

gunicorn -k uvicorn.workers.UvicornWorker main:app

Found this on github issues

Upvotes: 43

Dustin Ingram
Dustin Ingram

Reputation: 21550

App Engine requires your main.py file to declare an app variable which corresponds to a WSGI Application.

Since FastAPI is an asynchronous web framework, it is not compatible with WSGI (which is synchronous).

Your best option would be to use a service like Cloud Run, which would allow you to define your own runtime and use an asynchronous HTTP server compatible with FastAPI.

Upvotes: 8

Related Questions