FastAPI 통합
junyul-kr[fastapi] extra는 Starlette 기반 미들웨어 ComplyMiddleware를 포함합니다. HTML 응답에 자동으로 컴플라이언스 배너를 주입하고, 렌더링 시점에 transparency.notice_shown 이벤트를 기록합니다.
설치
# 공개 PyPI 릴리스 또는 고객 전용 패키지 채널 연결 후
pip install "junyul-kr[fastapi]"앱 초기화 + 미들웨어
from fastapi import FastAPI
import junyul
from junyul.disclosure.fastapi import ComplyMiddleware
junyul.init(
api_key=os.environ["JUNYUL_API_KEY"],
tenant_secret=os.environ["JUNYUL_TENANT_SECRET"], # HMAC user anonymization
environment="production",
)
app = FastAPI()
# Auto-inject a compliance banner into every HTML response + record
# transparency.notice_shown event on each render.
app.add_middleware(
ComplyMiddleware,
default_asset_id="chatbot_v1",
locale="ko",
position="top",
)
@app.post("/chat")
@junyul.track(asset_id="chatbot_v1")
async def chat(req: ChatRequest):
return await call_llm(req.message)요청별 이벤트 기록
@app.post("/loan-decision")
async def decide(req: LoanRequest):
decision = await credit_model.score(req.features)
junyul.events.record_decision(
asset_id="loan_v3",
action="automated_decision_made",
legal_bases=["ai_basic_law_kr", "credit_info_36_2_kr", "pipa_37_2_kr"],
risk_tier="high",
subject_id=req.applicant_id, # HMAC'd locally via tenant_secret
outcome_hash=junyul.utils.canonical_hash({
"decision": decision.category,
"confidence": round(decision.confidence, 2),
}),
correlation_id=req.request_id,
)
return decision비동기 handler의 성능 영향
SDK는 이벤트를 메모리 큐에 O(1)로 넣고 즉시 반환합니다. 네트워크 전송은 백그라운드 태스크. 벤치마크 기준 record_* 호출의 p99 latency는 ~50μs입니다. 고영향 결정 앞에서도 응답 지연에 사실상 영향이 없습니다.
OpenTelemetry 연동
opentelemetry-api가 설치되어 있고 JUNYUL_OTEL_ENABLED=true인 경우, SDK가 현재 active span의 trace_id와 span_id를 자동으로 이벤트에 부착합니다. FastAPI를 otelcollector와 연결하셨다면 별도 작업 없이 감사 로그에 분산 추적 컨텍스트가 보존됩니다.
테스트
JUNYUL_ENVIRONMENT=test로 초기화하면 이벤트는 서버로 전송되지 않고junyul.testing.get_captured_events()로 assert 가능합니다. 기존 FastAPI TestClient 테스트를 수정 없이 재사용할 수 있습니다.