Search
moon
sun
โœ…

240706_1306_[Python] FastAPI & Uvicorn

FastAPI

โ€ข
FastAPI๋Š” ํ˜„๋Œ€์ ์ธ ๊ณ ์„ฑ๋Šฅ ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, Python์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค.
โ€ข
FastAPI๋Š” ๋น ๋ฅธ ๊ฐœ๋ฐœ ์†๋„์™€ ๋†’์€ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ํŠนํžˆ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์—ฌ ํšจ์œจ์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์œ ๋ฆฌํ•˜๋‹ค.

์ฃผ์š” ํŠน์ง•

1.
๊ณ ์„ฑ๋Šฅ
โ€ข
FastAPI๋Š” ASGI(Asynchronous Server Gateway Interface) ํ‘œ์ค€์„ ๋”ฐ๋ฅด๋ฉฐ, Uvicorn ๋˜๋Š” Hypercorn๊ณผ ๊ฐ™์€ ๊ณ ์„ฑ๋Šฅ ASGI ์„œ๋ฒ„์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋œ๋‹ค.
โ€ข
๋น„๋™๊ธฐ I/O๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ๋‚ฎ์€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ œ๊ณตํ•œ๋‹ค.
2.
์ž๋™ํ™”๋œ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ฐ ๋ฌธ์„œํ™”
โ€ข
FastAPI๋Š” Pydantic์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ์„ ์ž๋™ํ™”ํ•œ๋‹ค.
โ€ข
OpenAPI์™€ JSON Schema๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ, API ๋ฌธ์„œ๋ฅผ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•˜๊ณ  ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
3.
๋น ๋ฅธ ๊ฐœ๋ฐœ ์†๋„
โ€ข
๊ฐ„๊ฒฐํ•˜๊ณ  ์ง๊ด€์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค.
โ€ข
ํƒ€์ž… ํžŒํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ IDE์˜ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
4.
๋น„๋™๊ธฐ ์ง€์›
โ€ข
Python์˜ ๋น„๋™๊ธฐ ๊ธฐ๋Šฅ(Async/Await)์„ ์™„๋ฒฝํžˆ ์ง€์›ํ•˜์—ฌ, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•˜๋‹ค.
5.
๋ณด์•ˆ
โ€ข
OAuth2, JWT ๋“ฑ์˜ ์ธ์ฆ ์‹œ์Šคํ…œ์„ ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค.
โ€ข
CORS, CSRF ๋“ฑ์˜ ๋ณด์•ˆ ๊ธฐ๋Šฅ๋„ ์‰ฝ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์„ค์น˜ ๋ฐ ๊ธฐ๋ณธ ์‚ฌ์šฉ ์˜ˆ์‹œ

โ€ข
FastAPI๋ฅผ ์„ค์น˜ํ•˜๋ ค๋ฉด pip๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
pip install fastapi uvicorn
Shell
๋ณต์‚ฌ
โ€ข
FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž‘์„ฑํ•˜๋Š” ๊ธฐ๋ณธ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: str = None): return {"item_id": item_id, "q": q}
Python
๋ณต์‚ฌ
โ€ข
์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Uvicorn์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
uvicorn main:app --reload
Shell
๋ณต์‚ฌ
โ€ข
์œ„ ๋ช…๋ น์–ด๋Š” main.py ํŒŒ์ผ์˜ app ๊ฐ์ฒด๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ž๋™์œผ๋กœ ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•œ๋‹ค.

API ๋ฌธ์„œ

โ€ข
FastAPI๋Š” ์ž๋™์œผ๋กœ API ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
โ€ข
์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹ค์Œ URL๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค:
โ—ฆ
Swagger UI: http://127.0.0.1:8000/docs
โ—ฆ
Redoc: http://127.0.0.1:8000/redoc

๊ณ ๊ธ‰ ๊ธฐ๋Šฅ

โ€ข
FastAPI๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•œ๋‹ค.
โ—ฆ
๊ฒฝ๋กœ ์ž‘์—…(Path Operations): ๋‹ค์–‘ํ•œ HTTP ๋ฉ”์„œ๋“œ(GET, POST, PUT, DELETE ๋“ฑ)๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ๋กœ ์ž‘์—…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
โ—ฆ
์˜์กด์„ฑ ์ฃผ์ž…: ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
โ—ฆ
๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…: ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰ํ•  ์ž‘์—…์„ ์ •์˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
โ—ฆ
์›น์†Œ์ผ“: ์‹ค์‹œ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•œ ์›น์†Œ์ผ“์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์š”์•ฝ

โ€ข
FastAPI๋Š” ํ˜„๋Œ€์ ์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋กœ, ๋†’์€ ์„ฑ๋Šฅ๊ณผ ํŽธ๋ฆฌํ•œ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•œ๋‹ค.
โ€ข
ํŠนํžˆ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์™€ ์ž๋™ํ™”๋œ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ฐ ๋ฌธ์„œํ™” ๊ธฐ๋Šฅ์ด ๋›ฐ์–ด๋‚˜, ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Uvicorn

