FastAPI
An easy way to create Restful apis in python
Installation:
pip install fastapi[all] #this installs fast api and all options including uvicorn (the web host) similar to gunicorn
separate installations:
pip install fastapi
pip install uvicorn[standard]
... other dependencies
The separate installtion is more suitable for production server to keep the minimum.
Helloworld
Pretty similar to Flask. Create an app and decorate the get / post method for different path.
The helloworld here use the root / path. The returned message is a json object (dictionary in python)
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
Run the app
uvicorn helloworld:app --host 127.0.0.1 --port 8080 --reload
again similar to gunicorn, points to the python file, the app instance, the host and port
Go to web browser open http://localhost:8080/
Restful API docs
The cool thing is it automatically generates the docs (JSON schema) for the api.
Go to http://localhost:8080/docs
It will list all the apis available with the service
The JSON schema is at http://localhost:8080/openapi.json
With JSON schema describing the API, one can automatically generate code for calling the api.
GET with parameter
you can send parameters within the URL to the api, simply add a sayhi function
@app.get("/sayhi")
async def sayhi(msg):
return {"received": msg}
From python, send a get request to the api. Note the parameter is part of the request url
import requests
api_url = "http://localhost:8080/sayhi?msg=good day"
response = requests.get(api_url)
print(response.text)
The script will return {"received":"good day"}
POST with data
The API now receives data in the request body. This requires to define the structure of the data in the request body.
Use pydantic's data model to define the request body structure.
The echo api below simply expects a request body with name and msg in string format.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Info(BaseModel):
name: str
msg: str
@app.post("/echo/")
async def echo(info: Info):
return info
Call the API with request body.
Pass in the JSON data.
import requests
api_url = "http://localhost:8080/echo"
payload = {"name": 'john', "msg": 'good day'}
response = requests.post(api_url, json=payload)
response_data = response.json()
print(response_data)
The response is {'name': 'john', 'msg': 'good day'}
Run the app from Gunicorn
Uvicorn supports async request which is lacked in flask, but still it is not a workers manager.
So in production it needs to be run from a manager like Gunicorn, similar to running flask from Gunicorn.
Gunicorn is compatible with it, and only needs to specify the worker class as below
gunicorn helloworld:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8080