๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐™‹๐™ฎ๐™ฉ๐™๐™ค๐™ฃ/๐™๐™–๐™จ๐™ฉ ๐˜ผ๐™‹๐™„

Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #3 pydantic, query, request body

by beomcoder 2023. 2. 23.
728x90
๋ฐ˜์‘ํ˜•

 

 

Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #2 ๊ฒฝ๋กœ ๋™์ž‘ ์ƒ์„ฑ

Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #1 ํŠน์ง• ๋ฐ ์„ค์น˜ ๋ฐฑ์—”๋“œ๋กœ Django, flask๋งŒ ์‚ฌ์šฉํ•˜๋‹ค๊ฐ€ ๊ฐ€๋ณ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ์— Fast API๋„ ์ข‹๋‹ค๊ณ  ํ•˜์—ฌ ํ•œ๋ฒˆ ๊ณต๋ถ€ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค. ์ฃผ์š” ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๊ณ  ํ•œ๋‹ค. ์šฐ์„ ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ

beomcoder.tistory.com

REST APIํ˜•์‹์œผ๋กœ ํ•œ๋ฒˆ ์‚ฌ์šฉํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค. ๋จผ์ € pydantic์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.

pydantic์€ ํƒ€์ž… ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ฆํ•˜๊ณ  ์„ค์ •๋“ค์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. 

pydantic์€ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์—์„œ ํƒ€์ž…์„ ๊ฐ•์ œํ•˜๊ณ  ํƒ€์ž…์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๋•Œ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์ค€๋‹ค.

FastAPI, Project Jupyter, Microsoft, AWS ๋“ฑ ๋งŽ์€ ๊ณณ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

 

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None
    
app = FastAPI()

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

 

๊ทธ๋ฆฌ๊ณ  ํฌ์ŠคํŠธ๋งจ์œผ๋กœ ํ•œ๋ฒˆ ํ…Œ์ŠคํŠธํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค. ํฌ์ŠคํŠธ๋งจ์€ ๋‹ค๋ฅธ๋ถ„์˜ ๋ธ”๋กœ๊ทธ์— ์ž˜ ์จ์ ธ ์žˆ๋‹ค.

ํฌ์ŠคํŠธ๋งจ์— ๋Œ€ํ•ด์„œ๋„ ๊ธ€์„ ์“ฐ๊ธฐ์—” ๊ท€์ฐฎ๋‹ค.

 

 

ํฌ์ŠคํŠธ๋งจ(postman) ์‚ฌ์šฉ๋ฒ•(์„ค์น˜, ๋‹ค์šด๋กœ๋“œ)

์ „๋ถ€ํ„ฐ ์›น ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ ์•„์ฃผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ–ˆ๋˜ ํ”„๋กœ๊ทธ๋žจ(์„œ๋น„์Šค)๊ฐ€ ์žˆ์–ด ์†Œ๊ฐœํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ ํฌ์ŠคํŠธ๋งจ(postman)์ž…๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด http(https ํฌํ•จ) ์š”์ฒญ์„ ๋‚ ๋ฆฌ๊ณ  ์‘๋‹ต์„ ๋ณด์—ฌ์ฃผ๋Š” ์„œ

nhj12311.tistory.com

 

 

ํ˜•์‹์„ ๋งž์ถฐ์„œ ์ž˜ ์จ์ฃผ๋ฉด ์ž˜ ๋œ๋‹ค.

pydantic์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•ด๋ณด๋ฉด

 

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str  
    # str๋‹ค์Œ์— = OOO์œผ๋กœ default๊ฐ’์ด ์—†์œผ๋ฉด ํ•„์ˆ˜๋กœ ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.
    
    description: Union[str, None] = None 
    # strํ˜•์œผ๋กœ ์ ์–ด์•ผ default๊ฐ’์ด ์žˆ์œผ๋ฏ€๋กœ ์ ์–ด๋„ ๋˜๊ณ  ์ ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
    
    price: float
    tax: Union[float, None] = None

 

