Reputation: 371
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.
"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'
"
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
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
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
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
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
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
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