I work in an environment where we are required to use a self-signed SSL certificate (not my fault, and I cannot do anything to change this).
Historically, we have been able to set the SSL_CERT_FILE environment variable to use this certificate and urllib.request.urlopen() works just fine. This is true up to Python 3.12. With Python 3.13, however, the first script below fails to open the specified URL. In order to retrieve the same result in Python 3.13, I have to use the second script below (basically, finding the self-signed cert file myself, constructing an SSLContext with that file, and handing that off to urlopen).
Code that works in Python<=3.12
#!/usr/bin/env python
import os
import ssl
from urllib.request import urlopen
if __name__ == "__main__":
url = "https://docs.python.org/3.10/library/ssl.html#module-ssl"
with urlopen(url) as fh:
data = fh.read()
print(f"Retrieved {len(data)} bytes.")
To reproduce this behavior in Python 3.13, I have to change the code:
#!/usr/bin/env python
import os
import ssl
from urllib.request import urlopen
if __name__ == "__main__":
url = "https://docs.python.org/3.10/library/ssl.html#module-ssl"
cafile = os.getenv("SSL_CERT_FILE")
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations(cafile=cafile)
with urlopen(url, context=context) as fh:
data = fh.read()
print(f"Specifying CERT file: retrieved {len(data)} bytes.")
My question is: Is the use of SSL_CERT_FILE intentionally or accidentally deprecated in Python 3.13?
From the documentation of urllib.urlopen:
Changed in version 3.13: Remove cafile, capath and cadefault parameters: use the context parameter instead.
These parameters where used when calling ssl.create_default_context which ultimately used SSL_CTX_load_verify_locations, the very function which then used SSL_CERT_FILE unless a cafile was explicitly given.
Since these parameters are now removed ssl.create_default_context is no longer called and therefore SSL_CERT_FILE no longer works.
Given that the change is documented it looks intentional. It is not clear though if it was also intentional that SSL_CERT_FILE stops working as a side effect. But it isn't clear either if SSL_CERT_FILE was even officially supported (which would include it being documented) or if this was just an undocumented side effect of calling SSL_CTX_load_verify_locations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With