Metadata-Version: 2.4
Name: overwatch-admin
Version: 0.1.0
Summary: Admin panel for FastAPI applications with SQLAlchemy models
Project-URL: Homepage, https://github.com/overwatch/overwatch
Project-URL: Documentation, https://overwatch.readthedocs.io
Project-URL: Repository, https://github.com/overwatch/overwatch
Project-URL: Issues, https://github.com/overwatch/overwatch/issues
Author-email: Overwatch Contributors <contributors@overwatch.dev>
License: MIT
Keywords: admin,crud,dashboard,fastapi,panel,sqlalchemy
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.11
Requires-Dist: aiofiles>=23.2.1
Requires-Dist: alembic>=1.12.0
Requires-Dist: fastapi>=0.104.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: passlib[bcrypt]>=1.7.4
Requires-Dist: pydantic-settings>=2.1.0
Requires-Dist: pydantic[email]>=2.5.0
Requires-Dist: python-jose[cryptography]>=3.3.0
Requires-Dist: python-multipart>=0.0.6
Requires-Dist: sqlalchemy>=2.0.0
Provides-Extra: dev
Requires-Dist: black>=23.11.0; extra == 'dev'
Requires-Dist: httpx>=0.25.2; extra == 'dev'
Requires-Dist: isort>=5.12.0; extra == 'dev'
Requires-Dist: mypy>=1.7.1; extra == 'dev'
Requires-Dist: pre-commit>=3.6.0; extra == 'dev'
Requires-Dist: pyrefly>=0.1.3; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.1; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=7.4.3; extra == 'dev'
Requires-Dist: ruff>=0.1.6; extra == 'dev'
Provides-Extra: mysql
Requires-Dist: aiomysql>=0.2.0; extra == 'mysql'
Provides-Extra: postgresql
Requires-Dist: asyncpg>=0.29.0; extra == 'postgresql'
Provides-Extra: sqlite
Requires-Dist: aiosqlite>=0.21.0; extra == 'sqlite'
Description-Content-Type: text/markdown

# Overwatch - Agnostic Admin Panel for FastAPI

