Skip to content

fsecada01/component-framework

Repository files navigation

Component Framework

BETA SOFTWARE — APIs are stabilising. Core features are complete and test-covered. Minor breaking changes may still occur before 1.0.

Framework-agnostic server components with LiveView-style interactivity inspired by Phoenix LiveView and Laravel Livewire.

CI Docs Python 3.11+ License: MIT Status: Beta


Development Status

Current Version: 0.4.0-beta API Documentation: fsecada01.github.io/component-framework

The framework has a complete, tested feature set covering the full Beta roadmap. APIs are solidifying — the core lifecycle, permissions, composition, and testing utilities are stable. We welcome feedback before the 1.0 release.


Adapter Support

Framework Status Install extra Notes
FastAPI ✅ Supported [fastapi] Includes JinjaX renderer and WebSocket adapter
Django ✅ Supported [django] Includes Channels, Cotton, and template renderer
Litestar ✅ Supported [litestar] HTTP + WebSocket adapters (0.4.0+)
Flask 🗓 Planned Tracking issue #5

Installation

Install only what you need — pydantic is the only mandatory dependency:

# Django projects
pip install "component-framework[django]"

# FastAPI projects
pip install "component-framework[fastapi]"

# Litestar projects
pip install "component-framework[litestar]"

# Multiple adapters
pip install "component-framework[fastapi,django,litestar]"

# Everything
pip install "component-framework[all]"

Migrating from 0.2.x

⚠️ Breaking change in 0.3.0: fastapi, uvicorn, and jinjax are no longer installed by default.

If you were using the FastAPI adapter, add [fastapi] to your install command:

# Before
pip install component-framework

# After
pip install "component-framework[fastapi]"

CI pipelines — any workflow step that installs component-framework without specifying an extras group will stop receiving FastAPI automatically. Update all install commands in your GitHub Actions, Dockerfile, tox.ini, Makefile, or other CI configuration files.

See CHANGELOG.md for the full list of changes.


Features

Core

  • Framework-agnostic — Works with FastAPI, Django, Litestar, and more
  • Server-driven UI — State lives on the server, not the client
  • Minimal JavaScript — HTMX handles frontend interactions
  • Reusable components — Clean OOP boundaries with lifecycle hooks
  • Pluggable renderers — Jinjax, Django templates, or your own
  • Async event handlersasync def on_* handlers properly awaited via async_dispatch()
  • SSE streamingStreamingComponent for long-running operations with intermediate renders
  • State size guard — Configurable warning (64 KB) and hard limit (512 KB) on serialised state

Forms & Validation

  • Pydantic validation — Type-safe form handling
  • Field-level errors — Live error feedback
  • Automatic state sync — Form state synchronised with component state

Access Control

  • Permission classesAllowAny, IsAuthenticated, IsStaff, IsSuperuser, DjangoModelPermission
  • FBV decoratorslogin_required_component, permission_required_component, staff_required_component returning JSON 401/403
  • Component-level controlpermission_classes attribute checked by both FBV and CBV automatically
  • JSON-only responses — No login redirects for API/HTMX consumers

Rate Limiting

  • RateLimitMixin — Per-component, per-user sliding-window rate limiting
  • Configurable — Custom limits and windows per component class
  • 429 responses — Consistent JSON {"error": "Rate limit exceeded"} on breach

Component Composition

  • SlotComponent — Named and default slot support
  • CompositeComponent — Compose components from named child components
  • Context propagation — Parent context flows to child components

Optimistic UI

  • OptimisticMixinget_optimistic_patch() for instant client-side feedback before server confirmation
  • Rollback support — Revert on error

Django Integration

  • Model binding — Direct ORM integration
  • Query optimisationselect_related, prefetch_related
  • Transaction support — Safe database updates
  • Django templates — Native template rendering
  • Cotton supportdjango-cotton integration
  • CBVs — Class-based views with auth/permissions, JSON error responses

Real-Time Updates

  • WebSocket support — Real-time component updates
  • SSE streamingStreamingComponent with async generator handlers for progressive rendering
  • Broadcasting — Multi-client synchronisation
  • Django Channels — Full Channels integration
  • FastAPI WebSocket — Native FastAPI support
  • Litestar WebSocket — Native Litestar support

