서비스 학습
SOURCE · be/app/api/dependencies.py · 2026-09-06

Route가 구체적인 Adapter를
직접 찾지 않게 한다

세 줄짜리 함수지만 architecture의 경계다. 현재 application의 lifespan이 소유한 inference engine을 꺼내 route에 전달한다.

왜 route에서 request.app.state를 바로 읽지 않는가?

직접 읽어도 실행은 된다. 하지만 모든 route가 storage 위치를 알게 되고 test마다 application state를 조작해야 한다. FastAPI dependency 하나로 감싸면 route는 InferenceEngine만 요구하고, test는 이 dependency를 가짜 engine으로 교체할 수 있다.

전체 코드

from fastapi import Request

from app.engines.base import InferenceEngine


def get_inference_engine(request: Request) -> InferenceEngine:
    """Read the engine owned by this application's active lifespan."""
    return request.app.state.inference_engine

한 줄씩 해석

request: Request

FastAPI가 현재 HTTP 요청마다 만들어 전달하는 object다. request.app은 그 요청을 받고 있는 FastAPI application을 가리킨다. Client가 보내는 JSON body와는 다른 server-side object다.

-> InferenceEngine

구체 type을 TurboFieldfareAdapter라고 쓰지 않는다. Route가 필요한 것은 readiness와 generate 능력이지 구현 이름이 아니기 때문이다. 나중에 다른 engine adapter가 같은 Protocol을 구현해도 route signature를 유지할 수 있다.

request.app.state.inference_engine

main.py lifespan의 startup 구간에서 저장한 동일 object를 반환한다. 따라서 여러 요청은 같은 Adapter를 공유하며 생성용·probe용 HTTP connection pool을 각각 재사용한다. request.app.state는 server 객체를 보관하는 공간이지 React 화면 state가 아니다. 정상적인 server에서는 lifespan 진입 후에만 route를 받으므로 값이 존재한다.

Test에서 의존성을 바꾸는 개념 예제

아래는 test_settings·ReadyEngine·import를 생략한 의사 코드이며, test_health.py를 그대로 복사한 실행 가능한 전체 코드는 아니다. 실제 테스트는 Settings를 직접 만들고 이와 같은 dependency_overrides 방식을 사용한다.

application = create_app(test_settings)
application.dependency_overrides[get_inference_engine] = (
    lambda: ReadyEngine()
)

with TestClient(application) as client:
    response = client.get("/readyz")
Production route → get_inference_engine → TurboFieldfareAdapter Test route → dependency override → ReadyEngine

가짜 engine은 실제 server 주소나 15GB model 없이 200/503 route 분기를 검사한다. Adapter 자체는 별도의 MockTransport·실제 TCP 회귀 테스트와 초기 live smoke 기록으로 검사하므로 실패 원인을 계층별로 구분할 수 있다.

현재의 의도적인 한계

함수는 state 값이 없을 때 친절한 503을 만들지 않는다. 정상 ASGI lifecycle에서는 startup 완료 전 요청을 받지 않으므로 state 부재는 배포 장애가 아니라 programming error에 가깝다. 이를 임의로 숨기면 잘못된 application 조립이 장기간 발견되지 않을 수 있다.

← 이전Route 모으기다음 →Liveness와 readiness