Skip to main content

Lightweight full-stack async Python web framework built on Starlette designed for rapid development without compromising in UX

Project description

Z8ter

Z8ter is a lightweight, async Python web framework built on Starlette, designed for rapid development without compromising UX. It combines SSR-first rendering, auto-discovered routes, pluggable authentication, and CLI tooling into one cohesive developer experience.


Status: Public Alpha — Z8ter is under active development and not yet recommended for production. APIs may change without notice.


Features

  • File-based Routing — Views under endpoints/views/ map to routes automatically
  • SSR + Islands — Server-side rendering by default, with React "islands" for interactivity
  • Decorator-driven APIs — Define REST APIs using decorators; auto-mounted under /api/<name>
  • Pluggable Auth — Session middleware, Argon2 password hashing, and route guards like @login_required
  • Composable BuilderAppBuilder wires config, templating, Vite, sessions, and auth in order
  • CLI Tooling — Scaffold projects, pages, and APIs with z8 new, z8 create_page, z8 create_api
  • Modern Frontend — Vite, React, TypeScript, Tailwind CSS, and DaisyUI ready out of the box

Quickstart

# Scaffold a new app without installing anything globally
uvx --from z8ter z8 new myapp
cd myapp
uv sync              # Install Python dependencies
npm install          # Install Node dependencies
uv run z8 run dev    # Start the dev server
Alternative: Using pip instead of uv
# Install the CLI into the active virtualenv first
pip install z8ter
z8 new myapp
cd myapp
python3 -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\Activate.ps1
pip install -r requirements.txt
npm install
z8 run dev

Visit http://localhost:8000 to see your app.


Installation

# One-off CLI usage
uvx --from z8ter z8 --help

# Persistent CLI install
uv tool install z8ter

# Or inside an existing project environment
uv add z8ter

# Or using pip
pip install z8ter

Project Structure

myapp/
├── main.py                 # Application entry point
├── .env                    # Environment configuration
├── endpoints/
│   ├── views/              # SSR page views → URLs
│   │   ├── index.py        # → /
│   │   └── about.py        # → /about
│   └── api/                # REST API endpoints
│       └── hello.py        # → /api/hello/*
├── templates/              # Jinja2 templates
│   ├── base.jinja
│   └── pages/
├── content/                # YAML page content
├── static/                 # Static assets
└── src/ts/                 # TypeScript/React code
    ├── app.ts
    └── ui-components/      # React Web Components

Creating Pages

z8 create_page products
# endpoints/views/products.py
from z8ter.endpoints.view import View
from z8ter.requests import Request
from z8ter.responses import Response


class Products(View):
    async def get(self, request: Request) -> Response:
        return self.render(request, "pages/products.jinja")

Creating APIs

z8 create_api users
# endpoints/api/users.py
from z8ter.endpoints.api import API
from z8ter.requests import Request
from z8ter.responses import JSONResponse


class Users(API):
    @API.endpoint("GET", "/")
    async def list_users(self, request: Request):
        return JSONResponse({"ok": True, "users": []})

    @API.endpoint("GET", "/{user_id:int}")
    async def get_user(self, request: Request):
        user_id = request.path_params["user_id"]
        return JSONResponse({"ok": True, "user": {"id": user_id}})

Application Setup

# main.py
from z8ter.builders.app_builder import AppBuilder

builder = AppBuilder()
builder.use_config(".env")
builder.use_templating()
builder.use_vite()
builder.use_errors()

app = builder.build(debug=True)

With Authentication

from z8ter.builders.app_builder import AppBuilder
from app.repos import SessionRepo, UserRepo

builder = AppBuilder()
builder.use_config(".env")
builder.use_templating()
builder.use_vite()
builder.use_auth_repos(session_repo=SessionRepo(), user_repo=UserRepo())
builder.use_authentication()
builder.use_app_sessions()
builder.use_errors()

app = builder.build(debug=True)

Protected Routes

from z8ter.endpoints.view import View
from z8ter.auth.guards import login_required


class Dashboard(View):
    @login_required
    async def get(self, request):
        user = request.state.user
        return self.render(request, "pages/dashboard.jinja", {"user": user})

Module Overview

Module Purpose
z8ter.core ASGI wrapper around Starlette
z8ter.endpoints Base View and API classes
z8ter.builders AppBuilder and composable setup steps
z8ter.auth Session management, crypto, guards, middleware
z8ter.route_builders Auto-discovery of views and APIs
z8ter.vite Vite asset integration (dev server + manifest)
z8ter.cli CLI commands: new, create_page, create_api, run
z8ter.config Environment-based configuration
z8ter.errors Centralized error handling

CLI Commands

Command Description
z8 new <name> Create a new project
z8 create_page <name> Scaffold a page (view + template + content + TS)
z8 create_api <name> Scaffold an API endpoint
z8 run [dev|prod|LAN|WAN] Run the server

Documentation

Full documentation is available in the docs/ folder:


Requirements

  • Python 3.10+
  • Node.js 18+ (for frontend tooling)

License

MIT License — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

z8ter-0.2.7.tar.gz (180.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

z8ter-0.2.7-py3-none-any.whl (197.9 kB view details)

Uploaded Python 3

File details

Details for the file z8ter-0.2.7.tar.gz.

File metadata

  • Download URL: z8ter-0.2.7.tar.gz
  • Upload date:
  • Size: 180.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for z8ter-0.2.7.tar.gz
Algorithm Hash digest
SHA256 4745ce9e00e24a03308cc28316f502b40988d53bde11d7827bbda28dbb61505f
MD5 1a8725b2f453c7ada9f1d980acf35eba
BLAKE2b-256 c4b0b3d0135596af63a782f405908aaa0e4cd3f6ad52d76391027ba4b19d177e

See more details on using hashes here.

File details

Details for the file z8ter-0.2.7-py3-none-any.whl.

File metadata

  • Download URL: z8ter-0.2.7-py3-none-any.whl
  • Upload date:
  • Size: 197.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for z8ter-0.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 4c9cdb56453924fa7c7d8f9c8c79ab9b0434f5f601878ca99a742891c74c535d
MD5 193a3baa4c33db87a1829c73b531d6f6
BLAKE2b-256 e9f76b64139a7f54c53e67de8d8ec4491d60729d642f95a0d40789b172bfc93b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page