Caching

  • CacheMixin — Configurable per-component render caching
  • Cache invalidation — Manual and event-driven invalidation
  • Django cache backend — Works with any Django cache backend

Testing Utilities

  • ComponentTestCase — Test components without HTTP, without a running server
  • Event simulationdispatch_event(), mount_component()
  • State assertionsassert_state(), assert_rendered()
  • pytest fixtures — Ready-to-use fixtures for common patterns

Quick Start

Installation

git clone https://github.com/fsecada01/component-framework.git
cd component-framework

# Install with uv (recommended)
uv pip install -e ".[dev]"

FastAPI Example

python examples/fastapi_example.py
# Open http://localhost:8000

Django Example

cd examples/django_example
python manage.py migrate
python manage.py runserver
# Open http://localhost:8000

Documentation

API Reference: fsecada01.github.io/component-framework

Generated from docstrings by pdoc and deployed to GitHub Pages on every push to master and on every v* release tag.

Guide Description
Architecture Overview Core design and component lifecycle
Django Implementation Django adapter setup and patterns
Class-Based Views CBV auth/permission patterns
E-Commerce Example Real-time cart + product demo

AI / LLM Context


Example Components

Simple Counter

from component_framework.core import Component, registry

@registry.register("counter")
class Counter(Component):
    template_name = "counter.html"

    def mount(self):
        self.state["count"] = 0

    def on_increment(self, amount: int = 1):
        self.state["count"] += amount

Form with Validation

from pydantic import BaseModel, EmailStr
from component_framework.core import FormComponent

class ContactSchema(BaseModel):
    name: str
    email: EmailStr
    message: str

@registry.register("contact_form")
class ContactForm(FormComponent):
    schema = ContactSchema

    def on_submit(self):
        send_email(self.validated_data)

Component with Permissions & Rate Limiting

from component_framework.core.permissions import IsAuthenticated
from component_framework.adapters.django_ratelimit import RateLimitMixin

@registry.register("order_actions")
class OrderActions(RateLimitMixin, Component):
    permission_classes = [IsAuthenticated]
    rate_limit = 10          # requests
    rate_limit_window = 60   # seconds

    def on_submit_order(self):
        ...

Component Composition

from component_framework.core.composition import SlotComponent, CompositeComponent

@registry.register("card")
class Card(SlotComponent):
    template_name = "card.html"
    slots = ["header", "body", "footer"]

@registry.register("product_page")
class ProductPage(CompositeComponent):
    components = {
        "card": Card,
        "cart": CartComponent,
    }

Django Model Component

from component_framework.adapters.django_model import DjangoModelComponent

@registry.register("order_editor")
class OrderEditor(DjangoModelComponent):
    model = Order
    state_fields = ["status", "notes", "total"]
    select_related = ["customer"]

    def on_update_status(self, status: str):
        self.instance.status = status
        self.save_instance()

Testing with ComponentTestCase

from component_framework.testing import ComponentTestCase

class TestCounter(ComponentTestCase):
    def test_increment(self):
        component = self.mount_component("counter")
        self.assert_state(component, count=0)
        self.dispatch_event(component, "increment", amount=5)
        self.assert_state(component, count=5)

Architecture

Browser (HTMX/WebSocket/SSE)
        |
Framework Adapter  (FastAPI / Django / Litestar)
        |
Component Framework Core
  - Component lifecycle  (mount → hydrate → handle_event → render → dehydrate)
  - Event routing        (convention-based on_<event> handlers, sync + async)
  - State management     (server-owned JSON state with size guards)
  - Streaming            (StreamingComponent for SSE progressive rendering)
  - Permissions          (per-component permission_classes)
  - Composition          (SlotComponent, CompositeComponent)
        |
Backend (Database / Services)

Project Structure

component-framework/
├── src/component_framework/
│   ├── core/                        # Framework-agnostic core
│   │   ├── component.py             # Base Component class + lifecycle
│   │   ├── form.py                  # Pydantic form validation
│   │   ├── websocket.py             # WebSocket manager
│   │   ├── registry.py              # Component registration
│   │   ├── renderer.py              # Renderer interface
│   │   ├── state.py                 # State storage
│   │   ├── streaming.py             # StreamingComponent + SSE support
│   │   ├── permissions.py           # Permission classes (Beta)
│   │   └── composition.py           # Slot + composite components (Beta)
│   │
│   ├── adapters/                    # Framework adapters
│   │   ├── fastapi.py               # FastAPI integration
│   │   ├── fastapi_websocket.py     # FastAPI WebSocket
│   │   ├── django_views.py          # Django views (FBV + CBV)
│   │   ├── django_model.py          # Django model binding
│   │   ├── django_renderer.py       # Django template rendering
│   │   ├── django_websocket.py      # Django Channels
│   │   ├── django_permissions.py    # FBV permission decorators (Beta)
│   │   ├── django_ratelimit.py      # Rate limiting mixin (Beta)
│   │   ├── jinjax_renderer.py       # Jinjax rendering
│   │   ├── litestar.py              # Litestar HTTP + SSE adapter
│   │   └── litestar_websocket.py    # Litestar WebSocket adapter
│   │
│   ├── testing.py                   # ComponentTestCase + fixtures (Beta)
│   ├── components/                  # Example components
│   └── templatetags/components.py   # Django template tags
│
├── examples/
│   ├── fastapi_example.py           # FastAPI demo
│   ├── litestar_example.py          # Litestar demo
│   └── django_example/              # Complete Django app
│
├── tests/                           # 23 test modules, 404 tests
│   ├── test_component.py            # Core component + async dispatch tests
│   ├── test_form.py                 # Form validation tests
│   ├── test_registry.py             # Registry tests
│   ├── test_state.py                # State storage tests
│   ├── test_streaming.py            # StreamingComponent + SSE tests
│   ├── test_websocket.py            # WebSocket manager tests
│   ├── test_fastapi_adapter.py      # FastAPI adapter tests
│   ├── test_fastapi_sse.py          # FastAPI SSE endpoint tests
│   ├── test_fastapi_websocket.py    # FastAPI WebSocket tests
│   ├── test_litestar_adapter.py     # Litestar adapter tests
│   ├── test_litestar_sse.py         # Litestar SSE endpoint tests
│   ├── test_django_views.py         # Django views tests
│   ├── test_django_model.py         # Django model binding tests
│   ├── test_django_renderer.py      # Django renderer tests
│   ├── test_django_websocket.py     # Django Channels tests
│   ├── test_templatetags.py         # Template tags tests
│   ├── test_permissions.py          # Permission class tests (Beta)
│   ├── test_composition.py          # Composition tests (Beta)
│   ├── test_testing_utils.py        # Testing utility tests (Beta)
│   ├── test_caching.py              # Cache mixin tests (Beta)
│   ├── test_ratelimit.py            # Rate limit tests (Beta)
│   ├── test_optimistic.py           # Optimistic UI tests (Beta)
│   └── test_optional_extras.py      # Optional extras isolation tests
│
├── docs/                            # Documentation
│   ├── make.py                      # pdoc build script
│   ├── docs_settings.py             # Minimal Django settings for pdoc
│   ├── pdoc_templates/              # Custom pdoc templates (terminal brutalism)
│   ├── update_gh_pages.py           # CI helper: versions.json + root index
│   └── examples/ecommerce.md        # Real-time e-commerce walkthrough
│
├── .github/workflows/
│   ├── ci.yml                       # Tests, lint, type check (Python 3.11–3.14)
│   └── docs.yml                     # pdoc build + versioned GitHub Pages deploy
│
├── justfile                         # Task runner
├── .pre-commit-config.yaml          # ruff + ty hooks
└── pyproject.toml

Testing

# Run full test suite
just test

# Verbose output
just test-verbose

# Core tests only
just test-core

# Adapter tests only
just test-adapters

# Or pytest directly
pytest tests/ -q --tb=short

CI runs against Python 3.11, 3.12, 3.13, and 3.14 on every push and pull request.


Development

Setup

