Twine unequivocally refuses to use self-signed SSL certs:

I genuinely can’t fathom how “switch to plain HTTP” would be a better recommendation over “let’s add a —trusted-host” (@jaraco’s comment on issue 387), but here we are.

Easy option: SSL cert bundle

You can pass --cert to Twine to specify a certificate bundle to use, but it has to include the entire certificate chain all the way back to the root CA! A typical “just pull the domain cert from the browser” does NOT give you this!

Second easy option: fork with support

Several forks of Twine exist which have added support for this feature, typically among others:

  1. https://github.com/strayge/twine-unofficial (seems like last maintained early 2023)
  • there are of these but i closed all the tabs and can’t find them anymore :(

Monkey-patching out cert validation

You can also monkey-patch Twine to nuke its ability to verify SSL certificates.

Security hole

This is a bad idea, and if either of the two “easy” options work for you, you should definitely do that instead. This opens you up to man-in-the-middle attacks!

I blended together a monkey-patch from the closed-not-planned PR 463 and twine-unofficial to come up with this patch that seems to work (py 3.13):

import twine.repository
import twine.__main__
import urllib3
 
def kill_session_verify(self, *args, **kwargs):
    self.session.verify = False
    
def install_hook():
    twine.repository.Repository.set_certificate_authority = kill_session_verify
    urllib3.disable_warnings()
    
def main():
    install_hook()
    twine.__main__.main()
    
if __name__ == '__main__':
    main()

Save this as something like twine_hacked.py and then call it instead of the twine module. Viola.

python