일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 네트워크보안
- 프로그래밍
- 데이터분석
- 인공지능
- 컴퓨터비전
- 데이터과학
- 소프트웨어공학
- 소프트웨어
- 네트워크
- 데이터베이스
- 알고리즘
- 사이버보안
- 웹개발
- 데이터구조
- 자바스크립트
- 자료구조
- 빅데이터
- 클라우드컴퓨팅
- 2
- 프로그래밍언어
- 머신러닝
- 코딩
- 보안
- I'm Sorry
- 컴퓨터공학
- 파이썬
- 컴퓨터과학
- 딥러닝
- 버전관리
- Yes
- Today
- Total
스택큐힙리스트
FastAPI(Python)에서 요청을 로깅하기 위해 미들웨어와 의존성 주입을 사용하는 동안 차단된 코드 본문
[17.08.2021 13:08:25.08S]: {event_type: 들어오는 요청, id: 3fb33dc0-cb86-49e9-9a0f-c48596e58061}
[17.08.2021 13:08:25.08S]: {event_type: 나가는 응답, id: 3fb33dc0-cb86-49e9-9a0f-c48596e58061}
INFO: 127.0.0.1:50285 - POST /without-dependency-injection HTTP/1.1 200 OK
모든 것이 잘 작동합니다! 미들웨어가 요청을 잡아 로그를 작성하고, 요청을 실행하고, 서버 응답과 함께 로그를 작성하고, 응답을 클라이언트에게 반환합니다.
의존성을 추가하면 동작이 변경됩니다.
의존성 주입이 있는 엔드포인트입니다:
@app.post(/generate-token/, tags=[테스트])
async def create_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
# ...
# 토큰 생성 코드
return {token:f{token}}
그리고 여기에 콘솔 로그가 있습니다:
[17.08.2021 13:13:08.13S]: {event_type: 들어오는 요청, id: 3b6398de-5b20-40ad-820e-24733425e6c7}
위와 같이 보시다시피, 응답이 나가는 이벤트는 없습니다. 미들웨어가 요청을 잡아서 들어오는 요청 데이터를 로그로 기록하고 실행에 요청을 보냈습니다. 그리고 코드는 서버가 새 요청을 받을 때까지 차단되었어요. 그 후에 클라이언트가 서버로부터 응답을 받게 됩니다.
만약 미들웨어나 의존성 주입을 제거한다면, 모든 것은 잘 작동합니다.
왜 코드가 클라이언트로부터 새 요청이 올 때까지 차단되는지 아는 사람은 있나요? 이 동작을 어떻게 수정할 수 있을까요?
답변 1
마지막 링크는 또한 헤이팅 문제의 원인이기도 한다고 언급하고 있습니다. 이는 StreamingResponse
때문에 응답의 읽기가 첫 번째 읽기에서 소진되며, 두 번째 읽기가 영원히 기다리기 때문에 매달림이 발생합니다. (여기서 첫 번째와 두 번째 읽기란: ASGI 앱에서 메시지는 http.response.start
, http.response.body
등과 같은 다양한 유형으로 클라이언트와 앱 사이로 전송됩니다).
해결책 (일부분, 응답 로그를 기록하지만 요청에 대한 학습이 이루어지면 업데이트할 것입니다)
따라서, BaseHTTPMiddleware
와 관련된 것은 사용하지 마십시오. 이에 대응하기 위해 저는 모든 사용자 정의 미들웨어를 ASGI 사양에 따라 작성했습니다. 여기에는 다음 링크에서 찾을 수 있는 사양이 있습니다: 여기
다음과 같이 사용자 정의 미들웨어를 작성할 수 있습니다:
from starlette.types import ASGIApp, Receive, Send, Message
class LogResponseMDW:
def __init__(self, app: ASGIApp) -> None:
self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send):
async def send_wrapper(message: Message):
# 이곳에서 APP 레이어에서 오는 응답을 캡쳐합니다.
# 먼저 message[type]을 확인해야 합니다.
# http.response.body 타입일 때 응답 본문은 message에 있을 것입니다.
print(fmessage: {message}) # 메세지 타입을 확인한 후 여기에 기록합니다.
await send(message)
await self.app(scope, receive, send_wrapper)
# 이렇게 앱에 미들웨어를 추가할 수 있습니다:
app.add_middleware(LogResponseMDW)
답변 2
FastAPI는 Python으로 작성된 웹 프레임워크로, 개발을 단순하고 효율적으로 만들어주는 강력한 기능들을 제공합니다. 이 프레임워크에서는 미들웨어와 의존성 주입을 활용하여 요청을 로깅하는 작업을 수행할 수 있습니다.먼저, 미들웨어는 FastAPI에서 요청이 처리되기 전과 후에 실행되는 코드 조각입니다. 요청을 처리하기 전에 미들웨어를 사용하면 로깅, 인증, 데이터 변환 등 여러 가지 작업을 수행할 수 있습니다. 이는 개발자에게 유연성과 커스터마이징의 여지를 제공합니다.
의존성 주입은 FastAPI에서 다양한 기능들을 사용할 수 있도록 도와주는 중요한 개념입니다. 이를 통해 다른 모듈, 클래스 또는 함수에 대한 의존성을 자동으로 해결할 수 있습니다. 로깅 작업에서도 의존성 주입을 활용하여 로거 객체를 주입 받을 수 있습니다. 이는 코드의 재사용성과 테스트 용이성을 향상시켜줍니다.
요청 로깅 작업에 대한 예시를 살펴보겠습니다. 미들웨어를 사용하여 요청 정보를 처리할 수 있습니다. FastAPI에서 제공하는 'Request' 클래스를 사용하여 요청과 관련된 정보를 얻을 수 있습니다. 이를 활용하여 요청의 경로, HTTP 메서드, 요청 본문 등을 기록할 수 있습니다. 그리고 의존성 주입을 통해 로깅에 사용할 로거 객체를 주입받아 로깅 작업을 수행할 수 있습니다. 이를 통해 모든 요청에 대한 로깅을 쉽게 구현할 수 있습니다.
요약하자면, FastAPI에서 미들웨어와 의존성 주입을 활용하여 요청 로깅 작업을 수행할 수 있습니다. 이를 통해 개발자들은 효율적이고 유지보수가 용이한 코드를 작성할 수 있습니다. 미들웨어를 사용하여 요청 처리 전과 후에 다양한 작업을 수행할 수 있으며, 의존성 주입을 통해 로거 객체를 주입받아 로깅 작업을 수행할 수 있습니다. 이러한 기능들을 적절히 활용하면 FastAPI를 활용한 개발 프로세스를 효과적으로 개선할 수 있습니다.