Skip to main content

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

  1. Use environment variables for secrets:

    jwt = SCGJwtToken(os.getenv('JWT_SECRET'))
    
  2. Set reasonable expiration times:

    token = jwt.sign(payload, expires_in=86400)  # 24 hours
    
  3. Always use HTTPS in production

  4. Validate tokens on server side:

    try:
        payload = jwt.verify(token)
    except ValueError as e:
        return error_response('Invalid token')
    
  5. 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

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)

Source distribution for scg-jwt-token 2.0.1
File Size Uploaded
scg_jwt_token-2.0.1.tar.gz 8.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for scg-jwt-token 2.0.1
File Interpreter ABI Platform
scg_jwt_token-2.0.1-py3-none-any.whl Python 3 none any Details

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

Release history Release notifications | RSS feed

This release

2.0.1 This release

2 release files

2.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page