본문 바로가기
파이썬

[Python] HTTPX: 파이썬 HTTP 클라이언트

by 책 읽는 개발자_테드 2022. 4. 28.
반응형

목차

· HTTPX란?

· 시작하기

· 사용법


HTTPX란?


· sync, async API들을 제공하고, HTTP1.1과 HTTP/2를 모두 제공하는 완전한 기능을 갖춘 파이썬 3를 위한 클라이언트 

· 파이썬 3.6 이상 버전에서 사용할 수 있다.

 

시작하기


설치

$ pip install httpx

 

- HTTP/2를 지원하고 싶다면,

$ pip install httpx[http2]

 

- brotli decoder를 지원하고 싶다면,

$ pip install httpx[brotli]

 

간단한 예제

import httpx


response = httpx.get('https://www.example.org/')
print("response:", response)
print("response.status_code:", response.status_code)
print("response.headers['content-type']:", response.headers['content-type'])
print("response.text:", response.text)

결과

 

사용법


HTTP GET, PUT, DELETE, HEAD, OPTIONS 메서드 사용하기

import httpx

r = httpx.get('https://httpbin.org/get')
print(r)

r = httpx.put('https://httpbin.org/put', data={'key': 'value'})
print(r)

r = httpx.delete('https://httpbin.org/delete')
print(r)

r = httpx.head('https://httpbin.org/get')
print(r)

r = httpx.options('https://httpbin.org/get')
print(r)

.결과

 

URL에 파라미터 전달하기

· params 키워드를 사용하면, 요청에 URL 쿼리 파라미터를 추가할 수 있다.

import httpx

 
params = {'key1': 'value1', 'key2': 'value2'}
response = httpx.get('https://httpbin.org/get', params=params)

 

· 값이 어떻게 URL 문자열로 인코딩되지는 확인하기 위해 요청에 사용된 결과 URL을 검사할 수 있다.

print(response.url)

결과

 

· 아이템들의 리스트를 값으로 전달할 수도 있다.

params = {'key1': 'value1', 'key2': ['value2', 'value3']}
response = httpx.get('https://httpbin.org/get', params=params)
print(response.url)

결과

 

Response content

· HTTPX는 응답 컨텐츠를 Unicode text로 자동 디코딩 한다.

import httpx

response = httpx.get('https://www.example.org/')
print(response.text)
 

결과

 

· 어떤 인코딩이 응답 디코드에 사용되는지 확인할 수 있다.

print(response.encoding)
 

결과

 

· 어떤 경우에는 응답이 명확한 인코딩을 포함하지 않을 수 있다. 이러한 경우 HTTPX는 자동으로 인코딩을 결정한다.

print(response.encoding)
print(response.text)

결과

 

· 표준 동작을 재정의하고, 사용할 인코딩을 명시적으로 설정할 수 있다.

response.encoding = 'ISO-8859-1'

 

JSON Response Content

· Web API 응답을 JSON으로 인코딩할 수 있다.

결과

 

Custom Headers

· headers 키워드 인수를 사용하면, 발신 요청에 추가 헤더를 포함할 수 있다.

import httpx

url = 'https://httpbin.org/headers'
headers = {'user-agent': 'my-app/0.0.1'}
response = httpx.get(url, headers=headers)

 

Form 인코딩 데이터 전송하기

· POST, PUT 같은 요청은 요청 바디에 데이터를 포함할 수 있다. 흔한 방법 중 하나는 HTML 폼을 위해 사용되는 form-encoded 데이터를 포함하는 것이다. 

import httpx

data = {'key1': 'value1', 'key2': 'value2'}
response = httpx.post("https://httpbin.org/post", data=data)
print(response.text)

 

· from-encoded 데이터는 주어진 키에 여러 값들을 포함 수 있다.

data = {'key1': ['value1', 'value2']}

 

Multipart 인코딩을 통해 파일 업로드 하기

· Http multipart 인코딩을 사용하여 파일을 업로드할 수 있다.

import httpx

files = {'upload-file': open("./test", 'rb')}
response = httpx.post("https://httpbin.org/post", files=files)
print(response.text)

