SSL - HTTPX (original) (raw)
When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates (a.k.a. CA bundle) delivered by a trusted certificate authority (CA).
Enabling and disabling verification
By default httpx will verify HTTPS connections, and raise an error for invalid SSL cases...
>>> httpx.get("https://expired.badssl.com/") httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:997)
You can disable SSL verification completely and allow insecure requests...
>>> httpx.get("https://expired.badssl.com/", verify=False) <Response [200 OK]>
Configuring client instances
If you're using a Client()
instance you should pass any verify=<...>
configuration when instantiating the client.
By default the certifi CA bundle is used for SSL verification.
For more complex configurations you can pass an SSL Context instance...
`` import certifi import httpx import ssl
This SSL context is equivelent to the default verify=True
.
ctx = ssl.create_default_context(cafile=certifi.where()) client = httpx.Client(verify=ctx) ``
Using the truststore package to support system certificate stores...
`import ssl import truststore import httpx
Use system certificate stores.
ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) client = httpx.Client(verify=ctx) `
Loding an alternative certificate verification store using the standard SSL context API...
`import httpx import ssl
Use an explicitly configured certificate store.
ctx = ssl.create_default_context(cafile="path/to/certs.pem") # Either cafile or capath. client = httpx.Client(verify=ctx) `
Client side certificates
Client side certificates allow a remote server to verify the client. They tend to be used within private organizations to authenticate requests to remote servers.
You can specify client-side certificates, using the .load_cert_chain() API...
ctx = ssl.create_default_context() ctx.load_cert_chain(certfile="path/to/client.pem") # Optionally also keyfile or password. client = httpx.Client(verify=ctx)
Working with SSL_CERT_FILE
and SSL_CERT_DIR
Unlike requests
, the httpx
package does not automatically pull in the environment variables SSL_CERT_FILE or SSL_CERT_DIR. If you want to use these they need to be enabled explicitly.
For example...
`` # Use SSL_CERT_FILE
or SSL_CERT_DIR
if configured.
Otherwise default to certifi.
ctx = ssl.create_default_context( cafile=os.environ.get("SSL_CERT_FILE", certifi.where()), capath=os.environ.get("SSL_CERT_DIR"), ) client = httpx.Client(verify=ctx) ``
Making HTTPS requests to a local server
When making requests to local servers, such as a development server running on localhost
, you will typically be using unencrypted HTTP connections.
If you do need to make HTTPS connections to a local server, for example to test an HTTPS-only service, you will need to create and use your own certificates. Here's one way to do it...
- Use trustme to generate a pair of server key/cert files, and a client cert file.
- Pass the server key/cert files when starting your local server. (This depends on the particular web server you're using. For example, Uvicorn provides the
--ssl-keyfile
and--ssl-certfile
options.) - Configure
httpx
to use the certificates stored inclient.pem
.
ctx = ssl.create_default_context(cafile="client.pem") client = httpx.Client(verify=ctx)