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.0.tar.gz (81.2 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.0-py3-none-any.whl (82.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nicegui_rdm-0.1.0.tar.gz
  • Upload date:
  • Size: 81.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for nicegui_rdm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a5ff3c0ed960917232ffb59cc0b40933b0e940dfb3953d305ec229584954eb11
MD5 dad90e4f3312883ada9f4416048f6da7
BLAKE2b-256 0f8c7d42f30b29a289a88e1a1dadc9169c82321eb85c30af0efd7e5494fc17e3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nicegui_rdm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 82.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for nicegui_rdm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee6149bedc993235ea27b0dc8f8c148d4165f96ba454e1a17344fae27c19d693
MD5 6b28558d47f57ffef72c7d6a1d6d19e9
BLAKE2b-256 69655060d509153f3544be1408ccdfe43f1ee84e33e8dbb2afed9174486cbf7b

See more details on using hashes here.

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