最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用FastAPI構(gòu)建高性能RESTful API的完整指南

 更新時(shí)間:2025年11月04日 09:24:23   作者:天天進(jìn)步2015  
FastAPI是一個(gè)現(xiàn)代、高性能的Python Web框架,專(zhuān)為構(gòu)建API而設(shè)計(jì),本指南將帶你從基礎(chǔ)到高級(jí),全面掌握FastAPI的使用,感興趣的小伙伴跟隨小編一起學(xué)習(xí)一下吧

引言

FastAPI是一個(gè)現(xiàn)代、高性能的Python Web框架,專(zhuān)為構(gòu)建API而設(shè)計(jì)。它基于標(biāo)準(zhǔn)的Python類(lèi)型提示,提供了自動(dòng)的API文檔生成、數(shù)據(jù)驗(yàn)證和序列化等強(qiáng)大功能。本指南將帶你從基礎(chǔ)到高級(jí),全面掌握FastAPI的使用。

為什么選擇FastAPI

FastAPI相比其他框架有以下顯著優(yōu)勢(shì):

  • 高性能: 性能可與NodeJS和Go媲美,是最快的Python框架之一
  • 開(kāi)發(fā)效率高: 比傳統(tǒng)框架減少約40%的開(kāi)發(fā)時(shí)間
  • 自動(dòng)文檔: 自動(dòng)生成交互式API文檔(Swagger UI和ReDoc)
  • 類(lèi)型安全: 基于Python類(lèi)型提示,提供編輯器自動(dòng)補(bǔ)全和類(lèi)型檢查
  • 標(biāo)準(zhǔn)化: 基于OpenAPI和JSON Schema標(biāo)準(zhǔn)
  • 異步支持: 原生支持async/await語(yǔ)法

環(huán)境搭建

安裝依賴(lài)

# 創(chuàng)建虛擬環(huán)境
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# 安裝FastAPI和ASGI服務(wù)器
pip install fastapi
pip install "uvicorn[standard]"

第一個(gè)API應(yīng)用

創(chuàng)建main.py文件:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

運(yùn)行應(yīng)用:

uvicorn main:app --reload

訪(fǎng)問(wèn)http://localhost:8000即可看到返回結(jié)果,訪(fǎng)問(wèn)http://localhost:8000/docs可以看到自動(dòng)生成的交互式文檔。

核心概念

路徑參數(shù)

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

FastAPI會(huì)自動(dòng)進(jìn)行類(lèi)型轉(zhuǎn)換和驗(yàn)證,如果item_id不是整數(shù),會(huì)返回清晰的錯(cuò)誤信息。

查詢(xún)參數(shù)

