Fastapi - python 高性能的 web 框架
1.为什么选择 Fastapi
快速:拥有非常高的性能,归功于 Starlette 和 Pydantic;Starlette 用于路由匹配,Pydantic 用于数据验证
开发效率:功能开发效率提升 200% 到 300%
减少 bug:减少 40% 的因为开发者粗心导致的错误
智能:内部的类型注解非常完善,编辑器可处处自动补全
简单:框架易于使用,文档易于阅读
简短:使代码重复最小化,通过不同的参数声明实现丰富的功能
健壮:可以编写出线上使用的代码,并且会自动生成交互式文档
标准化:基于(并完全兼容)API 的相关开放标准:OpenAPI (以前被称为 Swagger) 和 JSON Schema。
技术背景:python3.6+、Starlette、Pydantic
2.依赖安装
# 假如你想将应用程序部署到生产环境,你可能要执行以下操作:
pip install fastapi
# 安装 uvicorn 来作为服务器:
pip install uvicorn
3.项目启动
最简单的 FastAPI 文件可能像下面这样:
# @File : main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
终端执行
uvicorn main:app --reload
uvicorn main:app
命令含义如下:
main
:main.py
文件(一个 Python「模块」)。app
:在main.py
文件中通过app = FastAPI()
创建的对象。--reload
:让服务器在更新代码后重新启动。仅在开发时使用该选项。
Result:
服务器默认端口为 8000
打开浏览器访问 http://127.0.0.1:8000。
你将看到如下的 JSON 响应:
{"message": "Hello World"}
4.交互式 API 文档
跳转到 http://127.0.0.1:8000/docs。
你将会看到自动生成的交互式 API 文档(由 Swagger UI 提供):
5.基本的项目结构
5.1 FastTest/FastTest
本目录下的文件请勿轻易修改
-
项目配置文件,配置开发环境,数据库链接,项目启动配置
-
核心文件,用于项目初始化以及 Application 对象的生成方便 ./manager.py 中项目的启动
-
三方的工具包以及自行封装的接口返回格式
-
中间件文件
自定义中间件 使用 app.middleware 装饰来实现一个中间件(两种方法)
import time from flask import Request from starlette.middleware.cors import CORSMiddleware def register_cors(app, DEBUG=None) -> None: @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) return response if DEBUG: app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.add_middleware(add_process_time_header)
中间件会接受两个参数
- call_next:是一个函数,将 request 作为参数
call_next
- 会将 request 传递给相应的路径操作函数
- 然后会返回路径操作函数产生的响应,赋值给 response
- 可以在中间件 return 前对 response 进行操作
-
FastTest/urls.py & /app01/urls.py
路由注册
app01/urls.py 加载路由
…
FastTest/urls.py
include
app01, …# *FastTest/urls.py* # 加载 app 对象 import app01.urls import app_test.urls def register_routers(app) -> None: # 注册主页 app.include_router(app01.urls.router, prefix='/v1') app.include_router(app01.urls.router2, prefix='/v2') # 注册 test 路由 app.include_router(app_test.urls.router, prefix="/test") # *app01/views/index.py* from FastTest.extension import return_json_response, response_err, err_log async def v1_index(): try: return return_json_response(data={ 'v1/': '之乎者也' }) except Exception as e: # 日志记录 err_log('doudianrank', e) return response_err(e) # *app01/urls.py* from fastapi import APIRouter from app01.views.api.index import v1_api_index from app01.views.index import v1_index router = APIRouter() ''' 路由注册 router.add_api_route(path:str, func:callable[, tags:list, methods:list]) @path str 路由 @func callable 视图函数 @tags list 路由标签,openapi/dosc 上会按照 tags 进行分组 @methods list Http 请求方法 默认 ['GET', 'POST'] ''' router.add_api_route('/', v1_index, tags=['app01_v1_index'], methods=['GET']) router2 = APIRouter() router2.add_api_route('/api/', v1_api_index, tags=['app01_v1_api_index'])