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
PREVIOUS[FastAPI] 기본 사용법