Requests PreparedRequest와 누락된 환경 설정
준비된 사용자 정의 요청을 Requests의 일반 프록시 및 CA 처리와 맞추되 모든 저수준 send가 프록시를 무시한다고 가정하지 마세요.
요청이 session.get()에서는 되지만 PreparedRequest로 다시 작성한 뒤 인증서 검증에 실패할 수 있습니다. 저수준 send 경로는 일반 request 메서드와 같은 환경 병합을 하지 않습니다.
import requests
with requests.Session() as session:
request = requests.Request("GET", "https://example.com/")
prepared = session.prepare_request(request)
settings = session.merge_environment_settings(
prepared.url, {}, None, None, None
)
response = session.send(
prepared,
timeout=(5, 15),
**settings,
)
response.raise_for_status()
print(response.status_code)
원하는 URL 변경을 마친 뒤 최종 준비된 URL로 병합하세요. 프록시와 우회 결정은 목적지에 따라 달라지므로 이전 URL로 얻은 설정이 실제 전송 요청에 맞지 않을 수 있습니다.
CA 설정은 놓치기 쉽습니다
일반 환경 신뢰가 켜져 있고 검증을 명시적으로 재정의하지 않았다면 병합은 REQUESTS_CA_BUNDLE와 대체 CURL_CA_BUNDLE를 고려합니다. 기본 verify로 send를 직접 호출하면 이 CA 조회를 하지 않습니다. 검증을 끄는 것은 차이를 감출 뿐 원하는 인증서 저장소를 제공하지 않습니다.
Session.prepare_request()는 세션의 준비 동작도 적용합니다. Request.prepare()로 요청을 직접 만드는 것은 별도 선택입니다. 세션 쿠키나 다른 세션 준비가 자동 적용될 것으로 기대하지 마세요.
프록시에는 더 구체적인 규칙이 있습니다
모든 PreparedRequest가 프록시 환경 변수를 무시한다는 말은 부정확합니다. Requests 2.34.2에서 send는 proxies 키워드 인수가 없을 때 기본 프록시를 결정합니다. send에 proxies={}를 주면 그 특정 기본값 결정 분기를 건너뜁니다.
merge_environment_settings에 전달하는 빈 딕셔너리는 역할이 다릅니다. 병합은 적용 가능한 환경 경로를 채운 뒤 send에 전달할 수 있습니다. 두 코드에서 빈 딕셔너리가 있다는 사실만 보면 이를 받는 메서드가 다르다는 점을 놓칩니다.
사용자 정의 요청 구성 코드에서 준비, 환경 병합, 전송을 함께 두세요. 앱이 의도적으로 trust_env=False를 쓰면 병합은 그 정책을 따릅니다. 환경 설정을 일부러 끈 클라이언트에 강제로 적용하는 수단이 아닙니다.