@app.get("/items/")
async def read_items(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

查詢(xún)參數(shù)在URL中以?skip=0&limit=10的形式傳遞。

請(qǐng)求體

使用Pydantic模型定義請(qǐng)求體:

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

@app.post("/items/")
async def create_item(item: Item):
    return item

Pydantic會(huì)自動(dòng)驗(yàn)證請(qǐng)求數(shù)據(jù),并提供清晰的錯(cuò)誤提示。

數(shù)據(jù)驗(yàn)證

使用Field進(jìn)行高級(jí)驗(yàn)證

from pydantic import BaseModel, Field

class Item(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    price: float = Field(..., gt=0, description="價(jià)格必須大于0")
    quantity: int = Field(default=1, ge=1, le=1000)
    tags: list[str] = Field(default_factory=list)

使用Query、Path和Body

from fastapi import Query, Path, Body

@app.get("/items/{item_id}")
async def read_item(
    item_id: int = Path(..., title="商品ID", ge=1),
    q: str | None = Query(None, min_length=3, max_length=50),
    size: int = Query(default=10, le=100)
):
    return {"item_id": item_id, "q": q, "size": size}

響應(yīng)模型

定義響應(yīng)結(jié)構(gòu)

class ItemResponse(BaseModel):
    id: int
    name: str
    price: float
    
    class Config:
        from_attributes = True

@app.post("/items/", response_model=ItemResponse)
async def create_item(item: Item):
    # 假設(shè)保存到數(shù)據(jù)庫(kù)后返回
    return {"id": 1, **item.dict()}

多種響應(yīng)狀態(tài)碼

from fastapi import status

@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
    return item

@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
    return None

錯(cuò)誤處理

拋出HTTP異常

from fastapi import HTTPException

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    if item_id not in items_db:
        raise HTTPException(
            status_code=404,
            detail="商品未找到",
            headers={"X-Error": "Item not found"}
        )
    return items_db[item_id]

自定義異常處理器

from fastapi.responses import JSONResponse
from fastapi import Request

class CustomException(Exception):
    def __init__(self, name: str):
        self.name = name

@app.exception_handler(CustomException)
async def custom_exception_handler(request: Request, exc: CustomException):
    return JSONResponse(
        status_code=418,
        content={"message": f"處理 {exc.name} 時(shí)出錯(cuò)"}
    )

依賴(lài)注入

基礎(chǔ)依賴(lài)

from fastapi import Depends

async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons

類(lèi)作為依賴(lài)

class Pagination:
    def __init__(self, skip: int = 0, limit: int = 100):
        self.skip = skip
        self.limit = limit

@app.get("/users/")
async def read_users(pagination: Pagination = Depends()):
    return {"skip": pagination.skip, "limit": pagination.limit}

數(shù)據(jù)庫(kù)會(huì)話(huà)依賴(lài)

from sqlalchemy.orm import Session

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users/")
async def read_users(db: Session = Depends(get_db)):
    users = db.query(User).all()
    return users

認(rèn)證和授權(quán)

JWT認(rèn)證示例

from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Security
import jwt

security = HTTPBearer()

def verify_token(credentials: HTTPAuthorizationCredentials = Security(security)):
    token = credentials.credentials
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return payload
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="無(wú)效的token")

@app.get("/protected/")
async def protected_route(payload: dict = Depends(verify_token)):
    return {"user": payload["sub"]}

OAuth2密碼流

from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # 驗(yàn)證用戶(hù)名和密碼
    user = authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(status_code=401, detail="用戶(hù)名或密碼錯(cuò)誤")
    
    access_token = create_access_token(data={"sub": user.username})
    return {"access_token": access_token, "token_type": "bearer"}

數(shù)據(jù)庫(kù)集成

SQLAlchemy集成

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, index=True)
    name = Column(String)

Base.metadata.create_all(bind=engine)

@app.post("/users/")
def create_user(user: UserCreate, db: Session = Depends(get_db)):
    db_user = User(**user.dict())
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

中間件

添加CORS中間件

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

自定義中間件

from fastapi import Request
import time

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

后臺(tái)任務(wù)

from fastapi import BackgroundTasks

def write_log(message: str):
    with open("log.txt", mode="a") as log:
        log.write(message + "\n")

@app.post("/send-notification/")
async def send_notification(
    email: str,
    background_tasks: BackgroundTasks
):
    background_tasks.add_task(write_log, f"通知發(fā)送到: {email}")
    return {"message": "通知將在后臺(tái)發(fā)送"}

文件上傳和下載

文件上傳

from fastapi import File, UploadFile

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    contents = await file.read()
    return {
        "filename": file.filename,
        "content_type": file.content_type,
        "size": len(contents)
    }

多文件上傳

@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile] = File(...)):
    return [{"filename": file.filename} for file in files]

測(cè)試

使用TestClient

from fastapi.testclient import TestClient

client = TestClient(app)

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Hello World"}

def test_create_item():
    response = client.post(
        "/items/",
        json={"name": "測(cè)試商品", "price": 99.99}
    )
    assert response.status_code == 201
    assert response.json()["name"] == "測(cè)試商品"

性能優(yōu)化

使用異步操作

import httpx

@app.get("/external-api/")
async def call_external_api():
    async with httpx.AsyncClient() as client:
        response = await client.get("https://api.example.com/data")
        return response.json()

數(shù)據(jù)庫(kù)查詢(xún)優(yōu)化

from sqlalchemy.orm import joinedload

@app.get("/users/{user_id}/posts/")
def get_user_posts(user_id: int, db: Session = Depends(get_db)):
    # 使用eager loading避免N+1查詢(xún)問(wèn)題
    user = db.query(User).options(
        joinedload(User.posts)
    ).filter(User.id == user_id).first()
    return user.posts