๋ณ€์ˆ˜๋ฅผ ์ ๊ณ  ํƒ€์ž…์„ ์ ๊ณ  default๊ฐ’์„ ์ ์–ด์ฃผ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋ณด๋‚ด๋Š”์ชฝ์—์„œ ๋ฌด์กฐ๊ฑด ์ ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

ํƒ€์ž… ๋‹ค์Œ์— = None, '๊น€์•„๋ฌด๊ฐœ' ๋“ฑ์œผ๋กœ default๊ฐ’์ด ์žˆ๋‹ค๋ฉด ์ ์ง€ ์•Š์•„๋„ ๊ดœ์ฐฎ๋‹ค.

 

์ฟผ๋ฆฌ๋ฌธ์œผ๋กœ ์กฐ๊ธˆ ๋” ์ž์„ธํ•˜๊ฒŒ ๊ฐ’์˜ ๋ฒ”์œ„๋ฅผ ์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

DB์— 50๊ธ€์ž๊นŒ์ง€ ์ €์žฅํ•˜๊ฒŒ ํ•ด๋†“์•˜๋Š”๋ฐ ๊ธ€์ž์ˆ˜๊ฐ€ ๋งŽ๋‹ค๊ฑฐ๋‚˜

๋‚˜์ด๋ฅผ ์ €์žฅํ•˜๋Š”๋ฐ ์Œ์ˆ˜๊ฐ’์ด ๋“ค์–ด์˜ค๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ฏธ์—ฐ์— ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ฐธ๊ณ ๋กœ ์ฟผ๋ฆฌ๋ฌธ์€ body์— ๋ณด๋‚ด๋ฉด ์ฟผ๋ฆฌ๋กœ ๋ณด๋‚ด๋ผ๊ณ  ์•Œ๋ ค์ค€๋‹ค.

Query๋ผ๊ณ  ๊ฐ์‹ธ์ง„ ๊ฐ’์€ ์ด๋Ÿฐ์‹์œผ๋กœ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค.

from typing import Union
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

๊ฐ„๋‹จํ•œ ๋ถ€๋ถ„์€ ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์˜ˆ์ œ๊ฐ€ ๋‚˜์™€์žˆ๋‹ค.

 

q: Union[str, None] = Query(default=None, max_length=50)

 

q๋ฅผ ๋ฐ›๋Š”๋ฐ, ํƒ€์ž…์€ strํ˜•์ด๊ฑฐ๋‚˜ None์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  default๊ฐ’์€ None์ด๊ณ , q๋Š” 50๊ธ€์ž๊นŒ์ง€๋งŒ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ด์„ํ•˜๋ฉด ๋œ๋‹ค.

 

from typing import Union
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(
        default=None, min_length=3, max_length=50, regex="^fixedquery$"
    )
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

์ด๊ฑด ์ •๊ทœ์‹์ธ๋ฐ ๋‚˜๋Š” ์ž˜ ์•ˆ์“ธ ๊ฒƒ ๊ฐ™๋‹ค.

regex์— ์ •๊ทœ์‹์„ ์“ฐ๋ฉด ๋œ๋‹ค.

 

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(
        default=None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
    )
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

 

title๊ณผ description์€ ํ•จ์ˆ˜์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๋Š” ๋ณ€์ˆ˜์ด๋‹ค.

๋‚˜์ค‘์— ๋ณธ์ธ์ด ์•Œ์•„ ๋จน์„ ์ˆ˜ ์žˆ๊ฒŒ ์ ์–ด๋†“๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•˜๋‹ค.

๋ณ€์ˆ˜๊ฐ’์ด๋ผ์„œ ๋ณด๋‚ด๋Š”์ชฝ์—์„œ title๊ณผ description์— ๊ฐ’์„ ๋„ฃ์–ด์„œ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

 

from fastapi import FastAPI, Path, Query

app = FastAPI()


@app.get("/items/{item_id}")
async def read_items(
    *,
    item_id: int = Path(title="The ID of the item to get", ge=0, le=1000),
    q: str,
    size: float = Query(gt=0, lt=10.5)
):
    results = {"item_id": item_id, "size": size}
    if q:
        results.update({"q": q})
    return results

 

