SCG JWT Token for Python
A simple, secure, and universal JWT library for web and mobile applications.
Installation
pip install scg-jwt-token
Quick Start
from scg_jwt_token import SCGJwtToken
# Create JWT instance
jwt = SCGJwtToken("your-secret-key")
# Create token
token = jwt.sign({
"user_id": 123,
"email": "user@example.com",
"role": "user"
})
# Verify token
try:
payload = jwt.verify(token)
print(f"User: {payload['email']}")
except ValueError as e:
print(f"Invalid token: {e}")
Features
- Stateless: No database storage needed for tokens
- Secure: Uses HMAC SHA-256 with proper JWT standards
- Universal: Works with web apps, mobile apps, APIs, and microservices
- Zero Dependencies: Pure Python implementation
- Type Hints: Full TypeScript-style type annotations
- Production Ready: Comprehensive error handling and validation
API Reference
SCGJwtToken
Constructor
jwt = SCGJwtToken(secret_key)
Methods
sign(payload, expires_in=3600, issuer=None, audience=None)
Create a JWT token.
token = jwt.sign(
{"user_id": 123, "role": "admin"},
expires_in=86400, # 24 hours
issuer="my-app",
audience="app-users"
)
verify(token, issuer=None, audience=None)
Verify and decode a token.
payload = jwt.verify(token)
decode(token)
Decode without verification (for debugging).
decoded = jwt.decode(token)
print(decoded['header'])
print(decoded['payload'])
is_expired(token)
Check if token is expired.
if jwt.is_expired(token):
print("Token expired")
refresh(token, expires_in=3600)
Create new token with updated expiration.
new_token = jwt.refresh(old_token, expires_in=86400)
get_stats()
Get performance statistics.
stats = jwt.get_stats()
print(f"Tokens created: {stats['tokens_created']}")
Quick Operations
from scg_jwt_token import QuickJWT
# Quick sign with auto-generated secret
result = QuickJWT.quick_sign({"user_id": 123})
print(f"Token: {result['token']}")
print(f"Secret: {result['secret']}")
# Quick verify
payload = QuickJWT.quick_verify(token, secret)
Web Framework Examples
Flask
from flask import Flask, request, jsonify
from scg_jwt_token import SCGJwtToken
import os
app = Flask(__name__)
jwt = SCGJwtToken(os.getenv('JWT_SECRET'))
@app.route('/api/login', methods=['POST'])
def login():
# Validate user credentials here
user = validate_user(request.json['email'], request.json['password'])
if user:
token = jwt.sign({
'user_id': user['id'],
'email': user['email'],
'role': user['role']
}, expires_in=86400)
return jsonify({'token': token, 'user': user})
return jsonify({'error': 'Invalid credentials'}), 401
@app.route('/api/protected', methods=['GET'])
def protected():
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
return jsonify({'error': 'Token required'}), 401
token = auth_header.split(' ')[1]
try:
user = jwt.verify(token)
return jsonify({'message': 'Access granted', 'user': user})
except ValueError:
return jsonify({'error': 'Invalid token'}), 403
Django
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from scg_jwt_token import SCGJwtToken
import json
import os
jwt = SCGJwtToken(os.getenv('JWT_SECRET'))
@csrf_exempt
def login_view(request):
if request.method == 'POST':
data = json.loads(request.body)
user = authenticate_user(data['email'], data['password'])
if user:
token = jwt.sign({
'user_id': user.id,
'email': user.email,
'role': user.role
})
return JsonResponse({'token': token})
return JsonResponse({'error': 'Invalid credentials'}, status=401)
def protected_view(request):
auth_header = request.META.get('HTTP_AUTHORIZATION')
if not auth_header or not auth_header.startswith('Bearer '):
return JsonResponse({'error': 'Token required'}, status=401)
token = auth_header.split(' ')[1]
try:
user = jwt.verify(token)
return JsonResponse({'user': user})
except ValueError:
return JsonResponse({'error': 'Invalid token'}, status=403)
FastAPI
from fastapi import FastAPI, HTTPException, Depends, Header
from scg_jwt_token import SCGJwtToken
import os
app = FastAPI()
jwt = SCGJwtToken(os.getenv('JWT_SECRET'))
async def verify_token(authorization: str = Header(None)):
if not authorization or not authorization.startswith('Bearer '):
raise HTTPException(status_code=401, detail='Token required')
token = authorization.split(' ')[1]
try:
return jwt.verify(token)
except ValueError:
raise HTTPException(status_code=403, detail='Invalid token')
@app.post('/api/login')
async def login(credentials: dict):
user = await authenticate_user(credentials['email'], credentials['password'])
if user:
token = jwt.sign({
'user_id': user['id'],
'email': user['email'],
'role': user['role']
})
return {'token': token}
raise HTTPException(status_code=401, detail='Invalid credentials')
@app.get('/api/protected')
async def protected(user: dict = Depends(verify_token)):
return {'user': user}
Why JWT Over Sessions
Traditional Session-Based Auth
- User Login → Create Session → Store in Database → Return Session ID
- User Request → Database Lookup → Validate Session → Process Request
- Every request = Database query = Slow & Resource Heavy
SCG JWT Token-Based Auth
- User Login → Create JWT Token → Return Token (NO database storage)
- User Request → Verify JWT Signature → Process Request
- No database queries = Lightning Fast & Highly Scalable
Security Best Practices
-
Use environment variables for secrets:
jwt = SCGJwtToken(os.getenv('JWT_SECRET'))
-
Set reasonable expiration times:
token = jwt.sign(payload, expires_in=86400) # 24 hours
-
Always use HTTPS in production
-
Validate tokens on server side:
try: payload = jwt.verify(token) except ValueError as e: return error_response('Invalid token')
-
Use proper Authorization headers:
Authorization: Bearer <your-jwt-token>
Testing
import unittest
from scg_jwt_token import SCGJwtToken
class TestSCGJwt(unittest.TestCase):
def setUp(self):
self.jwt = SCGJwtToken("test-secret")
def test_create_and_verify_token(self):
payload = {"user_id": 123, "role": "admin"}
token = self.jwt.sign(payload)
decoded = self.jwt.verify(token)
self.assertEqual(decoded['user_id'], 123)
self.assertEqual(decoded['role'], "admin")
def test_expired_token(self):
token = self.jwt.sign({"user_id": 123}, expires_in=-1)
with self.assertRaises(ValueError):
self.jwt.verify(token)
if __name__ == '__main__':
unittest.main()
Use Cases
Perfect for:
- Web Applications: Flask, Django, FastAPI applications
- Mobile APIs: REST APIs for mobile apps
- Microservices: Service-to-service authentication
- Single Page Apps: React, Vue, Angular frontends
- Cross-platform: Same authentication across all platforms
Requirements
- Python 3.7+
- No external dependencies
License
MIT License
Support
- GitHub Repository
- Report Issues
- Email: hemantthapa1998@gmail.com
- Business: contact@squidconsultancy.com
Built by Analytics With Harry and Squid Consultancy Group Limited.
Metadata
Release files for scg-jwt-token 2.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| scg_jwt_token-2.0.1.tar.gz | 8.2 kB | Without provenance | Details for scg_jwt_token-2.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| scg_jwt_token-2.0.1-py3-none-any.whl | Python 3 | none | any | Details for scg_jwt_token-2.0.1-py3-none-any.whl |
Total release size: 16.3 kB
Release files / scg_jwt_token-2.0.1.tar.gz
| Download URL | scg_jwt_token-2.0.1.tar.gz |
|---|---|
| Size | 8.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b5dbd3e9d7434192ad36ed86335eb039fdb092b064b1ab9a75d8e061f1aa2b8
|
|
BLAKE2b-256 checksum How to use checksums |
2466b6a5b299f7036a02fbeeb1965d08def085301f09207ca5ededb7932cdd6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / scg_jwt_token-2.0.1-py3-none-any.whl
| Download URL | scg_jwt_token-2.0.1-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59a0344486b2fad1fc770bc4b630bdc526c6deb7168eb6f9b031186ac01cc161
|
|
BLAKE2b-256 checksum How to use checksums |
ab6a544fbeba571d0907d34edac4378d9f796914e099c8cbeff7d3506e5b693d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Security for scg-jwt-token 2.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.