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_viewsetdecorator — 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 asCOUNT(*)all become SQL; a stage it declines falls back to the in-memory pass instead of failing, andpk_field_namecomes from the model's primary key (requires thedjangoextra).celery_viewsetdecorator — 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 theceleryextra).- 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.
- 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-Shapeheader. - 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/muxwsViewSetclass 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-viewsetson 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.
--celery needs Redis on localhost:6379. 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.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dynamicforms_fastapi_viewsets-0.9.0.tar.gz | 99.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dynamicforms_fastapi_viewsets-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 225.4 kB
Release files / dynamicforms_fastapi_viewsets-0.9.0.tar.gz
| Download URL | dynamicforms_fastapi_viewsets-0.9.0.tar.gz |
|---|---|
| Size | 99.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a04fb1d520308f4c6da2b60a489537df3c62ba0e4dc2b3e498f5714655eb9560
|
|
BLAKE2b-256 checksum How to use checksums |
90e40ae1830f7c65c23f98c921061f534ddc50ef5003b54d9fb48fb95c4d6044
|
| 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.9.0-py3-none-any.whl
| Download URL | dynamicforms_fastapi_viewsets-0.9.0-py3-none-any.whl |
|---|---|
| Size | 126.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c4dc48a958efd1a4fb4739d43514c8ec847a4ed76c9cf5866c94c0fc864acc9b
|
|
BLAKE2b-256 checksum How to use checksums |
160fb831de6d51f43df7b84603b0f01c70483566b95fff4df1b7575245d3c59f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|