Skip to main content

DynamicForms FastAPI Viewsets

Django REST Framework-style viewsets for FastAPI, with optional Celery-backed async execution and a matching Vue/TypeScript client counterpart.

  • Python mixins for FastAPI — compose CRUD and bulk endpoints from small, focused mixin classes.
  • route_viewset decorator — register a viewset on a FastAPI router with a single decorator call. Handles type resolution, lifecycle management and OpenAPI schema automatically.
  • CollectionViewSet — zero-boilerplate in-memory viewset backed by any Python list, set or dict. Great for prototyping and testing.
  • DjangoORMViewSet — back a viewset with a Django QuerySet. The filters it can compile, the sort order with its NULL placement, the page as LIMIT/OFFSET and the total as COUNT(*) all become SQL; a stage it declines falls back to the in-memory pass instead of failing, and pk_field_name comes from the model's primary key (requires the django extra).
  • celery_viewset decorator — move a viewset's execution to a Celery worker with no code changes to the viewset itself, for long-running or background processing scenarios (requires the celery extra).
  • Bulk operations — first-class support for bulk create, update, partial update and destroy.
  • muxws transport — reach the same viewsets over a single WebSocket instead of one HTTP request per call. A command goes through your application as an HTTP request does - its middleware, exception handlers, router dependencies and state - so both transports behave identically. In the demo, a burst of 100 requests takes 156 ms over REST and 37 ms over muxws.
  • Events — publish an event to a topic and every frontend following it learns of it, as a muxws push or on its next poll. ChangeEvents publishes every create, update and destroy of a viewset to its routed base path; custom events are declared with source(). Every event is recorded before it is pushed, so a dropped push costs latency, not an event. On the frontend, watch() on a ViewSet follows its topic and applyChanges() applies each change to a list of rows.
  • Three list shapes — a bare array, offset paging, or cursor paging. A viewset declares which, and may let a client pick per request with an X-List-Shape header.
  • Declarative filters — declare which fields accept which operators and get query parameters, an OpenAPI schema and filtering for free; backends translate what they can into their own query.
  • Vue / TypeScript counterpart — mirror mixin classes and the restViewSet / muxwsViewSet class factory give you a fully typed client that matches your backend viewset exactly: the mixins a ViewSet declares are its public surface, so calling an action it did not declare is a compile error rather than a runtime 404 (published separately as @dynamicforms/fastapi-viewsets on npm).

Installation

pip install dynamicforms-fastapi-viewsets

# with Celery-backed viewset support
pip install "dynamicforms-fastapi-viewsets[celery]"

# with the muxws WebSocket transport
pip install "dynamicforms-fastapi-viewsets[muxws]"

# with the Django ORM backend (Django 4.2+ and asgiref)
pip install "dynamicforms-fastapi-viewsets[django]"

Requires Python 3.10+, FastAPI and Pydantic 2.11+.

Quick example

from fastapi import APIRouter, FastAPI
from pydantic import BaseModel

from fastapi_viewsets.collection_viewset import CollectionViewSet
from fastapi_viewsets.decorators.route_viewset import route_viewset
from fastapi_viewsets.mixins import BulkViewSetMixin


class Item(BaseModel):
    id: int
    name: str


database: dict[int, Item] = {1: Item(id=1, name="First element")}

app = FastAPI()
router = APIRouter()


@route_viewset(router, base_path="/items", pk_field_name="id")
class ItemViewSet(CollectionViewSet[int, Item], BulkViewSetMixin[int, Item]):
    def __init__(self):
        super().__init__(container=database, pk_field="id")


app.include_router(router)

See the full documentation for guides on the mixin system, route_viewset, CollectionViewSet, DjangoORMViewSet, celery_viewset, the list pipeline and pagination, the muxws transport, and the Vue client.

Demo

python demo.py                       # backend on :8000, frontend on :5173
python demo.py --celery              # ... with every viewset call routed through a Celery worker
npm run test:e2e                     # drives the demo in a browser

An infinite-scrolling grid over a 5000-track library, cursor-paged. Switch the whole grid between the REST and muxws transports and between the in-memory and SQLite backends, and compare their latency side by side. Sorting and filtering are server-side.

The grid follows its viewset's change events (ChangeEvents on the backend, watch() in the grid). Click a Favorite cell to toggle it: every tab showing the library applies the change, over muxws as a push, over REST on its next poll. A sorted or filtered grid reloads its list on the change: the row may have moved or left it.

--celery needs Redis on localhost:6379. The worker runs the viewset calls of both backends and publishes their events through Redis. It runs as one process, because the in-memory library is a dict held by each process; the SQLite library is one file shared by every process. The end-to-end suite starts its own backend and dev server on their own ports.

License

MIT — see LICENSE.

Metadata

Release files for dynamicforms-fastapi-viewsets 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dynamicforms-fastapi-viewsets 0.11.0
File Size Uploaded
dynamicforms_fastapi_viewsets-0.11.0.tar.gz 130.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dynamicforms-fastapi-viewsets 0.11.0
File Interpreter ABI Platform
dynamicforms_fastapi_viewsets-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 295.7 kB

Release files / dynamicforms_fastapi_viewsets-0.11.0.tar.gz

Download URL dynamicforms_fastapi_viewsets-0.11.0.tar.gz
Size 130.8 kB
Tags Source
SHA-256 checksum
How to use checksums
1a9580c22ed69d4984a6bd0a85cb2e8eb00330e7edb85aae558f14392bc09553
BLAKE2b-256 checksum
How to use checksums
96147a37fc3df39149b36efc0d9d0baf0db13a81d61cb4d5dda46992d08bf075
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.2

Release files / dynamicforms_fastapi_viewsets-0.11.0-py3-none-any.whl

Download URL dynamicforms_fastapi_viewsets-0.11.0-py3-none-any.whl
Size 164.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7051a7b3efd172eccb774341b40690f4dd056474a4a8047e6eb5dbf1864513b5
BLAKE2b-256 checksum
How to use checksums
29a0de9612fff9b48f82b9b115456e29ca0aac2e8b1422d5c76a1aa188ab4d5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.2

Release history Release notifications | RSS feed

This release

0.11.0 This release

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.4

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page