Metadata-Version: 2.4
Name: arvel
Version: 0.7.0
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: 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: httpx>=0.28.1
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>=25.5.0
Requires-Dist: typer>=0.26.4
Requires-Dist: uvicorn[standard]>=0.48.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.29.0; extra == 'all'
Requires-Dist: bcrypt>=5.0.0; extra == 'all'
Requires-Dist: boto3>=1.40.61; extra == 'all'
Requires-Dist: faker>=40.19.1; extra == 'all'
Requires-Dist: fakeredis>=2.36.0; extra == 'all'
Requires-Dist: google-cloud-storage>=3.10.1; extra == 'all'
Requires-Dist: ipython>=9.14.0; extra == 'all'
Requires-Dist: moto[s3]>=5.2.1; 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.29.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.19.1; extra == 'dev'
Requires-Dist: fakeredis>=2.36.0; extra == 'dev'
Requires-Dist: moto[s3]>=5.2.1; extra == 'dev'
Provides-Extra: gcs
Requires-Dist: google-cloud-storage>=3.10.1; 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.0; 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, an Eloquent-style ORM (Arvent), 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).
