Python / FastAPI маршрут ба параметр

FastAPI маршрут ба параметр

Өмнөх хичээлд FastAPI-ийн үндсийг сурсан. Энэ хичээлд маршрутыг илүү нарийвчлан судална — алдаа зохицуулах, хариуны загвар тодорхойлох, маршрутыг бүлэглэх. Эдгээр ойлголт нь бодит API бичихэд өдөр тутам хэрэглэгдэнэ.

HTTPException — алдаа зөв буцаах

Хэрэглэгч байхгүй өгөгдөл хүсэх, эрх хүрэхгүй байх зэрэг нөхцөлд зөв HTTP status кодтой алдаа буцааха хэрэгтэй:

python
from fastapi import FastAPI, HTTPException

app = FastAPI()

сурагчид = {
    1: {"нэр": "Болд", "xp": 150},
    2: {"нэр": "Сарнай", "xp": 320},
}

@app.get("/сурагч/{сурагч_id}")
def сурагч_авах(сурагч_id: int):
    if сурагч_id not in сурагчид:
        raise HTTPException(
            status_code=404,
            detail="Сурагч олдсонгүй"
        )
    return сурагчид[сурагч_id]

raise HTTPException(status_code=404) нь FastAPI-д зөв JSON алдааг автоматаар форматлан буцаана:

json
{
  "detail": "Сурагч олдсонгүй"
}

Хамгийн түгээмэл status кодууд: 400 (буруу хүсэлт), 401 (нэвтрээгүй), 403 (эрх хүрэхгүй), 404 (олдсонгүй), 422 (баталгаажуулалтын алдаа), 500 (серверийн алдаа).

Response model — хариуны загвар

Pydantic ашиглан API хэдийг буцааж болохыг тодорхой зааж өгнө. Энэ нь нууц талбарыг санамсаргүйгээр буцааснаас сэргийлдэг чухал механизм:

python
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class СурагчОруулга(BaseModel):
    нэр: str
    нас: int
    нууц_үг: str        # нууцлаг талбар

class СурагчХариу(BaseModel):
    id: int
    нэр: str
    нас: int
    # нууц_үг орхигдуулав — хэзээ ч гадагш гарахгүй

МЭДЭЭЛЭЛ = {}

@app.post("/сурагч", response_model=СурагчХариу)
def сурагч_үүсгэх(оруулга: СурагчОруулга):
    шинэ_id = len(МЭДЭЭЛЭЛ) + 1
    МЭДЭЭЛЭЛ[шинэ_id] = {
        "id": шинэ_id,
        **оруулга.model_dump()
    }
    return МЭДЭЭЛЭЛ[шинэ_id]
    # response_model нь нууц_үг-г автоматаар шүүж хасна

APIRouter — маршрутыг бүлэглэх

Бодит төсөлд бүх маршрутыг main.py-д бичвэл файл маш том болно. APIRouter ашиглан файлуудад тараана:

python
# routers/сурагчид.py
from fastapi import APIRouter, HTTPException

router = APIRouter(prefix="/сурагчид", tags=["Сурагчид"])

МЭДЭЭЛЭЛ = {}

@router.get("/")
def жагсаах():
    return list(МЭДЭЭЛЭЛ.values())

@router.get("/{id}")
def авах(id: int):
    if id not in МЭДЭЭЛЭЛ:
        raise HTTPException(status_code=404, detail="Олдсонгүй")
    return МЭДЭЭЛЭЛ[id]

@router.delete("/{id}")
def устгах(id: int):
    if id not in МЭДЭЭЛЭЛ:
        raise HTTPException(status_code=404, detail="Олдсонгүй")
    del МЭДЭЭЛЭЛ[id]
    return {"амжилт": True}
python
# main.py
from fastapi import FastAPI
from routers import сурагчид

app = FastAPI()
app.include_router(сурагчид.router)

prefix="/сурагчид" нь бүх маршрутад автоматаар /сурагчид угтвар нэмнэ. tags=["Сурагчид"] нь Swagger /docs дотор бүлэглэж харуулна.

Dependency injection — нийтлэг логикийг хуваалцах

Олон endpoint-т нэг ижил шалгалт хийх шаардлагатай үед Depends ашиглана:

python
from fastapi import FastAPI, Depends, HTTPException, Header
from typing import Optional

app = FastAPI()

def api_key_шалгах(x_api_key: Optional[str] = Header(None)):
    if x_api_key != "нууц-түлхүүр-123":
        raise HTTPException(status_code=401, detail="API key буруу")
    return x_api_key

@app.get("/нууц-өгөгдөл", dependencies=[Depends(api_key_шалгах)])
def нууц_өгөгдөл():
    return {"өгөгдөл": "зөвхөн зөв key-тэй хандах боломжтой"}

@app.get("/өөр-нууц", dependencies=[Depends(api_key_шалгах)])
def өөр_нууц():
    return {"мэдээлэл": "энэ ч гэсэн хамгаалагдсан"}

Depends() нь нэг удаа бичсэн шалгалтыг олон endpoint-т дахин ашиглах боломж олгодог — кодын давталтыг арилгана.

Дараагийн хичээлд:

FastAPI + өгөгдлийн сан — SQLite өгөгдлийн сантай холбогдох, өгөгдөл хадгалах, уншихын тулд sqlite3 болон Pydantic хэрхэн хамтран ажилладгийг сурна.