響應(yīng)緩存

from functools import lru_cache

@lru_cache(maxsize=128)
def get_settings():
    return Settings()

@app.get("/settings/")
def read_settings(settings: Settings = Depends(get_settings)):
    return settings

部署

使用Docker

創(chuàng)建Dockerfile:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

生產(chǎn)環(huán)境配置

# 使用Gunicorn + Uvicorn workers
# 命令行運(yùn)行:
# gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000

環(huán)境變量配置

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    app_name: str = "FastAPI應(yīng)用"
    database_url: str
    secret_key: str
    
    class Config:
        env_file = ".env"

settings = Settings()

最佳實(shí)踐

項(xiàng)目結(jié)構(gòu)

project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models/
│   │   ├── __init__.py
│   │   └── user.py
│   ├── schemas/
│   │   ├── __init__.py
│   │   └── user.py
│   ├── routers/
│   │   ├── __init__.py
│   │   └── users.py
│   ├── dependencies.py
│   └── database.py
├── tests/
├── requirements.txt
└── .env

使用APIRouter組織路由

from fastapi import APIRouter

router = APIRouter(
    prefix="/users",
    tags=["users"],
    responses={404: {"description": "Not found"}}
)

@router.get("/")
async def read_users():
    return [{"username": "user1"}]

@router.get("/{user_id}")
async def read_user(user_id: int):
    return {"user_id": user_id}

# 在main.py中
app.include_router(router)

版本控制

from fastapi import APIRouter

api_v1 = APIRouter(prefix="/api/v1")
api_v2 = APIRouter(prefix="/api/v2")

@api_v1.get("/items/")
async def get_items_v1():
    return {"version": "1.0"}

@api_v2.get("/items/")
async def get_items_v2():
    return {"version": "2.0", "data": []}

app.include_router(api_v1)
app.include_router(api_v2)

總結(jié)

FastAPI是一個(gè)強(qiáng)大而現(xiàn)代的Python Web框架,它結(jié)合了高性能、開(kāi)發(fā)效率和優(yōu)秀的開(kāi)發(fā)者體驗(yàn)。通過(guò)本指南,你已經(jīng)學(xué)習(xí)了:

  • FastAPI的核心概念和基礎(chǔ)用法
  • 數(shù)據(jù)驗(yàn)證和序列化
  • 依賴(lài)注入系統(tǒng)
  • 認(rèn)證和授權(quán)
  • 數(shù)據(jù)庫(kù)集成
  • 性能優(yōu)化技巧
  • 生產(chǎn)環(huán)境部署

繼續(xù)深入學(xué)習(xí)FastAPI的官方文檔,并在實(shí)際項(xiàng)目中應(yīng)用這些知識(shí),你將能夠構(gòu)建出高性能、可維護(hù)的RESTful API應(yīng)用。