결과

 

· 파일 값에 튜플 아이템들을 사용하여, 파일 이름과 컨텐츠 타입을 명시적으로 설정할 수 있다.

import httpx


files = {'upload-file': ('./test', open("./test", 'rb'), 'application/json')}
response = httpx.post("https://httpbin.org/post", files=files)
print(response.text)
 

· data=... 매개변수를 사용하면, 파일이 아닌 데이터 필드를 multipart form에 포함시킬 수 있다.

import httpx


data = {'message': 'Hello, world!'}
files = {'file': open('./test', 'rb')}
r = httpx.post("https://httpbin.org/post", data=data, files=files)
print(r.text)​

결과

 

JSON 인코딩 Data 전송하기

· json=... 매개변수를 사용하면 json 데이터를 요청에 포함할 수 있다.

import httpx

data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']}
response = httpx.post("https://httpbin.org/post", json=data)
print(response.text)

결과

 

Response Status Codes

· 응답의 HTTP 상태 코드를 확인할 수 있다.

import httpx


response = httpx.get('https://httpbin.org/get')
print(response.status_code)

 

· 텍스트 구문을 통해 상태 코드를 쉽게 사용할 수 있다.

# informational
CONTINUE = 100, "Continue"
SWITCHING_PROTOCOLS = 101, "Switching Protocols"
PROCESSING = 102, "Processing"
EARLY_HINTS = 103, "Early Hints"
# success
OK = 200, "OK"
CREATED = 201, "Created"
ACCEPTED = 202, "Accepted"
NON_AUTHORITATIVE_INFORMATION = 203, "Non-Authoritative Information"
NO_CONTENT = 204, "No Content"
RESET_CONTENT = 205, "Reset Content"
PARTIAL_CONTENT = 206, "Partial Content"
MULTI_STATUS = 207, "Multi-Status"
ALREADY_REPORTED = 208, "Already Reported"
IM_USED = 226, "IM Used"
# redirection
MULTIPLE_CHOICES = 300, "Multiple Choices"
MOVED_PERMANENTLY = 301, "Moved Permanently"
FOUND = 302, "Found"
SEE_OTHER = 303, "See Other"
NOT_MODIFIED = 304, "Not Modified"
USE_PROXY = 305, "Use Proxy"
TEMPORARY_REDIRECT = 307, "Temporary Redirect"
PERMANENT_REDIRECT = 308, "Permanent Redirect"
# client error
BAD_REQUEST = 400, "Bad Request"
UNAUTHORIZED = 401, "Unauthorized"
PAYMENT_REQUIRED = 402, "Payment Required"
FORBIDDEN = 403, "Forbidden"
NOT_FOUND = 404, "Not Found"
METHOD_NOT_ALLOWED = 405, "Method Not Allowed"
NOT_ACCEPTABLE = 406, "Not Acceptable"
PROXY_AUTHENTICATION_REQUIRED = 407, "Proxy Authentication Required"
REQUEST_TIMEOUT = 408, "Request Timeout"
CONFLICT = 409, "Conflict"
GONE = 410, "Gone"
LENGTH_REQUIRED = 411, "Length Required"
PRECONDITION_FAILED = 412, "Precondition Failed"
REQUEST_ENTITY_TOO_LARGE = 413, "Request Entity Too Large"
REQUEST_URI_TOO_LONG = 414, "Request-URI Too Long"
UNSUPPORTED_MEDIA_TYPE = 415, "Unsupported Media Type"
REQUESTED_RANGE_NOT_SATISFIABLE = 416, "Requested Range Not Satisfiable"
EXPECTATION_FAILED = 417, "Expectation Failed"
IM_A_TEAPOT = 418, "I'm a teapot"
MISDIRECTED_REQUEST = 421, "Misdirected Request"
UNPROCESSABLE_ENTITY = 422, "Unprocessable Entity"
LOCKED = 423, "Locked"
FAILED_DEPENDENCY = 424, "Failed Dependency"
TOO_EARLY = 425, "Too Early"
UPGRADE_REQUIRED = 426, "Upgrade Required"
PRECONDITION_REQUIRED = 428, "Precondition Required"
TOO_MANY_REQUESTS = 429, "Too Many Requests"
REQUEST_HEADER_FIELDS_TOO_LARGE = 431, "Request Header Fields Too Large"
UNAVAILABLE_FOR_LEGAL_REASONS = 451, "Unavailable For Legal Reasons"
# server errors
INTERNAL_SERVER_ERROR = 500, "Internal Server Error"
NOT_IMPLEMENTED = 501, "Not Implemented"
BAD_GATEWAY = 502, "Bad Gateway"
SERVICE_UNAVAILABLE = 503, "Service Unavailable"
GATEWAY_TIMEOUT = 504, "Gateway Timeout"
HTTP_VERSION_NOT_SUPPORTED = 505, "HTTP Version Not Supported"
VARIANT_ALSO_NEGOTIATES = 506, "Variant Also Negotiates"
INSUFFICIENT_STORAGE = 507, "Insufficient Storage"
LOOP_DETECTED = 508, "Loop Detected"
NOT_EXTENDED = 510, "Not Extended"
NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required"

 

