有一個很是簡單的需求:編寫一個 HTTP接口,使用 POST 方式發送一個 JSON 字符串,接口裏面讀取發送上來的參數,對其中某個參數進行處理,並返回。python
若是咱們使用 Flask 來開發這個接口,那麼代碼是這樣的:web
from flask import Flask, request
app = Flask(__name__)
@app.route('/insert', methods=['POST'])
def insert():
info = request.json
name = info['name']
age = info['age']
age_after_10_years = age + 10
msg = f'此人名叫:{name},10年後,此人年齡:{age_after_10_years}'
return {'success': True, 'msg': msg}
複製代碼
代碼看起來已經很簡潔了。咱們用requests
發個請求看看效果,以下圖所示:json
看起來沒什麼問題。flask
如今,我搞點破壞,把age
字段改爲字符串,再運行一下:api
不出所料,報錯了。瀏覽器
如今咱們把age
字段改回數字,可是直接移除name
字段:bash
又報錯了。app
爲了防止用戶不按規矩提交數據,咱們必需在接口裏面作好各類異常數據的判斷。因而增長判斷之後的代碼變得複雜了:框架
@app.route('/insert', methods=['POST'])
def insert():
info = request.json
name = info.get('name', '')
if not name:
return {'success': False, 'msg': 'name 參數不可省略,不可爲空!'}
age = info.get('age', 0)
if not isinstance(age, int):
return {'success': False, 'msg': 'age參數不是數字!'}
age_after_10_years = age + 10
msg = f'此人名叫:{name},10年後,此人年齡:{age_after_10_years}'
return {'success': True, 'msg': msg}
複製代碼
看來,用 Flask,雖然能讓你用很短的代碼寫出一個能工做的項目。但要寫成一個能夠正常使用的項目,仍是須要你本身寫更多代碼。異步
下面咱們來看一下,現代化的 web 框架:FaskApi
能把這個工程簡化到什麼程度:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class People(BaseModel):
name: str
age: int
address: str
salary: float
@app.post('/insert')
def insert(people: People):
age_after_10_years = people.age + 10
msg = f'此人名字叫作:{people.name},十年後此人年齡:{age_after_10_years}'
return {'success': True, 'msg': msg}
複製代碼
咱們仍是使用 requests 發一條信息給 FastApi 開發的 HTTP接口。對於正常數據,正常使用:
如今咱們把age
字段改爲字符串:
返回友好的提示信息,告訴我類型錯誤:age 字段不是 integer
。
咱們再試一試把name
字段去掉:
返回友好信息,提示值錯誤:name字段丟失
。
整個過程當中,對類型的檢查全都由 FastApi 本身完成。咱們省下來不少時間。
我用了 Flask 四年,但在使用了5分鐘 FastApi 之後,我決定之後再也不使用 Flask 了。
回過頭來,咱們好好介紹一下 FastApi。
使用pip
或者pipenv
便可安裝 FastApi:
pip install fastapi
pipenv install fastapi
複製代碼
安裝完成之後,咱們來完成第一個 API:
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
def index():
return {'message': '你已經正確建立 FastApi 服務!'}
複製代碼
這裏的寫法跟 Flask 幾乎一致。只不過在 Flask 中,咱們定義路由的裝飾器爲@app.route('/')
。而這裏寫爲@app.get('/')
以下圖所示:
寫好代碼之後,咱們須要使用uvicorn
來運行 FastApi。首先使用pip
或者pipenv
安裝uvicorn
:
pip install uvicorn
pipenv install uvicorn
複製代碼
而後執行命令:
uvicorn main:app --reload
複製代碼
其中main
表示咱們的代碼文件爲main.py
,app
表示咱們初始化的FastApi 對象的名字。--reload
參數表示在修改了代碼之後當即生效,不須要重啓。
運行命令之後,咱們訪問http://127.0.0.1:8000
能夠看到接口已經正確返回了 JSON 格式的數據:
那麼如何定義一個帶參數的 GET 方法呢?咱們再寫一段代碼:
@app.get('/query/{uid}')
def query(uid):
msg = f'你查詢的 uid 爲:{uid}'
return {'success': True, 'msg': msg}
複製代碼
寫好代碼之後,咱們直接在瀏覽器裏面訪問新的地址,能夠看到修改已經生效了,以下圖所示:
若是想限定uid 只能是數字,不能是字符串怎麼辦呢?你只須要多加4個字符
:
@app.get('/query/{uid}')
def query(uid: int):
msg = f'你查詢的 uid 爲:{uid}'
return {'success': True, 'msg': msg}
複製代碼
對函數query
的參數使用類型標註,標註爲 int 類型。如今咱們再來訪問一下接口:
當 query 後面的參數不是整數時,正常報錯了。
咱們再來看一下本文一開始的 POST 方法。在使用 Flask 的時候,咱們須要手動驗證用戶 POST 提交上來的數據是什麼格式的,字段對不對。
但使用 FastApi 的時候,咱們只須要類型標註就能解決全部問題。首先咱們導入from pydantic import BaseModel
,而後繼承BaseModel
實現咱們容許 POST 方法提交上來的數據字段和格式:
from pydantic import BaseModel
app = FastAPI()
class People(BaseModel):
name: str
age: int
address: str
salary: float
複製代碼
People
這個類經過類型標註,指定了它裏面的4個字段和他們的類型。如今,咱們來實現 POST 方法:
@app.post('/insert')
def insert(people: People):
age_after_10_years = people.age + 10
msg = f'此人名字叫作:{people.name},十年後此人年齡:{age_after_10_years}'
return {'success': True, 'msg': msg}
複製代碼
insert
函數的參數people
經過類型標註指定爲People
類型。
當咱們使用 POST 方式提交數據時,FastApi 自動會以People
中定義的字段爲基準來校驗數據,發現不對就返回報錯信息。
除了開發接口變得很是簡單外,FastApi 還會自動幫咱們生成接口文檔。你們訪問http://127.0.0.1:8000/docs
,能夠看到接口文檔已經自動生成好了:
這個接口不只能看,並且直接就能在接口頁面修改樣例數據,發送請求,現場測試:
以上是對 FastApi 的極簡介紹。有興趣的同窗能夠查閱它的官方文檔
最後,告訴你們,FastApi 是一個異步 Web 框架,它的速度很是很是很是快。遠遠超過 Flask。
FastApi 是最快的幾個 Web 框架之一。速度能夠匹敵 Golang寫的接口。詳細的對比能夠看:one of the fastest Python frameworks available