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