Production-ready authentication system for Python web applications
Project description
Dwarapaal
Production-ready authentication system for Python web applications
A flexible, secure authentication solution for Flask, FastAPI, and Django applications. Built with Python, MongoDB, and JWT.
Features
- User Registration with email verification
- Email Verification via secure tokens
- User Login with JWT access and refresh tokens
- Password Reset with secure token-based flow
- Role-Based Authorization (user, admin, moderator)
- Protected Routes with JWT middleware
- Input Validation using Pydantic
- Password Hashing with bcrypt
- Token Security with SHA-256 hashing
- Professional Email Templates
- Type Safety with Python type hints
- Multi-Framework: Flask, FastAPI, Django
Why dwarapaal Auth?
- Quick Integration – Add authentication in minutes
- Enterprise Security – Battle-tested security practices
- Framework Agnostic – Works with Flask, FastAPI, Django
- Email Ready – Built-in verification and password reset
- Role-Based Access – Easy authorization
- Type Safe – Full type hints and Pydantic models
- Production Ready – Used in production applications
Installation
# Basic installation
pip install dwarapaal
# With Flask support
pip install dwarapaal[flask]
# With FastAPI support
pip install dwarapaal[fastapi]
# With Django support
pip install dwarapaal[django]
# With email support
pip install dwarapaal[email]
# All features
pip install dwarapaal[flask,fastapi,django,email]
Requirements:
- Python 3.8+
- MongoDB 4.0+
Quick Start
Flask Example
from flask import Flask, request, jsonify
from dwarapaal_auth import (
dwarapaalConfig,
EmailConfig,
init_dwarapaal,
require_auth,
require_role,
)
app = Flask(__name__)
# Configure dwarapaal Auth
email_config = EmailConfig(
host="smtp.gmail.com",
port=587,
username="your-email@gmail.com",
password="your-app-password",
from_address="noreply@yourapp.com",
use_tls=True
)
config = dwarapaalConfig(
mongo_uri="mongodb://localhost:27017/myapp",
jwt_secret="your-secret-key-change-in-production",
email_config=email_config,
)
# Initialize
db = init_dwarapaal(config)
# Protected route
@app.route("/api/profile")
@require_auth
def get_profile():
user = request.current_user
return jsonify({"user": user})
# Admin-only route
@app.route("/api/admin/users")
@require_auth
@require_role(["admin"])
def get_users():
users = db.users.find({})
return jsonify({"users": list(users)})
if __name__ == "__main__":
app.run()
FastAPI Example
from fastapi import FastAPI, Depends
from dwarapaal_auth import dwarapaalConfig, init_dwarapaal
from dwarapaal_auth.fastapi import get_current_user, require_roles
app = FastAPI()
# Configure and initialize
config = dwarapaalConfig(
mongo_uri="mongodb://localhost:27017/myapp",
jwt_secret="your-secret-key",
)
db = init_dwarapaal(config)
# Protected route
@app.get("/api/profile")
async def get_profile(current_user: dict = Depends(get_current_user)):
return {"user": current_user}
# Admin-only route
@app.get("/api/admin/users")
async def get_users(current_user: dict = Depends(require_roles(["admin"]))):
users = list(db.users.find({}))
return {"users": users}
Configuration
Environment Variables
Create a .env file:
# Database
MONGO_URI=mongodb://localhost:27017/dwarapaal_auth
# JWT
JWT_SECRET=your-super-secret-jwt-key-change-in-production
# Email (SMTP)
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-app-specific-password
EMAIL_FROM=noreply@yourapp.com
# Application
PORT=5000
Configuration Object
from dwarapaal_auth import dwarapaalConfig, EmailConfig
email_config = EmailConfig(
host="smtp.gmail.com",
port=587,
username="your-email@gmail.com",
password="your-password",
from_address="noreply@yourapp.com",
use_tls=True
)
config = dwarapaalConfig(
# Database
mongo_uri="mongodb://localhost:27017/myapp",
database_name="auth_db",
# JWT
jwt_secret="your-secret-key",
jwt_algorithm="HS256",
access_token_expire_minutes=15,
refresh_token_expire_days=7,
# Security
bcrypt_rounds=12,
# Email
email_config=email_config,
# Tokens
verification_token_expire_hours=24,
reset_token_expire_hours=1,
# Application
base_url="http://localhost:5000",
)
API Reference
Authentication Service
from dwarapaal_auth.services import AuthService
auth_service = AuthService()
# Register user
await auth_service.register(user_data)
# Verify email
await auth_service.verify_email(token)
# Login
result = await auth_service.login(credentials)
# Forgot password
await auth_service.forgot_password(email)
# Reset password
await auth_service.reset_password(token, new_password)
Models
from dwarapaal_auth.models import (
UserCreate,
UserLogin,
User,
UserRole,
TokenPair,
)
# Create user
user_data = UserCreate(
username="johndoe",
email="john@example.com",
password="SecurePass123!"
)
# Login credentials
credentials = UserLogin(
email="john@example.com",
password="SecurePass123!"
)
# User roles
role = UserRole.ADMIN # or UserRole.USER, UserRole.MODERATOR
Middleware
Flask Decorators
from dwarapaal_auth import require_auth, require_role
@app.route("/api/profile")
@require_auth
def get_profile():
user = request.current_user
return jsonify(user)
@app.route("/api/admin/dashboard")
@require_auth
@require_role(["admin"])
def admin_dashboard():
return jsonify({"message": "Admin dashboard"})
FastAPI Dependencies
from fastapi import Depends
from dwarapaal_auth.fastapi import get_current_user, require_roles
@app.get("/api/profile")
async def get_profile(current_user: dict = Depends(get_current_user)):
return {"user": current_user}
@app.get("/api/admin/dashboard")
async def admin_dashboard(
current_user: dict = Depends(require_roles(["admin"]))
):
return {"message": "Admin dashboard"}
Security
Password Requirements
- Minimum 8 characters
- Maximum 100 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Security Features
| Feature | Implementation |
|---|---|
| Password Hashing | Bcrypt (12 rounds) |
| Token Hashing | SHA-256 |
| JWT | HS256 algorithm |
| Email Verification | Required before login |
| Input Validation | Pydantic models |
| Role-Based Access | Middleware decorators |
Complete Examples
Flask Application
from flask import Flask, request, jsonify
from dwarapaal_auth import (
dwarapaalConfig,
EmailConfig,
init_dwarapaal,
require_auth,
require_role,
)
from dwarapaal_auth.routes.auth_routes import create_flask_auth_routes
import os
app = Flask(__name__)
# Initialize
config = dwarapaalConfig(
mongo_uri=os.getenv("MONGO_URI"),
jwt_secret=os.getenv("JWT_SECRET"),
email_config=EmailConfig(
host=os.getenv("EMAIL_HOST"),
port=int(os.getenv("EMAIL_PORT")),
username=os.getenv("EMAIL_USER"),
password=os.getenv("EMAIL_PASS"),
from_address=os.getenv("EMAIL_FROM"),
),
)
db = init_dwarapaal(config)
# Register auth routes
auth_bp = create_flask_auth_routes()
app.register_blueprint(auth_bp, url_prefix="/api/auth")
# Your routes
@app.route("/api/profile")
@require_auth
def get_profile():
return jsonify({"user": request.current_user})
@app.route("/api/admin/users")
@require_auth
@require_role(["admin"])
def get_users():
users = db.users.find({}, {"password": 0})
return jsonify({"users": list(users)})
if __name__ == "__main__":
app.run(port=5000)
FastAPI Application
from fastapi import FastAPI, Depends
from dwarapaal_auth import dwarapaalConfig, init_dwarapaal
from dwarapaal_auth.fastapi import get_current_user, require_roles
from dwarapaal_auth.routes.auth_routes import create_fastapi_auth_routes
app = FastAPI()
# Initialize
config = dwarapaalConfig(
mongo_uri="mongodb://localhost:27017/myapp",
jwt_secret="your-secret-key",
)
db = init_dwarapaal(config)
# Include auth routes
app.include_router(
create_fastapi_auth_routes(),
prefix="/api/auth",
tags=["Authentication"]
)
# Your routes
@app.get("/api/profile")
async def get_profile(current_user: dict = Depends(get_current_user)):
return {"user": current_user}
@app.get("/api/admin/users")
async def get_users(current_user: dict = Depends(require_roles(["admin"]))):
users = list(db.users.find({}, {"password": 0}))
return {"users": users}
Testing
# Install dev dependencies
pip install dwarapaal-auth-py[dev]
# Run tests
pytest
# Run with coverage
pytest --cov=dwarapaal_auth --cov-report=html
# Run specific test
pytest tests/test_auth.py::test_register
Development
Setup
# Clone repository
git clone https://github.com/unkown812/dwarapaal-auth-py.git
cd dwarapaal-auth-py
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
Building
# Build package
python -m build
# Install locally
pip install dist/dwarapaal_auth_py-1.0.0-py3-none-any.whl
Publishing
# Test on TestPyPI
python -m twine upload --repository testpypi dist/*
# Publish to PyPI
python -m twine upload dist/*
Troubleshooting
Email Not Sending
For Gmail users:
- Enable 2-factor authentication
- Create an App Password: https://myaccount.google.com/apppasswords
- Use the App Password in your configuration
JWT Token Issues
# Check token expiration
from dwarapaal_auth.services import TokenService
token_service = TokenService()
payload = token_service.verify_token(token)
print(payload)
MongoDB Connection
# Check MongoDB is running
mongosh
# Test connection
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
print(client.server_info())
Contributing
Contributions welcome! See CONTRIBUTING.md for guidelines.
Development Guidelines
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure all tests pass
- Format code with Black
- Submit a pull request
# Format code
black dwarapaal_auth/
# Check types
mypy dwarapaal_auth/
# Lint
flake8 dwarapaal_auth/
# Run tests
pytest
License
ISC License - see LICENSE file for details.
Author
Jay Jogane
- GitHub: @unkown812
- LinkedIn: Jay Jogane
Acknowledgments
Built with:
- PyMongo - MongoDB driver
- PyJWT - JWT implementation
- Bcrypt - Password hashing
- Pydantic - Data validation
- Flask - Web framework
- FastAPI - Modern web framework
Roadmap
Version 1.x (Current)
- Core authentication
- Flask support
- FastAPI support
- Role-based auth
Version 2.0 (Planned)
- Django support
- OAuth integration
- Two-factor authentication
- Session management
- Account lockout
Version 3.0 (Future)
- SAML support
- Multi-tenancy
- Advanced rate limiting
- Admin dashboard
Performance
Benchmarks on typical hardware:
| Operation | Avg Time |
|---|---|
| Registration | 180ms |
| Login | 120ms |
| Token Verification | 5ms |
| Password Hashing | 150ms |
Project details
Release history Release notifications | RSS feed
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 dwarapaal-1.0.0.tar.gz.
File metadata
- Download URL: dwarapaal-1.0.0.tar.gz
- Upload date:
- Size: 24.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f1db789ec16df44bbad394c96825551235c50a5c6a0e679c23ac6b67d9b63a1
|
|
| MD5 |
005351c1da33c6f16fb31264ac1867eb
|
|
| BLAKE2b-256 |
595aadd94ee131cb17f7088f626633fec5b75354412ff915aa884b2d307c15a2
|
File details
Details for the file dwarapaal-1.0.0-py3-none-any.whl.
File metadata
- Download URL: dwarapaal-1.0.0-py3-none-any.whl
- Upload date:
- Size: 21.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bdd03b14f2d4bca5efd801108ddde68287eecf0e02e1e46f3d3ec0cf03b90f52
|
|
| MD5 |
babcb85961da9951630d9d976f1ece80
|
|
| BLAKE2b-256 |
1f6789aa5efad64e677898fa8cff39e6e9ca8fc53a81c00c9207cabd39c4a7dd
|