FastApi持續更新

Daydayup,ran發表於2021-07-04

image.png

FastAPI 框架,高效能,易於學習,高效編碼,生產可用
官方文件: https://fastapi.tiangolo.com
FastAPI 是一個用於構建 API 的現代、快速(高效能)的 web 框架,使用 Python 3.6+ 並基於標準的 Python 型別提示。
關鍵特性:

  • 快速:可與 NodeJSGo 比肩的極高效能(歸功於 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 # 更改埠號
image.png

二、程式碼執行伺服器除錯:

if __name__ == '__main__':
    import uvicorn

    uvicorn.run("main:app", reload=True, port=5555)

image.png

FastApi提供互動式Api文件一:這很方便我們管理自己的介面

現在訪問 http://localhost:8000/docs 就會生成一個Swagger文件
image.png

FastApi提供互動式Api文件二:這很方便我們管理自己的介面

現在訪問 http://127.0.0.1:8000/redoc 就會生成一個redoc文件
image.png
// todo:fastapi中何時用Path、Query、Header/Body

如果你想即「get」又「post」同時請求,你可以這麼做:

@app.api_route("/login", methods=("GET", "POST", "PUT"))
def login():
    """這是一個登陸介面"""
    return {"msg": "login success", "code": 200}

image.png

何時用「Form」,何時用「Body」,何時用「Header」呢

如果你你以表單的形式傳遞資料,那你就應該用「Form」,看一下程式碼

@app.post("/login1")
def login_form(username=Form(None), password=Form(None)):
    return {"username": username, "password": password}

image.png
如果你你以JSON的形式傳遞資料,那你就應該用「Body」,看一下程式碼

@app.post("/login")
def login(data=Body(None)):
    return {"data": data}

image.png
如果你你想傳遞「Header」資料,那你就應該用「Header」,看一下程式碼

@app.get("/user")
def user(id, num=Header(None)):
    return {"id": id, "num": num}

image.png

如何定製一個返回資訊,看程式碼

作用:就是將自己定義好的響應結果返回回來

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)

image.png

如何將自己寫的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)

image.png
如果你的程式碼中有引入到css樣式,你就可以向我這樣,你會發現樣式就被引入進來了

image.png如果你想自定義傳參進來,你可以試試這樣:

image.png

如果你想實現這樣的例子

Kapture 2021-07-04 at 11.28.05.gif

# 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)

image.png
在這裡我說一下為什麼要將狀態碼設定為302,如果你不設定這個status_code,瀏覽器傳送給後端的請求狀態碼為307,因為307的狀態碼是不能從post請求跳轉到get請求,原因是post請求如果要跳轉到get請求不通用,如果想進行跳轉,需要將307更改為302。
image.pngimage.png

# 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 %}

image.png

關聯資料庫,將資料儲存化

第一步:我們需要安裝依賴庫

pip install tortoise-orm
pip install aiomysq

第二步:電腦需要安裝mysql,安裝除錯過程不在贅述

以我為例:先建立一個db為fastapi的庫

create database fastapi;

image.png

第三步:配置資料庫

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)

image.png

例項一:將資料儲存到資料庫並返回給前端

# 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)

image.png
然後建立一個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 當每次修改資料後會更新本地時間

image.png
這時候我們來執行下程式碼:
Kapture 2021-07-04 at 16.36.46.gif
可以發現返回了,並沒有返回新增的資料,那我們再去資料庫看,點選資料庫更新按鈕後,可以發現我們的資料已經儲存到了表中表。
Kapture 2021-07-04 at 16.39.05.gif
image.png
可以看到資料庫已經存了我們提交的資料,現在我們只需要改一下index.html檔案一個地方就可以解決
image.png
最後效果
Kapture 2021-07-04 at 16.43.39.gif

相關文章