Skip to content

Repository files navigation

Orionis Framework

Orionis Framework

Write Python. Build the whole application.

Async-first. Laravel-inspired. Built for Python 3.14+.

PyPI version Python 3.14+ Test suite Status: alpha MIT license

Quick Start • Code Tour • Features • Documentation • Community


The endpoint is just the beginning.

Then come the database, authentication, validation, file uploads, scheduled work, and all the decisions that turn a demo into an application.

Orionis is an async-first, full-stack Python framework that connects those pieces. A service container at the center. A fluent ORM for your data. Shared conventions across HTTP, console commands, and tests.

For APIs, server-rendered applications, and internal tools that need more than an HTTP layer, without leaving the Python ecosystem.

Early access: Orionis is in alpha. APIs may change before 1.0; this is not a production-stability promise. Try it on a real problem, tell us where it gets in your way, and help shape the framework.

Why Orionis

  • Structure that feels familiar. Laravel-inspired providers, controllers, facades, migrations, and fluent APIs, built around Python's async/await.
  • Dependencies declared, not hunted down. Type-hint a service contract; the container resolves it in controllers, commands, and test methods. Choose singleton, request-scoped, or transient lifetimes.
  • APIs and HTML belong in the same app. Return JSON, render an async Jinja2 view, stream a file, or redirect with validation errors and old input.
  • Your infrastructure has a home. Configuration, caching, storage, logging, and scheduling follow the same application lifecycle.

Batteries, Connected

These are implemented capabilities, not a roadmap.

Area What you get today
HTTP Granian with ASGI and RSGI, named routes, typed path parameters, middleware, CORS, rate limiting, streaming, and file responses.
Validation msgspec schemas, nested payloads, field constraints, custom rules, and multi-error responses. Invalid API input becomes HTTP 422.
Authentication Session login and opaque personal access tokens, request-scoped identity, roles, permissions, and resource policies.
ORM & Database Async Active Record, a shared fluent query builder, relationships, eager loading, soft deletes, scopes, model events, pagination, transactions, and migrations.
Views & Sessions Async Jinja2, CSRF integration, flash messages, old form input, error bags, and file, memory, cache, or database session stores.
Cache Memory, file, Redis, Memcached, and database stores, with TTLs, counters, and lock APIs.
Storage Local and in-memory drivers, uploads, streams, and optional S3, Azure Blob, and Google Cloud Storage integrations.
Console & Scheduling Reactor commands, scaffolding, Rich output, and APScheduler tasks with memory, Redis, or database job stores.
Everyday Essentials Argon2id and bcrypt hashing, AES encryption, rotating logs, translations, collections, and date/time utilities.
Testing An integrated runner, async test cases, dependency injection, discovery, filtering, and CLI failure exit codes.

Database backends include SQLite, PostgreSQL, MySQL, Oracle, and SQL Server. External services require configuration; cloud SDKs and some database drivers use the optional extras declared in pyproject.toml.

A place for every part of your application
app/
  http/          Controllers, schemas, and middleware
  models/        Application models
  contracts/     Service interfaces
  services/      Business logic
  providers/     Dependency bindings and startup hooks
  console/       Commands and schedules
bootstrap/       Application composition
config/          Typed application configuration
database/        Migrations
resources/       Views and translations
routes/          Web, API, and console entry points
tests/           Application tests
orionis/         Framework source in this development repository

Quick Start

You need Python 3.14+ and uv. To explore the current implementation, run this repository's development app:

git clone --branch=1.x https://github.com/orionis-framework/framework.git
cd framework
uv sync --python=3.14

Copy .env.example to .env: use cp .env.example .env on macOS/Linux or Copy-Item .env.example .env in PowerShell. Keep these local settings for a first run without external database or cache servers:

DB_CONNECTION=sqlite
DB_DATABASE=database/database.sqlite
CACHE_STORE=memory
SESSION_DRIVER=file

On Windows, set $env:PYTHONIOENCODING = "utf-8" before running Reactor.

uv run python reactor migrate
uv run python reactor serve

Open the address printed by serve. This is a framework development checkout, not a generated application skeleton.

Already have a Python project? uv add orionis installs the package; application bootstrap and configuration are still required.

A Real Endpoint

Accept a project name, validate it, persist a model, and return 201 Created. The supporting model and migration are included below.

Declare the input in app/http/schemas/create_project.py:

from orionis.schemas import Schema
from orionis.schemas.constraints import MaxLength, MinLength
from orionis.schemas.fields import Field


class CreateProject(Schema):
    name: Field[str, MinLength(3), MaxLength(120)]

Write the action in app/http/controllers/project_controller.py:

from app.http.schemas.create_project import CreateProject
from app.models.project import Project
from orionis.http import HttpResponse, response


