Metadata-Version: 2.4
Name: arvel
Version: 0.27.1
Summary: The Laravel of Python — FastAPI + Pydantic + SQLAlchemy, end-to-end type-safe.
Project-URL: Homepage, https://arvel.dev
Project-URL: Documentation, https://arvel.dev
Project-URL: Repository, https://github.com/mohamed-rekiba/arvel
Project-URL: Issues, https://github.com/mohamed-rekiba/arvel/issues
Author: Arvel contributors
License: MIT
Keywords: fastapi,framework,laravel,pydantic,sqlalchemy,web
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: FastAPI
Classifier: Framework :: Pydantic :: 2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.14
Requires-Dist: aiohttp>=3.14.1
Requires-Dist: alembic>=1.18.4
Requires-Dist: anyio>=4.13.0
Requires-Dist: argon2-cffi>=25.1.0
Requires-Dist: croniter>=6.2.2
Requires-Dist: cryptography>=48.0.0
Requires-Dist: email-validator>=2.3.0
Requires-Dist: fastapi>=0.136.3
Requires-Dist: httpx2>=2.3.0
Requires-Dist: itsdangerous>=2.2.0
Requires-Dist: jinja2>=3.1.6
Requires-Dist: msgspec>=0.21.1
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.42.1
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.42.1
Requires-Dist: opentelemetry-exporter-prometheus>=0.63b1
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.63b1
Requires-Dist: opentelemetry-instrumentation-logging>=0.63b1
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.63b1
Requires-Dist: opentelemetry-sdk>=1.42.1
Requires-Dist: pydantic-settings>=2.14.1
Requires-Dist: pydantic>=2.13.4
Requires-Dist: python-dotenv>=1.2.2
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: sqlalchemy[asyncio]>=2.0.50
Requires-Dist: starlette>=1.2.1
Requires-Dist: structlog>=26.1.0
Requires-Dist: typer>=0.26.7
Requires-Dist: uvicorn[standard]>=0.49.0
Requires-Dist: whenever>=0.10.0
Provides-Extra: all
Requires-Dist: aioboto3>=15.5.0; extra == 'all'
Requires-Dist: aiomysql>=0.3.2; extra == 'all'
Requires-Dist: aiosmtplib>=5.1.1; extra == 'all'
Requires-Dist: aiosqlite>=0.22.1; extra == 'all'
Requires-Dist: arvel-audit; extra == 'all'
Requires-Dist: arvel-image; extra == 'all'
Requires-Dist: arvel-image[heif]; extra == 'all'
Requires-Dist: arvel-oauth; extra == 'all'
Requires-Dist: arvel-permission; extra == 'all'
Requires-Dist: arvel-search; extra == 'all'
Requires-Dist: asyncpg>=0.31.0; extra == 'all'
Requires-Dist: authlib>=1.7.2; extra == 'all'
Requires-Dist: azure-storage-blob>=12.30.0; extra == 'all'
Requires-Dist: bcrypt>=5.0.0; extra == 'all'
Requires-Dist: boto3>=1.40.61; extra == 'all'
Requires-Dist: faker>=40.22.0; extra == 'all'
Requires-Dist: fakeredis>=2.36.1; extra == 'all'
Requires-Dist: google-cloud-storage>=3.11.0; extra == 'all'
Requires-Dist: ipython>=9.14.1; extra == 'all'
Requires-Dist: moto[s3]>=5.2.2; extra == 'all'
Requires-Dist: openapi-spec-validator>=0.9.0; extra == 'all'
Requires-Dist: premailer>=3.10.0; extra == 'all'
Requires-Dist: psycopg[binary]>=3.3.4; extra == 'all'
Requires-Dist: pyjwt[crypto]>=2.13.0; extra == 'all'
Requires-Dist: pymysql>=1.2.0; extra == 'all'
Requires-Dist: redis>=7.4.0; extra == 'all'
Requires-Dist: taskiq-aio-pika>=0.6.0; extra == 'all'
Requires-Dist: taskiq-redis>=1.2.2; extra == 'all'
Requires-Dist: taskiq>=0.12.4; extra == 'all'
Requires-Dist: websockets>=16.0; extra == 'all'
Provides-Extra: audit
Requires-Dist: arvel-audit; extra == 'audit'
Provides-Extra: azure
Requires-Dist: azure-storage-blob>=12.30.0; extra == 'azure'
Provides-Extra: bcrypt
Requires-Dist: bcrypt>=5.0.0; extra == 'bcrypt'
Provides-Extra: broadcasting
Requires-Dist: websockets>=16.0; extra == 'broadcasting'
Provides-Extra: dev
Requires-Dist: faker>=40.22.0; extra == 'dev'
Requires-Dist: fakeredis>=2.36.1; extra == 'dev'
Requires-Dist: moto[s3]>=5.2.2; extra == 'dev'
Provides-Extra: gcs
Requires-Dist: google-cloud-storage>=3.11.0; extra == 'gcs'
Provides-Extra: image
Requires-Dist: arvel-image; extra == 'image'
Provides-Extra: image-heif
Requires-Dist: arvel-image[heif]; extra == 'image-heif'
Provides-Extra: jwt
Requires-Dist: authlib>=1.7.2; extra == 'jwt'
Requires-Dist: pyjwt[crypto]>=2.13.0; extra == 'jwt'
Provides-Extra: mail
Requires-Dist: aiosmtplib>=5.1.1; extra == 'mail'
Requires-Dist: premailer>=3.10.0; extra == 'mail'
Provides-Extra: mysql
Requires-Dist: aiomysql>=0.3.2; extra == 'mysql'
Requires-Dist: pymysql>=1.2.0; extra == 'mysql'
Provides-Extra: oauth
Requires-Dist: arvel-oauth; extra == 'oauth'
Provides-Extra: openapi
Requires-Dist: openapi-spec-validator>=0.9.0; extra == 'openapi'
Provides-Extra: permission
Requires-Dist: arvel-permission; extra == 'permission'
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.31.0; extra == 'postgres'
Requires-Dist: psycopg[binary]>=3.3.4; extra == 'postgres'
Provides-Extra: queue
Requires-Dist: taskiq>=0.12.4; extra == 'queue'
Provides-Extra: queue-amqp
Requires-Dist: taskiq-aio-pika>=0.6.0; extra == 'queue-amqp'
Provides-Extra: queue-redis
Requires-Dist: taskiq-redis>=1.2.2; extra == 'queue-redis'
Provides-Extra: redis
Requires-Dist: redis>=7.4.0; extra == 'redis'
Provides-Extra: s3
Requires-Dist: aioboto3>=15.5.0; extra == 's3'
Requires-Dist: boto3>=1.40.61; extra == 's3'
Provides-Extra: search
Requires-Dist: arvel-search; extra == 'search'
Provides-Extra: shell
Requires-Dist: ipython>=9.14.1; extra == 'shell'
Provides-Extra: sqlite
Requires-Dist: aiosqlite>=0.22.1; extra == 'sqlite'
Description-Content-Type: text/markdown

