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

Back-end & Server/FastAPI

[FastAPI] ๋งค๊ฐœ๋ณ€์ˆ˜

728x90
๋ฐ˜์‘ํ˜•

 

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

 

Swagger UI / ReDoc

FastAPI๋Š” /docs๋ฅผ ํ†ตํ•ด API ๋ฌธ์„œ์™€ API๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋Š” Swagger UI ํŽ˜์ด์ง€๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

๋˜ /redoc๋กœ ReDoc ํŽ˜์ด์ง€๋„ ์ œ๊ณตํ•œ๋‹ค.

 

 

 

๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜

FastAPI๋Š” ํŒŒ์ด์ฌ ํ‘œ์ค€ Type Annotation์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฝ๋กœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜์— ์žˆ๋Š” ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด FastAPI๋Š” ์ž๋™์œผ๋กœ ์ „๋‹ฌ ๋ฐ›์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํŒŒ์‹ฑํ•œ๋‹ค.

from fastapi import FastAPI

app = FastAPI()

@app.get("/test/{item_id}")
async def apiTest(item_id: int):
    return {"item_id": item_id}
http://127.0.0.1/test/3

 

item_id๋ฅผ int๋กœ ํƒ€์ž…์„ ์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „๋‹ฌ ๋ฐ›์€ 3์„ int ํƒ€์ž…์œผ๋กœ ํŒŒ์‹ฑํ•œ ๋ชจ์Šต์ด๋‹ค.

 

์ •์˜ํ•œ ํƒ€์ž… ๋Œ€์‹  ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•˜์—ฌ ์ž˜๋ชป๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ ค์ค€๋‹ค.

(๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์€ Pydantic์— ์˜ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค.)

 

routing(๊ฒฝ๋กœ์„ค์ •)์‹œ ์ˆœ์„œ๋ฅผ ์ž˜ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค. 

{item_id} ๊ฐ™์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ๋กœ์™€ ๊ณ ์ •์ ์ธ ๊ฒฝ๋กœ๊ฐ€ ์žˆ์„ ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์ œ์ผ ์•ž์— ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.

from fastapi import FastAPI

app = FastAPI()

@app.get("/test/{item_id}")
async def apiTest1(item_id: str):
    return {"item_id": item_id}


@app.get("/test/hello")
async def apiTest2():
    return {"msg": "์•ˆ๋…•ํ•˜์„ธ์š”"}

๋งŒ์•ฝ ๊ณ ์ •๊ฒฝ๋กœ๊ฐ€ ๋จผ์ € ๋‚˜์˜ค๋ฉด item_id์˜ ๊ฐ’์ด ๊ณ ์ • ๊ฒฝ๋กœ(hello)๋กœ ์ธ์‹ํ•œ๋‹ค.

 

๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์ „์— ์ •์˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด enum(์—ด๊ฑฐํ˜•)์„ ์‚ฌ์šฉํ•˜๋ฉด๋œ๋‹ค.

from fastapi import FastAPI
from enum import Enum
# models
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier

app = FastAPI()


class ModelName(str, Enum):
    rfc = "RandomForestClassifier"
    logistic = "LogisticRegression"
    tree = "DecisionTreeClassifier"


@app.get("/models/{model_name}")
async def getModel(model_name: ModelName):
    if model_name is ModelName.rfc:
        return {"model_name": "RandomForestClassifier", "model": RandomForestClassifier()}
    if model_name.value == ModelName.logistic:
        return {"model_name": "XGBClassifier", "model": LogisticRegression()}
    if model_name.value == ModelName.tree:
        return {"model_name": "DecisionTreeClassifier", "model": DecisionTreeClassifier()}
    return {"message": "Invalid model name"}

 

 

Starlette์˜ ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

from fastapi import FastAPI

app = FastAPI()


@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
    return {"file_path": file_path}

 

 

์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜

๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด "์ฟผ๋ฆฌ" ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ž๋™ ํ•ด์„ํ•œ๋‹ค.

