httpx request兼容性
HTTPX旨在与requests API广泛兼容,尽管在某些地方存在一些设计差异。
本文档概述了 API 的不同之处...
重定向
与 requests不同,HTTPX 在默认情况下不遵循重定向。
我们在这里的行为不同,因为自动重定向可以很容易地掩盖不必要的网络调用。
您仍然可以启用行为以自动跟踪重定向,但您需要明确执行此操作...
response = client.get(url, follow_redirects=True)
或者实例化客户端,默认情况下启用重定向跟随...
client = httpx.Client(follow_redirects=True)
客户端实例
requests.Session
的 HTTPX 等效值为 httpx.Client
。
session = requests.Session(**kwargs)
通常等效于
client = httpx.Client(**kwargs)
请求网址
response.url
将返回一个URL实例,而不是一个字符串。
如果需要字符串实例,请使用str(response.url)
。
确定下一个重定向请求
requests
库公开了一个response.next
属性,可用于获取下一个重定向请求。
session = requests.Session()
request = requests.Request("GET", ...).prepare()
while request is not None:
response = session.send(request, allow_redirects=False)
request = response.next
在 HTTPX 中,此属性改为命名为response.next_request
。例如:
client = httpx.Client()
request = client.build_request("GET", ...)
while request is not None:
response = client.send(request)
request = response.next_request
请求内容
对于上传原始文本或二进制内容,我们更喜欢使用content
参数,以便更好地将这种用法与上传表单数据的情况分开。
例如,content=...
用于上传原始内容:
# Uploading text, bytes, or a bytes iterator.
httpx.post(..., content=b"Hello, world")
和 data=...
用于发送表单数据:
# Uploading form data.
httpx.post(..., data={"message": "Hello, world"})
使用 data=<text/byte content>
将引发弃用警告,并且预计在 HTTPX 1.0 版本中将完全删除。
上传文件
HTTPX 严格强制要求上载文件必须以二进制模式打开,以避免因尝试上载以文本模式打开的文件而导致的字符编码问题。
内容编码
HTTPX使用utf-8
编码str
请求体。例如,当使用content=<str>
时,请求正文将在通过线路发送之前编码为utf-8
。这与使用latin1
的请求不同。如果需要显式编码,请显式传递编码的字节,例如content=<str>.encode("latin1")
。对于响应体,假设服务器没有发送显式编码,那么HTTPX将尽最大努力找出合适的编码。HTTPX使用charset_normalizer
猜测用于解码响应的编码。回退到那个位置,或者任何少于32个八位字节的内容都将使用utf-8
和error="replace"
解码器策略进行解码。
Cookies
如果使用client实例,则应始终在client上设置 Cookie,而不是按请求设置。
支持以下用法:
client = httpx.Client(cookies=...)
client.post(...)
不支持以下用法:
client = httpx.Client()
client.post(..., cookies=...)
我们更喜欢在这里强制实施更严格的 API,因为它提供了对 cookie 持久性的更清晰的期望,尤其是在发生重定向时。
状态代码
在我们的文档中,我们更喜欢大写版本,例如 codes.NOT_FOUND
,但也提供小写版本,以便与requests API
兼容。
请求包括 HTTPX 不支持的状态代码的各种同义词。
流式处理响应
HTTPX 提供了一个.stream()
接口,而不是使用stream=True
。这可确保流式处理响应始终在流块外部正确关闭,并使其在视觉上更清晰,流式处理 I/O API 可在哪些点与响应一起使用。
例如:
with httpx.stream("GET", "https://www.example.com") as response:
...
在stream()
块请求中,数据通过以下方式提供:
-
.iter_bytes()
- 而不是response.iter_content()
-
.iter_text()
- 而不是response.iter_content(decode_unicode=True)
-
.iter_lines()
- 对应于response.iter_lines()
-
.iter_raw()
- 用这个代替response.raw
-
.read()
- 阅读整个响应正文,制作request.text
和response.content
可用。
代理密钥
当httpx.Client(proxies={...})
用于映射到选定的不同代理时,我们使用完整的URL方案,例如proxies={"http://": ..., "https://": ...}
。
这与requestsproxies={"http": ..., "https": ...}
的用法不同。
此更改是为了更好地与更复杂的映射保持一致,其中可能还包括域名,例如proxies={"all://": ..., "all://www.example.com": None}
为将所有请求映射到代理,但对“www.example.com”的请求除外,这些请求具有显式排除。
另请注意,requests.Session.request(...)
允许proxies=...
参数,而不允许httpx.Client.request(...)
。
SSL 配置
使用Client
实例时,trust_env
、verify
和cert
参数应始终在客户端实例化时传递,而不是传递给请求方法。
如果需要多个不同的 SSL 配置,则应为每个 SSL 配置使用不同的客户端实例。
Request支持REQUESTS_CA_BUNDLE
指向文件或目录的请求。HTTPX支持SSL_CERT_FILE
(对于文件)和SSL_CERT_DIR
(对于目录)OpenSSL变量。
HTTP 方法上的请求正文
HTTP 的GET
、DELETE
、HEAD
和OPTIONS
方法被指定为不支持请求正文。为了与此保持一致,.get
、.delete
、.head
和.options
函数不支持content
、 files
、 data
或json
参数。
如果您确实需要使用这些 http 方法发送请求数据,则应改用.request泛型函数。
httpx.request(
method="DELETE",
url="https://www.example.com/",
content=b'A request body on a DELETE request.'
)
检查成功和失败响应
我们不支持response.is_ok
,因为那里的命名是模棱两可的,并且可能错误地暗示等同于response.status_code == codes.OK
.相反,我们提供response.is_success
属性,该属性可用于检查 2xx
响应。
请求实例化
在 HTTPX 中没有预准备请求的概念。如果您需要自定义请求实例化,请参见请求实例。
此外,httpx.Request()不支持auth 、timeout 、follow_redirects 、proxies、verify和cert参数。但是,这些在httpx.request 、httpx.get、httpx.post 等 以及 Client 实例中可用。
模拟
如果您需要模拟 HTTPX,就像requests
对responses
和requests-mock
测试实用程序一样,请参阅 RESPX。
网络层
requests将大部分 HTTP 网络代码推迟到优秀的 urllib3 库。
另一方面,HTTPX使用HTTPCore作为其核心HTTP网络层,这与urllib3不同。
查询参数
requests
忽略值为 None
的params
(例如 requests.get(..., params={"foo": None})
)。 HTTPX 不支持此功能
事件挂接
requests
允许事件挂钩改变 Request
和 Response
对象。有关request
的相关内容,请参阅文档中给出的示例。
在 HTTPX 中,事件挂钩可以访问请求和响应的属性,但事件挂钩回调不能改变原始请求/响应。
如果您正在寻找更多控制,请考虑查看自定义传输。