FastAPI 框架,高效能,易於學習,高效編碼,生產可用
官方文件: https://fastapi.tiangolo.com
FastAPI 是一個用於構建 API 的現代、快速(高效能)的 web 框架,使用 Python 3.6+ 並基於標準的 Python 型別提示。
關鍵特性:
- 快速:可與 NodeJS 和 Go 比肩的極高效能(歸功於 Starlette 和 Pydantic)。最快的 Python web 框架之一。
- 高效編碼:提高功能開發速度約 200% 至 300%。*
- 更少 bug:減少約 40% 的人為(開發者)導致錯誤。*
- 智慧:極佳的編輯器支援。處處皆可自動補全,減少除錯時間。
- 簡單:設計的易於使用和學習,閱讀文件的時間更短。
- 簡短:使程式碼重複最小化。通過不同的引數宣告實現豐富功能。bug 更少。
- 健壯:生產可用級別的程式碼。還有自動生成的互動式文件。
- 標準化:基於(並完全相容)API 的相關開放標準
安裝FastApi:
pip3 install fastapi
pip3 install unicorn
開始第一個Demo
# 建立一個main.py檔案
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello FastApi"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
執行伺服器:
一、命令執行伺服器:
uvicorn main:app --reload --port 8888 # 更改埠號
二、程式碼執行伺服器除錯:
if __name__ == '__main__':
import uvicorn
uvicorn.run("main:app", reload=True, port=5555)
FastApi提供互動式Api文件一:這很方便我們管理自己的介面
現在訪問 http://localhost:8000/docs 就會生成一個Swagger文件
FastApi提供互動式Api文件二:這很方便我們管理自己的介面
現在訪問 http://127.0.0.1:8000/redoc 就會生成一個redoc文件
// todo:fastapi中何時用Path、Query、Header/Body
如果你想即「get」又「post」同時請求,你可以這麼做:
@app.api_route("/login", methods=("GET", "POST", "PUT"))
def login():
"""這是一個登陸介面"""
return {"msg": "login success", "code": 200}
何時用「Form」,何時用「Body」,何時用「Header」呢
如果你你以表單的形式傳遞資料,那你就應該用「Form」,看一下程式碼
@app.post("/login1")
def login_form(username=Form(None), password=Form(None)):
return {"username": username, "password": password}
如果你你以JSON的形式傳遞資料,那你就應該用「Body」,看一下程式碼
@app.post("/login")
def login(data=Body(None)):
return {"data": data}
如果你你想傳遞「Header」資料,那你就應該用「Header」,看一下程式碼
@app.get("/user")
def user(id, num=Header(None)):
return {"id": id, "num": num}
如何定製一個返回資訊,看程式碼
作用:就是將自己定義好的響應結果返回回來
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/user")
def user():
return JSONResponse(content={"msg": "get user"}, # 內容
status_code=202, # 狀態碼,預設為200
headers={"a": "b"})
if __name__ == '__main__':
import uvicorn
uvicorn.run("04_response:app", reload=True)
如何將自己寫的html網站動態載入到fastapi(jinja2模板返回Html頁面)
我們需要安裝一些依賴庫
1、jinja2
pip install jinjia2
2、aiofiles
pip install aiofiles
廢話不多說,看程式碼
from fastapi import FastAPI, Requestfrom fastapi.templating import Jinja2Templates # 需要進入的庫from starlette.staticfiles import StaticFiles # 引入靜態檔案庫app = FastAPI()# 指定靜態檔案存放路徑app.mount("/page", StaticFiles(directory="page"), name="page")# 指定html 存放目錄template = Jinja2Templates("page")@app.get("/home")def home (req: Request): return template.TemplateResponse("index.html", context={"request": req})if __name__ == '__main__': import uvicorn uvicorn.run("d05_templates:app", reload=True)
如果你的程式碼中有引入到css樣式,你就可以向我這樣,你會發現樣式就被引入進來了
如果你想自定義傳參進來,你可以試試這樣:
如果你想實現這樣的例子
# main.pyfrom fastapi import FastAPI, Request, Formfrom fastapi.responses import RedirectResponsefrom fastapi.templating import Jinja2Templatesapp = FastAPI()template = Jinja2Templates("pages")todos = ["寫部落格", "看電影", "玩遊戲"]@app.get("/")async def index(req: Request): return template.TemplateResponse("index.html", context={"request": req, "todos": todos})@app.post("/todo")async def todo(todo=Form(None)): """處理使用者傳送過來的 todolist 資料""" todos.insert(0, todo) return RedirectResponse('/', status_code=302)if __name__ == '__main__': import uvicorn uvicorn.run("main:app", reload=True)
在這裡我說一下為什麼要將狀態碼設定為302,如果你不設定這個status_code,瀏覽器傳送給後端的請求狀態碼為307,因為307的狀態碼是不能從post請求跳轉到get請求,原因是post請求如果要跳轉到get請求不通用,如果想進行跳轉,需要將307更改為302。
# index.html <meta charset="UTF-8"> <title>Title</title><h1>待辦事項</h1><div> <form action="/todo" method="post"> <input name="todo" type="text" placeholder="請新增待辦事件..."> <input type="submit" value="新增"> </form></div> {% for todo in todos %} <p>{{ todo }}</p> {% endfor %}
關聯資料庫,將資料儲存化
第一步:我們需要安裝依賴庫
pip install tortoise-orm
pip install aiomysq
第二步:電腦需要安裝mysql,安裝除錯過程不在贅述
以我為例:先建立一個db為fastapi的庫
create database fastapi;
第三步:配置資料庫
from tortoise.contrib.fastapi import register_tortoise# 資料庫繫結register_tortoise(app, db_url="mysql://root:Ranyong_520@localhost:3306/fastapi", modules={"models": []}, add_exception_handlers=True, generate_schemas=True)
例項一:將資料儲存到資料庫並返回給前端
# d06_templates.pyfrom fastapi import FastAPI, Request, Formfrom fastapi.responses import RedirectResponsefrom fastapi.templating import Jinja2Templatesfrom tortoise.contrib.fastapi import register_tortoisefrom dao.models import Todoapp = FastAPI()template = Jinja2Templates("pages")# 資料庫繫結register_tortoise(app, db_url="mysql://root:Ranyong_520@localhost:3306/fastapi", modules={"models": ['dao.models']}, # 設定模型類 add_exception_handlers=True, generate_schemas=True)@app.get("/")async def index(req: Request): # 從資料庫獲取 todos 的程式碼 # ORM,獲取所有的 todos todos = await Todo.all() # 獲取所有的todos print(todos) return template.TemplateResponse("index.html", context={"request": req, "todos": todos})@app.post("/todo")async def todo(content=Form(None)): """處理使用者傳送過來的 todolist 資料""" await Todo(content=content).save() return RedirectResponse('/', status_code=302)if __name__ == '__main__': import uvicorn uvicorn.run("d06_templates:app", reload=True)
然後建立一個dao的資料夾裡面建立一個models的py檔案
from tortoise import Model, fields
class Todo(Model):
"""資料庫當中的表 todo"""
id = fields.IntField(pk=True) # id為int型別的 pk:是將id作為主鍵
content = fields.CharField(max_length=500) # todo項裡面的內容 例如:todos = ["寫部落格", "看電影", "玩遊戲"]
created_at = fields.DatetimeField(auto_now_add=True) # auto_now_add 當每次插入新資料的時候會引用本地時間
updated_at = fields.DatetimeField(auto_now=True) # auto_now 當每次修改資料後會更新本地時間
這時候我們來執行下程式碼:
可以發現返回了
可以看到資料庫已經存了我們提交的資料,現在我們只需要改一下index.html檔案一個地方就可以解決
最後效果