โ€ข
Uvicorn์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
1.
ASGI ์„œ๋ฒ„: Uvicorn์€ ASGI(Asynchronous Server Gateway Interface)๋ฅผ ๊ตฌํ˜„ํ•œ ์„œ๋ฒ„๋กœ, ๋น„๋™๊ธฐ Python ์›น ํ”„๋ ˆ์ž„์›Œํฌ(์˜ˆ: FastAPI, Starlette)๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ASGI๋Š” WSGI์˜ ๋น„๋™๊ธฐ ๋ฒ„์ „์œผ๋กœ, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์—ฌ ๋” ๋†’์€ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
2.
๊ณ ์„ฑ๋Šฅ: Uvicorn์€ Cython๊ณผ ํ•จ๊ป˜ ๊ตฌํ˜„๋˜์–ด ๋งค์šฐ ๋น ๋ฅธ ์†๋„๋ฅผ ์ž๋ž‘ํ•œ๋‹ค. ์ด๋Š” ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ๋‚ฎ์€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์š”๊ตฌํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•˜๋‹ค.
3.
๊ฐ„ํŽธํ•œ ์‚ฌ์šฉ: ์„ค์ •๊ณผ ์‚ฌ์šฉ์ด ๊ฐ„ํŽธํ•˜๋ฉฐ, ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์š” ํŠน์ง•

โ€ข
HTTP/2 ๋ฐ WebSocket ์ง€์›: HTTP/2์™€ WebSocket์„ ์ง€์›ํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์œ ๋ฆฌํ•˜๋‹ค.
โ€ข
์ž๋™ ๋ฆฌ๋กœ๋”ฉ: ๊ฐœ๋ฐœ ์ค‘ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์„œ๋ฒ„๋ฅผ ์ž๋™์œผ๋กœ ์žฌ์‹œ์ž‘ํ•˜์—ฌ ๊ฐœ๋ฐœ ํŽธ์˜์„ฑ์„ ๋†’์ธ๋‹ค.
โ€ข
๊ณ ์„ฑ๋Šฅ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ: ๋น„๋™๊ธฐ I/O๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ๊ณ ์„ฑ๋Šฅ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.
โ€ข
์œ ์—ฐ์„ฑ: ๋‹ค์–‘ํ•œ Python ์›น ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ASGI ํ‘œ์ค€์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธํ™˜์„ฑ์ด ์ข‹๋‹ค.

์„ค์น˜ ๋ฐ ์‚ฌ์šฉ ์˜ˆ์‹œ

โ€ข
Uvicorn์€ pip๋ฅผ ํ†ตํ•ด ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
pip install uvicorn
Shell
๋ณต์‚ฌ
โ€ข
Uvicorn์„ ์‚ฌ์šฉํ•˜์—ฌ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋Š” ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"}
Python
๋ณต์‚ฌ
โ€ข
์œ„์™€ ๊ฐ™์€ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Uvicorn์œผ๋กœ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค:
uvicorn main:app --reload
Shell
๋ณต์‚ฌ
โ€ข
-reload ์˜ต์…˜์€ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์„œ๋ฒ„๋ฅผ ์ž๋™์œผ๋กœ ์žฌ์‹œ์ž‘ํ•˜๋Š” ๊ฐœ๋ฐœ ๋ชจ๋“œ ์˜ต์…˜์ด๋‹ค.

์š”์•ฝ

โ€ข
Uvicorn์€ Python ๋น„๋™๊ธฐ ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์œ„ํ•œ ๊ณ ์„ฑ๋Šฅ ASGI ์„œ๋ฒ„๋กœ, ๊ฐ„ํŽธํ•œ ์„ค์ •๊ณผ ๋†’์€ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
โ€ข
FastAPI, Starlette ๋“ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„๋Œ€์ ์ธ ๋น„๋™๊ธฐ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•˜๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”๐Ÿ˜Š

โ€ข
ํ•œ๊ตญ์ „์ž๊ธฐ์ˆ ์—ฐ๊ตฌ์› ๊น€์˜๊ด‘์ž…๋‹ˆ๋‹ค.
โ€ข
๊ด€๋ จ ๊ธฐ์ˆ  ๋ฌธ์˜์™€ R&D ๊ณต๋™ ์—ฐ๊ตฌ ์‚ฌ์—… ๊ด€๋ จ ๋ฌธ์˜๋Š” โ€œglory@keti.re.krโ€๋กœ ์—ฐ๋ฝ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

Hello ๐Ÿ˜Š

โ€ข
I'm Yeonggwang Kim from the Korea Electronics Research Institute.
โ€ข
For technical and business inquiries, please contact me at โ€œglory@keti.re.krโ€