์ฟผ๋ฆฌ๋Š” URL์—์„œ ?ํ›„์— ๋‚˜์˜ค๊ณ  &์œผ๋กœ ๊ตฌ๋ถ„๋˜๋Š” ํ‚ค-๊ฐ’ ์Œ์˜ ์ง‘ํ•ฉ์ด๋‹ค.

from fastapi import FastAPI

app = FastAPI()

fakeDB = [{"item1": "foo"}, {"item2": "bar"}, {"item3": "baz"}]


@app.get("/items")
async def readItem(skip: int = 0, limit: int = 10):
    return fakeDB[skip:skip+limit]

 

"ํŽธ์ง‘๊ธฐ, ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ, ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ, ์ž๋™๋ฌธ์„œํ™”"๋ฅผ ์ง€์›ํ•œ๋‹ค.

 

 

Query, Path, Field ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ

Query ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ : ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: str = Query(..., min_length=3, max_length=50)):
    return {"q": q}

 

...์€ ๊ธฐ๋ณธ๊ฐ’

min_length์™€ max_length๋กœ ๋ฌธ์ž์—ด์˜ ๊ธธ์ด ์ œํ•œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. (q์˜ ๊ธธ์ด๊ฐ€ 3๊ฐœ)

 

 

Path ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ : ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int = Path(..., gt=0)):
    return {"item_id": item_id}

 

...์€ ๊ธฐ๋ณธ๊ฐ’

gt=0์€ 0 ์ดˆ๊ณผ์˜ ๋œป(ge, lt, le, ...)

 

 

Field ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ : ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์˜ ํ•„๋“œ๋ฅผ ์„ธ๋ถ€์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str = Field(..., title="์ƒํ’ˆ๋ช…",
                      description="์ƒํ’ˆ์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.", min_length=3, max_length=50)
    price: int = Field(..., title="๊ฐ€๊ฒฉ", description="์ƒํ’ˆ์˜ ๊ฐ€๊ฒฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”.", gt=0)


items: list = []


@app.post("/items/")
async def create_item(item_id: int, item: Item):
    results: dict = {"item_id": item_id, "item": item}
    items.append(results)
    return {"message": "good"}


@app.get("/items/{item_id}")
async def get_item(item_id: int):
    result: Item = None
    for item in items:
        if item['item_id'] == item_id:
            result: Item = item['item']
            break
    return result

 

 

Cookie ๋งค๊ฐœ๋ณ€์ˆ˜

Cookie ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ฟ ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

from fastapi import FastAPI, Cookie, HTTPException
from fastapi.responses import Response
app = FastAPI()

# ์ฟ ํ‚ค ์ƒ์„ฑ
@app.get("/set-cookie")
async def set_cookie():
    response = Response("Create Cookie")
    response.set_cookie(key="ads_id", value="abc123")
    return response

# ์ฟ ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ
@app.get("/items/")
async def read_items(ads_id: str = Cookie(None)):
    if ads_id is None:
        raise HTTPException(status_code=400, detail="Ads ID๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.")
    return {"ads_id": ads_id}

 

 

 

Header ๋งค๊ฐœ๋ณ€์ˆ˜

FastAPI์—์„œ ์š”์ฒญ์˜ ํ—ค๋” ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

ํŠน์ • ํ—ค๋” ๊ฐ’์„ ํ•„์š”๋กœ ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/items/")
async def read_items(user_agent: str = Header(default=None)):
    return {"user_agent": user_agent}

 

728x90
๋ฐ˜์‘ํ˜•

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

[FastAPI] Form  (0) 2024.02.20
[FastAPI] ๋ชจ๋ธ  (0) 2024.02.20
[FastAPI] ๋™์‹œ์„ฑ๊ณผ async / await  (0) 2024.02.19
[FastAPI] ํƒ€์ž… ์ง€์ •, Pydantic  (0) 2024.02.19
[FastAPI] ๊ฐœ์š”  (0) 2024.02.19