@dynamicforms/fastapi-viewsets

RESTful viewsets for Vue
4,734 1
Install
npm install @dynamicforms/fastapi-viewsets
Latest Version:0.13.1
Older releases:3
License:MIT
Last Updated:Oct 21, 2026
Links: GitHub  ·  npm
Maintainer: velis

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.
  • 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, events, 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.

Related Packages

taskwire

Progress reporting and awaitable dialogs for long-running server-side operations...

959 0
@dynamicforms/vuetify-modal-form-kit

Vue 3 + Vuetify 3 library providing a promise-based programmatic dialog API with...

4,818 0
@dynamicforms/vuetify-inputs

Vuetify input components with guaranteed visual consistency across all form fiel...

11,709 0
@dynamicforms/translatable

Reactive translatable strings for @dynamicforms libraries: a library declares En...

2,596 0
@dynamicforms/vue-forms

A Vue.js library for form state management with built-in validation, conditional...

9,035 0

Version History

Version Released Vue License
0.13.1 MIT
0.13.0 MIT
0.12.1 MIT
0.12.0 MIT
0.11.4 MIT