FastAPI 是一個用于構建 API 的現代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于標準的 Python 類型提示。
關鍵特性:
- 快速:可與 NodeJS 和 Go 比肩的極高性能(歸功于 Starlette 和 Pydantic)。最快的 Python web 框架之一。
- 高效編碼:提高功能開發速度約 200% 至 300%。
- 更少 bug:減少約 40% 的人為(開發者)導致錯誤。
- 智能:極佳的編輯器支持。處處皆可自動補全,減少調試時間。
- 簡單:設計的易于使用和學習,閱讀文檔的時間更短。
- 簡短:使代碼重復最小化。通過不同的參數聲明實現豐富的功能。bug 更少。
- 健壯:生產可用級別的代碼。還有自動生成的交互式文檔。
- 標準化:基于(并完全兼容)API 的相關開放標準:OpenAPI (以前被稱為 Swagger) 和 JSON Schema。
以上這段是 FastAPI 官方文檔的介紹,通過我自己的使用,發現雖然效率提升沒有官方說得那么高,但是確實會快很多,而且我認為這個框架的代碼書寫更 pythonic 一點,如果用習慣了,在寫別的 Python 代碼時,也更加規范一些。
熟悉 Flask 的人上手 FastAPI 可能會比較快一些,一個 py 腳本就能搭起來一個網站,但是我們開發項目的時候,肯定不會把所有邏輯都塞在一個腳本里面,因此就需要提供一個像 Django 那樣的完整項目框架,業務開發只要按照固定的規則添加就行了。雖然官方提供了一個項目框架模板,但是由于 FastAPI 自由度比較高,所以大家可以根據自己的習慣去實現一個項目框架,我就根據自己使用 Django 的習慣實現了一個我認為比較合適的框架結構。下面就是大概的介紹。
簡介
使用FastAPI + MySQL + Tortoise-orm 作為主要數據庫操作,項目結構參考GitHub上兩個項目:
- CoderCharm / fastapi-mysql-generator
- FastAPI-demo
功能
- JWT token 認證。
- 使用 Tortoise-orm models(MySql).
- 基于 casbin 的權限驗證
- loguru 日志模塊使用
權限控制
- 登錄、注冊及路由中含有openapi的接口不進行登錄和權限認證
async def jwt_authentication(
request: Request,
x_token: str = Header(
None,
title='登錄Token',
description='登錄、注冊及開放API不需要此參數'
)
):
"""
除了開放API、登錄、注冊以外,其他均需要認證
:param request:
:return:
"""
if 'openapi' in request.url.path.lower() or
'login' in request.url.path.lower() or
'register' in request.url.path.lower():
return None
....
- 全局登錄認證(除以上接口外,其余接口均進行登錄認證)
App = FastAPI(
debug=settings.DEBUG,
title=settings.TITLE,
description=settings.DESCRIPTION,
docs_url=settings.DOCS_URL,
redoc_url=settings.REDOC_URL,
dependencies=[Depends(jwt_authentication)]
)
全局進行 Depends(jwt_authentication) 依賴注入
- 接口權限認證
首先通過 auth/add 和 auth/del 接口進行權限配置
@router.get(
"/info",
summary="獲取當前用戶信息",
name="獲取當前用戶信息",
response_model=schema.UserOut,
response_model_exclude_unset=True,
dependencies=[Depends(Authority('user,check'))]
)
在接口上添加 Depends(Authority('user,check')) 依賴注入來判斷權限
- 操作權限認證
在接口中進行特殊權限認證,只要使用check_authority函數判斷即可,如果無權限會拋出異常
await check_authority(f'{request.state.user.username},auth,add')
配置
配置文件:
core/config/development_config.py 和 production_config.py
- 修改 API 文檔默認地址
為了通過權限認證,將 API 文檔地址修改為包含 openapi 的 URL
# 文檔地址 默認為docs
DOCS_URL: str = "/openapi/docs"
# 文檔關聯請求數據接口
OPENAPI_URL: str = "/openapi/openapi.json"
# redoc 文檔
REDOC_URL: Optional[str] = "/openapi/redoc"
- 超級管理員
設置用戶角色為 super 的用戶為超級管理員
SUPER_USER: str = 'super'
配置數據庫
# 數據庫配置
DATABASE_CONFIG: dict = {
'connections': {
# Dict format for connection
'default': 'mysql://root:123456@127.0.0.1:3306/testdb'
},
'apps': {
'models': {
# 設置key值“default”的數據庫連接
'default_connection': 'default',
'models': [
'apps.user.model',
'auth.casbin_tortoise_adapter'
]
}
}
}
數據庫使用 Tortoise-orm 庫,因為我一直在使用 Django,Django 自有一套 ORM 模型操作,用起來比較方便也比較熟悉,很多人使用 sqlalchemy,我覺得這個不方便,而 Tortoise-orm 是借鑒了 Django ORM 來實現的異步數據庫操作庫,對于使用了 Django 的人來講比較友好
運行
# 進入項目目錄
pipenv install
# 進入虛擬環境
pipenv shell
# 運行服務器
python run.py
總結
項目地址不方便貼,可以私信我,有什么好的建議或者問題都可以提出來,希望有人能共同完善。