Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run UVICORN in Heroku?

So I have figured out how to code a fastAPI and I am ready to deploy my script to heroku that I have worked with fastAPI (https://fastapi.tiangolo.com/) however the problem is that when I do a request to heroku it will just return:

<html>
  <head>
    <title>Internal Server Error</title>
  </head>
  <body>
    <h1><p>Internal Server Error</p></h1>

  </body>
</html>

Which means the script is on but I can't see the error and locally it works totally fine I would say.

I am not able to see any logs where the problem is however I would say my problem might be that I am not sure if my procfile is correct because I haven't edited it at all and I am quite new at this and I am here to ask how I am able to run my fastapi script in heroku?

What I know is that to be able to run the script, you have to use command uvicorn main:app --reload and it won't work if you do etc py main.py What am I doing wrong?

like image 298
Thrillofit86 Avatar asked Dec 18 '19 11:12

Thrillofit86


People also ask

How do I use FastAPI on Heroku?

Open the command prompt and navigate to the location where you want to create a new application. Create a directory named fastapi-demo and set the current directory to it by running the following commands. Now launch the VS Code from the command prompt by typing code . and hit enter.

How do you set up Uvicorn?

You can also configure Uvicorn using environment variables with the prefix UVICORN_ . For example, in case you want to run the app on port 5000 , just set the environment variable UVICORN_PORT to 5000 . CLI options and the arguments for uvicorn. run() take precedence over environment variables.


2 Answers

The answer(s) are correct, but to use FastAPI in production running as WSGI with ASGI workers is a better choice here is why, i ran a benchmark for this question, so here is the results.

Gunicorn with Uvicorn workers

Requests per second:    8665.48 [#/sec] (mean)
Concurrency Level:      500
Time taken for tests:   0.577 seconds
Complete requests:      5000
Time per request:       57.700 [ms] (mean)

Pure Uvicorn

Requests per second:    3200.62 [#/sec] (mean)
Concurrency Level:      500
Time taken for tests:   1.562 seconds
Complete requests:      5000
Time per request:       156.220 [ms] (mean)

As you can see there is a huge difference in RPS(Request per second) and response time for each request.

Procfiles

Gunicorn with Uvicorn Workers

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

Pure uvicorn

web: uvicorn main:app --workers 4
like image 97
Yagiz Degirmenci Avatar answered Sep 22 '22 02:09

Yagiz Degirmenci


I've tested your setup and after some checking (never used Heroku before) I'm guessing your uvicorn never binds to the appointed port (was the heroku-cli command heroku local working for you?)

Your Procfile could look like this;

web: uvicorn src.main:app --host=0.0.0.0 --port=${PORT:-5000}

This example assumes you have your source code within a subfolder named 'src' which has an empty __init__.py (indicating a Python module, you probably want to add src to the PYTHONPATH instead, see app.json) and main.py containing your fastapi app;

import socket
import sys

from fastapi import FastAPI

app = FastAPI()

hostname = socket.gethostname()

version = f"{sys.version_info.major}.{sys.version_info.minor}"


@app.get("/")
async def read_root():
    return {
        "name": "my-app",
        "host": hostname,
        "version": f"Hello world! From FastAPI running on Uvicorn. Using Python {version}"
    }

I have added my working example to github which you can view on heroku (for now)

like image 44
Hedde van der Heide Avatar answered Sep 22 '22 02:09

Hedde van der Heide