以上就是使用FastAPI構(gòu)建高性能RESTful API的完整指南的詳細(xì)內(nèi)容,更多關(guān)于FastAPI構(gòu)建高性能API的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Django 自定義404 500等錯(cuò)誤頁(yè)面的實(shí)現(xiàn)

    Django 自定義404 500等錯(cuò)誤頁(yè)面的實(shí)現(xiàn)

    這篇文章主要介紹了Django 自定義404 500等錯(cuò)誤頁(yè)面的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Python使用XPath實(shí)現(xiàn)動(dòng)態(tài)屬性的精準(zhǔn)定位

    Python使用XPath實(shí)現(xiàn)動(dòng)態(tài)屬性的精準(zhǔn)定位

    在Web自動(dòng)化測(cè)試和數(shù)據(jù)爬取過(guò)程中,動(dòng)態(tài)生成的元素屬性常常讓定位工作變得棘手,本文將深入探討如何使用XPath的強(qiáng)大功能,結(jié)合Python實(shí)現(xiàn)動(dòng)態(tài)屬性的精準(zhǔn)定位,提供可復(fù)用的解決方案和實(shí)戰(zhàn)案例,有需要的可以了解下
    2026-04-04
  • Python TCP接收數(shù)據(jù)不全的問(wèn)題解決

    Python TCP接收數(shù)據(jù)不全的問(wèn)題解決

    本文主要介紹了Python TCP接收數(shù)據(jù)不全的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Python爬蟲(chóng)實(shí)現(xiàn)HTTP網(wǎng)絡(luò)請(qǐng)求多種實(shí)現(xiàn)方式

    Python爬蟲(chóng)實(shí)現(xiàn)HTTP網(wǎng)絡(luò)請(qǐng)求多種實(shí)現(xiàn)方式

    這篇文章主要介紹了Python爬蟲(chóng)實(shí)現(xiàn)HTTP網(wǎng)絡(luò)請(qǐng)求多種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Python獲取網(wǎng)頁(yè)內(nèi)容的靠譜方法

    Python獲取網(wǎng)頁(yè)內(nèi)容的靠譜方法

    如果你希望使用更加安全和可靠的方式下載網(wǎng)頁(yè)內(nèi)容,并且希望避免 requests 中的 SSL 問(wèn)題,有幾個(gè)替代方案和改進(jìn)方法,可以更好地處理 SSL 驗(yàn)證、證書(shū)問(wèn)題等,本文給大家介紹了幾種Python獲取網(wǎng)頁(yè)內(nèi)容的靠譜方法,需要的朋友可以參考下
    2025-02-02
  • Python的encode和decode使用指南

    Python的encode和decode使用指南

    在編程的浩瀚海洋中,字符編碼與解碼無(wú)疑是那塊最神秘、卻又最基礎(chǔ)的羅塞塔石碑,今天我們將徹底撕開(kāi)Python中 encode() 和 decode() 的華麗面具,直抵其二進(jìn)制靈魂的最深處,需要的朋友可以參考下
    2026-02-02
  • 基于Python制作一個(gè)文本翻譯器

    基于Python制作一個(gè)文本翻譯器

    translate非標(biāo)準(zhǔn)庫(kù)是python中可以實(shí)現(xiàn)對(duì)多種語(yǔ)言進(jìn)行互相翻譯的庫(kù),本文就將利用這個(gè)庫(kù)制作一個(gè)文本翻譯器,實(shí)現(xiàn)中譯英的功能,需要的可以參考一下
    2022-04-04
  • pytorch中的inference使用實(shí)例

    pytorch中的inference使用實(shí)例

    今天小編就為大家分享一篇pytorch中的inference使用實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • Python Flask結(jié)合前端Fetch搞定表單提交和頁(yè)面刷新

    Python Flask結(jié)合前端Fetch搞定表單提交和頁(yè)面刷新

    本文帶你深入理解現(xiàn)代前端 Fetch API 的工作原理,并手把手教你如何與 Flask 后端優(yōu)雅結(jié)合,實(shí)現(xiàn)無(wú)刷新登錄、數(shù)據(jù)動(dòng)態(tài)增刪改查等交互,感興趣的小伙伴可以了解下
    2025-12-12
  • 利用Python腳本實(shí)現(xiàn)批量將圖片轉(zhuǎn)換為WebP格式

    利用Python腳本實(shí)現(xiàn)批量將圖片轉(zhuǎn)換為WebP格式

    Python語(yǔ)言的簡(jiǎn)潔語(yǔ)法和庫(kù)支持使其成為圖像處理的理想選擇,本文將介紹如何利用Python實(shí)現(xiàn)批量將圖片轉(zhuǎn)換為WebP格式的腳本,WebP作為一種高效的圖像格式,能顯著減小文件大小,優(yōu)化網(wǎng)絡(luò)傳輸,需要的朋友可以參考下
    2025-06-06

最新評(píng)論

德昌县| 高雄市| 博客| 东安县| 衡阳市| 金山区| 衡山县| 昌宁县| 南靖县| 江孜县| 云安县| 长岭县| 易门县| 潞城市| 马龙县| 塔城市| 乐平市| 福建省| 龙川县| 澄城县| 紫阳县| 建德市| 宜宾市| 上思县| 余干县| 怀来县| 扶风县| 定远县| 巢湖市| 伊春市| 拉孜县| 化德县| 乌兰察布市| 凤台县| 资溪县| 桂阳县| 连平县| 元江| 霍城县| 浙江省| 田林县|