๊ทธ๋ฆฌ๊ณ  Query์™€ ๋น„์Šทํ•˜๊ฒŒ Path๋ผ๋Š” ๊ฒƒ๋„ ์žˆ๋‹ค.

์ด ์ฝ”๋“œ์—์„œ๋Š” ์„ค๋ช…ํ•  ๋ถ€๋ถ„์ด ์กฐ๊ธˆ ์žˆ๋‹ค.

๋จผ์ €

 

1. read_items( *, :

์ด๊ฑฐ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ์—†๋Š” ๋ณ€์ˆ˜ ์•ž์— ๊ธฐ๋ณธ๊ฐ’์ด ์žˆ๋Š” ๋ณ€์ˆ˜๊ฐ€ ๋“ค์–ด์˜ฌ ์ˆ˜ ์—†๋Š”๋ฐ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฌธ๋ฒ•์ด๋‹ค.

q๋Š” default๊ฐ’์ด ์—†๊ณ , item_id๋Š” default๊ฐ’์ด ์žˆ๋‹ค.๊ทธ๋ƒฅ q์™€ item_id์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๋ฉด ํ•ด๊ฒฐ๋  ์ผ์ด์ง€๋งŒ ์‹ ๊ธฐํ•œ ๋ฌธ๋ฒ•์ด๋ผ ํ•œ๋ฒˆ ์‚ฌ์šฉํ•ด๋ณธ๋‹ค.

 

2. Path :

Path๋Š” ๊ฒฝ๋กœ๋งค๊ฐœ๋ณ€์ˆ˜์— ์‚ฌ์šฉํ•œ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ์ ํ˜€์žˆ๋“ฏ์ด ๊ฒฝ๋กœ์— ์ ์–ด์ฃผ๋Š” ๋ณ€์ˆ˜์ด๋‹ค.

 

ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์œ„ ์‚ฌ์ง„๊ณผ ๊ฐ™๋‹ค.

์—ฌ๊ธฐ์„œ๋„ ์ •ํ•ด์ฃผ์—ˆ๋˜ 0<= item_id <= 1000, 0< size <10.5๋ฅผ ์ง€์ผœ์ฃผ์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Path๋ผ๊ณ  ์จ์ฃผ์—ˆ๋˜๊ฑด ๊ผญ ๊ฒฝ๋กœ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ ์–ด์ฃผ์–ด์•ผ ํ•˜๊ณ , Query๋กœ ์„ ์–ธํ•œ๊ฑด Query์— ๋ณด๋‚ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

3. ge, gt, lt, le:

ge๋Š” greater than or equal์˜ ์•ฝ์ž์ด๋‹ค. ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ( >= ) ์˜ ์˜๋ฏธ๋‹ค.

gt๋Š” greater than์˜ ์•ฝ์ž์ด๋‹ค. ์ปค์•ผ ํ•œ๋‹ค๋Š” ( > ) ์˜ ์˜๋ฏธ๋‹ค.

lt์™€ le๋Š” ์ž‘๊ฑฐ๋‚˜, ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€์˜ ์˜๋ฏธ๋‹ค. 

 

 

๋‹ค์Œ์—” ์ด์ œ body์— ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ์ž์„ธํ•˜๊ฒŒ ๊ณต๋ถ€ํ•ด๋ณธ๋‹ค.

 

Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #4 body ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ฃผ๊ณ  ๋ฐ›๊ธฐ

Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #3 pydantic, query, request body Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #2 ๊ฒฝ๋กœ ๋™์ž‘ ์ƒ์„ฑ Fast API ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ #1 ํŠน์ง• ๋ฐ ์„ค์น˜ ๋ฐฑ์—”๋“œ๋กœ Django, flask๋งŒ ์‚ฌ์šฉํ•˜๋‹ค๊ฐ€ ๊ฐ€๋ณ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ์— Fast API๋„ ์ข‹๋‹ค๊ณ  ํ•˜์—ฌ

beomcoder.tistory.com

 

 

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€