
๐ฐ FastAPI ๊ณต์๋ฌธ์๋ฅผ ๋ณด๋ฉด์ ๊ฐ์ธ์ ์ผ๋ก ์ ๋ฆฌํ ๊ธ ์
๋๋ค.
Metadata Docs
/docs๋ก ์ ์ํ์ ๋ ๋์ค๋ Swagger UI ํ์ด์ง์ Metadata๋ฅผ ์ถ๊ฐํ ์ ์๋ค.
FastAPI()์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ๋ฉด ๋๋ค.
Parameter | Type | Description |
title | str | API์ ์ ๋ชฉ |
summary | str | API ์์ฝ |
description | str | API ์ค๋ช |
version | string | API ๋ฒ์ |
terms_of_service | str | API์ ์ฝ๊ด์ URL |
contact | dict | API ๊ด๋ จ ์ฐ๋ฝ์ ๋ณด, fields -> (name:str, url:str, email:str) |
license_info | dict | API ๊ด๋ จ ๋ผ์ด์ผ์ค ์ ๋ณด, fields -> (name:str, identifier:str, url:str) |
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
description = """
Jinja2 Template & Static Test. ๐
## Template
Use -> **Jinja2Templates()**
## Static
Use -> StaticFiles()
Thank You..!
"""
app = FastAPI(
title="Jinja2Template & Static Test App",
description=description,
summary="I like FastAPI...",
version="0.0.1",
terms_of_service="http://example.com/terms/",
contact={
"name": "Pupba",
"url": "http://x-force.example.com/contact/",
"email": "pupba13@x-force.example.com"
},
license_info={
"name": "MIT",
"url": "https://opensource.org/license/mit"
}
)
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: str):
return templates.TemplateResponse(
request=request, name="index.html", context={"id": id}
)

๋งค๊ฐ๋ณ์๋ก url์ ์ ๋ฌํด openapi.json์ ๋ํ ๊ฒฝ๋ก๋ฅผ ์์๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
app = FastAPI(openapi_url="/api/v1/openapi.json")
/docs์ /redoc ํ์ด์ง๋ฅผ ์์ ๊ฑฐ๋ ์์์ ์ฃผ์๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
app = FastAPI(docs_url="/documentation", redoc_url=None)
# None์ ๊ฒฝ์ฐ ํ์ด์ง ๋นํ์ฑํ
Testing
fastapi์ TestClient๋ฅผ ์ฌ์ฉํด ์๋ํฌ์ธํธ ๋์์ ํ ์คํธํ ์ ์๋ค.
TestClient๋ httpx๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋์๊ธฐ ๋๋ฌธ์ httpx๋ฅผ ์ค์นํด์ผ ํ๋ค.
pip install httpx
main.py
from typing import Dict
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
app = FastAPI()
@app.get("/items/{id}", response_model=Dict[str, str])
async def read_item(id: str):
return {"id": id}
@app.get("/item/{item}", response_model=Dict[str, str])
async def get_item(item: str):
return {"Item": item}
Testing file - /tests/test_main.py
from fastapi.testclient import TestClient
from ..main import app
client = TestClient(app)
def test_read_item():
response = client.get('/items/foo')
assert response.status_code == 200
assert response.json() == {"id": "foo"}
def test_read_item_bad():
response = client.get('/items/')
assert response.status_code == 404
assert response.json() == {"detail": "Not Found"}
def test_get_item():
response = client.get('/item/foo')
assert response.status_code == 200
assert response.json() == {"Item": "foo"}
def test_get_item_bad():
response = client.get('/item/')
assert response.status_code == 404
assert response.json() == {"detail": "Not Found"}
์ด์ pytest๋ฅผ ์ค์นํ๊ณ test๋ฅผ ํ ์ ์๋ค.
pip install pytest
* pytest๋ฅผ ์คํํ ๋๋ /app/... ๊ฐ์ด ํ์ผ๋ค์ด ํจํค์ง๋ก ๋ฌถ์ฌ์์ด์ผ ํจ, (ํ ์คํธ ์ ์ ํ์ผ ์ ์ธ)ํ์ผ์ด๋ ํจํค์ง ์ด๋ฆ์ test ๊ด๋ จ๋ ์ด๋ฆ์ด ์๋ค์ด๊ฐ๊ฒ ์กฐ์ฌ!
pytest

์ด๋ ๊ฒ API๋ค์ ํ ์คํธ ํด๋ณผ ์ ์๋ค.
Debugging
uvicorn์ ์ฌ์ฉํด์ FastAPI App์ ์คํํ ์ ์๋ค.
์คํ ํฌํธ, ์ฃผ์ ๋ฑ์ ์ค์ ํ ์ ์๋ค.
from typing import Dict
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/items/{id}", response_model=Dict[str, str])
async def read_item(id: str):
return {"id": id}
@app.get("/item/{item}", response_model=Dict[str, str])
async def get_item(item: str):
return {"Item": item}
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8080)

IDE์ Debug ๊ธฐ๋ฅ์ผ๋ก Debugging์ ์ํํ ์ ์๋ค.

'Back-end & Server > FastAPI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[FastAPI] ๋ฐฐํฌ (0) | 2024.02.24 |
---|---|
[FastAPI] Template (0) | 2024.02.23 |
[FastAPI] Background Task (0) | 2024.02.23 |
[FastAPI] ํ์ผ ๋ถํ (0) | 2024.02.23 |
[FastAPI] Relational Database (0) | 2024.02.22 |