[![Python](https://img.shields.io/badge/Python-3.11+-blue.svg)](https://python.org)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.104+-green.svg)](https://fastapi.tiangolo.com)
[![SQLAlchemy](https://img.shields.io/badge/SQLAlchemy-2.0+-red.svg)](https://sqlalchemy.org)
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Overwatch is a reusable, agnostic admin panel package for FastAPI applications that automatically generates CRUD interfaces for SQLAlchemy models. It provides an Admin experience with enhanced features including audit logging, permissions, and a modern TypeScript frontend built with Medusa UI.

## ✨ Features

- **🔧 Model Agnostic**: Works with any SQLAlchemy model
- **🎨 Modern UI**: TypeScript frontend with Medusa UI components
- **🔐 Authentication**: Secure JWT-based authentication system
- **👥 Role Management**: Hierarchical roles with fine-grained permissions
- **📊 Audit Logging**: Complete audit trail of all admin actions
- **🔍 Search & Filter**: Advanced search and filtering capabilities
- **📄 Pagination**: Efficient pagination for large datasets
- **⚡ Bulk Operations**: Bulk create, update, and delete operations
- **📤 Export**: Export data in various formats
- **🎛️ Customization**: Highly configurable and extensible
- **🚀 Performance**: Async operations and optimized queries

## 🚀 Quick Start

### Installation

```bash
pip install overwatch-admin
```

### Basic Usage

```python
from fastapi import FastAPI
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from overwatch import OverwatchAdmin, OverwatchConfig

# Create FastAPI app
app = FastAPI()

# Define your models
Base = declarative_base()

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True)
    email = Column(String(100))

# Initialize Overwatch admin
admin = OverwatchAdmin(
    app=app,
    db_session=get_db_session,  # Your database session dependency
    models=[User],  # Your SQLAlchemy models
    admin_title="My Admin Panel"
)

# Configure model display
admin.configure_model(
    User,
    list_fields=["id", "username", "email"],
    search_fields=["username", "email"],
)

app.run()
```

## 📋 Requirements

- Python 3.11+
- FastAPI 0.104+
- SQLAlchemy 2.0+
- Async database driver (asyncpg, aiosqlite, etc.)

## 🏗️ Architecture

Overwatch is built with a modular architecture:

```
overwatch/
├── core/           # Configuration and database setup
├── models/         # Overwatch internal models (admin, audit)
├── services/       # Business logic layer
├── api/           # FastAPI route handlers
├── schemas/       # Pydantic models
├── utils/         # Utility functions
└── frontend/      # TypeScript frontend (optional)
```

## ⚙️ Configuration

Overwatch can be configured through environment variables or direct configuration:

```python
from overwatch import OverwatchConfig
from overwatch.core.config import SecurityConfig

config = OverwatchConfig(
    admin_title="My Admin Panel",
    security=SecurityConfig(
        secret_key="your-secret-key",
        access_token_expire_minutes=30,
        password_min_length=8,
    ),
    per_page=25,
    enable_audit_log=True,
    enable_dashboard=True,
    cors_origins=["http://localhost:3000"],
)
```

### Environment Variables

```bash
OVERWATCH_ADMIN_TITLE="My Admin Panel"
OVERWATCH_SECURITY__SECRET_KEY="your-secret-key"
OVERWATCH_SECURITY__ACCESS_TOKEN_EXPIRE_MINUTES=30
OVERWATCH_THEME__PRIMARY_COLOR="#3b82f6"
OVERWATCH_PER_PAGE=25
OVERWATCH_ENABLE_AUDIT_LOG=true
```

## 🔐 Authentication & Authorization

### Built-in Authentication

Overwatch comes with a complete authentication system separate from your application's user system:

```python
# Create admin user
admin = await admin.create_admin(
    username="superadmin",
    password="secure-password",
    email="admin@example.com",
    role="super_admin"
)
```

### Roles & Permissions

- **Super Admin**: Full access to all resources
- **Admin**: Standard CRUD operations
- **Read Only**: View-only access

### Custom Permissions

```python
admin.configure_model(
    User,
    permissions={
        "read": "admin",
        "write": "super_admin",
        "delete": "super_admin"
    }
)
```

## 📊 Model Configuration

### Basic Configuration

```python
admin.configure_model(
    User,
    list_fields=["id", "username", "email", "is_active"],
    search_fields=["username", "email", "full_name"],
    exclude_fields=["password_hash"],
    readonly_fields=["id", "created_at"],
    per_page=50,
    order_by="username"
)
```

### Custom Actions

```python
admin.configure_model(
    User,
    custom_actions=[
        {
            "name": "activate_users",
            "label": "Activate Selected",
            "action": "POST",
            "url": "/api/users/bulk-activate",
            "icon": "user-check"
        }
    ]
)
```

## 🔍 Search & Filtering

Overwatch automatically generates search functionality based on your model fields:

```python
admin.configure_model(
    Product,
    search_fields=["name", "description", "category"],
    # Search will work across these text fields
)
```

### Advanced Filtering

```python
# Filter by status
GET /admin/api/products?is_active=true

# Search by name
GET /admin/api/products?search=laptop

# Sort by price
GET /admin/api/products?sort_by=price&sort_direction=desc
```

## 📄 Pagination

All list endpoints support pagination:

```python
# Page 2, 25 items per page
GET /admin/api/users?page=2&per_page=25

# Response format
{
    "items": [...],
    "total": 150,
    "page": 2,
    "per_page": 25,
    "pages": 6
}
```

## ⚡ Bulk Operations

### Bulk Create

```python
# POST /admin/api/users/bulk
{
    "items": [
        {"username": "user1", "email": "user1@example.com"},
        {"username": "user2", "email": "user2@example.com"}
    ]
}
```

### Bulk Update

```python
# PUT /admin/api/users/bulk
{
    "item_ids": [1, 2, 3],
    "updates": {"is_active": false}
}
```

### Bulk Delete

```python
# DELETE /admin/api/users/bulk
{
    "item_ids": [1, 2, 3]
}
```

## 📤 Export

Export functionality is built-in:

```python
# Export to CSV
GET /admin/api/users/export?format=csv

# Export to JSON
GET /admin/api/users/export?format=json

# Export with filters
GET /admin/api/users/export?format=csv&is_active=true
```

## 📊 Audit Logging

All admin actions are automatically logged:

```python
# View audit logs
GET /admin/api/audit-logs

# Filter by admin
GET /admin/api/audit-logs?admin_id=1

# Filter by action
GET /admin/api/audit-logs?action=create
```

### Audit Log Entry

```python
{
    "id": 123,
    "admin_id": 1,
    "admin_username": "superadmin",
    "action": "create",
    "resource_type": "User",
    "resource_id": 456,
    "old_values": null,
    "new_values": {"username": "newuser", "email": "user@example.com"},
    "ip_address": "192.168.1.100",
    "user_agent": "Mozilla/5.0...",
    "success": true,
    "created_at": "2024-01-15T10:30:00Z"
}
```

## 🎨 Frontend Customization

Overwatch comes with a modern TypeScript frontend built with Medusa UI:

### Theme Configuration

```python
config = OverwatchConfig(
    theme={
        "primary_color": "#3b82f6",
        "secondary_color": "#64748b",
        "mode": "light",  # light, dark, auto
        "font_family": "Inter, system-ui, sans-serif"
    }
)
```

### Custom CSS

```python
# Override styles in your application
static_files = {
    "/admin/custom.css": "path/to/your/custom.css"
}
```

## 🔧 Advanced Usage

### Custom Database

Overwatch can use a separate database:

```python
config = OverwatchConfig(
    database={
        "url": "postgresql+asyncpg://overwatch:password@localhost/overwatch_db",
        "echo": False
    }
)
```

### Custom Middleware

```python
from overwatch.middleware import audit_middleware

app.add_middleware(
    audit_middleware,
    exclude_paths=["/health", "/metrics"]
)
```

### Integration with Existing Admin

Overwatch can work alongside existing admin systems:

```python
# Use different prefix to avoid conflicts
admin = OverwatchAdmin(
    app=app,
    db_session=get_db_session,
    models=[User],
    prefix="/overwatch-admin"  # Different from existing /admin
)
```

## 🧪 Testing

```python
import pytest
from fastapi.testclient import TestClient
from overwatch import OverwatchAdmin

app = FastAPI()
admin = OverwatchAdmin(app=app, db_session=get_db_session, models=[User])

client = TestClient(app)

def test_login():
    response = client.post("/admin/api/auth/login", data={
        "username": "admin",
        "password": "password"
    })
    assert response.status_code == 200

def test_users_list():
    # First login to get token
    login_response = client.post("/admin/api/auth/login", data={
        "username": "admin",
        "password": "password"
    })
    token = login_response.json()["access_token"]

    # Then access protected endpoint
    response = client.get(
        "/admin/api/users",
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200
```

## 🚀 Deployment

### Docker

```dockerfile
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .
RUN uvicorn main:app --host 0.0.0.0 --port 8000

EXPOSE 8000
```

### Environment Variables

```bash
# Production
OVERWATCH_SECURITY__SECRET_KEY="your-very-secure-secret-key"
OVERWATCH_SECURITY__ACCESS_TOKEN_EXPIRE_MINUTES=15
OVERWATCH_DATABASE__URL="postgresql+asyncpg://user:pass@localhost/overwatch"
OVERWATCH_CORS_ORIGINS="https://admin.yourapp.com"
```

## 📚 Examples

See the `examples/` directory for complete examples:

- **Basic Example**: Simple setup with User/Product models
- **Advanced Example**: Custom configuration, permissions, and actions
- **Multi-DB Example**: Using separate databases
- **Custom UI Example**: Custom frontend components

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

### Development Setup

```bash
git clone https://github.com/your-org/overwatch.git
cd overwatch

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

# Run linting
ruff check .
ruff format .

# Run type checking
pyright
```

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🙏 Acknowledgments

- **FastAPI** - The web framework that makes Overwatch possible
- **SQLAlchemy** - Powerful ORM for database operations
- **Medusa UI** - Beautiful UI component library
- **Pydantic** - Data validation and settings management

## 📞 Support

- 📖 [Documentation](https://overwatch.readthedocs.io)
- 🐛 [Issue Tracker](https://github.com/your-org/overwatch/issues)
- 💬 [Discussions](https://github.com/your-org/overwatch/discussions)
- 📧 [Email](mailto:support@overwatch.dev)

---

**Overwatch** - Making admin panels in FastAPI simple and beautiful. 🚀