- 예시:

print(response.status_code == httpx.codes.OK)

결과

 

· 2XX 성공 코드가 아닌 응답에 대해 예외를 일으킬 수 있다.

not_found = httpx.get('https://httpbin.org/status/404')
not_found.raise_for_status()

결과

 

Response Headers

· 응답 헤더는 dictionary와 유사한 인터페이스로 사용할 수 있다.

import httpx


response = httpx.get('https://httpbin.org/get')
print(response.headers)

결과

- 단일 응답 헤더의 여러 값들은 RFC 7230에 따라 단일 쉼표로 구분된 값으로 표시된다. 

 

· 헤더 데이터 타입대소문자를 구분하지 않으므로 모든 대문자를 사용할 수 있다.

print(response.headers['Content-Type'])
print(response.headers['content-type'])
print(response.headers.get('Content-Type'))
print(response.headers.get('content-type'))

결과

 

쿠키(Cookies)

· 응답에 설정된 모든 쿠키는 쉽게 액세스할 수 있다.

import httpx


response = httpx.get('https://httpbin.org/cookies/set?chocolate=chip')
print(response.cookies['chocolate'])

결과

 

· cookies 매개변수를 사용하면, 외부 요청에 쿠키를 포함할 수 있다.

cookies = {"ted": "robin"}
response = httpx.get('https://httpbin.org/cookies', cookies=cookies)
print(response.json())

결과

· 쿠키는 도메인 또는 경로 별로 쿠키에 접근하기 위한 추가적인 API가 있는, Cookies 인스턴스에서 반환된다.

cookies = httpx.Cookies()
cookies.set('cookie_on_domain', 'hello, there!', domain='httpbin.org')
cookies.set('cookie_off_domain', 'nope', domain='example.org')
response = httpx.get('http://httpbin.org/cookies', cookies=cookies)
print(response.json())

결과

 

인증(Authentication)

· HTTPX는 기본 및 다이제스트 HTTP 인증을 지원한다.

TODO: HTTP 기본 및 다이제스트 인증

 

· 기본 인증 자격 증명을 제공하려면 2-tuple의 일반 텍스트 str 또는 bytes 객체를 요청 함수에 대한 auth 인수로 전달한다.

httpx.get("https://example.com", auth=("my_user", "password123"))

 

· 다이제스트 인증을 위한 자격 증명을 제공하려면, 일반 텍스트 사용자 이름과 암호를 인수로 사용하여 DigestAuth 객체를 인스턴스화해야 한다. 이후 해당 객체는 요청 메서드에 auth 인수로 전달할 수 있다.

auth = httpx.DigestAuth("my_user", "password123")
httpx.get("https://example.com", auth=auth)

 

 

TODO: Binary Response Content, Sending Binary Request Data, Streaming ResponsesStreaming Responses, Redirection and History, Timeouts

 

출처

https://www.python-httpx.org/

반응형

댓글