Skip to content

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이 사용하는:

  • uvicorn - 애플리케이션을 로드하고 제공하는 서버.
  • orjson - ORJSONResponse을 사용하려면 필요.

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.

os.kill(os.getpid(), signal.SIGTERM)

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

라우팅 경로중 / Suffix를 제거해주자.

See also

Favorite site