Skip to main content

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 Installation Quick Start Documentation Examples


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:

  1. Enable 2-factor authentication
  2. Create an App Password: https://myaccount.google.com/apppasswords
  3. 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

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for new features
  4. Ensure all tests pass
  5. Format code with Black
  6. 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


Acknowledgments

Built with:


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

If this project helped you, please star it on GitHub!

Coded and Crafted by Jay Jogane

Back to Top

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dwarapaal-1.0.0.tar.gz (24.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dwarapaal-1.0.0-py3-none-any.whl (21.7 kB view details)

Uploaded Python 3

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

Hashes for dwarapaal-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0f1db789ec16df44bbad394c96825551235c50a5c6a0e679c23ac6b67d9b63a1
MD5 005351c1da33c6f16fb31264ac1867eb
BLAKE2b-256 595aadd94ee131cb17f7088f626633fec5b75354412ff915aa884b2d307c15a2

See more details on using hashes here.

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

Hashes for dwarapaal-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdd03b14f2d4bca5efd801108ddde68287eecf0e02e1e46f3d3ec0cf03b90f52
MD5 babcb85961da9951630d9d976f1ece80
BLAKE2b-256 1f6789aa5efad64e677898fa8cff39e6e9ca8fc53a81c00c9207cabd39c4a7dd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page