Skip to main content

Modular Python web framework with hot-mount dynamic modules — FastAPI + SQLAlchemy + Jinja + HTMX + Alpine.

Project description

HotFrame

Modular Python web framework with hot-mount dynamic modules.

Python 3.12+ License PyPI


What is hotframe

hotframe is a Python web framework that unifies FastAPI, SQLAlchemy 2.0, Jinja2, HTMX, and Alpine.js under Django-like ergonomics. It adds a hot-mount module engine — load and unload plugins at runtime without restarting the process — and a Turbo/Livewire-style HTMX layer for server-driven UI. Built for teams who want the productivity of Rails or Django with the async performance of FastAPI.


Quickstart

pip install hotframe
hf startproject myapp
cd myapp
hf runserver
INFO     hotframe.modules - Mounted: core, auth, admin (3 modules)
INFO     hotframe.server - Uvicorn running on http://127.0.0.1:8000
INFO     hotframe.server - Press CTRL+C to quit

The CLI installs two aliases: hf (short) and hotframe (explicit).


Key Features

  • Hot-mount dynamic modules — Load and unload Python modules at runtime via a DB registry with topological dependency resolution. No process restart required.

  • HTMX layer (Turbo/Livewire-style)@htmx_view decorator, named frames, TurboStream responses, out-of-band swaps, and server-sent event broadcasting. Build rich UIs without writing JavaScript.

  • Django-like ergonomicsAppConfig, settings.py, management commands, scaffolding CLI. Familiar conventions so teams onboard in minutes, not days.

  • AsyncEventBus + HookRegistry — WordPress-style actions and filters across modules. Decouple features without tight imports. Fully async-native.

  • SQLAlchemy 2.0 + Alembic — Async sessions, per-module migration namespaces, and automatic migration discovery. No shared migration root.

  • Jinja2 + Alpine.js integration — Template inheritance, context processors, CSP-safe nonce injection, and Alpine.js wired out of the box.

  • OpenTelemetry observability — Traces, metrics, and structured logs built into the request lifecycle. Zero extra setup for OTLP exporters.

  • CLI scaffoldinghf startproject, hf startapp, hf startmodule, hf makemigrations, hf migrate. Generate production-ready skeletons from the command line.

  • Interactive shellhf shell opens a Python REPL with the app fully booted: app, settings, db, events, hooks, slots, and runtime are pre-loaded. Use it for ad-hoc queries, slot debugging, or inspecting module state. Install pip install "hotframe[shell]" for the optional IPython backend with auto-await.

  • Reusable components — Server-rendered UI widgets with a required template.html and optional Pydantic-typed props, colocated HTTP routes, and per-component static assets. Apps and hot-mount modules contribute components; hf startproject scaffolds alert and badge as editable examples. Invoke from any template via {{ render_component('name', ...) }} or {% component 'name' %}...{% endcomponent %}.

  • HTTP client subsystemAuthenticatedClient wraps httpx.AsyncClient with pluggable Auth strategies (BearerAuth, ApiKeyAuth, BasicAuth, HmacAuth, CustomAuth) and a per-app registry on app.state.http_clients. Since 0.0.9, an Angular-style interceptor pipeline layers RetryInterceptor, CircuitBreakerInterceptor, and RefreshInterceptor (plus any custom interceptor) around every registered client, auto-discovered from apps/shared/interceptors/ and modules/*/interceptors.py. See docs/HTTP_CLIENTS.md and docs/http-interceptors.md.


Comparison

Feature Rails Turbo Laravel Livewire Phoenix LiveView Django + htmx hotframe
Language Ruby PHP Elixir Python Python
Server-driven UI Yes Yes Yes Partial Yes
Hot-reload modules No No No No Yes
Async-native No No Yes No Yes
ORM ActiveRecord Eloquent Ecto Django ORM SQLAlchemy 2.0
Per-module migrations No No No No Yes
Plugin hooks system No No No No Yes
CLI scaffolding Yes Yes Yes Yes Yes
PyPI installable No No No Yes Yes

Minimal Example

Define a module with a model, a route, and a template in under 20 lines:

# modules/blog/module.py
from hotframe import ModuleConfig

class BlogModule(ModuleConfig):
    name = "blog"
    version = "1.0.0"
    dependencies = ["core", "auth"]
# modules/blog/models.py
from hotframe import Base
from sqlalchemy.orm import Mapped, mapped_column

class Post(Base):
    __tablename__ = "blog_posts"
    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str]
    body: Mapped[str]
# modules/blog/routes.py
from fastapi import APIRouter, Request
from hotframe import htmx_view, DbSession
from .models import Post

router = APIRouter()

@router.get("/blog")
@htmx_view(module_id="blog", view_id="list")
async def post_list(request: Request, db: DbSession):
    posts = await db.execute(select(Post))
    return {"posts": posts.scalars().all()}
<!-- modules/blog/templates/blog/index.html -->
<div hx-get="/blog" hx-trigger="every 30s" hx-swap="innerHTML">
  {% for post in posts %}
    <article>{{ post.title }}</article>
  {% endfor %}
</div>

Architecture Overview

hotframe is organized in three layers:

Runtime layer — the framework core. Boots FastAPI, wires middleware, initializes the DB engine, and exposes the public API (@htmx_view, router, settings, EventBus, HookRegistry).

Module layer — each module is a Python package with a ModuleConfig subclass, its own models, views, templates, migrations, and static assets. The module engine resolves dependency order, mounts routes and Alembic migration contexts, and registers hook namespaces. Modules can be installed, uninstalled, enabled, and disabled at runtime via the admin API without touching the running process.

HTMX layer — sits on top of FastAPI responses. The @htmx_view decorator detects HX-Request headers and returns partial renders or full-page responses automatically. TurboStream helpers produce text/vnd.turbo-stream.html responses for out-of-band DOM updates. The EventBus integrates with server-sent events for real-time broadcasting to named HTMX frames.

The CLI (hf) is a Typer application that wraps Uvicorn, Alembic, and the scaffolding generators. It reads settings.py from the project root and discovers modules automatically from the modules/ directory.


Documentation

Documentation is available in the docs/ directory.


License

Apache 2.0. Copyright 2026 ERPlora.


Contributing

See CONTRIBUTING.md. Feedback and issue reports are welcome while the project is in pre-alpha. Code contributions open on first stable release.

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

hotframe-0.1.1.tar.gz (1.7 MB view details)

Uploaded Source

Built Distribution

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

hotframe-0.1.1-py3-none-any.whl (264.9 kB view details)

Uploaded Python 3

File details

Details for the file hotframe-0.1.1.tar.gz.

File metadata

  • Download URL: hotframe-0.1.1.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hotframe-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4720e97037059cdf5e67f29e30308147f8f7243a9fcaa2e3a3026a3a7b7bed3f
MD5 d88603410c1f8553501b4a949c2fe8ee
BLAKE2b-256 3e106a14e7ca913c92453d98ce89974749188c68f85057412a7616f7797f5844

See more details on using hashes here.

Provenance

The following attestation bundles were made for hotframe-0.1.1.tar.gz:

Publisher: release.yml on ERPlora/hotframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hotframe-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: hotframe-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 264.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hotframe-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9dc7c431ccba6bbaee8ae4ebe44d6fd3641d595e410fc28d42a04f799c9bd81d
MD5 c3bf8cb717391fb8cb2d359885df4808
BLAKE2b-256 11b42292dd7ca53fc321a9e09c8c354c4adac941e0af2b60ff393859e3c2f4e9

See more details on using hashes here.

Provenance

The following attestation bundles were made for hotframe-0.1.1-py3-none-any.whl:

Publisher: release.yml on ERPlora/hotframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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