Skip to main content

Reactive Data Management for NiceGUI with Tortoise ORM

Project description

nicegui-rdm: Reactive Data Management

Why: in a nutshell

ng_rdm offers a clean and modern set of (non-Quasar) tables with all the plumbing you need to build database-backed NiceGUI applications. Moreover, these tables can automatically refresh when back-end data is added or modified. Hence: reactive data management.

Background (feel free to skip)

ng_rdm is based on two ideas:

  1. For my own apps I needed to add reactivity to database applications: changes in data should be reflected in UI components, without the user having to refresh a page. Imagine a table showing items, counts, stock being updated in near real-time as data is changing. This is the core of the library, implemented in models and store. Note: this is similar to but complementary to the reactivity we can easily achieve ‘client-side’ with NiceGUI bindings etc.

  2. Secondly, I've always been fighting Quasar's “composite” UI components such as tables, dialogs, cards, etc.: layer upon layer of div's and the most obnoxious CSS imaginable. Thanks to NiceGUI's websocket architecture we can move the logic for and behavior of those components from JavaScript/VueJS over to the Python side. In components/widgets you'll find tables that create clean html with semantic CSS selectors and that tie in to store observability – entirely in Python.

See below for a more detailed overview of the architecture.

Installation

pip install nicegui-rdm

Architecture

┌──────────────────────────────────────────────────────────┐
│  UI Components                                           │
│  ActionButtonTable · ListTable · SelectionTable          │
│  EditDialog · EditCard · DetailCard · ViewStack          │
└──────────────┬─────────────────────────────────┬─────────┘
               │  1. user action                 ▲
               ▼                                 │  6. notify_observers
┌──────────────┴─────────────────────────────────┴─────────┐
│  Store Layer                                             │
│  Store (base) · DictStore · TortoiseStore                │
│  MultitenantTortoiseStore · StoreRegistry                │
│  CRUD · validation · observer pattern                    │
└──────────────┬─────────────────────────────────┬─────────┘
               │  2. validate & write            ▲
               ▼                                 │  5. return result
┌──────────────┴─────────────────────────────────┴─────────┐
│  Data Layer                                              │
│  Tortoise ORM · QModel                                   │
│  SQLite · PostgreSQL · MySQL                             │
└──────────────────────────────────────────────────────────┘

User actions flow down through the Store layer (which validates and normalizes) to the database. On success, the Store broadcasts a StoreEvent up to all subscribed UI components, which automatically rebuild via @ui.refreshable_method. This is the reactive loop that keeps tables and detail views in sync with the database without manual refresh.

Quick Start

from nicegui import app, ui
from tortoise import fields

from ng_rdm import TortoiseStore, init_db, close_db, FieldSpec, Validator
from ng_rdm.models import QModel
from ng_rdm.components import (
    rdm_init, Column, TableConfig, FormConfig,
    ActionButtonTable, EditDialog,
)

# 1. Define a model with validation
class Task(QModel):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100)

    field_specs = {
        "name": FieldSpec(validators=[
            Validator("Name is required", lambda v, _: bool(v and v.strip()))
        ])
    }

# 2. Initialize database and create a store (module level)
init_db(app, "sqlite://tasks.db", modules={"models": [__name__]}, generate_schemas=True)
app.on_shutdown(close_db)

task_store = TortoiseStore(Task)

# 3. Build a page
@ui.page("/")
async def index():
    rdm_init()  # load CSS + Bootstrap Icons

    columns = [Column("name", "Task name")]
    table_config = TableConfig(columns=columns)
    form_config = FormConfig(columns=columns, title_add="New Task", title_edit="Edit Task")

    # EditDialog for add/edit; ActionButtonTable for display
    dlg = EditDialog(data_source=task_store, config=form_config,
                     on_saved=lambda _: table.build.refresh())
    table = ActionButtonTable(
        data_source=task_store, config=table_config,
        on_add=dlg.open_for_new, on_edit=dlg.open_for_edit,
    )
    await table.build()

ui.run()

What's Included

TablesActionButtonTable (CRUD with per-row action buttons), ListTable (read-only clickable rows), SelectionTable (checkbox multi-select)

FormsEditDialog (modal create/edit), EditCard (inline form)

NavigationViewStack (list/detail/edit flow), Tabs (tabbed content)

DisplayDetailCard (read-only detail view), Dialog (modal overlay), StepWizard (multi-step form)

LayoutButton, IconButton, Icon, Row, Col, Separator

Store layerDictStore (in-memory), TortoiseStore (ORM-backed), MultitenantTortoiseStore (tenant-scoped)

See components/API.md for the full component API reference.

Examples

Run any example with python -m ng_rdm.examples.<name> and open http://localhost:8080.

Example Description
catalog Component catalog — showcases all widgets
master_detail ViewStack master-detail navigation
custom_datasource Custom RdmDataSource implementation
vanilla_store Basic store usage without UI components
topic_filtering Topic-based observer filtering

Some notes

Requirements

  • Python 3.12+
  • NiceGUI >= 1.4.0
  • Tortoise ORM >= 0.20.0
  • pytz

License

MIT

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

nicegui_rdm-0.1.1.tar.gz (81.3 kB view details)

Uploaded Source

Built Distribution

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

nicegui_rdm-0.1.1-py3-none-any.whl (83.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for nicegui_rdm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 dbe126202cf37b189658a6937d169e6f3a961bce8f56fbd91dfd1dfbd094bbaa
MD5 07ec6bd250c69948964e38dda2dac97d
BLAKE2b-256 4c27ac7955ac64313f20f45443e39043ef29a6de244b3f409c6db915674f2fab

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on kleynjan/nicegui-rdm

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

File details

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

File metadata

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

File hashes

Hashes for nicegui_rdm-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e771e0fef67aefe9eb5042a890fd588010f75a61769603e67650df95e22aabc2
MD5 e985156af0135c8a90f66be7afc1198f
BLAKE2b-256 b5d055e7bd0b3efb01636c0e0c683d4f0fc21acbe4e0ec9a6ba96a333db95606

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on kleynjan/nicegui-rdm

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