FastAPI
FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트에 기초한 Python3.6+의 API를 빌드하기 위한 웹 프레임워크입니다.
Categories
- Tutorial - User Guide
- FastAPI:FirstSteps
- FastAPI:PathParameters
- FastAPI:QueryParameters
- FastAPI:RequestBody
- FastAPI:QueryParameters and String Validations
- FastAPI:PathParameters and Numeric Validations
- FastAPI:Body:MultipleParameters
- FastAPI:Body:Fields
- FastAPI:Body:NestedModels
- FastAPI:DeclareRequestExampleData
- FastAPI:ExtraDataTypes
- FastAPI:CookieParameters
- FastAPI:HeaderParameters
- FastAPI:ResponseModel:ReturnType
- FastAPI:ExtraModels
- FastAPI:ResponseStatusCode
- FastAPI:FormData
- FastAPI:RequestFiles
- FastAPI:RequestForms
- FastAPI:HandlingErrors
- FastAPI:PathOperationConfiguration
- FastAPI:JSONCompatibleEncoder
- FastAPI:Body:Updates
- FastAPI:Dependencies
- Classes as Dependencies
- Sub-dependencies
- Dependencies in path operation decorators
- Global Dependencies
- Dependencies with yield
- FastAPI:Security
- Security - First Steps
- Get Current User
- Simple OAuth2 with Password and Bearer
- OAuth2 with Password (and hashing), Bearer with JWT tokens
- FastAPI:Middleware
- FastAPI:CORS
- FastAPI:SQLDatabases
- FastAPI:BiggerApplications - Multiple Files
- FastAPI:BackgroundTasks
- FastAPI:Metadata
- FastAPI:StaticFiles
- FastAPI:Testing
- FastAPI:Debugging
- Advanced User Guide
- FastAPI:PathOperationAdvancedConfiguration
- FastAPI:AdditionalStatusCodes
- FastAPI:ReturnResponseDirectly
- FastAPI:CustomResponse - HTML, Stream, File, others
- FastAPI:AdditionalResponsesInOpenAPI
- FastAPI:ResponseCookies
- FastAPI:ResponseHeaders
- FastAPI:Response:ChangeStatusCode
- FastAPI:AdvancedDependencies
- FastAPI:AdvancedSecurity
- OAuth2 scopes
- HTTP Basic Auth
- FastAPI:UsingTheRequestDirectly
- FastAPI:UsingDataclasses
- FastAPI:AdvancedMiddleware
- FastAPI:SQL (Relational) Databases with Peewee
- FastAPI:AsyncSQL (Relational) Databases
- FastAPI:NoSQL (Distributed / Big Data) Databases
- FastAPI:SubApplications - Mounts
- FastAPI:BehindProxy
- FastAPI:Templates
- FastAPI:GraphQL
- FastAPI:WebSockets
- FastAPI:LifespanEvents - 수명 이벤트
- FastAPI:CustomRequestAndAPIRouteClass
- FastAPI:TestingWebSockets
- FastAPI:TestingEvents: startup - shutdown
- FastAPI:TestingDependenciesWithOverrides
- FastAPI:TestingDatabase
- FastAPI:AsyncTests
- FastAPI:SettingsAndEnvironmentVariables
- FastAPI:ConditionalOpenAPI
- FastAPI:ExtendingOpenAPI
- FastAPI:OpenAPICallbacks
- FastAPI:OpenAPIWebhooks
- FastAPI:IncludingWSGI - Flask, Django, others
- FastAPI:GenerateClients
- FastAPI:Deployment
Optional dependencies
Pydantic이 사용하는:
- email_validator - 이메일 유효성 검사.
Starlette이 사용하는:
- HTTPX - TestClient를 사용하려면 필요.
- jinja2 - 기본 템플릿 설정을 사용하려면 필요.
- python-multipart -
request.form()
과 함께 "parsing"의 지원을 원하면 필요. - itsdangerous -
SessionMiddleware
지원을 위해 필요. - pyyaml - Starlette의
SchemaGenerator
지원을 위해 필요 (FastAPI와 쓸때는 필요 없을 것입니다). - graphene -
GraphQLApp
지원을 위해 필요. - ujson - UJSONResponse를 사용하려면 필요.
FastAPI / Starlette이 사용하는:
pip install fastapi[all]
를 통해 이 모두를 설치 할 수 있습니다.
Features
- Python 기반 : Starlette, Pydantic, Uvicorn
- Node와 Go수준의 성능
- 빠르고 쉬운 개발. 짧은 코드. 훌륭한 재사용성
- Production Ready
- OpenAPI(Swagger) 및 JSON Schema 등의 표준 기반
- 훌륭한 에디터 지원(코드 자동완성)
- 비동기 API 및 데이터 검증 지원
프로그래밍 방식으로 실행
Uvicorn#프로그래밍 방식으로 실행 항목을 참조:
import uvicorn
from fastapi import FastAPI # type: ignore
certfile = "..."
keyfile = "..."
app = FastAPI()
# ...
if __name__ == "__main__":
uvicorn.run(app, port=5000, log_level="info", ssl_certfile=certfile, ssl_keyfile=keyfile)
클래스 메소드 라우팅
FastAPI:APIRouter#add_api_route를 사용한다.
간단히:
from fastapi import FastAPI, APIRouter
class Hello:
def __init__(self, name: str):
self.name = name
self.router = APIRouter()
self.router.add_api_route("/hello", self.hello, methods=["GET"])
def hello(self):
return {"Hello": self.name}
app = FastAPI()
hello = Hello("World")
app.include_router(hello.router)
Request Validation and Serialization
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
async def create_item(item: Item):
# Access validated and deserialized item properties
item_name = item.name
item_price = item.price
# ...
Cross-Origin Resource Sharing (CORS)
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Configure CORS settings
origins = [
"http://localhost",
"http://localhost:3000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Authentication and Authorization
from fastapi import FastAPI
from fastapi.security import OAuth2PasswordBearer
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")
@app.get("/items/")
async def get_items(token: str = Depends(oauth2_scheme)):
# Validate and verify the token
# Perform authorization checks
# ...
Healthcheck access log 숨기기
import logging
import uvicorn
from fastapi import FastAPI
app = FastAPI()
# Define the filter
class EndpointFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
return record.args and len(record.args) >= 3 and record.args[2] != "/health"
# Add filter to the logger
logging.getLogger("uvicorn.access").addFilter(EndpointFilter())
# Define the API endpoints
@app.get('/health')
def health():
print('health endpoint')
@app.get('/test')
def test():
print('test endpoint')
Graceful shutdown
The key libraries to achieve graceful shutting down to a Uvicorn server running a FastAPI application are the built in os and signal modules. Given an endpoint with which a client can request the server to shutdown.
FastAPI example:
import os
import signal
import fastapi
import uvicorn
from fastapi.responses import JSONResponse
app = fastapi.FastAPI()
def hello():
return fastapi.Response(status_code=200, content='Hello, world!')
def shutdown():
os.kill(os.getpid(), signal.SIGTERM)
return fastapi.Response(status_code=200, content='Server shutting down...')
@app.on_event('shutdown')
def on_shutdown():
print('Server shutting down...')
app.add_api_route('/hello', hello, methods=['GET'])
app.add_api_route('/shutdown', shutdown, methods=['GET'])
if __name__ == '__main__':
uvicorn.run(app, host='localhost', port=8000)
Flask 보다 FastAPI 가 좋은점?
WARNING |
검증 필요. |
- 파이썬 웹 어플리케이션 개발에 주로 사용되던 Flask의 단점을 보완한 프레임워크
- DI 중심 설계 덕분에 버그 가능성은 낮고, 생산성과 성능은 높음
- Flask의 각 구성요소들은 FastAPI에서 어떻게 대체할 수 있는지 정리
- 성능도 성능이지만, 좋은 공식 문서, 프레임워크 수준의 OpenAPI Specification과 같은 강력한 편의 기능도 장점
- Flask는 왜 이렇게 하지 못 했는지, 비슷한 부류인 Sanic은 왜 인기가 없었는지를 Python의 역사와 함께 풀어냄
Performance Tips
여러 성능 최적화 팁
- 상황에 따라 gc가 병목일 수 있다. 이런 경우 gc 발동 조건을 튜닝할 수 있다.
- Built-in list는 충분히 빠르지 않다. 필요시 array나 numpy를 사용하자.
- multiprocess는 커뮤니케이션 오버헤드가 높기에, low-latency 시나리오에서 조심히 사용해야한다.
- Pytorch를 multiprocess 환경에서 쓴다면 num_threads를 조정하자.
- Pydantic은 아주 느리다. 불필요한 곳에서 가급적 사용하지 말자.
- Pandas DataFrame은 생성에 많은 시간이 걸리므로, 유의해서 사용해야 한다.
- 바닐라 json 패키지는 느리다. orjson이나 ujson을 사용하자.
- Class는 충분히 빠르지 않을 수 있다. 너무 문제가 되면 dict를 사용하자.
- Python 3.11은 덜 느리다.
- (보너스) line profiler 사용법
Troubleshooting
422 Unprocessable Entity
서버가 요청 엔티티의 "컨텐츠 형식"을 이해했고 요청 엔티티의 문법도 올바르지만 요청된 지시를 처리할 수 없음을 나타냅니다.
즉, Content-Type
헤더를 다시 확인해 보자.
307 Temporary Redirect
- (FastAPI) 307 temporary redirect 에러 해결 방법 by bskyvision.com
- Http 307 Temporary Internal Redirect 원인과 에러 해결 방법
- (FastAPI) 307 temporary redirect 해결 방법 (Python)
라우팅 경로중 /
Suffix를 제거해주자.
See also
- Python
- SQLModel - Python용 SQL DB 라이브러리 - FastAPI에서 SQL DB접속을 쉽게하기 위해 만들어짐 (같은 개발자)
- uvicorn
- Mangum - AWS Lambda support for ASGI applications
- Typer - FastAPI of CLIs
Favorite site
- FastAPI web site
- FastAPI 톺아보기 - 부제: python 백엔드 봄은 온다
- Fast API Pydantic을 이용한 Type Hinting (fastapi, pydantic)
- Developing FastAPI Application using K8s & AWS - PyCharm Guide (Python, FastAPI, k8s, AWS)
- (FastAPI/Python) 양방향 통신을 위한 웹소켓 in FastAPI — Dev In Seoul (FastAPI, WebSocket, broadcaster, redis)
- FastAPI 한줄씩 따라읽기 | GeekNews