Metadata-Version: 2.4
Name: overflask
Version: 0.8.1
Summary: Flask scaffolding CLI with component architecture and support for SQLAlchemy, Redis caching, async tasks, and Elasticsearch analytics
Author: rklaus
License-Expression: MIT
Project-URL: Repository, https://gitlab.com/overflask/overflask
Project-URL: Tracker, https://gitlab.com/overflask/overflask/-/issues
Project-URL: Changelog, https://gitlab.com/overflask/overflask/-/blob/main/CHANGELOG.md
Keywords: flask,scaffolding,cli,sqlalchemy,redis,elasticsearch,tasks,analytics
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Flask
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: flask>=3.0
Requires-Dist: packaging>=24.0
Requires-Dist: python-dotenv>=1.0
Requires-Dist: sqlalchemy>=2.0
Requires-Dist: redis>=5.0
Requires-Dist: elasticsearch>=8.0
Requires-Dist: croniter>=3.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-tmp-files>=0.0.2; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# overflask

A CLI tool that scaffolds Flask projects with component-based architecture, and a runtime library that adds SQLAlchemy models, Redis caching, async/recurring tasks, and Elasticsearch analytics on top of Flask.

## Create a project

Via Docker (no install required):

```bash
docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/workspace overflask/overflask create myapp
```

Or install and run locally:

```bash
pip install overflask @ git+https://gitlab.com/overflask/overflask.git
overflask create myapp
```

The CLI prompts for an initial component name and Postgres/Redis connection details, generates the project, pre-fills `.env`, and optionally starts the database containers.

```
myapp/
├── manage.py           # project CLI
├── settings.py         # configuration
├── requirements.pip    # dependencies
├── compose.yaml        # Docker Compose
├── conftest.py         # pytest fixtures
├── ops/
│   ├── env.template
│   ├── migrations/     # Alembic
│   └── setup-traefik.sh
├── docs/
└── components/
    └── myapp/
        ├── models.py
        ├── views.py
        ├── services.py
        ├── cli.py
        ├── tasks.py
        └── tests.py
```

## Add a component

```bash
python manage.py component add auth
```

Creates `components/auth/` with the same structure and registers it in `settings.COMPONENTS`.

## Runtime library

Generated projects import directly from `overflask`:

### Models

```python
from overflask import ModelBase
from sqlalchemy.orm import Mapped, mapped_column

class User(ModelBase):
    # __tablename__ auto-set to "auth_users"
    id: Mapped[int] = mapped_column(primary_key=True)
    email: Mapped[str] = mapped_column(String(255), unique=True)
```

Table names are derived automatically as `{component}_{plural_snake_case_model_name}`.

### Redis cache

```python
from overflask import cached

@cached(ttl=300)
def get_user(user_id: int):
    ...
```

Backed by Redis db 15 with stampede prevention via locking.

### Async tasks

```python
from overflask import async_task

@async_task
def send_welcome_email(user_id: int, email: str) -> None:
    ...

# Enqueue immediately or with a delay
send_welcome_email.queue(user_id=42, email="alice@example.com")
send_welcome_email.queue(timedelta(minutes=5), user_id=42, email="alice@example.com")
```

### Recurring tasks

```python
from overflask import recurring_task

@recurring_task("0 9 * * MON-FRI")
def daily_report() -> None:
    ...
```

Tasks are stored in Elasticsearch and dispatched via Redis. Run the supporting processes:

```bash
python manage.py tasks scheduler   # polls ES, dispatches due tasks
python manage.py tasks worker      # executes tasks from Redis queue
```

### Analytics

```python
from overflask.analytics import Analytics

Analytics.record("user.registered", area="auth", plan="free")
Analytics.record("purchase.completed", area="billing", amount=99)
```

Events are buffered in-process and bulk-flushed to Elasticsearch in the background. Each `area` gets its own monthly index (`myapp_analytics_auth-2026.03`).

## Database migrations

```bash
python manage.py db migrate -m "add users table"
python manage.py db upgrade
python manage.py db downgrade 001
```

## Testing

```bash
pytest               # all tests
pytest -m unit       # unit tests only (no DB)
pytest -m integration
pytest -n auto       # parallel
```

Integration tests run against a real PostgreSQL instance using a cloned template database — fast isolation without `create_all()` per test. Redis is always replaced with fakeredis.

## Deployment

The generated project ships with a Gunicorn config and Traefik integration for HTTPS:

```bash
bash ops/setup-traefik.sh   # one-time Traefik setup per server
docker compose up -d
docker compose exec web python manage.py db upgrade
```

See `docs/traefik.md` and `docs/gunicorn.md` in the generated project for details.

## Development

```bash
pip install -e ".[dev]"
pytest
ruff check src/ tests/
ruff format src/ tests/
```
