Metadata-Version: 2.4
Name: fastapi-console
Version: 0.1.4
Summary: Drop-in admin panel for FastAPI + SQLAlchemy apps
Project-URL: Homepage, https://github.com/borhan006/fastapi-console
Project-URL: Documentation, https://borhan006.github.io/fastapi-console/
Project-URL: Repository, https://github.com/borhan006/fastapi-console
Project-URL: Changelog, https://github.com/borhan006/fastapi-console/releases
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.20.0
Requires-Dist: alembic==1.18.4
Requires-Dist: bcrypt>=4.0.0
Requires-Dist: fastapi>=0.136.3
Requires-Dist: itsdangerous>=2.2.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: pyjwt>=2.13.0
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: sqlalchemy>=2.0.0
Requires-Dist: uvicorn>=0.49.0
Provides-Extra: dev
Requires-Dist: hatch>=1.13.0; extra == 'dev'
Requires-Dist: httpx>=0.27.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.5.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'docs'
Provides-Extra: mysql
Requires-Dist: aiomysql>=0.2.0; extra == 'mysql'
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.29.0; extra == 'postgres'
Description-Content-Type: text/markdown

# FastAPI Console

[![PyPI version](https://img.shields.io/pypi/v/fastapi-console.svg)](https://pypi.org/project/fastapi-console/)
[![Python versions](https://img.shields.io/pypi/pyversions/fastapi-console.svg)](https://pypi.org/project/fastapi-console/)
[![License](https://img.shields.io/pypi/l/fastapi-console.svg)](https://github.com/borhan006/fastapi-console/blob/main/LICENSE)

A drop-in admin panel for FastAPI + SQLAlchemy apps, inspired by Django Unfold.

## Features

- Zero-config auto-discovery of SQLAlchemy models
- Built-in authentication, RBAC, and audit logging
- Modern UI with Tailwind CSS, HTMX, and Alpine.js
- Fully customizable widgets, themes, and templates
- CLI for user management (`fconsole create-superuser`, `list-users`, `changepassword`)
- Async-first with support for PostgreSQL, MySQL, and SQLite

## Installation

```bash
pip install fastapi-console
```

For database-specific async drivers:

```bash
pip install fastapi-console[postgres]  # PostgreSQL via asyncpg
pip install fastapi-console[mysql]     # MySQL via aiomysql
```

## Quick Start

```python
from contextlib import asynccontextmanager
from fastapi import FastAPI
from sqlalchemy import Column, Float, Integer, String
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import DeclarativeBase, sessionmaker

from fastapi_console import Admin
from fastapi_console.auth.backend import BuiltinAuthBackend


class Base(DeclarativeBase):
    pass


class Product(Base):
    __tablename__ = "products"
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    price = Column(Float, nullable=False)


DATABASE_URL = "sqlite+aiosqlite:///./app.db"
SECRET_KEY = "change-me-to-a-random-secret-key-in-production"

engine = create_async_engine(DATABASE_URL)
async_session = sessionmaker(engine, class_=AsyncSession)


@asynccontextmanager
async def lifespan(app: FastAPI):
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield
    await engine.dispose()


app = FastAPI(lifespan=lifespan)
admin = Admin(
    app=app,
    engine=engine,
    base=Base,
    secret_key=SECRET_KEY,
    auth_backend=BuiltinAuthBackend(),
)
admin.register(Product)
```

## CLI Usage

```bash
# Create a superuser
fconsole create-superuser -e admin@example.com -p mypassword

# List all admin users
fconsole list-users

# Change a user's password
fconsole changepassword -e admin@example.com -p newpassword
```

All commands accept `-d DATABASE_URL` or read the `DATABASE_URL` environment variable.

## Configuration

### Environment Variables

| Variable | Description | Default |
|---|---|---|
| `DATABASE_URL` | Async database connection string | `sqlite+aiosqlite:///./app.db` |
| `SECRET_KEY` | Signing key for sessions/CSRF/JWT (min 32 chars) | Required in production |

### Admin Options

```python
admin = Admin(
    app=app,
    engine=engine,
    base=Base,
    secret_key=SECRET_KEY,
    title="My Admin",           # Admin panel title
    admin_path="/admin",        # URL prefix
    dark_mode_default=False,    # Dark mode on by default
    # Theme
    theme=ThemeConfig(preset="modern", primary_color="#6366F1"),
    # Auth
    auth_backend=BuiltinAuthBackend(),
    # Environment badge
    environment_label="Production",
    environment_color="danger",
)
```

### Database Support

- **SQLite** (default, built-in via `aiosqlite`)
- **PostgreSQL**: `pip install fastapi-console[postgres]` + set `DATABASE_URL=postgresql+asyncpg://...`
- **MySQL**: `pip install fastapi-console[mysql]` + set `DATABASE_URL=mysql+aiomysql://...`

## Development

```bash
# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Lint
ruff check fastapi_console/

# Build distribution
pip install hatch
hatch build
```

## License

MIT
