Skip to content

Instantly share code, notes, and snippets.

@iuriguilherme
Last active January 17, 2024 16:40
Show Gist options
  • Save iuriguilherme/15de867bc467775f5e46ac308117c286 to your computer and use it in GitHub Desktop.
Save iuriguilherme/15de867bc467775f5e46ac308117c286 to your computer and use it in GitHub Desktop.
FastAPI and Quart together
#!/usr/bin/env python
## FastAPI is a great tool for... fast APIs... but there are better
## solutions for web apps such as Django, Web2Py and Flask. Talking
## about Flask, there is the Quart project which aims to be the full
## async version of Flask that you can use today.
##
## I have read the following documentation to reach the result of this
## gist:
##
## * <https://fastapi.tiangolo.com/tutorial/middleware/>
## * <https://fastapi.tiangolo.com/advanced/middleware/>
## * <https://fastapi.tiangolo.com/advanced/sub-applications/>
## * <https://fastapi.tiangolo.com/advanced/behind-a-proxy/>
## * <https://fastapi.tiangolo.com/advanced/wsgi/>
## * <https://pgjones.gitlab.io/quart/tutorials/deployment.html>
## * <https://flask.palletsprojects.com/en/1.1.x/patterns/appdispatch/#app-dispatch>
## * <https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/>
##
## This gist example will configure FastAPI to handle requests on
## http://127.0.0.1:8000/api/ and the web application will be handled
## by Quart on http://127.0.0.1:8000/
##
## Packages needed to run this script:
## pip install fastapi quart uvicorn
from fastapi import FastAPI
from quart import Quart
fastapi_app = FastAPI()
quart_app = Quart(__name__)
## Alternatively use Flask instead of Quart
## You must change the rest of the code accordingly
#from flask import Flask
#from fastapi.middleware.wsgi import WSGIMiddleware
#flask_app = Flask(__name_)
## Example Quart Route
## https://pgjones.gitlab.io/quart/tutorials/quickstart.html
@quart_app.route("/")
async def webapp():
return u"Hello Quart"
## If using Flask:
#@flask_app.route("/")
#def webapp():
# return u"Hello Flask"
## Example FastAPI Route
## https://fastapi.tiangolo.com/tutorial/first-steps/
@fastapi_app.get("/api")
async def api():
return {"Hello": "FastAPI"}
### This is the important part:
## The Quart's route "/" will be available as a FastAPI's ASGI
## Middleware at http://127.0.0.1:8000/
fastapi_app.mount("/", quart_app)
## If using Flask:
#fastapi_app.mount("/", WSGIMiddleware(flask_app))
## If you want to use hypercorn or something else, change your code
## Running `uvicorn app:fastapi_app` from the command line will work
## Running `python app.py` will also work because of the following:
if __name__ == '__main__':
import uvicorn
uvicorn.run(
'__main__:fastapi_app',
host='127.0.0.1',
port=8000,
log_level='info',
)
@iuriguilherme
Copy link
Author

iuriguilherme commented Nov 19, 2020

To use a Flask application instead of Quart, change line 57 to:

fastapi_app.mount("/", WSGIMiddleware(flask_app))

Remeber to import WSGIMiddleware:

from fastapi.middleware.wsgi import WSGIMiddleware

@kphretiq
Copy link

kphretiq commented Jun 3, 2021

This works great! The only bummer I've encountered so far is that due to the quart app being mounted on fastapi, you apparently lose the ability to run quart stuff from the command line. If you are used to happily using click to add a bunch of switches to your flask/quart app, it looks like it goes away with this technique.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment