개요
Python Tornado를 사용해서 API를 개발하고 있는데, 다른 서버에 요청을 보낸 후 추가로 처리해야 하는 부분을 콜백 방식으로 구현하려고 한다.
관련하여 Requests 라이브러리에서 제공하는 hooks에 대해 적어둔다.
+ tornado에서 httpclient.HTTPRequest를 사용하여 요청을 보낼 수도 있는데, 이번 글에선 requests 라이브러리를 사용해 보겠다.
hooks
requests 라이브러리는 요청 프로세스 일부를 조작하거나 이벤트 처리 신호를 보내는 데 사용할 수 있는 hook 기능을 제공한다. requests 응답 후에 호출되는 콜백 함수에 해당한다.
실행할 콜백함수는 요청 시 hooks 매개변수에 hook 이름을 키로 하고 실행할 함수를 값으로 하는 딕셔너리 형식으로 전달한다. 함수는 리스트로 묶어 여러 함수를 전달할 수 있으며, 전달된 순서대로 호출된다.
hooks={'response': print_url}
hooks={'response': [print_url, record_hook]}
-- 예시
requests.get('https://httpbin.org/', hooks={'response': print_url})
requests.post('https://httpbin.org/', hooks={'response': [print_url, record_hook]})
전달하는 콜백함수는 첫 번째 매개변수로 응답을 전달해야 하며, 예외도 자체적으로 처리해야 한다.
def print_url(r, *args, **kwargs):
print(r.url)
또한 값을 반환하면 응답을 변경하는 것으로 처리되므로 주의해야 한다.
🤔 전달하는 함수의 첫번째 매개변수가 response로 지정되어 있어서 첫번째 매개변수로 인스턴스가 전달되어야 하는 클래스 내부 함수로 정의하여 사용하기는 어려울 것 같다.
테스트
간단히 요청에 대한 응답의 상태 코드와 내용을 출력하는 함수를 실행해 본다.
import requests
def print_response(resp, *args, **kwargs):
print(resp.status_code)
print(resp.json())
if __name__ == '__main__':
requests.get('http://localhost:8888',
hooks={'response': print_response})
추가적인 함수 호출이 없어도 전달한 함수가 잘 실행된 것을 확인할 수 있다. 다만 보통 함수 실행하는 함수에는 전달할 매개변수가 있기 마련이라 매개변수를 전달하여 실행하는 방법에 대해서도 고민을 해봐야 할 것 같다.
참고 문서
https://requests.readthedocs.io/en/latest/user/advanced/#event-hooks