Typing stubs for PyJWT (jwt package)
This library provides PEP 561 type stubs for the popular `PyJWT` library, which is commonly imported as `jwt`. It enables static type checkers like MyPy, PyCharm, and Pyright to analyze code that uses `PyJWT`. `types-jwt` is part of the `typeshed` project, which centrally manages type definitions for many third-party Python packages. `types-jwt` version 0.1.3 was released in May 2021. However, it's important to note that since `PyJWT` version 2.0.0 (released December 2020) and later include their own inline type annotations, `types-jwt` is primarily relevant for projects using older versions of `PyJWT` (pre-2.0.0) or specific legacy setups.
Common errors
-
ModuleNotFoundError: No module named 'jwt'
cause The `PyJWT` runtime library, which provides the `jwt` module, is not installed in your Python environment. You may have only installed `types-jwt`, which is a stub-only package.fixInstall the `PyJWT` library: `pip install PyJWT`. -
MyPy error: Incompatible types in assignment (expression has type "bytes", variable has type "str") or similar type errors related to `jwt.encode()` or `jwt.decode()` when both `PyJWT >= 2.0.0` and `types-jwt` are installed.
cause There is a conflict or redundancy between the inline type annotations provided by `PyJWT` version 2.0.0+ and the external stubs from `types-jwt`. `PyJWT` itself began including type information in version 2.0.0.fixUninstall `types-jwt` if you are using `PyJWT` version 2.0.0 or newer: `pip uninstall types-jwt`. Rely on the inline types from `PyJWT`. -
MyPy error: 'Module' object has no attribute 'encode' or 'decode' even after installing types-jwt.
cause This often occurs if `PyJWT` is not installed, or if there's an environment issue where MyPy cannot find the correct `PyJWT` installation to apply the stubs to. Also, older `PyJWT` versions might have inconsistent typing.fixEnsure `PyJWT` is installed (`pip install PyJWT`). Verify your environment setup. If using `PyJWT < 2.0.0`, ensure `types-jwt` is installed. If using `PyJWT >= 2.0.0`, ensure `types-jwt` is *not* installed and that `PyJWT`'s own `py.typed` file is being recognized.
Warnings
- breaking `types-jwt` (and `types-PyJWT`) are largely redundant for `PyJWT` versions 2.0.0 and higher. Starting with `PyJWT` 2.0.0 (released December 2020), the `PyJWT` library itself includes inline type annotations. Users should uninstall `types-jwt` if they are using `PyJWT >= 2.0.0` to avoid potential conflicts, redundant packages, or unexpected type-checking behavior.
- gotcha Installing `types-jwt` does NOT install the actual `PyJWT` runtime library. `types-jwt` only provides static type hints. To use JWT functionality (e.g., `jwt.encode`, `jwt.decode`), you must explicitly install `PyJWT` (e.g., `pip install PyJWT`) in addition to `types-jwt`.
- gotcha Type stub packages from `typeshed` are designed for static analysis tools (like MyPy) and should not be directly imported in your application's runtime code. All imports for JWT operations should come from the actual `PyJWT` library (i.e., `import jwt` or `from jwt import ...`). Importing from `types_jwt` will result in a `ModuleNotFoundError` or `ImportError` at runtime.
Install
-
pip install types-jwt
Imports
- encode
from types_jwt import encode
from jwt import encode
- decode
from types_jwt import decode
from jwt import decode
Quickstart
import jwt
import os
from datetime import datetime, timedelta, timezone
from typing import Dict, Any # These types are enhanced by types-jwt if PyJWT < 2.0
# Note: This quickstart uses PyJWT (the runtime library)
# types-jwt provides type hints for this code during static analysis.
# Replace with a strong, secret key in a real application
secret_key: bytes = os.environ.get('JWT_SECRET_KEY', 'your-super-secret-key').encode('utf-8')
algorithm: str = "HS256"
# 1. Encode a JWT
payload: Dict[str, Any] = {
"user_id": 123,
"username": "testuser",
"exp": datetime.now(timezone.utc) + timedelta(hours=1), # Token expires in 1 hour
"iat": datetime.now(timezone.utc) # Issued at time
}
try:
encoded_jwt: str = jwt.encode(payload, secret_key, algorithm=algorithm)
print(f"Encoded JWT: {encoded_jwt}")
# 2. Decode the JWT
decoded_payload: Dict[str, Any] = jwt.decode(
encoded_jwt, secret_key, algorithms=[algorithm]
)
print(f"Decoded Payload: {decoded_payload}")
except jwt.ExpiredSignatureError:
print("Token has expired!")
except jwt.InvalidTokenError as e:
print(f"Invalid token: {e}")