{"library":"pyjwt-key-fetcher","title":"PyJWT Key Fetcher","description":"PyJWT Key Fetcher is an async Python library designed to fetch JSON Web Key Sets (JWKS) for JWT token verification. It automatically retrieves issuer configurations (e.g., from OpenID Connect discovery endpoints) to locate JWKS URIs and fetch the correct public keys. This library acts as an improved async replacement for `PyJWKClient` from PyJWT. The current version is 0.8.0, and it maintains a relatively active release cadence with several updates per year.","language":"python","status":"active","last_verified":"Sun May 17","install":{"commands":["pip install pyjwt-key-fetcher"],"cli":null},"imports":["from pyjwt_key_fetcher import AsyncKeyFetcher","from pyjwt_key_fetcher.provider import Provider"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import asyncio\nimport jwt\nfrom pyjwt_key_fetcher import AsyncKeyFetcher\n\nasync def main():\n    # Example token from PyJWT documentation for demonstration\n    # In a real app, this would come from an Authorization header\n    token = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRTFRVVJCT1RNNE16STVSa0ZETlRZeE9UVTFNRGcyT0Rnd1EwVXpNVGsxUWpZeVJrUkZRdyJ9.eyJpc3MiOiJodHRwczovL2Rldi04N2V2eDlydS5hdXRoMC5jb20vIiwic3ViIjoiYVc0Q2NhNzl4UmVMV1V6MGFFMkg2a0QwTzNjWEJWdENAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZXhwZW5zZXMtYXBpIiwiaWF0IjoxNTcyMDA2OTU0LCJleHAiOjE1NzIwMDY5NjQsImF6cCI6ImFXNENjYTc5eFJlTFdVejBhRTJINmtEME8zY1hCVnRDIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.PUxE7xn52aTCohGiWoSdMBZGiYAHwE5FYie0Y1qUT68IHSTXwXVd6hn02HTah6epvHHVKA2FqcFZ4GGv5VTHEvYpeggiiZMgbxFrmTEY0csL6VNkX1eaJGcuehwQCRBKRLL3zKmA5IKGy5GeUnIbpPHLHDxr-GXvgFzsdsyWlVQvPX2xjeaQ217r2PtxDeqjlf66UYl6oY6AqNS8DH3iryCvIfCcybRZkc_hdy-6ZMoKT6Piijvk_aXdm7-QQqKJFHLuEqrVSOuBqqiNfVrG27QzAPuPOxvfXTVLXL2jek5meH6n-VWgrBdoMFH93QEszEDowDAEhQPHVs0xj7SIzA\"\n\n    fetcher = AsyncKeyFetcher(valid_issuers=[\"https://dev-87evx9ru.auth0.com/\"])\n    try:\n        key_entry = await fetcher.get_key(token)\n        # The fetched key_entry can then be used with PyJWT's decode function\n        decoded_token = jwt.decode(\n            jwt=token,\n            options={\"verify_exp\": False}, # Set to True for production\n            audience=\"https://expenses-api\",\n            issuer=\"https://dev-87evx9ru.auth0.com/\",\n            **key_entry\n        )\n        print(\"Successfully decoded token:\", decoded_token)\n    except Exception as e:\n        print(f\"Error decoding token: {e}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())","lang":"python","description":"This example demonstrates how to use `AsyncKeyFetcher` to retrieve a signing key from a JWT's issuer, and then use that key with `PyJWT` to decode and verify the token. It includes `valid_issuers` for security and explicitly passes `audience` and `issuer` to `jwt.decode` for full validation.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-17","installed_version":"0.8.0","pypi_latest":"0.8.0","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":5.7,"avg_import_s":0.74,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.62,"mem_mb":16.6,"disk_size":"50.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":6.6,"import_time_s":0.48,"mem_mb":16.6,"disk_size":"54M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.79,"mem_mb":17.7,"disk_size":"53.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":5.4,"import_time_s":0.73,"mem_mb":17.7,"disk_size":"57M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.94,"mem_mb":18.1,"disk_size":"45.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":4.2,"import_time_s":0.92,"mem_mb":18.1,"disk_size":"49M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.95,"mem_mb":18.5,"disk_size":"44.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":4.6,"import_time_s":0.91,"mem_mb":18.5,"disk_size":"48M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.55,"mem_mb":16.4,"disk_size":"52.2M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyjwt-key-fetcher","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":7.6,"import_time_s":0.55,"mem_mb":16.4,"disk_size":"56M"}]}}