๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Back-end & Server/FastAPI

[FastAPI] ํŒŒ์ผ ๋ถ„ํ• 

728x90
๋ฐ˜์‘ํ˜•

 

๐Ÿฐ FastAPI ๊ณต์‹๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด์„œ ๊ฐœ์ธ์ ์œผ๋กœ ์ •๋ฆฌํ•œ ๊ธ€ ์ž…๋‹ˆ๋‹ค.

 

FastAPI๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๊ธฐ๋Šฅ์ด ๋งŽ๊ณ  ๊ทœ๋ชจ๊ฐ€ ํฌ๋ฉด ์ฝ”๋“œ ๊ด€๋ฆฌ๊ฐ€ ํž˜๋“ค๋‹ค. ์ด๋•Œ๋Š” ํŒŒ์ผ์„ ๋ถ„ํ• ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.

 

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒŒ์ผ์„ ๋ถ„๋ฆฌํ•œ๋‹ค. 

 

 

routers - API ์—”๋“œํฌ์ธํŠธ

from fastapi import APIRouter

router = APIRouter()


@router.get("/users/", tags=['users'])
async def read_items():
    return [{'username': 'Abdule'}, {'username': 'Bubi'}, {'username': 'Collson'}]


@router.get("/users/me", tags=['users'])
async def read_users_me():
    return {'username': 'Pupba'}


@router.get("/users/{username}", tags=['users'])
async def read_users(username: str):
    return {'username': username}

 

APIRouter ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ API ์—”๋“œํฌ์ธํŠธ๋ฅผ ์„ ์–ธํ•˜๊ณ  router ์ธ์Šคํ„ด์Šค๋ฅผ FastAPI app์— ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

Dependencies - ์ข…์†์„ฑ ์ •์˜

from typing import Annotated
from fastapi import Header, HTTPException


async def get_token_header(x_token: Annotated[str, Header()]):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")


async def get_query_token(token: str):
    if token != "jessica":
        raise HTTPException(
            status_code=400, detail="No Jessica token provided")

 

์ข…์†์„ฑ์„ ์ •์˜ํ•˜์—ฌ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

import json
from fastapi import APIRouter, Depends, HTTPException
from ..dependencies import get_token_header
from typing import Dict

router = APIRouter(
    prefix='/items',
    tags=['items'],
    dependencies=[Depends(get_token_header)],
    responses={404: {"description": "Not found"}}
)

path = "./routers/fake_db.json"
with open(path) as f:
    json_object = dict(json.load(f))['items']


def findItem(target: str) -> dict:
    result: dict = {}
    for i in json_object:
        if list(i.values())[0] == target:
            result = i
            break
    return result


@router.get("/items/", response_model=Dict[str, str])
async def read_items():
    return json_object


@router.get("/{item_name}/", response_model=Dict[str, str])
async def read_item(item_name: str):
    result: dict = findItem(item_name)
    if result == {}:
        raise HTTPException(status_code=404, detail="Item not found")
    return result


@router.put(
    "{item_name}",
    tags=['custom'],
    responses={403: {"description": "Operation forbidden"}}
)
async def update_item(item_name: str):
    result: dict = findItem(item_name)
    if {} == result:
        raise HTTPException(
            status_code=403, detail="You can only update the item: plumbus")
    return {item_name: "Banana"}

 

APIRouter์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์—ฌ ์—”๋“œํฌ์ธํŠธ์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • prefix : APIRouter์— ์†ํ•œ ์—”๋“œํฌ์ธํŠธ๋“ค์˜ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •, ex. '/items' -> '/items/{item_name}
  • tags : APIRouter์— ์†ํ•œ ์—”๋“œํฌ์ธํŠธ๋“ค์˜ tags๋ฅผ ์„ค์ •, ์—”๋“œํฌ์ธํŠธ ๊ทธ๋ฃนํ™”์— ์‚ฌ์šฉ
  • dependencies : APIRouter์— ์†ํ•œ ์—”๋“œํฌ์ธํŠธ๋“ค์˜ ์˜์กด์„ฑ์„ ์„ค์ •
  • responses : APIRouter์— ์†ํ•œ ์—”๋“œํฌ์ธํŠธ๋“ค์˜ ์‘๋‹ต์— ๋Œ€ํ•œ ์„ค์ •

 

 

Main - ๋ฉ”์ธ APP

์•ž์— ๋งŒ๋“  ๋ชจ๋“ˆ๋“ค์„ ์‹คํ–‰ํ•  ๋ฉ”์ธ APP์„ ์ •์˜ํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

๊ทธ ์ „์— internal ํด๋”๋ฅผ ๋งŒ๋“ค์–ด ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์™€ ๊ณต์œ ํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ ์ •์˜ ํŒŒ์ผ์„ ์„ ์–ธํ•˜๊ณ  ๋ฉ”์ธ์—์„œ ์ˆ˜์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ธฐ์กด ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

from fastapi import APIRouter

router = APIRouter()

@router.post("/")
async def update_admin():
    return {"message": "Admin getting schwifty"}

 

์ด๋ ‡๊ฒŒ ์ •์˜ํ•œ ํŒŒ์ผ์„ main์—์„œ prefix, tags ๋“ฑ์„ ์ˆ˜์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

from fastapi import Depends, FastAPI

from .dependencies import get_query_token, get_token_header
from .internal import admin
from .routers import items, users

app = FastAPI(dependencies=[Depends(get_query_token)])

app.include_router(users.router)
app.include_router(items.router)
app.include_router(
    admin.router,
    prefix="/admin",
    tags=["admin"],
    dependencies=[Depends(get_token_header)],
    responses={418: {"description": "I'm a teapot"}},
)


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

 

app์˜ include_router๋ฅผ ํ†ตํ•ด ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ •์˜ํ•œ router ์ธ์Šคํ„ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ admin ๋ถ€๋ถ„์ฒ˜๋Ÿผ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ internal ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

728x90
๋ฐ˜์‘ํ˜•

'Back-end & Server > FastAPI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[FastAPI] Template  (0) 2024.02.23
[FastAPI] Background Task  (0) 2024.02.23
[FastAPI] Relational Database  (0) 2024.02.22
[FastAPI] ๋ฏธ๋“ค์›จ์–ด  (0) 2024.02.20
[FastAPI] ๊ฒฝ๋กœ ์ž‘๋™ ์„ค์ •  (0) 2024.02.20