Python

[Python] Requests hooks - 응답에 대한 콜백 구현하기

비번변경 2024. 8. 9. 15:09

개요

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

https://onaeonae1.tistory.com/67

https://alexwlchan.net/2017/requests-hooks/