class ProjectController:
    __slots__ = ()

    async def store(self, payload: CreateProject) -> HttpResponse:
        project = await Project.create(payload.toDict())
        return response.json(project.toDict(), status_code=201)

Register the route in routes/api.py:

from app.http.controllers.project_controller import ProjectController
from orionis.support.facades.router import Route

Route.post("/projects", [ProjectController, "store"]).name("projects.store")

The container supplies a validated CreateProject instance before the action runs. A missing, too-short, or too-long name produces 422 with field errors. No manual body parsing or validation call in the controller.

Complete the example: model and migration

Create app/models/project.py:

from typing import ClassVar
from orionis.orm import BigInteger, Model, String


class Project(Model):
    __slots__ = ()

    fillable: ClassVar[list[str]] = ["name"]
    timestamps: ClassVar[bool] = False

    id = BigInteger().primary().autoIncrement()
    name = String(120)

Add m202609140001_create_projects_table.py under database/migrations/:

from orionis.database.contracts.migration import Migration
from orionis.support.facades.schema import Schema


class CreateProjectsTable(Migration):
    __slots__ = ()

    async def up(self) -> None:
        async with Schema.create("projects") as table:
            table.id()
            table.string("name", 120)

    async def down(self) -> None:
        await Schema.drop("projects")

Run uv run python reactor migrate again, then send a JSON request body such as {"name": "Orionis Playground"} to the new route. This is a public demo endpoint; add authentication and authorization for protected application data.

Models or Tables. One Query Language.

Inside an async controller or service, after applying the migration:

from app.models.project import Project
from orionis.support.facades.db import DB

page = await (
    Project.where("name", "like", "Orionis%")
    .orderBy("id", "desc")
    .paginate(per_page=20, page=1)
)

rows = await DB.table("projects").select("id", "name").get()

Models add hydration, casts, relationships, and lifecycle behavior. Direct table queries return records without requiring a model. Both use the same query language and SQLAlchemy Core's async engine, not SQLAlchemy's ORM session.

Reactor, Every Day

One entry point for the work around your application:

Command Purpose
uv run python reactor serve Start the development HTTP server.
uv run python reactor make:command DailyReport Scaffold an application command.
uv run python reactor make:provider ProjectServiceProvider Scaffold a service provider.
uv run python reactor migrate Apply pending database migrations.
uv run python reactor migrate:status Inspect migration status.
uv run python reactor schedule:list Inspect registered scheduled tasks.
uv run python reactor schedule:work Run the scheduler.
uv run python reactor test --start-dir=tests/orm --verbosity=1 Run a focused test suite in this checkout.
uv run python reactor list Discover the available commands.

Custom commands can use the same injected services as your HTTP controllers. Scheduled tasks run those command signatures through APScheduler.

Familiar Foundations

Orionis builds on the ecosystem rather than asking you to leave it:

Granian for Rust-powered HTTP. msgspec for typed validation and encoding. SQLAlchemy Core for async database execution. Jinja2 for templates. APScheduler for scheduling. Rich for the terminal.

Orionis supplies the application architecture that connects them. Its request path uses precompiled routing and cached reflection metadata; actual throughput depends on your routes, middleware, database, and deployment.

Documentation

The documentation website is still growing alongside the alpha. For implementation-level detail, start with these versioned guides:

Guide Explore
Container & DI Providers, service lifetimes, scopes, and facades.
Validation Schemas, field constraints, custom rules, and errors.
ORM & Database (Spanish) Models, relationships, queries, migrations, and transactions.
Views Async templates and their integration with forms and sessions.
Storage Disks, uploads, streams, and cloud drivers.
Mail Mailables, direct sends, MIME, storage attachments, SMTP, and .eml files.
Testing Async test cases, injected dependencies, and the runner.

Most module guides also have a sibling README.es.md. Authentication code lives in orionis/auth; the project website introduces the framework.

Project Status

Alpha. Open source. Actively evolving. Pin the version you evaluate and review changes before upgrading. Compatibility and production readiness should be assessed against your own application requirements.

Background tasks run in process, after a response; they are not a durable queue. Mail supports synchronous composition with asynchronous SMTP or file delivery. Durable queues, WebSockets, and Inertia/Vite integrations are not implemented yet. Authentication currently covers sessions and personal access tokens, not JWT, OAuth, MFA, or password-reset flows.

Build It With Us

The most useful contribution is a real use case. Build a small feature, bring a reproducible bug, improve an example, or tell us which API feels awkward. You do not need to know the whole framework to improve one part of it.

Sponsor Orionis

Created and maintained by Raul Mauricio Uñate Castro. Released under the MIT license.


The next part of your application already has a home.

About

⚡Orionis Framework Core

Resources

Stars

23 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages