Python 在urllib3中使用证书

Python 在urllib3中使用证书,python,google-app-engine,ssl,Python,Google App Engine,Ssl,我是Python新手。我正在使用urllib3与api对话。我使用这个而不是请求的原因是我想在GAE上托管我的应用程序。我的应用程序使用证书。当我发布数据时,会出现以下错误: TypeError: __init__() got an unexpected keyword argument 'cert_reqs' 如何在我的urlopen呼叫中包含证书?下面是一段代码 CA_CERTS = ('client-2048.crt', 'client-2048.key') http = urllib

我是Python新手。我正在使用urllib3与api对话。我使用这个而不是请求的原因是我想在GAE上托管我的应用程序。我的应用程序使用证书。当我发布数据时,会出现以下错误:

TypeError: __init__() got an unexpected keyword argument 'cert_reqs'
如何在我的urlopen呼叫中包含证书?下面是一段代码

CA_CERTS = ('client-2048.crt', 'client-2048.key')

http = urllib3.PoolManager()
r = http.urlopen('POST', url, body=payload, headers={'X-Application': '???', 'Content-Type': 'application/x-www-form-urlencoded'}, cert_reqs='REQUIRED', ca_certs=CA_CERTS)
print r.status, r.data
您可以下拉到可以直接执行的级别:

from urllib3.connectionpool import HTTPSConnectionPool
conn = HTTPSConnectionPool('httpbin.org', ca_certs='/etc/pki/tls/cert.pem', cert_reqs='REQUIRED')
或者,更简单地说,或者通过
connection\u from\u url()
helper函数:

conn = urllib3.connection_from_url('https://httpbin.org', ca_certs='/etc/pki/tls/cert.pem', cert_reqs='REQUIRED')
请注意,
ca\u certs
是用于验证远程服务器证书的证书捆绑包的文件名。使用
证书文件
密钥文件
向远程服务器出示客户端证书:

conn = urllib3.connection_from_url('https://httpbin.org', cert_file='client-2048.crt', key_file='client-2048.key', ca_certs='/etc/pki/tls/cert.pem', cert_reqs='REQUIRED')
然后发出您的请求:

response = conn.request('POST', 'https://httpbin.org/post', fields={'field1':1234, 'field2':'blah'})
>>> print response.data
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "field1": "1234",
    "field2": "blah"
  },
  "headers": {
    "Accept-Encoding": "identity",
    "Connection": "close",
    "Content-Length": "220",
    "Content-Type": "multipart/form-data; boundary=048b02ad15274fc485c2cb2b6a280034",
    "Host": "httpbin.org",
    "X-Request-Id": "92fbc1da-d83e-439c-9468-65d27492664f"
  },
  "json": null,
  "origin": "220.233.14.203",
  "url": "http://httpbin.org/post"
}

您应该将
cert\u reqs='REQUIRED'
ca\u certs=ca\u certs
参数直接传递给
PoolManager()
实例化

因此,可以将原始示例更改为:

CA_CERTS=('client-2048.crt','client-2048.key')
http=urllib3.PoolManager(cert\u reqs='REQUIRED',ca\u certs=ca\u certs)
r=http.urlopen('POST',url,body=payload,headers={'X-Application':'?','Content-Type':'Application/X-www-form-urlencoded'})
打印r.状态、r.数据

传递
用户代理
标题似乎有帮助
在我的情况下,除了其他答案之外

不确定这是否是一种常见行为,但我的服务器在使用自签名证书且不使用
用户代理执行HTTPS请求时将返回
403-拒绝访问
错误

忽略证书时(即使用空的
ssl.SSLContext
),不需要
用户代理
头,请求将成功。只有在使用
ca\u certs
参数时,我才需要包含
用户代理

http=urllib3.PoolManager(cert\u reqs='REQUIRED',ca\u certs='/path/to/cacert.pem')
r=http.urlopen('GET',url,headers={'User-Agent':'myapp/v0.1.0'})
打印(r.数据)
我找不到任何来源,说明在使用自签名证书时可能需要
用户代理
。关于这一点的任何澄清都是非常受欢迎的


阅读有关用户代理的更多信息。

除非您使用套接字(启用计费),否则任何出站请求都将使用urlfetch。@TimHoffman:我很困惑。我有另一个应用程序运行在一个非计费帐户上,它使用urllib3和urlopen()是的,但它下面调用的是urlfetch,因此您的应用程序最终仅限于urlfetch提供的功能。连接池在appengine上对任何并发性都不是很有用。您应该查看异步请求