{"library":"ndg-httpsclient","title":"ndg-httpsclient: Enhanced HTTPS with PyOpenSSL","description":"ndg-httpsclient provides enhanced HTTPS support for Python's standard library modules `httplib` and `urllib2` (Python 2) or `http.client` and `urllib.request` (Python 3) using PyOpenSSL. It allows for advanced SSL/TLS features like Server Name Indication (SNI) and robust peer certificate verification, extending capabilities beyond the default standard library implementation. The current version is 0.5.1, with a relatively slow release cadence focused on compatibility and critical fixes.","language":"python","status":"active","last_verified":"Wed May 13","install":{"commands":["pip install ndg-httpsclient"],"cli":null},"imports":["from ndg.httpsclient.utils import open_url","from ndg.httpsclient.ssl_peer_verification import ServerSSLCertVerification","from ndg.httpsclient.ssl_peer_verification import SubjectAlternativeNameMatcher"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import sys\nimport ssl\n# PyOpenSSL is a dependency that ndg-httpsclient leverages\nfrom OpenSSL import SSL\n\n# ndg-httpsclient patches these modules, so they should benefit from its enhancements\nif sys.version_info[0] >= 3:\n    import urllib.request as request_mod\n    import http.client as http_client_mod\nelse:\n    import urllib2 as request_mod\n    import httplib as http_client_mod\n\n# The primary utility for direct use is open_url\nfrom ndg.httpsclient.utils import open_url\n\n# For this example, we'll try a common HTTPS URL.\n# In a real-world scenario, you might pass specific client certificates (c, k)\n# or a custom CA bundle (ca) for peer verification.\ntarget_url = \"https://www.google.com\"\n\nprint(f\"Attempting to connect to {target_url} using ndg-httpsclient's open_url...\")\n\ntry:\n    # open_url utilizes the PyOpenSSL-backed HTTPS handling provided by ndg-httpsclient\n    # For more robust verification, you'd provide `ca='path/to/ca-bundle.pem'`\n    response = open_url(target_url)\n\n    print(f\"Connection successful!\")\n    print(f\"HTTP Status Code: {response.getcode()}\")\n    print(f\"Content-Type: {response.info()['Content-Type']}\")\n    # Read and decode a small part of the content to demonstrate success\n    # Do not read full content for quickstart to avoid large output\n    content_snippet = response.read(200).decode('utf-8', errors='ignore')\n    print(f\"Partial Content: {content_snippet}...\")\n\nexcept SSL.Error as e:\n    print(f\"SSL Error during connection: {e}\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")","lang":"python","description":"This quickstart demonstrates using `ndg-httpsclient`'s `open_url` utility to make an HTTPS request. This function internally leverages the PyOpenSSL-enhanced `HTTPSHandler` that the library integrates into Python's standard HTTP client modules. For more advanced use, like client certificate authentication or custom CA bundles, additional arguments can be passed to `open_url`.","tag":null,"tag_description":null,"last_tested":"2026-04-24","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-13","installed_version":"0.5.1","pypi_latest":"0.5.1","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":2.5,"avg_import_s":0.6,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.46,"mem_mb":10.8,"disk_size":"35.9M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.45,"mem_mb":10.6,"disk_size":"34.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.6,"import_time_s":0.35,"mem_mb":10.8,"disk_size":"36M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":10.6,"disk_size":"35M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.72,"mem_mb":12.2,"disk_size":"38.6M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.85,"mem_mb":12.1,"disk_size":"37.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.4,"import_time_s":0.66,"mem_mb":12.2,"disk_size":"39M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.69,"mem_mb":12.1,"disk_size":"38M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.87,"mem_mb":14,"disk_size":"30.4M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.9,"mem_mb":13.8,"disk_size":"29.3M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.2,"import_time_s":0.84,"mem_mb":14,"disk_size":"31M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":1.18,"mem_mb":13.8,"disk_size":"30M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.47,"mem_mb":10.4,"disk_size":"29.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":10.3,"disk_size":"28.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.4,"import_time_s":0.51,"mem_mb":10.4,"disk_size":"30M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.63,"mem_mb":10.3,"disk_size":"29M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.36,"mem_mb":10.9,"disk_size":"36.2M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.42,"mem_mb":10.7,"disk_size":"35.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.1,"import_time_s":0.39,"mem_mb":10.9,"disk_size":"37M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"ndg-httpsclient","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.4,"mem_mb":10.7,"disk_size":"35M"}]}}