pydantic-jwt
Structural JWT validation as a Pydantic type.
pydantic-jwt gives you a JWTStr type that validates a string is a
well-formed JSON Web Token (RFC 7519) — three base64url segments, valid
JSON header/payload, and a non-empty alg. It does not verify the
cryptographic signature; use it to catch malformed tokens early, at the
schema layer, before doing real verification with a library like PyJWT.
Install
pip install pydantic-jwt
Basic usage
from pydantic import BaseModel
from pydantic_jwt import JWTStr
class Auth(BaseModel):
token: JWTStr
auth = Auth(token="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dGVzdA")
print(auth.token.header) # {'alg': 'HS256'}
print(auth.token.payload) # {'sub': '1234567890'}
print(auth.token.algorithm) # 'HS256'
print(auth.token.signature) # b'test'
If the string isn't a valid JWT, Pydantic raises a normal ValidationError:
Auth(token="not-a-jwt")
# pydantic_core._pydantic_core.ValidationError: 1 validation error for Auth
# token
# Value must include header, payload, and signature separated by dots [type=jwt_format, ...]
Additional constraints
For extra checks beyond structural validity — allowed algorithms, token
expiry (exp), not-before (nbf) — use JWTConstraints with Annotated:
from typing import Annotated
from pydantic import BaseModel
from pydantic_jwt import JWTStr, JWTConstraints
class Auth(BaseModel):
token: Annotated[
JWTStr,
JWTConstraints(allowed_algorithms=("HS256", "RS256")),
]
By default, JWTConstraints() rejects expired tokens (exp in the past)
and tokens that aren't active yet (nbf in the future).
JWTConstraints options
| Field | Default | Description |
|---|---|---|
allowed_algorithms |
None |
Tuple of allowed alg values. None allows any algorithm. |
exp_name |
"exp" |
Payload key used for the expiry check. |
allow_exp |
False |
If True, skip the expiry check entirely. |
nbf_name |
"nbf" |
Payload key used for the not-before check. |
allow_nbf |
False |
If True, skip the not-before check entirely. |
# allow expired tokens, only restrict algorithm
token: Annotated[JWTStr, JWTConstraints(allowed_algorithms=("HS256",), allow_exp=True)]
# use non-standard claim names
token: Annotated[JWTStr, JWTConstraints(exp_name="expires_at", nbf_name="not_before")]
What this does not do
- No signature verification.
JWTStronly checks structure, not authenticity. Anyone can craft a structurally valid JWT with any payload they like — never trust claims from an unverified token. - No decoding shortcuts for auth. For real authentication flows,
verify the signature with a dedicated library (e.g.
PyJWT,python-jose) using the correct key and algorithm, then optionally layerJWTStr/JWTConstraintson top for schema-level sanity checks.
Requirements
- Python >= 3.10
- Pydantic >= 2.10.0
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydantic_jwt-0.1.0.tar.gz.
File metadata
- Download URL: pydantic_jwt-0.1.0.tar.gz
- Upload date:
- Size: 64.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f15a4b78d17a2d1f62dd52d0641c79b8c81ec096af7d4478860c2d234393621
|
|
| MD5 |
af63250dcf056b73027679546854217b
|
|
| BLAKE2b-256 |
a2ddc1e9f44262ed6ef9956bbd97027e4f6b0cecb2da8f5ec5caf5f09f0e83ac
|
Provenance
The following attestation bundles were made for pydantic_jwt-0.1.0.tar.gz:
Publisher:
publish.yml on dmi03/pydantic-jwt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_jwt-0.1.0.tar.gz -
Subject digest:
4f15a4b78d17a2d1f62dd52d0641c79b8c81ec096af7d4478860c2d234393621 - Sigstore transparency entry: 2581231567
- Sigstore integration time:
-
Permalink:
dmi03/pydantic-jwt@04dc2a6e414e3567544cd4ba889f801226393719 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dmi03
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@04dc2a6e414e3567544cd4ba889f801226393719 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pydantic_jwt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pydantic_jwt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51f7ff3f9a5f8002576c6a307b5114194bf99818ae160cd4bf87a6a9dd3858ec
|
|
| MD5 |
6652cc8c8ad0551c96b04bd62d314151
|
|
| BLAKE2b-256 |
b68a17f57b034c1457925e3fcc398c5575b5c45d38e5daf3615e4d90b844e99d
|
Provenance
The following attestation bundles were made for pydantic_jwt-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on dmi03/pydantic-jwt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_jwt-0.1.0-py3-none-any.whl -
Subject digest:
51f7ff3f9a5f8002576c6a307b5114194bf99818ae160cd4bf87a6a9dd3858ec - Sigstore transparency entry: 2581231603
- Sigstore integration time:
-
Permalink:
dmi03/pydantic-jwt@04dc2a6e414e3567544cd4ba889f801226393719 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dmi03
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@04dc2a6e414e3567544cd4ba889f801226393719 -
Trigger Event:
workflow_dispatch
-
Statement type: