A dependency injection container, a service-provider boot lifecycle, an Active-Record-style async ORM, and a Laravel-style CLI — built on Starlette and SQLAlchemy 2.0.
$ pip install zeython $ zeython new "My App" $ cd my_app && pip install -e . && zeython serve
Python has excellent web libraries. It has very few opinionated, batteries-included frameworks in the Django/Laravel/Rails sense — Zeython is that assembly, done once.
Request handling, the ORM, and migrations — no bolted-on asyncio.run calls anywhere in the stack.
RBAC, two-factor auth, OAuth2/OIDC (SSO), and an automatic audit trail on any model — not bolted on later.
Controllers, models, and routes live in predictable places: app/Controllers, app/Models, routes/.
zeython new, serve, make:*, db:* cover project creation, code generation, and migrations.
A generated OpenAPI spec and Swagger UI at /docs, built by reading what's actually registered.
@app.websocket(...) handlers and a WebSocketHub broadcast registry — no separate server.
An MCP server (zeython mcp) gives coding agents tools to inspect real routes, schema, and docs.
Full type hints and a real pytest suite — not scaffolding wrapped around unfinished features.
zeython.ai binds an LLM client in the container — Anthropic, OpenAI, or Gemini — zero-config by default, one line to go live.
A Laravel Blade-inspired directive syntax — @if, @foreach, @extends/@section, components — compiled straight to Jinja2, plus a production-grade Tailwind CSS pipeline with no Node.js required.
JSON API and server-rendered HTML aren't a choice you make once for the whole app — both are first-class, route by route.
from sqlalchemy import String, Text from sqlalchemy.orm import Mapped, mapped_column from zeython import Model class Post(Model): __tablename__ = "posts" title: Mapped[str] = mapped_column(String(255)) body: Mapped[str] = mapped_column(Text)
from starlette.responses import JSONResponse from zeython import Controller, NotFoundException from app.Models.post import Post class PostController(Controller): async def index(self, request): return JSONResponse([p.to_dict() for p in await Post.all()]) async def store(self, request): data = await request.json() post = await Post.create(**data) return JSONResponse(post.to_dict(), status_code=201)
from zeython import render from app.Models.post import Post @app.get("/posts/{id}", name="post.show") async def show(request): post = await Post.find(int(request.path_params["id"])) return render(request, "posts/show.blade.html", {"post": post})
@extends('layouts.app') @section('content') <h1>{{ post.title }}</h1> @if(post.published) <p>{{ post.body }}</p> @else <p>Draft</p> @endif @endsection
Not a hello-world demo — auth, security, background work, and observability, all shipped and tested.
One command per concept — models, controllers, jobs, policies, middleware, migrations.
# scaffold a model, controller, and migration zeython make model Post zeython make controller Post zeython db revision -m "add posts table" zeython db migrate # jobs, policies, middleware, seeders — same pattern zeython make job SendWelcomeEmail zeython make policy PostPolicy zeython route:list
Scaffold a project, wire a route, and be serving requests in under a minute.