첫걸μ¶
κ°μ₯ λ¨μν FastAPI νμΌμ λ€μκ³Ό κ°μ΄ λ³΄μΌ κ²λλ€:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
μλ₯Ό main.py
μ 볡μ¬ν©λλ€.
λΌμ΄λΈ μλ²λ₯Ό μ€νν©λλ€:
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
μ°Έκ³
uvicorn main:app
λͺ
λ Ήμ λ€μμ μλ―Έν©λλ€:
main
: νμΌmain.py
(νμ΄μ¬ "λͺ¨λ").app
:main.py
λ΄λΆμapp = FastAPI()
μ€μμ μμ±ν μ€λΈμ νΈ.--reload
: μ½λ λ³κ²½ ν μλ² μ¬μμ. κ°λ°μλ§ μ¬μ©.
μΆλ ₯μ μλμ κ°μ μ€μ΄ μμ΅λλ€:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
ν΄λΉ μ€μ λ‘컬μμ μ±μ΄ μλΉμ€λλ URLμ 보μ¬μ€λλ€.
νμΈνκΈ°¶
λΈλΌμ°μ λ‘ http://127.0.0.1:8000λ₯Ό μ¬μμμ€.
μλμ κ°μ JSON μλ΅μ λ³Ό μ μμ΅λλ€:
{"message": "Hello World"}
λνν API λ¬Έμ¶
μ΄μ http://127.0.0.1:8000/docsλ‘ κ°λ΄ λλ€.
μλ λνν API λ¬Έμλ₯Ό λ³Ό μ μμ΅λλ€ (Swagger UI μ 곡):
λμ API λ¬Έμ¶
κ·Έλ¦¬κ³ μ΄μ , http://127.0.0.1:8000/redocλ‘ κ°λ΄ λλ€.
λμ μλ λ¬Έμλ₯Ό λ³Ό μ μμ΅λλ€ (ReDoc μ 곡):
OpenAPI¶
FastAPIλ APIλ₯Ό μ μνκΈ° μν OpenAPI νμ€μ μ¬μ©νμ¬ μ¬λ¬λΆμ λͺ¨λ APIλ₯Ό μ΄μ©ν΄ "μ€ν€λ§"λ₯Ό μμ±ν©λλ€.
"μ€ν€λ§"¶
"μ€ν€λ§"λ 무μΈκ°μ μ μ λλ μ€λͺ μ λλ€. μ΄λ₯Ό ꡬννλ μ½λκ° μλλΌ μΆμμ μΈ μ€λͺ μΌ λΏμ λλ€.
API "μ€ν€λ§"¶
μ΄ κ²½μ°, OpenAPIλ APIμ μ€ν€λ§λ₯Ό μ΄λ»κ² μ μνλμ§ μ§μνλ κ·κ²©μ λλ€.
μ΄ μ€ν€λ§ μ μλ API κ²½λ‘, κ°λ₯ν λ§€κ°λ³μ λ±μ ν¬ν¨ν©λλ€.
λ°μ΄ν° "μ€ν€λ§"¶
"μ€ν€λ§"λΌλ μ©μ΄λ JSONμ²λΌ μ΄λ€ λ°μ΄ν°μ ννλ₯Ό λνλΌ μλ μμ΅λλ€.
μ΄λ¬ν κ²½μ° JSON μμ±, κ°μ§κ³ μλ λ°μ΄ν° νμ λ±μ λ»ν©λλ€.
OpenAPIμ JSON μ€ν€λ§¶
OpenAPIλ APIμ λν API μ€ν€λ§λ₯Ό μ μν©λλ€. λν μ΄ μ€ν€λ§μλ JSON λ°μ΄ν° μ€ν€λ§μ νμ€μΈ JSON μ€ν€λ§λ₯Ό μ¬μ©νμ¬ APIμμ 보λ΄κ³ λ°μ λ°μ΄ν°μ μ μ(λλ "μ€ν€λ§")λ₯Ό ν¬ν¨ν©λλ€.
openapi.json
νμΈ¶
κ°κ³΅λμ§ μμ OpenAPI μ€ν€λ§κ° μ΄λ»κ² μκ²Όλμ§ κΆκΈνλ€λ©΄, FastAPIλ μλμΌλ‘ APIμ μ€λͺ κ³Ό ν¨κ» JSON (μ€ν€λ§)λ₯Ό μμ±ν©λλ€.
μ¬κΈ°μμ μ§μ λ³Ό μ μμ΅λλ€: http://127.0.0.1:8000/openapi.json.
λ€μκ³Ό κ°μ΄ μμνλ JSONμ νμΈν μ μμ΅λλ€:
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
...
OpenAPIμ μ©λ¶
OpenAPI μ€ν€λ§λ ν¬ν¨λ λ κ°μ λνν λ¬Έμ μμ€ν μ μ 곡ν©λλ€.
κ·Έλ¦¬κ³ OpenAPIμ λͺ¨λ κ²μ κΈ°λ°μΌλ‘ νλ μμ κ°μ§ λμμ΄ μμ΅λλ€. FastAPIλ‘ λΉλν μμ©νλ‘κ·Έλ¨μ μ΄λ¬ν λμμ μ½κ² μΆκ° ν μ μμ΅λλ€.
APIμ ν΅μ νλ ν΄λΌμ΄μΈνΈλ₯Ό μν΄ μ½λλ₯Ό μλμΌλ‘ μμ±νλ λ°λ μ¬μ©ν μ μμ΅λλ€. μλ‘ νλ‘ νΈμλ, λͺ¨λ°μΌ, IoT μμ©νλ‘κ·Έλ¨μ΄ μμ΅λλ€.
λ¨κ³λ³ μμ½¶
1 λ¨κ³: FastAPI
μν¬νΈ¶
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
FastAPI
λ APIμ λν λͺ¨λ κΈ°λ₯μ μ 곡νλ νμ΄μ¬ ν΄λμ€μ
λλ€.
κΈ°μ μΈλΆμ¬ν
FastAPI
λ Starlette
λ₯Ό μ§μ μμνλ ν΄λμ€μ
λλ€.
FastAPI
λ‘ Starletteμ λͺ¨λ κΈ°λ₯μ μ¬μ©ν μ μμ΅λλ€.
2 λ¨κ³: FastAPI
"μΈμ€ν΄μ€" μμ±¶
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
μ¬κΈ° μλ app
λ³μλ FastAPI
ν΄λμ€μ "μΈμ€ν΄μ€"κ° λ©λλ€.
μ΄κ²μ λͺ¨λ APIλ₯Ό μμ±νκΈ° μν μνΈμμ©μ μ£Όμ μ§μ μ΄ λ κ²μ λλ€.
μ΄ app
μ λ€μ λͺ
λ Ήμμ uvicorn
μ΄ μ°Έμ‘°νκ³ κ²κ³Ό λμΌν©λλ€:
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
μλμ²λΌ μ±μ λ§λ λ€λ©΄:
from fastapi import FastAPI
my_awesome_api = FastAPI()
@my_awesome_api.get("/")
async def root():
return {"message": "Hello World"}
μ΄λ₯Ό main.py
νμΌμ λ£κ³ , uvicorn
μ μλμ²λΌ νΈμΆν΄μΌ ν©λλ€:
$ uvicorn main:my_awesome_api --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
3 λ¨κ³: κ²½λ‘ λμ μμ±¶
κ²½λ‘¶
μ¬κΈ°μ "κ²½λ‘"λ 첫 λ²μ§Έ /
μμ μμνλ URLμ λ§μ§λ§ λΆλΆμ λνλ
λλ€.
κ·Έλ¬λ―λ‘ μλμ κ°μ URLμμ:
https://example.com/items/foo
...κ²½λ‘λ λ€μκ³Ό κ°μ΅λλ€:
/items/foo
μ 보
"κ²½λ‘"λ μΌλ°μ μΌλ‘ "μ€λν¬μΈνΈ" λλ "λΌμ°νΈ"λΌκ³ λ λΆλ¦½λλ€.
APIλ₯Ό λΉλνλ λμ "κ²½λ‘"λ "κ΄μ¬μ¬"μ "리μμ€"λ₯Ό λΆλ¦¬νλ μ£Όμ λ°©λ²μ λλ€.
λμ¶
μ¬κΈ°μ "λμ(Operation)"μ HTTP "λ©μλ" μ€ νλλ₯Ό λνλ λλ€.
λ€μ μ€ νλμ΄λ©°:
POST
GET
PUT
DELETE
...μ΄κ΅μ μΈ κ²λ€λ μμ΅λλ€:
OPTIONS
HEAD
PATCH
TRACE
HTTP νλ‘ν μ½μμλ μ΄λ¬ν "λ©μλ"λ₯Ό νλ(λλ μ΄μ) μ¬μ©νμ¬ κ° κ²½λ‘μ ν΅μ ν μ μμ΅λλ€.
APIλ₯Ό λΉλνλ λμ μΌλ°μ μΌλ‘ νΉμ νλμ μννκΈ° μν΄ νΉμ HTTP λ©μλλ₯Ό μ¬μ©ν©λλ€.
μΌλ°μ μΌλ‘ λ€μμ μ¬μ©ν©λλ€:
POST
: λ°μ΄ν°λ₯Ό μμ±νκΈ° μν΄.GET
: λ°μ΄ν°λ₯Ό μ½κΈ° μν΄.PUT
: λ°μ΄ν°λ₯Ό μ λ°μ΄νΈνκΈ° μν΄.DELETE
: λ°μ΄ν°λ₯Ό μμ νκΈ° μν΄.
κ·Έλμ OpenAPIμμλ κ° HTTP λ©μλλ€μ "λμ"μ΄λΌ λΆλ¦ λλ€.
μ΄μ λΆν° μ°λ¦¬λ λ©μλλ₯Ό "λμ"μ΄λΌκ³ λ λΆλ₯Όκ²λλ€.
κ²½λ‘ λμ λ°μ½λ μ΄ν° μ μ¶
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/")
μ FastAPIμκ² λ°λ‘ μλμ μλ ν¨μκ° λ€μμΌλ‘ μ΄λνλ μμ²μ μ²λ¦¬νλ€λ κ²μ μλ €μ€λλ€.
- κ²½λ‘
/
get
λμ μ¬μ©
@decorator
μ 보
μ΄ @something
λ¬Έλ²μ νμ΄μ¬μμ "λ°μ½λ μ΄ν°"λΌ λΆλ¦
λλ€.
ν¨μ 맨 μμ λμ΅λλ€. λ§μΉ μμ μ₯μμ©(Decorative) λͺ¨μμ²λΌ(κ°μΈμ μΌλ‘ μ΄ μ©μ΄κ° μ¬κΈ°μ μ λνκ±° κ°μ΅λλ€).
"λ°μ½λ μ΄ν°" μλ μλ ν¨μλ₯Ό λ°κ³ κ·Έκ±Έ μ΄μ©ν΄ 무μΈκ° ν©λλ€.
μ°λ¦¬μ κ²½μ°, μ΄ λ°μ½λ μ΄ν°λ FastAPIμκ² μλ ν¨μκ° κ²½λ‘ /
μ ν΄λΉνλ get
λμνλΌκ³ μλ €μ€λλ€.
μ΄κ²μ΄ "κ²½λ‘ λμ λ°μ½λ μ΄ν°"μ λλ€.
λ€λ₯Έ λμλ μΈ μ μμ΅λλ€:
@app.post()
@app.put()
@app.delete()
μ΅μνμ§ μμ κ²λ€λ μμ΅λλ€:
@app.options()
@app.head()
@app.patch()
@app.trace()
ν
κ° λμ(HTTP λ©μλ)μ μνλ λλ‘ μ¬μ©ν΄λ λ©λλ€.
FastAPIλ νΉμ μλ―Έλ₯Ό κ°μ νμ§ μμ΅λλ€.
μ¬κΈ°μ μ 보λ μ§μΉ¨μμΌλΏ μꡬμ¬νμ΄ μλλλ€.
μλ₯Ό λ€μ΄ GraphQLμ μ¬μ©ν λ μΌλ°μ μΌλ‘ POST
λμλ§ μ¬μ©νμ¬ λͺ¨λ νλμ μνν©λλ€.
4 λ¨κ³: κ²½λ‘ λμ ν¨μ μ μ¶
λ€μμ μ°λ¦¬μ "κ²½λ‘ λμ ν¨μ"μ λλ€:
- κ²½λ‘: λ
/
μ λλ€. - λμ: μ
get
μ λλ€. - ν¨μ: λ "λ°μ½λ μ΄ν°" μλμ μλ ν¨μμ
λλ€ (
@app.get("/")
μλ).
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
μ΄κ²μ νμ΄μ¬ ν¨μμ λλ€.
GET
λμμ μ¬μ©νμ¬ URL "/
"μ λν μμ²μ λ°μ λλ§λ€ FastAPIμ μν΄ νΈμΆλ©λλ€.
μμ κ²½μ° async
ν¨μμ
λλ€.
async def
λμ μΌλ° ν¨μλ‘ μ μν μ μμ΅λλ€:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello World"}
Note
μ°¨μ΄μ μ λͺ¨λ₯΄κ² λ€λ©΄ Async: "In a hurry?"μ νμΈνμμμ€.
5 λ¨κ³: μ½ν μΈ λ°ν¶
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
dict
, list
, λ¨μΌκ°μ κ°μ§ str
, int
λ±μ λ°νν μ μμ΅λλ€.
Pydantic λͺ¨λΈμ λ°νν μλ μμ΅λλ€(λμ€μ λ μμΈν μ΄ν΄λ΄ λλ€).
JSONμΌλ‘ μλ λ³νλλ κ°μ²΄λ€κ³Ό λͺ¨λΈλ€μ΄ λ§μ΄ μμ΅λλ€(ORM λ±μ ν¬ν¨νμ¬). κ°μ₯ λ§μμ λλ κ²μ μ¬μ©νμμμ€, μ΄λ―Έ μ§μλκ³ μμ κ²λλ€.
μμ½¶
FastAPI
μν¬νΈ.app
μΈμ€ν΄μ€ μμ±.- (
@app.get("/")
μ²λΌ) κ²½λ‘ λμ λ°μ½λ μ΄ν° μμ±. - (μμ μλ
def root(): ...
μ²λΌ) κ²½λ‘ λμ ν¨μ μμ±. - (
uvicorn main:app --reload
μ²λΌ) κ°λ° μλ² μ€ν.