just install                # Install all deps (just: https://github.com/casey/just)

# Or manually
uv pip install -e ".[dev]"

just pre-commit-install     # Install ruff + ty pre-commit hooks

Common Commands

just format          # Format code with ruff
just lint            # Lint with ruff
just lint-fix        # Lint and auto-fix
just check           # lint + format-check + tests

just docs-build      # Build API docs -> docs/site/
just docs-serve      # Start pdoc dev server (localhost:8000)
just docs-check      # Verify pdoc is installed and show config
just docs-clean      # Remove docs/site/

just clean           # Remove build artifacts
just build           # Build the package

Claude Code Development

just claude                          # Interactive Claude Code
just claude-unsafe                   # Skip permission prompts (trusted env only)
just claude-prompt                   # Append CLAUDE.md as system prompt
just claude-unsafe-prompt            # System prompt + skip permissions
just claude-orchestrate              # Full orchestration workflow

# Override prompt file
just claude-prompt PROMPT_FILE=prompts/WORKFLOW.md
Prompt file Purpose
CLAUDE.md Project architecture, conventions, guidelines (default)
prompts/WORKFLOW.md Multi-agent orchestration, model selection, RTK token efficiency

Code Quality

  • ruff — Linting and formatting (line length: 100)
  • ty — Type checking (Astral's Rust-based)
  • pre-commit — Git hooks: trailing whitespace, YAML, merge conflicts, ruff, ty

Contributing

  1. Open an issue first to discuss major changes
  2. Follow existing code style (ruff)
  3. Add tests for new features
  4. Update docstrings (used for API docs)
  5. Keep PRs focused and small

Roadmap

Alpha (Complete)

  • Core component framework
  • FastAPI adapter
  • Django adapter
  • Form validation
  • Model binding
  • WebSocket support
  • Class-based views
  • CI pipeline (GitHub Actions)
  • Pre-commit hooks (ruff + ty)
  • Comprehensive test suite

Beta (Complete)

  • Permission classes and FBV decorators
  • Rate limiting (RateLimitMixin)
  • Component caching (CacheMixin)
  • Optimistic UI (OptimisticMixin)
  • Component composition (slots, composite)
  • Testing utilities (ComponentTestCase)
  • Versioned API documentation (GitHub Pages + pdoc)
  • Optional extras — FastAPI/Uvicorn/JinjaX no longer mandatory ([fastapi], [django], [all])

0.4.0 (Complete)

  • Litestar adapter — HTTP, WebSocket, SSE ([litestar] extra)
  • Async event handlers — async_dispatch() / async_handle_event()
  • SSE streaming — StreamingComponent with async generator handlers
  • State size guard — configurable warning (64 KB) and hard limit (512 KB)
  • JS double-serialisation fix in component-client.js

1.0 (Planned)

  • Stable, frozen public API
  • Performance benchmarks and optimisation
  • Devtools / inspector
  • Component marketplace / registry
  • Full user guide and tutorials

Performance

Current benchmarks (local development):

  • Component dispatch: < 1ms
  • State serialisation: < 1ms
  • Full HTTP cycle: ~10–20ms
  • WebSocket latency: < 10ms

Requirements

  • Python 3.11+
  • Pydantic 2.0+ (only mandatory runtime dependency)

Optional extras:

  • [fastapi] — FastAPI 0.109+, Uvicorn, JinjaX 0.41+
  • [django] — Django 4.2+, Django Channels 4.0+, channels-redis 4.1+, django-cotton 0.9+
  • [litestar] — Litestar 2.0+, Jinja2 3.1+
  • [websockets] — websockets 12.0+
  • [all] — all of the above

Known Limitations

  • State must be JSON-serialisable
  • WebSocket scaling requires a Redis channel layer
  • CSRF handling for WebSockets is manual
  • SSE streaming requires ASGI deployment (Django) or any async framework (FastAPI/Litestar)

License

MIT — see LICENSE for details.


Acknowledgments

Inspired by:


Support

About

Framework-agnostic server components with LiveView-style interactivity for Python (FastAPI / Django). HTMX-powered, no JS framework required.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors