[FastAPI] 기본 사용법

 

Fast API 기본 사용법

from fastapi import FastAPI
import uvicorn

app = FastAPI()

@app.get("/") # FastAPIR는 데코레이터로 GET, POST를 정의한다.
def read_root():
    return {'Hello':'World'}
    
if __name__ == '__main__':
    uvicorn.run(app, host = "0.0.0.0", port = 8000)
  • 이런 py파일을 실행시키면, 웹 서버가 켜진다. 이때, 터미널도 같이 켜저있어야한다.
  • URL Parameter
    • 이전에 봤던 Path Parameter와 Query Parameter가 존재
    • 언제 어떤 방식을 사용할지
    URL Parameter 언제 사용할지
    Path Parameter Resource를 식별해야 하는 경우
    Query Parameter 정렬, 필터링을 해야 하는 경우
    • 이렇게 하는 이유는 Resource가 없을 때, 서로 다른 방식으로 처리하기 때문이다.
    • Path Parameter는 내가 찾고자 하는 내용이 없으면 404 Error를 발생 시키지만, Query Parameter는 빈 리스트가 나온다. 그렇기에 Resource의 존재 유무를 파악하는데 에는 Path Parameter가 나온다.
  • Path Parameter
from fastapi import FastAPI
import uvicorn

app = FastAPI()

# {}안의 값이 변수가 되어 read_user 함수에 들어가게 된다.
@app.get("/users/{user_id}") 
def read_user(user_id):
    return {'user_id': user_id}
    
if __name__ == '__main__':
    uvicorn.run(app, host = "0.0.0.0", port = 8000)
  • Query Parameter
from fastapi import FastAPI
import uvicorn

app = FastAPI()

# 예시 DB
fruits_db =[{'fruit_name':'apple'}, {'fruit_name':'banana'}]

@app.get("fruits") 
def read_fruit(skip=0, limit=10):
    return fruits_db[skip:skip+limit]
    
if __name__ == '__main__':
    uvicorn.run(app, host = "0.0.0.0", port = 8000)
  • Optional Parameter
    • 특정 파라미터는 선택적으로 하고 싶은 경우
from fastapi import FastAPI
from Typing import Optional # 모듈 임포트
import uvicorn

app = FastAPI()

# 예시 DB
fruits_db =[{'fruit_name':'apple'}, {'fruit_name':'banana'}]

# q인자는 선택적으로 한다.(기본값은 None으로 설정)
@app.get("fruits/{fruit_id}") 
def read_fruit(fruit_id:str, q: Optional[str] = None):
    if q:
        return {'fruit_id':fruit_id, 'q':q}
    return {'fruit_id':fruit_id}
    
if __name__ == '__main__':
    uvicorn.run(app, host = "0.0.0.0", port = 8000)
  • Request Body(=Payload)
    • client에서 API에 데이터를 보낼 때 사용한다.
    • Request Body를 보내고 싶다면 Post Method를 사용한다. 하지만 항상 데이터가 포함되어야 하는 것은 아니다.(데이터가 포함되지 않으면 왜 쓰는지…)
    • contents type도 지정 할 수 있다.(default는 application/json)
    • 추가로 데이터 Validation도 같이 진행해준다.(ex. 내가 지정한 데이터 type으로 올바르게 입력되었는지 확인)
from fastapi import FastAPI
from Typing import Optional
import uvicorn

from pydantic import BaseModel

# pydantic.BaseModel로 Request Body 데이터 정의 
class Fruit(BaseModel):
    name:str
    description:Optional[str]=None
    Price:float
    tax: Optional[float] = None
    
app = FastAPI()

@app.post('/fruits/')
def create_item(fruit:Fruit):
    return fruit
    
if __main__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)
  • Response Body
    • API에서 client로 데이터를 보낼 때 사용한다.
    • Request body의 특정 데이터만 보낼 수 있다. 즉 Output Data를 정의에 맞게 변형한다.
    • 이 외에도 데이터 validation, Response에 대한 Json Schema 추가, 문서 자동화 등의 역할을 한다.
from fastapi import FastAPI
from Typing import Optional
import uvicorn

from pydantic import BaseModel

# request
class FruitIn(BaseModel):
    name:str
    description:Optional[str]=None
    Price:float
    tax: Optional[float] = None
    
# response
class FruitOut(BaseModel):
    name:str
    price:float
    tax:Optional['float'] = None
    
app = FastAPI()

# decorator의 response_model 인자로 주입
@app.post('/fruits/', response_model = FruitOut)
def create_item(fruit:FruitIn):
    return fruit
    
if __main__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)
  • Form
    • 입력(Form) 형태로 데이터를 받고 싶은 경우 사용한다.(python-multipart와 프론트 엔트 구축을 위한 Jinja2 설치 필요)
    • Form 클래스를 사용하면 Request의 Form Data에서 값을 가져온다.
from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates

import uvicorn

app = FastAPI()
templates = Jinja2Templates(directory='./')

@app.get("/login/")
def get_login_form(request: Request):
    return templates.TemplateResponse('login_form.html', context = {'request':request})

# Form을 통해 입력을 받은 데이터를 가져오겠다는 것
@app.post('/login/')
def login(username: str = Form(...), password: str = Form(...)):
    return {'username': username}
    
if __main__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)
  • File
    • File 업로드하고 싶은 경우에 사용(python-multipart필요)
from typing import List
from fastapi import FastAPI, File, UploadFile
from fastapi.response import HTMLResponse
import uvicorn

app = FastAPI()

@app.post('/files/')
def create_files(files: List[bytes] = File(...)):
    return {"file_sizes":[len(file) for file in files]}
    
@app.post('uploadfiles/')
def create_upload_files(files: List[bytes] = File(...)):
    return {"filenames":[file.filename for file in files]}
    
@app.get("/")
def main():
    content = """
    <body>
    <form action="/files/" enctype="multipart/form-data" method="post">
    <input name = "files" type="file" multiple>
    <input type = "submit">
    </form>
    <form action="/uploadfiles/" enctype="multipart/form-data" method="post">
    <input name = "files" type="file" multiple>
    <input type = "submit">
    </form>
    </body>
    """
    return HTMLResponse(content = content)
    
if __name__ == '__main__':
    uvicon.run(app, host="0.0.0.0", port = 8000