Install & Compatibility
Where this runs
tested against v1.8.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.000s · 18.6MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 1.6s · import 0.000s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
SanicJWT
✓ from sanic_jwt import SanicJWT
✗ from sanic_jwt import SanicJWT
This quickstart demonstrates how to set up `sanic-jwt` with a Sanic application. It includes a simple authentication function, a protected route using the `@protected()` decorator, and a public route. Users obtain a JWT by POSTing to the `/auth` endpoint with credentials, and then use this token in the `Authorization: Bearer` header for protected routes.
from sanic import Sanic, response
from sanic_jwt import SanicJWT, protected
import os
app = Sanic("my_jwt_app")
# Set a secret key for JWT signing. Crucial for security.
app.config.SANIC_JWT_SECRET = os.environ.get("SANIC_JWT_SECRET", "your-super-secret-key-that-no-one-knows")
# Define an asynchronous authentication function.
# This function handles both token verification (payload present) and user login (payload None).
async def authenticate(request, payload):
if payload: # Token verification for protected routes
# In a real app, you'd fetch user data from a DB based on payload (e.g., user_id)
user_id = payload.get("user_id")
if user_id:
return {"user_id": user_id, "username": payload.get("username", "user")} # Return user info for ctx
return False
else: # User login attempt for the /auth endpoint
# Expect username/password in request.json
username = request.json.get("username")
password = request.json.get("password")
if username == "test" and password == "test": # Dummy check
return {"user_id": 1, "username": "testuser"} # Return user info to be included in JWT payload
return False # Authentication failed
# Initialize Sanic-JWT with the app and your custom authentication function.
SanicJWT.setup(app, authenticate=authenticate)
@app.route("/protected")
@protected()
async def protected_route(request):
# Access user data via request.ctx.user after successful authentication
username = request.ctx.user.get('username', 'authenticated user')
return response.json({"message": f"Hello, {username}! This is a protected route."})
@app.get("/public")
async def public_route(request):
return response.json({"message": "This is a public route, accessible without a token."})
if __name__ == "__main__":
# To run:
# 1. Start the app: python your_script_name.py
# 2. Login (obtain token): curl -X POST -H "Content-Type: application/json" -d '{"username":"test","password":"test"}' http://localhost:8000/auth
# 3. Access protected route with token: curl -H "Authorization: Bearer <your_token_here>" http://localhost:8000/protected
app.run(host="0.0.0.0", port=8000, debug=True)
Debug
Known issues
breakingUpgrading `sanic-jwt` to v1.6.0 or newer introduces PyJWT v2 support. If your application or custom JWT handling code directly interacts with PyJWT, you may encounter breaking changes related to API updates, especially regarding `jwt.encode()` parameters (e.g., `algorithm='none'` deprecation) and bytes vs string handling.fixReview PyJWT v2 documentation for API changes. Update any direct PyJWT calls in your code. Ensure secrets and tokens are handled as bytes or strings as required by PyJWT v2.
affects: >=1.6.0
breakingVersions of `sanic-jwt` prior to v1.7.0 may not be fully compatible with Sanic versions 21.3 and newer. This can lead to unexpected errors or authentication failures due to internal API changes in Sanic.fixUpgrade `sanic-jwt` to version 1.7.0 or newer to ensure compatibility with Sanic 21.3+.
affects: <1.7.0 (when used with Sanic >=21.3)
deprecatedThe `request.query_args` attribute was deprecated and eventually removed from Sanic. Using it in your `authenticate` function or other custom logic will cause `AttributeError` on newer Sanic versions. `sanic-jwt` itself adjusted to use `request.args` in v1.3.1.fixReplace `request.query_args` with `request.args` in your application code.
affects: <1.3.1 (for sanic-jwt) or any version if using `request.query_args` directly
gotchaSince `sanic-jwt` v1.2.0, requests with invalid tokens (e.g., malformed, expired, invalid signature) will return an HTTP 401 Unauthorized status code instead of 403 Forbidden. This might require adjustments to client-side error handling logic.fixUpdate client-side code to correctly handle HTTP 401 responses for invalid or missing tokens.
affects: >=1.2.0
Upgrade
Version history
1.8.0latest on PyPI · released Jun 28, 2022
Audit
Dependencies
sanicrequiredCore web framework for which sanic-jwt provides authentication services.
PyJWTrequiredHandles the encoding and decoding of JSON Web Tokens.