# arvel

<p>
<a href="https://pypi.org/project/arvel/">
    <img src="https://img.shields.io/pypi/v/arvel?color=%2334D058" alt="PyPI">
</a>
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License">
</p>

The Laravel of Python — built natively on FastAPI + Pydantic + SQLAlchemy, end-to-end type-safe.

> **Status:** Pre-alpha. The public API can still change before `1.0`.

Arvel is a batteries-included application framework for async Python. It layers a service container,
typed configuration, the Arvent ORM, an HTTP stack (routing, form requests, API
resources, middleware), cache, sessions, storage, queues, events, broadcasting, mail, notifications,
scheduling, and auth on top of the standard async stack — without replacing FastAPI, Pydantic, or
SQLAlchemy.

Full documentation lives at **[arvel.dev](https://arvel.dev)**.

## Install

```bash
pip install arvel
# with extras:
pip install 'arvel[postgres,redis,queue]'
```

Arvel requires **Python 3.14+**.

## Hello, Arvel

The framework boots through an `Application`. You register configuration and service providers, then
resolve services from the container:

```python
from pathlib import Path

from arvel import Application, ServiceProvider
from arvel.config import ArvelSettings


class AppSettings(ArvelSettings):
    name: str = "MyApp"
    debug: bool = False


class Greeter:
    def __init__(self, settings: AppSettings) -> None:
        self.settings = settings

    def greet(self, who: str) -> str:
        prefix = "DEBUG: " if self.settings.debug else ""
        return f"{prefix}Hello from {self.settings.name}, {who}!"


class GreeterProvider(ServiceProvider):
    def register(self) -> None:
        self.app.container.singleton(Greeter)


async def main() -> None:
    app = (
        Application.configure(Path("."))
        .with_environment("production")
        .with_config_files([AppSettings])
        .with_providers([GreeterProvider])
        .create()
    )
    await app.boot()

    greeter = app.container.make(Greeter)
    print(greeter.greet("Arvel"))

    await app.shutdown()
```

In a generated project you don't write this by hand — `arvel new` scaffolds `bootstrap/app.py` and
`bootstrap/providers.py`, and `arvel serve` runs the ASGI app for you.

## What's inside

| Area | Highlights |
|---|---|
| **Container & providers** | Constructor injection, singletons, contextual bindings, `dep()` for FastAPI `Depends` |
| **Config** | `ArvelSettings` (pydantic-settings), `@register`, `Config.of(...)`, the `config()` helper |
| **HTTP** | `Route` decorators, `FormRequest` validation, `JsonResource`/`ResourceCollection`, middleware |
| **Arvent ORM** | `Model`, typed relations, soft deletes, scopes, attribute casts, a schema DSL → Alembic |
| **Auth** | JWT / session / token guards, `Gate` and policies, password resets, email verification |
| **Queues** | `Job`, the `Bus` facade, retries with backoff, dead-letter queue, graceful workers |
| **Events** | Typed `Event` models, inline and `ShouldQueue` listeners, the `Event` facade |
| **Mail & notifications** | Mailables (envelope/content), SMTP/log/array drivers, multi-channel notifications |
| **Cache / session / storage** | Pluggable drivers behind `Cache`, `Session`, and `Storage` facades |
| **Scheduling & broadcasting** | Cron-style scheduler, Reverb-compatible WebSocket server |

## CLI

Installing the package puts the `arvel` binary on your PATH. A few common commands:

```bash
arvel new my-app           # scaffold a project
arvel serve --reload       # run the ASGI dev server
arvel make:model Post -m   # generate a model + migration
arvel migrate              # run pending migrations
arvel queue:work           # process queued jobs
arvel schedule:work        # run the scheduler
arvel route:list           # inspect registered routes
arvel about                # show framework + environment info
```

Run `arvel --help` for the full list.

## License

MIT — see [LICENSE](../../LICENSE).
