http.client
1. 개요
1. 개요
http.client는 파이썬 표준 라이브러리에 포함된 HTTP 및 HTTPS 클라이언트 프로토콜 구현 모듈이다. 이 모듈은 파이썬 소프트웨어 재단에 의해 개발되었으며, 파이썬 2.0 버전부터 표준 라이브러리의 일부로 제공되었다. 주된 용도는 웹 서버와의 통신을 위해 HTTP 프로토콜을 사용하는 네트워크 프로그래밍이다.
이 모듈은 저수준의 HTTP 클라이언트 인터페이스를 제공하여, 개발자가 HTTP 요청을 구성하고 HTTP 응답을 처리하는 세부적인 제어를 가능하게 한다. urllib.request와 같은 고수준 라이브러리가 내부적으로 http.client를 사용하기도 한다. http.client는 RFC 2616과 같은 HTTP/1.1 표준을 준수하며, GET과 POST를 포함한 다양한 HTTP 메서드를 지원한다.
http.client 모듈을 사용하면 TCP/IP 소켓 연결을 직접 관리하지 않고도 HTTP 클라이언트 기능을 구현할 수 있다. 이를 통해 웹 API 호출, 웹 페이지 내용 가져오기, 또는 RESTful 서비스와의 상호작용과 같은 웹 클라이언트 애플리케이션을 구축하는 데 활용된다. 모듈은 기본적인 HTTP 통신뿐만 아니라 HTTPS를 통한 보안 연결도 지원한다.
2. 주요 기능
2. 주요 기능
http.client 모듈은 파이썬 표준 라이브러리에 포함된 HTTP 및 HTTPS 클라이언트 프로토콜의 저수준 구현을 제공한다. 이 모듈의 핵심 기능은 소켓을 직접 다루지 않고도 HTTP 요청을 구성하고 서버로 전송하며, 그에 대한 응답을 받아 처리할 수 있는 API를 제공하는 것이다. 이를 통해 웹 서버와의 기본적인 통신을 가능하게 한다.
주요 기능으로는 다양한 HTTP 메서드를 지원하는 것이 있다. GET, POST, PUT, DELETE, HEAD 등 표준 HTTP 요청을 쉽게 구성하여 전송할 수 있다. 또한, 요청에 필요한 HTTP 헤더를 자유롭게 추가하거나 수정할 수 있어, 인증이나 쿠키 관리와 같은 세부적인 통신 제어가 가능하다.
이 모듈은 HTTPS 연결을 위한 SSL/TLS 암호화도 기본적으로 지원한다. http.client.HTTPSConnection 클래스를 사용하면 SSL 컨텍스트를 설정하여 보안 연결을 구축할 수 있다. 또한, 프록시 서버를 통한 연결과 같은 고급 네트워크 환경에서의 사용도 고려되어 있다.
http.client는 높은 수준의 추상화를 제공하는 urllib.request 같은 모듈과 달리, HTTP 프로토콜의 동작을 보다 세밀하게 제어할 수 있는 저수준 인터페이스를 지향한다. 따라서 HTTP 상태 코드나 응답 헤더를 직접 분석해야 하는 경우나, 특정한 네트워크 동작이 필요한 네트워크 프로그래밍에 적합하다.
3. 기본 사용법
3. 기본 사용법
http.client 모듈을 사용한 기본적인 HTTP 요청은 HTTPConnection 또는 HTTPSConnection 객체를 생성하는 것으로 시작한다. 서버 주소와 포트를 지정하여 연결 객체를 만든 후, request() 메서드를 호출해 GET이나 POST와 같은 요청을 보낼 수 있다. 요청을 보낸 후에는 getresponse() 메서드를 통해 서버의 응답을 받아야 한다. 이렇게 얻은 HTTPResponse 객체를 통해 응답 상태 코드, 헤더, 그리고 본문 데이터를 읽어올 수 있다.
가장 간단한 GET 요청의 예는 다음과 같다. 먼저 http.client.HTTPConnection 클래스를 임포트하고, 연결을 생성한 후 request() 메서드에 요청 메서드와 경로를 인자로 전달한다. 응답을 받은 후에는 read() 메서드로 응답 본문을 바이트열로 읽어와 적절히 디코딩하여 사용한다. 모든 작업이 끝나면 close() 메서드로 연결을 명시적으로 닫아야 한다.
http.client는 저수준 모듈이기 때문에, 요청 헤더를 설정하거나 POST 요청 시 본문 데이터를 보내는 것도 직접 처리해야 한다. request() 메서드의 세 번째 인자로 본문 데이터를 전달하고, 네 번째 인자로 헤더를 딕셔너리 형태로 지정할 수 있다. 예를 들어, Content-Type 헤더를 설정하여 JSON 데이터를 전송하거나, 사용자 에이전트를 지정하는 것이 일반적이다.
4. 요청 메서드
4. 요청 메서드
http.client 모듈은 HTTP 및 HTTPS 프로토콜을 사용하여 서버와 통신할 수 있는 다양한 HTTP 요청 메서드를 지원한다. 이 모듈을 사용하면 GET, POST, PUT, DELETE, HEAD, OPTIONS 등 주요 메서드를 포함한 표준 메서드를 모두 활용할 수 있다. 각 메서드는 서버에 특정한 동작을 요청하며, RESTful API와 같은 현대적인 웹 서비스를 구현하는 데 필수적이다.
요청 메서드를 사용하기 위해서는 먼저 HTTPConnection 또는 HTTPSConnection 객체를 생성하여 서버에 연결해야 한다. 연결이 설정되면 request() 메서드를 호출할 때 첫 번째 인자로 사용할 메서드명을 문자열로 지정한다. 예를 들어, conn.request("GET", "/path")는 서버의 특정 경로에 GET 요청을 보낸다. POST 요청이나 PUT 요청을 보낼 때는 body 매개변수를 통해 전송할 데이터를 함께 제공할 수 있다.
주요 메서드의 일반적인 용도는 다음과 같다. GET은 리소스를 조회할 때, POST는 새로운 리소스를 생성하거나 데이터를 제출할 때 사용된다. PUT은 기존 리소스를 전체적으로 업데이트할 때, PATCH는 리소스의 일부만 수정할 때 활용된다. DELETE는 리소스를 삭제할 때, HEAD는 응답 본문 없이 헤더 정보만 얻을 때, OPTIONS는 서버가 지원하는 메서드를 확인할 때 주로 사용된다.
이러한 메서드들은 http.client의 저수준 인터페이스를 통해 정밀하게 제어할 수 있어, 웹 크롤러, 자동화 스크립트, 또는 사용자 정의 HTTP 클라이언트를 개발하는 데 적합하다. 메서드 사용 후에는 반드시 getresponse()를 호출하여 서버의 HTTP 응답을 받아 처리해야 한다.
5. 응답 처리
5. 응답 처리
http.client 모듈에서 HTTP 요청을 보내면 HTTPResponse 객체가 반환된다. 이 객체는 서버로부터 받은 응답을 처리하기 위한 다양한 메서드와 속성을 제공한다. 가장 기본적인 응답 정보는 .status, .reason, .getheaders(), .getheader(name) 등을 통해 접근할 수 있다. .status는 HTTP 상태 코드를 정수로 반환하며, .reason은 해당 상태 코드에 대한 설명 문자열을 반환한다. 응답 헤더는 .getheaders() 메서드로 전체를 리스트로 받거나, .getheader('Content-Type')과 같이 특정 헤더 값을 조회할 수 있다.
응답 본문은 HTTPResponse 객체 자체가 파일 객체와 유사한 인터페이스를 가지므로, .read() 메서드를 호출하여 읽어야 한다. 이 메서드는 응답 본문 전체를 바이트열로 반환한다. 대용량 응답의 경우, .read(size)를 사용하여 일정 크기씩 청크로 읽거나, .readinto(buffer) 메서드를 활용하여 미리 할당된 버퍼에 읽어 들이는 방식으로 메모리 효율성을 높일 수 있다. 응답 본문을 읽은 후에는 .close() 메서드로 연결을 명시적으로 닫아야 하며, with 문을 사용하면 이를 자동으로 처리할 수 있다.
응답 처리 시 주의할 점은 응답 본문을 읽기 전에 상태 코드나 헤더를 먼저 확인하는 것이 일반적인 패턴이라는 것이다. 예를 들어, 상태 코드가 200(성공)인지 확인한 후에만 본문을 읽고 파싱하는 로직을 작성한다. 또한, Content-Type 헤더를 확인하여 응답이 JSON인지, HTML인지, 일반 텍스트인지 판단한 후에 적절한 디코딩(예: .decode('utf-8'))이나 파싱(예: json.loads())을 수행해야 한다.
6. 에러 처리
6. 에러 처리
http.client 모듈을 사용할 때 발생할 수 있는 네트워크 및 프로토콜 관련 예외를 적절히 처리하는 것은 안정적인 애플리케이션을 구축하는 데 필수적이다. 이 모듈은 여러 가지 내장 예외 클래스를 제공하여 다양한 실패 상황을 구분하여 처리할 수 있게 한다.
주요 예외 클래스로는 기본적인 HTTPException이 있으며, 이는 모든 http.client 관련 예외의 베이스 클래스 역할을 한다. 보다 구체적인 예외로는 서버로부터 잘못된 응답을 받았을 때 발생하는 BadStatusLine, 응답의 헤더 형식이 올바르지 않을 때 발생하는 InvalidURL과 HTTPResponse.read() 작업 중 발생하는 IncompleteRead 등이 있다. 또한, 소켓 수준의 연결 문제는 파이썬의 내장 socket.error (또는 OSError)로 발생하며, 이는 일반적으로 네트워크 연결 실패, 타임아웃, 호스트를 찾을 수 없는 경우 등을 의미한다.
에러 처리는 일반적으로 try...except 블록을 사용하여 수행된다. 네트워크 요청을 시도하는 코드를 try 블록 안에 작성하고, except 블록에서 특정 예외를 포착하여 대체 동작을 수행하거나 사용자에게 알리는 로직을 구현한다. 특히 HTTPConnection 객체의 request() 메서드 호출이나 HTTPResponse 객체에서 데이터를 읽는 과정은 예외 발생 가능성이 높은 지점이다. 적절한 예외 처리를 통해 프로그램이 예기치 않게 종료되는 것을 방지하고, 연결 재시도, 다른 서버로의 폴백(fallback), 사용자 친화적인 오류 메시지 표시 등의 복구 전략을 수립할 수 있다.
7. 고급 기능
7. 고급 기능
7.1. 연결 풀링
7.1. 연결 풀링
http.client 모듈은 HTTP 및 HTTPS 연결을 효율적으로 관리하기 위해 연결 풀링을 지원한다. 이 기능은 동일한 서버에 대한 반복적인 요청 시 매번 새로운 TCP 연결을 수립하는 오버헤드를 줄여준다. HTTPConnection 객체를 생성할 때 source_address나 timeout 같은 매개변수를 설정할 수 있으며, 이 객체는 내부적으로 연결을 재사용할 수 있는 상태로 유지한다.
연결 풀링의 핵심은 HTTPConnection 객체의 request() 메서드를 호출한 후, 같은 객체로 추가 요청을 보낼 수 있다는 점이다. 이때 close() 메서드를 명시적으로 호출하지 않으면, 소켓 연결은 열린 상태로 유지되어 다음 요청에 재사용된다. 이 방식은 특히 동일한 호스트에 여러 요청을 빠르게 보내야 하는 웹 스크래핑이나 API 호출 시 성능을 크게 향상시킨다.
고급 사용을 위해 http.client는 HTTPConnection의 하위 클래스인 HTTPSConnection을 제공하여 SSL/TLS 암호화 연결의 풀링도 가능하게 한다. 또한, HTTPConnection 클래스의 set_tunnel 메서드를 사용하면 프록시 서버를 경유하는 연결도 풀링 관리가 가능하다. 이러한 연결 풀링 메커니즘은 네트워크 대역폭 사용을 최적화하고 서버 부하를 줄이는 데 기여한다.
7.2. HTTPS/SSL
7.2. HTTPS/SSL
http.client 모듈은 기본적으로 HTTPS(SSL/TLS) 연결을 지원한다. 이를 통해 암호화된 통신 채널을 구축하여 데이터의 기밀성과 무결성을 보장할 수 있다. HTTPSConnection 클래스를 사용하면 SSL 인증서 검증을 포함한 보안 연결을 쉽게 설정할 수 있다. 이는 민감한 정보를 전송하거나 인증이 필요한 API와 통신할 때 필수적이다.
HTTPSConnection의 사용법은 HTTPConnection과 유사하지만, 추가적인 SSL 컨텍스트 매개변수를 받을 수 있다. 사용자는 ssl 모듈을 임포트하여 SSL 컨텍스트를 생성하고, 인증서 검증 정책이나 사용할 암호화 스위트 등을 세부적으로 제어할 수 있다. 특히 서버 인증서를 검증하지 않는 비보안 모드(예: ssl._create_unverified_context())는 개발 및 테스트 환경에서만 제한적으로 사용해야 한다.
기본적으로 모듈은 서버의 인증서를 검증하도록 설정되어 있다. 이는 중간자 공격과 같은 보안 위협을 방지하는 데 중요하다. 만약 자체 서명된 인증서를 사용하는 내부 서버에 접근해야 한다면, ssl 모듈을 통해 신뢰할 수 있는 인증서를 명시적으로 로드하는 방식으로 안전하게 연결을 구성할 수 있다.
7.3. 프록시 지원
7.3. 프록시 지원
http.client 모듈은 HTTP 및 HTTPS 요청을 보낼 때 프록시 서버를 경유하도록 설정하는 기능을 제공한다. 이를 통해 방화벽 뒤에 있는 클라이언트가 외부 네트워크에 접근하거나, 트래픽을 모니터링하거나, 캐시를 활용하는 등의 목적으로 프록시를 사용할 수 있다. 프록시 설정은 주로 HTTPConnection 또는 HTTPSConnection 객체를 생성할 때 proxy_host와 proxy_port 매개변수를 통해 이루어진다.
프록시를 통한 연결은 일반적인 직접 연결과는 다른 절차를 따른다. 클라이언트는 먼저 프록시 서버에 CONNECT 메서드를 사용하여 터널을 요청하고, 성공적으로 터널이 구축된 후에야 실제 목표 서버와의 SSL/TLS 핸드셰이크 또는 데이터 교환을 진행할 수 있다. http.client는 이러한 과정을 내부적으로 처리하여, 사용자가 프록시 설정만 하면 나머지 통신은 일반 연결과 동일한 방식으로 사용할 수 있도록 추상화한다.
프록시 서버가 인증을 요구하는 경우, Proxy-Authorization HTTP 헤더를 요청에 포함시켜야 한다. http.client에서는 set_tunnel 메서드를 사용하여 터널링 대상 호스트와 포트를 지정함과 동시에, 기본 인증 헤더를 설정할 수 있다. 또는, putheader 메서드를 직접 호출하여 헤더를 추가하는 방식으로도 프록시 인증 정보를 전달할 수 있다.
8. 다른 HTTP 클라이언트와의 비교
8. 다른 HTTP 클라이언트와의 비교
http.client 모듈은 파이썬의 저수준 HTTP 클라이언트 구현체이다. 이 모듈은 RFC 2616과 같은 HTTP 프로토콜 사양을 직접적으로 다루는 세밀한 제어가 필요할 때 주로 사용된다. 따라서 웹 서버와의 통신 과정에서 헤더를 직접 설정하거나, 청크 전송 인코딩과 같은 특정 프로토콜 기능을 명시적으로 관리해야 하는 경우에 적합하다. 그러나 일반적인 웹 개발이나 API 호출에는 더 높은 수준의 추상화를 제공하는 다른 라이브러리들이 더 널리 쓰인다.
가장 대표적인 대안은 requests 라이브러리이다. requests는 http.client 위에 구축된 써드파티 라이브러리로, 직관적인 API를 제공하여 코드를 훨씬 간결하고 가독성 높게 작성할 수 있게 한다. 예를 들어, 인증, 쿠키 관리, 세션 유지, JSON 직렬화 등이 자동으로 처리된다. 반면 http.client는 이러한 기능들을 수동으로 구현해야 하므로 개발 생산성이 낮다.
또 다른 표준 라이브러리 모듈인 urllib.request도 http.client보다 높은 수준의 인터페이스를 제공한다. urllib.request는 URL 열기, 기본적인 인증, 프록시 처리 등의 편의 기능을 포함하고 있어 http.client보다는 사용하기 쉽지만, requests 라이브러리만큼 완전하고 편리하지는 않다. http.client는 이러한 라이브러리들의 기반이 되는 핵심 프로토콜 계층으로, 내부 동작을 완전히 제어해야 하는 특수한 경우나 라이브러리 개발자에게 유용하다.
비동기 네트워크 프로그래밍이 필요한 현대적 애플리케이션에서는 aiohttp와 같은 비동기 IO 라이브러리가 선호된다. http.client 모듈 자체는 동기 방식으로 동작하므로, 많은 수의 동시 연결을 효율적으로 처리하는 비동기 환경에는 적합하지 않다. 결국, http.client의 사용은 HTTP 프로토콜의 저수준 세부 사항에 대한 완전한 통제가 최우선 요구사항일 때로 한정된다.
9. 사용 예제
9. 사용 예제
http.client 모듈을 사용한 기본적인 HTTP GET 요청과 응답 처리는 다음과 같은 코드 구조를 가진다. 먼저 http.client.HTTPConnection 객체를 생성하여 서버에 연결한 후, request() 메서드로 요청을 보내고 getresponse() 메서드로 응답 객체를 받는다. 응답의 상태 코드, 헤더, 본문을 읽어 처리할 수 있다.
```python
import http.client
# HTTP 연결 생성
conn = http.client.HTTPConnection("www.example.com")
try:
# GET 요청 보내기
conn.request("GET", "/")
# 응답 받기
response = conn.getresponse()
print(f"상태 코드: {response.status}")
print(f"응답 헤더: {response.getheaders()}")
# 응답 본문 읽기
data = response.read()
print(f"응답 본문: {data.decode()}")
finally:
# 연결 종료
conn.close()
```
보다 복잡한 요청, 예를 들어 POST 요청을 통해 JSON 데이터를 전송하거나 사용자 정의 HTTP 헤더를 추가하는 예제는 다음과 같다. request() 메서드의 body 매개변수에 데이터를, headers 매개변수에 딕셔너리 형태의 헤더를 전달한다. HTTPS를 사용하려면 http.client.HTTPSConnection 클래스를 사용하면 된다.
```python
import http.client
import json
# HTTPS 연결 생성 (보안 통신)
conn = http.client.HTTPSConnection("api.example.com")
# 전송할 데이터
payload = json.dumps({"key": "value"})
headers = {'Content-Type': 'application/json'}
try:
# POST 요청 보내기
conn.request("POST", "/endpoint", body=payload, headers=headers)
response = conn.getresponse()
if response.status == 200:
print("요청 성공:", response.read().decode())
else:
print(f"요청 실패. 상태 코드: {response.status}")
except Exception as e:
print(f"에러 발생: {e}")
finally:
conn.close()
```
이러한 예제들은 http.client가 저수준의 세밀한 제어가 가능한 HTTP 클라이언트 라이브러리임을 보여준다. REST API 호출, 웹 스크래핑, 또는 서버 상태 점검 등 다양한 네트워크 프로그래밍 작업에 활용될 수 있다.
