0
Preface
Shared them separately the other day (Introduction) A brief analysis of the Python web framework FastAPI - an API framework with higher performance than Flask and Tornada and (Advanced) Python web Framework FastAPI - A better API framework than Flask and Tornada .Today, we welcome you to the end of the FastAPI series, which is a supplement to and expansion of the previous articles.
Of course, these functions also play an extremely important role in the actual development.
1
Use of Middleware
Flask has hook functions that decorate certain methods and add specific functionality in some global or non-global situations.
There is also something like the hook function in the FastAPI, the middleware Middleware.
Calculate callback time
# -*- coding: UTF-8 -*-
import time
from fastapi import FastAPI
from starlette.requests import Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
print(response.headers)
return response
@app.get("/")
async def main():
return {"message": "Hello World"}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
Request redirection Middleware
from fastapi import FastAPI
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)
# Redirected to 301
@app.get("/")
async def main():
return {"message": "Hello World"}
Authorization allows Host access to the list (supports wildcard matching)
from fastapi import FastAPI
from starlette.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
app.add_middleware(
TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]
)
@app.get("/")
async def main():
return {"message": "Hello World"}
Cross-domain Resource Sharing
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
#List of domain names that allow cross-domain requests (inconsistent ports are also considered different domain names)
origins = [
"https://gzky.live",
"https://google.com",
"http://localhost:5000",
"http://localhost:8000",
]
# Wildcard matching, allowing domain names and methods
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
In front-end ajax requests, cross-domain issues should be considered when external links occur. If cross-domain is not allowed, the browser will automatically error and cross-domain resource security issues will occur.
So middleware is still used in a wide range of scenarios, such as crawls, which sometimes result in 301,302 Url requests when crawling the whole site.A redirection status code like this might be the redirection that the site administrator made when he set up the domain name (secondary domain name) not in the Host Access List. Of course, if you are also the site administrator, you can also do some anti-crawling based on the middleware.
More middleware references https://fastapi.tiangolo.com/advanced/middleware
2
BackgroundTasks
Create asynchronous task functions and use the async or normal def functions to call back-end functions.
send message
# -*- coding: UTF-8 -*-
from fastapi import BackgroundTasks, Depends, FastAPI
app = FastAPI()
def write_log(message: str):
with open("log.txt", mode="a") as log:
log.write(message)
def get_query(background_tasks: BackgroundTasks, q: str = None):
if q:
message = f"found query: {q}\n"
background_tasks.add_task(write_log, message)
return q
@app.post("/send-notification/{email}")
async def send_notification(
email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)
):
message = f"message to {email}\n"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}
The method is extremely simple, and there's no more bullshit. write_log is called as a task method, first the method name, then the parameter.
3
Custom Response Status Code
In some special scenarios we need to define the return status code ourselves
from fastapi import FastAPI
from starlette import status
app = FastAPI()
# 201
@app.get("/201/", status_code=status.HTTP_201_CREATED)
async def item201():
return {"httpStatus": 201}
# 302
@app.get("/302/", status_code=status.HTTP_302_FOUND)
async def items302():
return {"httpStatus": 302}
# 404
@app.get("/404/", status_code=status.HTTP_404_NOT_FOUND)
async def items404():
return {"httpStatus": 404}
# 500
@app.get("/500/", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
async def items500():
return {"httpStatus": 500}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
That's interesting, imagine someone wrote this code
async def getHtml(self, url, session):
try:
async with session.get(url, headers=self.headers, timeout=60, verify_ssl=False) as resp:
if resp.status in [200, 201]:
data = await resp.text()
return data
except Exception as e:
print(e)
pass
Interestingly, then, this function to get the Html source code will use the Http status code to determine if it is returning normally.So if, according to the above writing, I return a status code of 404 or 304 directly, but the response data is normal, won't the crawler be able to crawl anything?So hey hey you understand!!
4
About deployment
Deploying FastAPI applications is relatively easy
Uvicorn
FastAPI documentation recommends using Uvicorn to deploy applications (followed by hypercorn), which is a lightweight and efficient Web server framework based on asyncio (only supports Python versions 3.5.3 and above)
install
pip install uvicorn
Startup mode
uvicorn main:app --reload --host 0.0.0.0 --port 8000
Gunicorn
If you still like to deploy your project with Gunicorn, see below
install
pip install gunicorn
Startup mode
gunicorn -w 4 -b 0.0.0.0:5000 manage:app -D
Docker Deployment
The advantage of deploying an application with Docker is that you don't need to set up a specific running environment (in fact, the docker is pulling for you), you can build a FastAPI mirror through the Dockerfile, launch the Docker container, and easily access the application you deploy through port mapping.
Nginx
Hang up a layer of Nginx services based on Uvicorn/Gunicorn + FastAPI and a website will be ready to go online. In fact, using Uvicorn or Gunicorn directly is also OK, but Nginx can make your website look more like a website.