nicegui consolidation
This commit is contained in:
+83
-156
@@ -1,206 +1,133 @@
|
||||
---
|
||||
name: nicegui
|
||||
description: 'Design and scaffold a production-ready NiceGUI + FastAPI application architecture. Use for multi-page app planning, package boundaries, optional DB/LangGraph/docs integration, and implementation checklists.'
|
||||
description: 'Reference hub for NiceGUI and FastAPI application structure, UI composition, styling, bindable state, interactions, troubleshooting, testing, and source documentation. Use when planning, implementing, reviewing, or debugging NiceGUI applications; load only the references relevant to the task.'
|
||||
x-personal-mcp:
|
||||
id: nicegui
|
||||
version: 1.0.0
|
||||
version: 2.0.0
|
||||
tags:
|
||||
- nicegui
|
||||
- fastapi
|
||||
- ui
|
||||
- architecture
|
||||
- scaffolding
|
||||
- customization
|
||||
- frontend
|
||||
- testing
|
||||
- source-docs
|
||||
capabilities:
|
||||
- resource://skills/nicegui/document
|
||||
---
|
||||
|
||||
# NiceGUI
|
||||
# NiceGUI Reference
|
||||
|
||||
Design a production-minded NiceGUI + FastAPI architecture with clear boundaries, optional extensions, and a concrete implementation checklist.
|
||||
Use this skill as a progressive reference for NiceGUI applications built with FastAPI. Start with the routing map, load only the material needed for the current question, and reconcile it with the target project's NiceGUI version and established conventions.
|
||||
|
||||
## When to Use
|
||||
|
||||
- You need a reusable architecture plan before implementing a NiceGUI app.
|
||||
- You want FastAPI app-factory structure and lifespan wiring.
|
||||
- You need optional guidance for database, LangGraph workflows, or mounted static docs.
|
||||
- You want output that is concise, structured, and implementation-ready.
|
||||
- Planning or reviewing NiceGUI application structure and FastAPI composition.
|
||||
- Building or refactoring pages, components, layouts, and static assets.
|
||||
- Modeling UI state with bindings or bindable dataclasses.
|
||||
- Implementing forms, uploads, refreshes, live updates, or background work.
|
||||
- Diagnosing UI state, concurrency, navigation, or asset problems.
|
||||
- Verifying framework behavior against primary documentation.
|
||||
|
||||
## Inputs to Collect
|
||||
## How to Use This Skill
|
||||
|
||||
Collect these inputs up front. If not provided, make safe defaults and state assumptions.
|
||||
1. Classify the request using the discovery map below.
|
||||
2. Load the smallest relevant reference, or at most two references for a mixed concern.
|
||||
3. Inspect the target repository before applying guidance; preserve its sound local patterns.
|
||||
4. Check the pinned NiceGUI and integration versions before relying on version-specific APIs.
|
||||
5. Validate the changed behavior with focused tests and, for UI work, relevant viewport checks.
|
||||
|
||||
- Product scope and primary user journeys.
|
||||
- Required pages and route map.
|
||||
- Whether persistent data is required.
|
||||
- Whether AI orchestration (multi-step, streaming, approvals) is required.
|
||||
- Whether generated docs should be mounted in-app.
|
||||
- Runtime/deployment constraints (single service vs split services, environment requirements).
|
||||
## Progressive Discovery Map
|
||||
|
||||
## Outcome
|
||||
### Application Architecture
|
||||
|
||||
Produce:
|
||||
Load [application architecture](./references/architecture.md) for:
|
||||
|
||||
- A concise architecture explanation.
|
||||
- How core services, UI pages, and UI components fit together.
|
||||
- Explicit decision on DB ownership or involvement.
|
||||
- Explicit decision on AI workflow (or no AI).
|
||||
- A checklist implementation plan organized by package and domain.
|
||||
- FastAPI app factories and lifespan ownership
|
||||
- package boundaries and dependency direction
|
||||
- page registration and health routes
|
||||
- optional persistence, LangGraph, or mounted documentation
|
||||
- async responsiveness and baseline tests
|
||||
|
||||
## Procedure
|
||||
### Components And Styling
|
||||
|
||||
1. Frame the baseline architecture.
|
||||
2. Choose optional extensions (DB, AI, docs) using decision points below.
|
||||
3. Map modules, dependencies, and key boundaries.
|
||||
4. Define async behavior and UI responsiveness expectations.
|
||||
5. Define key functions/classes and configuration surfaces.
|
||||
6. Produce phased checklist with rollout or migration notes when relevant.
|
||||
7. Run completion checks before returning.
|
||||
Load [architecture and styling](./references/architecture-and-styling.md) for:
|
||||
|
||||
### 1) Baseline architecture
|
||||
- page, component, and service boundaries
|
||||
- component extraction decisions
|
||||
- Tailwind and Quasar styling order
|
||||
- responsive layout and static asset conventions
|
||||
|
||||
Use a src-layout with FastAPI as the ASGI app and NiceGUI registered via composition.
|
||||
### Bindable State
|
||||
|
||||
- App factory pattern: `create_app()`.
|
||||
- Lifespan for startup and shutdown resource management.
|
||||
- `api/` for HTTP handlers, `services/` for business logic.
|
||||
- `ui/pages/` for page modules, `ui/components/` for shared UI.
|
||||
- Health endpoint on FastAPI side: `/healthz`.
|
||||
Load [bindable dataclasses](./references/binding-dataclasses.md) for:
|
||||
|
||||
Recommended base shape:
|
||||
- typed local UI state
|
||||
- propagation and refresh behavior
|
||||
- nested structures and strict bindings
|
||||
- mutable defaults, performance, and version notes
|
||||
|
||||
```text
|
||||
.
|
||||
├─ pyproject.toml
|
||||
├─ .env.example
|
||||
├─ README.md
|
||||
├─ src/
|
||||
│ └─ app/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ main.py
|
||||
│ ├─ bootstrap.py
|
||||
│ ├─ config.py
|
||||
│ ├─ logging.py
|
||||
│ ├─ api/
|
||||
│ │ ├─ __init__.py
|
||||
│ │ └─ health.py
|
||||
│ ├─ services/
|
||||
│ │ ├─ __init__.py
|
||||
│ │ └─ example_service.py
|
||||
│ └─ ui/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ components/
|
||||
│ │ ├─ __init__.py
|
||||
│ │ └─ nav.py
|
||||
│ └─ pages/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ home.py
|
||||
│ ├─ dashboard.py
|
||||
│ └─ about.py
|
||||
└─ tests/
|
||||
├─ test_health.py
|
||||
└─ test_pages_registration.py
|
||||
```
|
||||
### Interaction Patterns
|
||||
|
||||
### 2) Decision points
|
||||
Load [interaction patterns](./references/interaction-patterns.md) for:
|
||||
|
||||
#### Database needed?
|
||||
- uploads and form submission
|
||||
- explicit refreshes
|
||||
- server-sent events and WebSockets
|
||||
- background work and duplicate-submission guards
|
||||
|
||||
- If no: keep `services/` pure and skip persistence layers.
|
||||
- If yes: add `db/` package with engine/session/model/repository layering.
|
||||
- Prefer one process-level engine and request-scoped sessions via `yield`.
|
||||
- Prefer Alembic migrations for schema changes.
|
||||
### Troubleshooting And Quality
|
||||
|
||||
#### AI workflow needed?
|
||||
Load [troubleshooting and quality gates](./references/troubleshooting-and-quality-gates.md) for:
|
||||
|
||||
- If no: keep `services/` focused on app logic only.
|
||||
- If yes: add `ai/` package (state, nodes, graph, runtime, contracts).
|
||||
- Keep graph internals out of `ui/pages/` and API handlers.
|
||||
- Use stable thread/session IDs for resumable flows.
|
||||
- upload failures and UI race conditions
|
||||
- stale assets and navigation drift
|
||||
- responsiveness, accessibility, reliability, and maintainability checks
|
||||
|
||||
#### Mounted docs needed?
|
||||
### Primary Sources
|
||||
|
||||
- If no: skip docs mounting.
|
||||
- If yes: mount generated static site under configurable route (default `/docs`).
|
||||
- Keep docs mounting in composition layer, not page modules.
|
||||
Load [source documentation](./references/source-documentation.md) when:
|
||||
|
||||
### 3) Page and component registration
|
||||
- behavior is version-sensitive or uncertain
|
||||
- an integration recommendation needs verification
|
||||
- upstream NiceGUI, FastAPI, Tailwind, Quasar, SQLAlchemy, Pydantic, or LangGraph documentation is required
|
||||
|
||||
- Require at minimum page modules for `/`, `/dashboard`, `/about`.
|
||||
- Prefer explicit registration pattern:
|
||||
- `ui/pages/__init__.py` exports `register_pages()`.
|
||||
- Each page module exports `register_page()`.
|
||||
- Shared shell components (header/nav/drawer) live in `ui/components/`.
|
||||
## Common Discovery Paths
|
||||
|
||||
### 4) Dependency direction rules
|
||||
### New Application Or Architecture Review
|
||||
|
||||
Prefer:
|
||||
1. Load [application architecture](./references/architecture.md).
|
||||
2. Add [architecture and styling](./references/architecture-and-styling.md) only when page and component design is in scope.
|
||||
|
||||
- `main/bootstrap` -> `config/logging` + `api` + `ui/pages` + `services`
|
||||
- `api` -> `services`
|
||||
- `ui/pages` -> `ui/components` + `services`
|
||||
- `services` -> helpers/clients (and `db/` when enabled)
|
||||
### Page Or Component Work
|
||||
|
||||
Avoid reverse imports from services into API or UI modules.
|
||||
1. Load [architecture and styling](./references/architecture-and-styling.md).
|
||||
2. Add [interaction patterns](./references/interaction-patterns.md) or [bindable dataclasses](./references/binding-dataclasses.md) according to the page behavior.
|
||||
|
||||
### 5) Async and UI responsiveness rules
|
||||
### Debugging Or Production Review
|
||||
|
||||
- Prefer `async def` for page handlers, service methods, and integrations when the call path includes I/O.
|
||||
- Use non-blocking clients/libraries where possible so long-running I/O does not freeze UI updates.
|
||||
- Do not run blocking calls (`time.sleep`, blocking HTTP/database clients) in UI event handlers.
|
||||
- For heavy CPU work, offload to worker/background execution and keep the UI loop free.
|
||||
- Show progress states for long actions (disable action button, show spinner/progress text, re-enable on completion).
|
||||
- Stream or chunk incremental results to the UI when workflows are multi-step or long-running.
|
||||
- Keep cancellation and timeout behavior explicit for user-triggered long tasks.
|
||||
- Ensure exceptions from async tasks are surfaced with user-friendly feedback and logged for diagnostics.
|
||||
1. Start with [troubleshooting and quality gates](./references/troubleshooting-and-quality-gates.md).
|
||||
2. Follow the symptom to one detailed reference.
|
||||
3. Confirm uncertain behavior in [source documentation](./references/source-documentation.md).
|
||||
|
||||
### 6) Testing minimums
|
||||
## General Defaults
|
||||
|
||||
- Test FastAPI health route behavior.
|
||||
- Test page registration wiring.
|
||||
- If DB enabled: session lifecycle and rollback behavior tests.
|
||||
- If AI enabled: graph happy path and interrupt/resume coverage.
|
||||
- If docs enabled: mounted docs route returns index page.
|
||||
- For async flows: test long-running actions preserve UI responsiveness (loading state, completion state, and error state).
|
||||
- Keep composition, transport, services, pages, and components directionally separated.
|
||||
- Keep business logic out of UI components and event handlers.
|
||||
- Avoid blocking I/O and CPU-heavy work in the UI event loop.
|
||||
- Prefer event-driven updates and explicit refreshes over unrelated polling.
|
||||
- Prefer Tailwind utilities, then Quasar props, then reusable component helpers; use minimal shared CSS when those are insufficient.
|
||||
- Provide loading, success, and failure states for user-triggered work.
|
||||
- Treat version-specific guidance as a prompt to verify the project's dependency version.
|
||||
|
||||
### 7) Styling architecture
|
||||
## Reference Use Contract
|
||||
|
||||
- Keep structure and layout in Python modules using NiceGUI class composition.
|
||||
- Keep visual polish in shared CSS files, loaded once at startup.
|
||||
- Prefer semantic reusable classes over ad hoc per-page styling.
|
||||
When applying this skill:
|
||||
|
||||
## Completion Checks
|
||||
|
||||
- Uses app factory and FastAPI lifespan.
|
||||
- Pages are modularized (not single-file UI).
|
||||
- Health endpoint exists on FastAPI side.
|
||||
- Dependency direction is clean and one-way.
|
||||
- Async-first guidance is applied where I/O exists, with explicit non-blocking UX states.
|
||||
- Optional DB/AI/docs decisions are explicit and reflected in structure.
|
||||
- Output includes architecture summary and package-organized checklist.
|
||||
|
||||
## Output Contract
|
||||
|
||||
Return:
|
||||
|
||||
- Concise high-level architecture.
|
||||
- How core services, pages, and shared components fit.
|
||||
- DB involvement and ownership stance.
|
||||
- AI workflow stance and runtime flow.
|
||||
- Checklist plan by package and domain:
|
||||
- key functions/classes
|
||||
- settings/config surfaces
|
||||
- rollout/migration notes (when relevant)
|
||||
|
||||
## Guardrails
|
||||
|
||||
- Do not collapse all pages into one file.
|
||||
- Do not use globals or implicit global side effects.
|
||||
- Do not block UI event handlers with synchronous I/O or long CPU tasks.
|
||||
- Always define loading/progress/error states for long user-triggered actions.
|
||||
- Keep code minimal but production-minded.
|
||||
- Prefer clarity and maintainability over clever abstractions.
|
||||
|
||||
## References
|
||||
|
||||
- Architecture and integration details: [NiceGUI architecture reference](./references/architecture.md)
|
||||
- Dataclass binding deep dive: [Bindable dataclasses in NiceGUI](./references/binding-dataclasses.md)
|
||||
- Source documentation links: [NiceGUI source documentation](./references/source-documentation.md)
|
||||
- return only guidance relevant to the current task
|
||||
- distinguish repository facts from reference recommendations
|
||||
- cite the appropriate source reference for framework-level claims
|
||||
- state assumptions when application requirements are missing
|
||||
- report the focused checks used to validate implementation changes
|
||||
@@ -0,0 +1,77 @@
|
||||
# Architecture and Styling Reference
|
||||
|
||||
## Project Boundaries
|
||||
|
||||
Use this dependency direction:
|
||||
|
||||
- pages import components and services
|
||||
- components contain presentation logic only
|
||||
- services contain business logic and do not import UI
|
||||
- static assets are mounted and loaded once at bootstrap
|
||||
|
||||
Suggested module split:
|
||||
|
||||
```text
|
||||
src/app/
|
||||
ui/pages/
|
||||
ui/components/
|
||||
ui/static/
|
||||
services/
|
||||
api/
|
||||
bootstrap.py
|
||||
```
|
||||
|
||||
## Component Extraction Rules
|
||||
|
||||
Extract to ui/components when a pattern appears in two or more pages.
|
||||
|
||||
Keep in-page if the layout is specific to a single route.
|
||||
|
||||
```python
|
||||
def card_section(title: str, content: str) -> ui.card:
|
||||
with ui.card().classes("w-full max-w-md") as card:
|
||||
ui.label(title).classes("text-lg font-bold")
|
||||
ui.label(content).classes("text-gray-600")
|
||||
return card
|
||||
```
|
||||
|
||||
## Tailwind-First Layout Pattern
|
||||
|
||||
Use Tailwind utility classes for structure and spacing.
|
||||
Use breakpoint classes for responsive behavior.
|
||||
Use .style() only for values that must be computed dynamically.
|
||||
|
||||
```python
|
||||
with ui.column().classes("w-full"):
|
||||
with ui.row().classes("w-full gap-4 flex-wrap sm:flex-nowrap"):
|
||||
ui.card().classes("flex-1 min-w-64")
|
||||
ui.card().classes("flex-1 min-w-64")
|
||||
```
|
||||
|
||||
## Styling Decision Order
|
||||
|
||||
1. Tailwind utility classes
|
||||
2. Quasar props
|
||||
3. Reusable styled component functions
|
||||
4. Minimal custom CSS loaded once at bootstrap (only when needed)
|
||||
|
||||
```python
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
app.mount("/static", StaticFiles(directory="src/app/static"), name="static")
|
||||
ui.add_css(open("src/app/static/css/base.css").read())
|
||||
```
|
||||
|
||||
## Static Asset Rules
|
||||
|
||||
- Keep custom CSS small and tokenized with variables.
|
||||
- Avoid per-page CSS injection.
|
||||
- Verify static mount paths and reverse proxy rewrites.
|
||||
|
||||
## Links
|
||||
|
||||
!!! info "Primary sources"
|
||||
- [NiceGUI elements](https://nicegui.io/documentation/element)
|
||||
- [NiceGUI binding properties](https://nicegui.io/documentation/section_binding_properties)
|
||||
- [Tailwind utility-first styling](https://tailwindcss.com/docs/utility-first)
|
||||
- [Quasar components](https://quasar.dev/vue-components)
|
||||
@@ -1,32 +1,75 @@
|
||||
# NiceGUI Architecture Reference
|
||||
# NiceGUI Application Architecture
|
||||
|
||||
This reference expands the workflow in the main skill file and is loaded only when needed.
|
||||
Load this reference for application composition, package boundaries, and optional subsystem decisions.
|
||||
|
||||
## Baseline package boundaries
|
||||
## Baseline Package Boundaries
|
||||
|
||||
- `main.py`: process entrypoint only.
|
||||
- `bootstrap.py`: app composition, router wiring, page registration, lifespan orchestration.
|
||||
- `config.py`: typed settings and env parsing.
|
||||
- `main.py`: process entry point and app factory exposure.
|
||||
- `bootstrap.py`: app composition, router wiring, page registration, and lifespan orchestration.
|
||||
- `config.py`: typed settings and environment parsing.
|
||||
- `logging.py`: centralized logging setup.
|
||||
- `api/`: HTTP transport layer; delegates to services.
|
||||
- `services/`: business/use-case logic.
|
||||
- `api/`: HTTP transport that delegates to services.
|
||||
- `services/`: business and use-case logic.
|
||||
- `ui/pages/`: route-level NiceGUI pages.
|
||||
- `ui/components/`: shared UI building blocks.
|
||||
- `ui/components/`: shared presentation building blocks.
|
||||
|
||||
## Required baseline behavior
|
||||
Recommended base shape:
|
||||
|
||||
```text
|
||||
.
|
||||
├─ pyproject.toml
|
||||
├─ .env.example
|
||||
├─ src/
|
||||
│ └─ app/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ main.py
|
||||
│ ├─ bootstrap.py
|
||||
│ ├─ config.py
|
||||
│ ├─ logging.py
|
||||
│ ├─ api/
|
||||
│ │ ├─ __init__.py
|
||||
│ │ └─ health.py
|
||||
│ ├─ services/
|
||||
│ │ ├─ __init__.py
|
||||
│ │ └─ example_service.py
|
||||
│ └─ ui/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ components/
|
||||
│ │ ├─ __init__.py
|
||||
│ │ └─ nav.py
|
||||
│ └─ pages/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ home.py
|
||||
│ ├─ dashboard.py
|
||||
│ └─ about.py
|
||||
└─ tests/
|
||||
├─ test_health.py
|
||||
└─ test_pages_registration.py
|
||||
```
|
||||
|
||||
## Required Baseline Behavior
|
||||
|
||||
- FastAPI is the base ASGI app.
|
||||
- NiceGUI pages are modular and registered from page modules.
|
||||
- Minimum pages: `/`, `/dashboard`, `/about`.
|
||||
- FastAPI health route: `/healthz`.
|
||||
- Lifespan handles startup/shutdown resources.
|
||||
- No global side effects at import time.
|
||||
- `create_app()` composes routes, resources, and NiceGUI.
|
||||
- Lifespan owns startup and shutdown resources.
|
||||
- NiceGUI pages are modular and explicitly registered.
|
||||
- FastAPI exposes a health route such as `/healthz`.
|
||||
- Imports do not trigger runtime global side effects.
|
||||
|
||||
## Optional extension: Database
|
||||
## Dependency Direction
|
||||
|
||||
Use only if persistence is required.
|
||||
Prefer:
|
||||
|
||||
Suggested additions:
|
||||
- `main/bootstrap` -> `config/logging` + `api` + `ui/pages` + `services`
|
||||
- `api` -> `services`
|
||||
- `ui/pages` -> `ui/components` + `services`
|
||||
- `services` -> helpers, clients, and `db/` when enabled
|
||||
|
||||
Avoid imports from services back into API or UI modules.
|
||||
|
||||
## Optional Persistence
|
||||
|
||||
Use only when the product requires durable data.
|
||||
|
||||
```text
|
||||
src/app/db/
|
||||
@@ -37,19 +80,15 @@ src/app/db/
|
||||
└─ repositories/
|
||||
```
|
||||
|
||||
Guidelines:
|
||||
- Create one engine and sessionmaker per process.
|
||||
- Provide request- or operation-scoped sessions with `yield`.
|
||||
- Keep transaction boundaries explicit in service or repository flows.
|
||||
- Never share sessions across concurrent tasks.
|
||||
- Use Alembic as the schema migration source of truth.
|
||||
|
||||
- One engine and one sessionmaker per process.
|
||||
- Request-scoped session dependency using `yield`.
|
||||
- Explicit transaction boundaries in service/repository flows.
|
||||
- Avoid shared sessions across concurrent tasks.
|
||||
- Use Alembic as schema source of truth.
|
||||
## Optional LangGraph AI
|
||||
|
||||
## Optional extension: LangGraph AI
|
||||
|
||||
Use only for multi-step AI orchestration or human-in-the-loop workflows.
|
||||
|
||||
Suggested additions:
|
||||
Use only for multi-step orchestration, resumable work, streaming, or human approval.
|
||||
|
||||
```text
|
||||
src/app/ai/
|
||||
@@ -60,33 +99,37 @@ src/app/ai/
|
||||
└─ contracts.py
|
||||
```
|
||||
|
||||
Guidelines:
|
||||
|
||||
- Keep graph internals outside API/UI modules.
|
||||
- Invoke graph through `services/ai_service.py`.
|
||||
- Use stable thread/session IDs for resumable sessions.
|
||||
- Keep graph internals outside API and UI modules.
|
||||
- Invoke graphs through a service such as `services/ai_service.py`.
|
||||
- Use stable thread or session IDs for resumable flows.
|
||||
- Keep interrupt payloads JSON-serializable.
|
||||
|
||||
## Optional extension: Mounted static docs
|
||||
## Optional Mounted Docs
|
||||
|
||||
Use only when generated docs should be served in-app.
|
||||
Use only when generated docs must be served by the application.
|
||||
|
||||
Suggested settings:
|
||||
|
||||
- `docs_enabled`
|
||||
- `docs_mount_path`
|
||||
- `docs_site_dir`
|
||||
- `docs_require_build` (optional)
|
||||
- `docs_require_build`
|
||||
|
||||
Guidelines:
|
||||
Mount docs in the composition layer, normalize the mount path, avoid route conflicts, and define behavior for missing build artifacts.
|
||||
|
||||
- Mount docs in composition layer (`bootstrap.py`).
|
||||
- Normalize mount path and avoid route conflicts.
|
||||
- Warn on missing build artifacts unless strict mode is enabled.
|
||||
## Async And Responsiveness
|
||||
|
||||
## Suggested output quality criteria
|
||||
- Use `async def` where a handler or service path performs I/O.
|
||||
- Prefer non-blocking clients and libraries.
|
||||
- Offload CPU-heavy work to worker or background execution.
|
||||
- Define progress, cancellation, timeout, completion, and error states for long actions.
|
||||
- Stream or chunk results when workflows are long-running or multi-step.
|
||||
|
||||
- Clear architecture summary with assumptions.
|
||||
- Explicit decisions for DB, AI, and docs.
|
||||
- Package-scoped implementation checklist.
|
||||
- Minimal test plan aligned to enabled features.
|
||||
## Testing Minimums
|
||||
|
||||
- Test the FastAPI health route.
|
||||
- Test page registration wiring.
|
||||
- If persistence is enabled, test session lifecycle and rollback behavior.
|
||||
- If AI is enabled, test happy paths and interrupt/resume behavior.
|
||||
- If docs are enabled, test the mounted index route.
|
||||
- For long actions, test loading, completion, and error states.
|
||||
@@ -1,119 +1,100 @@
|
||||
# Binding Dataclasses Deep Dive
|
||||
|
||||
This reference explains how to model state with NiceGUI bindable dataclasses and how to avoid common update and performance pitfalls.
|
||||
Use this reference to model NiceGUI state with bindable dataclasses and avoid common propagation and performance pitfalls.
|
||||
|
||||
## Primary Sources
|
||||
|
||||
- NiceGUI binding docs: [Binding properties](https://www.nicegui.io/documentation/section_binding_properties)
|
||||
- NiceGUI binding docs: [binding properties](https://www.nicegui.io/documentation/section_binding_properties)
|
||||
- Python dataclass docs: [dataclasses module](https://docs.python.org/3/library/dataclasses.html)
|
||||
- Data class design rationale: [PEP 557](https://peps.python.org/pep-0557/)
|
||||
|
||||
## What bindable_dataclass changes
|
||||
## Bindable Dataclass Behavior
|
||||
|
||||
`@binding.bindable_dataclass` extends standard dataclasses by turning fields into bindable properties so UI bindings can propagate immediately when a field is assigned.
|
||||
|
||||
Baseline pattern:
|
||||
`@binding.bindable_dataclass` extends standard dataclasses by turning fields into bindable properties, allowing UI bindings to propagate when a field is assigned.
|
||||
|
||||
```python
|
||||
from nicegui import binding, ui
|
||||
|
||||
|
||||
@binding.bindable_dataclass
|
||||
class Profile:
|
||||
name: str = 'Ada'
|
||||
name: str = "Ada"
|
||||
age: int = 37
|
||||
|
||||
|
||||
profile = Profile()
|
||||
|
||||
ui.input('Name').bind_value(profile, 'name')
|
||||
ui.number('Age', min=0).bind_value(profile, 'age')
|
||||
ui.label().bind_text_from(profile, 'name', backward=lambda n: f'User: {n}')
|
||||
ui.input("Name").bind_value(profile, "name")
|
||||
ui.number("Age", min=0).bind_value(profile, "age")
|
||||
ui.label().bind_text_from(profile, "name", backward=lambda name: f"User: {name}")
|
||||
```
|
||||
|
||||
## Propagation model and performance
|
||||
## Propagation And Performance
|
||||
|
||||
NiceGUI distinguishes between two link types:
|
||||
|
||||
- Bindable properties: efficient, event-like propagation on assignment.
|
||||
- Active links: polled in a refresh loop (default every 0.1s).
|
||||
- Bindable properties propagate efficiently when values are assigned.
|
||||
- Active links are checked in a refresh loop.
|
||||
|
||||
Practical implications:
|
||||
Prefer bindable dataclasses for frequently updated form state. Keep binding transforms pure and inexpensive. If an application has many active links, tune `binding_refresh_interval` in `ui.run(...)` only after measuring the impact.
|
||||
|
||||
- Prefer bindable dataclasses for frequently updated form state.
|
||||
- Keep transform functions pure and side-effect free.
|
||||
- If many active links exist, tune `binding_refresh_interval` in `ui.run(...)` carefully.
|
||||
|
||||
## Dataclass modeling rules that matter for binding
|
||||
## Dataclass Modeling Rules
|
||||
|
||||
- Use `field(default_factory=...)` for mutable defaults.
|
||||
- Avoid `frozen=True` for models that should be edited from UI controls.
|
||||
- Use `slots=True` only when you have confirmed compatibility with your inheritance and extension needs.
|
||||
- Avoid `frozen=True` for models edited by UI controls.
|
||||
- Use `slots=True` only after confirming compatibility with inheritance and extension needs.
|
||||
- Keep UI-editable fields explicit and typed.
|
||||
|
||||
Example with safe mutable defaults:
|
||||
|
||||
```python
|
||||
from dataclasses import field
|
||||
|
||||
from nicegui import binding
|
||||
|
||||
|
||||
@binding.bindable_dataclass
|
||||
class Filters:
|
||||
query: str = ''
|
||||
query: str = ""
|
||||
tags: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
## Nested structures and binding paths
|
||||
## Nested Structures
|
||||
|
||||
NiceGUI supports nested key paths via tuples for nested data (for example dictionaries and nested structures).
|
||||
NiceGUI supports tuple paths for nested data structures.
|
||||
|
||||
```python
|
||||
from nicegui import ui
|
||||
|
||||
data = {'user': {'name': 'Ada'}}
|
||||
data = {"user": {"name": "Ada"}}
|
||||
|
||||
ui.input('Name').bind_value(data, ('user', 'name'))
|
||||
ui.label().bind_text_from(data, ('user', 'name'))
|
||||
ui.input("Name").bind_value(data, ("user", "name"))
|
||||
ui.label().bind_text_from(data, ("user", "name"))
|
||||
```
|
||||
|
||||
When using nested dataclasses, keep updates explicit and predictable at the field level.
|
||||
Keep nested dataclass updates explicit and predictable at the field level.
|
||||
|
||||
## Strictness and refactor safety
|
||||
|
||||
Binding can warn when attributes do not exist.
|
||||
## Strictness And Refactor Safety
|
||||
|
||||
- Object attributes are checked by default.
|
||||
- Dictionary keys are not checked by default.
|
||||
- Use `strict=True` when you want missing-key warnings for dict-backed state.
|
||||
- Use `strict=True` when missing dictionary keys should produce warnings.
|
||||
|
||||
```python
|
||||
from nicegui import app, ui
|
||||
|
||||
ui.input().bind_value(app.storage.user, 'display_name', strict=True)
|
||||
ui.input().bind_value(app.storage.user, "display_name", strict=True)
|
||||
```
|
||||
|
||||
## Common pitfalls and safer alternatives
|
||||
## Common Pitfalls
|
||||
|
||||
- Pitfall: mutating nested mutable values in place and expecting immediate UI sync.
|
||||
- Safer alternative: assign back to the bound field after updates so change propagation is explicit.
|
||||
- In-place mutation may not produce immediate UI synchronization. Assign the updated value back to the bound field.
|
||||
- Heavy binding transforms can degrade refresh performance. Move expensive work to event handlers or services.
|
||||
- State shared across unrelated pages or users can leak data. Scope models to the appropriate page, client, or user context.
|
||||
|
||||
- Pitfall: heavy transform functions in bindings.
|
||||
- Safer alternative: keep transformations cheap and deterministic; move heavy work to event handlers.
|
||||
## Version Checks
|
||||
|
||||
- Pitfall: one model shared across unrelated pages or users.
|
||||
- Safer alternative: scope model instances to page/client/user context as needed.
|
||||
- `bindable_dataclass` was added in NiceGUI 2.11.0.
|
||||
- Depth-first binding propagation was documented in NiceGUI 2.16.0.
|
||||
- Binding `strict` behavior was documented in NiceGUI 3.0.0.
|
||||
- Tuple paths for nested properties were documented in NiceGUI 3.10.0.
|
||||
|
||||
## Version notes to remember
|
||||
|
||||
- `bindable_dataclass` added in NiceGUI 2.11.0.
|
||||
- Binding `strict` behavior documented as added in NiceGUI 3.0.0.
|
||||
- Tuple paths for nested properties documented as added in NiceGUI 3.10.0.
|
||||
- Depth-first binding propagation update documented in NiceGUI 2.16.0.
|
||||
|
||||
Verify behavior against the NiceGUI version pinned in your project before relying on version-specific semantics.
|
||||
|
||||
## Quick checklist
|
||||
|
||||
- Choose bindable dataclasses for interactive form-like state.
|
||||
- Use `default_factory` for mutable fields.
|
||||
- Keep transform functions pure.
|
||||
- Use strict mode intentionally.
|
||||
- Re-check version notes before migration work.
|
||||
Verify these behaviors against the NiceGUI version pinned by the target project.
|
||||
@@ -0,0 +1,110 @@
|
||||
# Interaction Patterns Reference
|
||||
|
||||
## Reactive State
|
||||
|
||||
Use bindable dataclasses for local page state.
|
||||
|
||||
```python
|
||||
from dataclasses import field
|
||||
from nicegui import binding, ui
|
||||
|
||||
@binding.bindable_dataclass
|
||||
class PageState:
|
||||
selected_id: int | None = None
|
||||
items: list = field(default_factory=list)
|
||||
|
||||
state = PageState()
|
||||
ui.label().bind_text_from(state, "selected_id")
|
||||
```
|
||||
|
||||
## File Upload Pattern
|
||||
|
||||
- Validate extension and size before storing.
|
||||
- Delegate storage to a service method.
|
||||
- Notify success and failure explicitly.
|
||||
|
||||
```python
|
||||
async def handle_upload(e: ui.events.UploadEventArguments):
|
||||
try:
|
||||
if e.size > 10 * 1024 * 1024:
|
||||
raise ValueError("File too large")
|
||||
if not e.name.endswith(".pdf"):
|
||||
raise ValueError("Only PDF allowed")
|
||||
await file_service.store(e.content.read(), e.name)
|
||||
ui.notify(f"Uploaded: {e.name}", type="positive")
|
||||
except ValueError as err:
|
||||
ui.notify(str(err), type="negative")
|
||||
|
||||
ui.upload(on_upload=handle_upload, auto_upload=True)
|
||||
```
|
||||
|
||||
## Form Submission Pattern
|
||||
|
||||
- Bind UI inputs to dataclass fields.
|
||||
- Perform validation in the service layer.
|
||||
- Clear form state on success.
|
||||
|
||||
```python
|
||||
@binding.bindable_dataclass
|
||||
class FormData:
|
||||
name: str = ""
|
||||
email: str = ""
|
||||
|
||||
data = FormData()
|
||||
ui.input("Name").bind_value(data, "name")
|
||||
ui.input("Email").bind_value(data, "email")
|
||||
|
||||
async def on_submit():
|
||||
try:
|
||||
await user_service.create_user(name=data.name, email=data.email)
|
||||
ui.notify("User created", type="positive")
|
||||
data.name = data.email = ""
|
||||
except ValueError as err:
|
||||
ui.notify(str(err), type="negative")
|
||||
|
||||
ui.button("Submit").on_click(on_submit)
|
||||
```
|
||||
|
||||
## Real-Time Updates Decision
|
||||
|
||||
Use SSE for one-way status streaming.
|
||||
Use WebSocket for bidirectional messaging.
|
||||
|
||||
SSE endpoint example:
|
||||
|
||||
```python
|
||||
@app.get("/events/status")
|
||||
async def status_stream():
|
||||
async def gen():
|
||||
while True:
|
||||
yield f"data: {await get_status()}\\n\\n"
|
||||
await asyncio.sleep(1)
|
||||
return StreamingResponse(gen(), media_type="text/event-stream")
|
||||
```
|
||||
|
||||
## Background Work Pattern
|
||||
|
||||
- Start long jobs in FastAPI background tasks.
|
||||
- Expose status via endpoint or streaming channel.
|
||||
- Guard buttons against duplicate submissions during in-flight tasks.
|
||||
|
||||
## Explicit Refresh Pattern
|
||||
|
||||
Use @ui.refreshable and call refresh intentionally instead of polling unrelated state.
|
||||
|
||||
```python
|
||||
@ui.refreshable
|
||||
async def item_list():
|
||||
items = await service.list()
|
||||
for item in items:
|
||||
ui.label(item.name)
|
||||
|
||||
ui.button("Refresh").on_click(lambda: item_list.refresh())
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
!!! info "Primary sources"
|
||||
- [NiceGUI action events](https://nicegui.io/documentation/section_action_events)
|
||||
- [FastAPI server-sent events](https://fastapi.tiangolo.com/advanced/server-sent-events/)
|
||||
- [FastAPI WebSockets](https://fastapi.tiangolo.com/advanced/websockets/)
|
||||
@@ -1,6 +1,14 @@
|
||||
# Source Documentation
|
||||
|
||||
Use these links for framework-specific details.
|
||||
Use these links to verify framework-specific behavior before relying on version-sensitive or integration-specific guidance.
|
||||
|
||||
## NiceGUI
|
||||
|
||||
!!! info "NiceGUI sources"
|
||||
- [Pages, routing, and FastAPI integration](https://www.nicegui.io/documentation/section_pages_routing)
|
||||
- [Binding properties and bindable dataclasses](https://www.nicegui.io/documentation/section_binding_properties)
|
||||
- [Action events](https://www.nicegui.io/documentation/section_action_events)
|
||||
- [Security best practices](https://www.nicegui.io/documentation/section_security)
|
||||
|
||||
## FastAPI
|
||||
|
||||
@@ -8,40 +16,34 @@ Use these links for framework-specific details.
|
||||
- [Lifespan events](https://fastapi.tiangolo.com/advanced/events/)
|
||||
- [Settings and environment variables](https://fastapi.tiangolo.com/advanced/settings/)
|
||||
- [Dependencies with yield](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/)
|
||||
- [SQL databases tutorial](https://fastapi.tiangolo.com/tutorial/sql-databases/)
|
||||
- [Server-sent events](https://fastapi.tiangolo.com/advanced/server-sent-events/)
|
||||
- [WebSockets](https://fastapi.tiangolo.com/advanced/websockets/)
|
||||
|
||||
## SQLAlchemy and Alembic
|
||||
## Styling
|
||||
|
||||
!!! info "Styling sources"
|
||||
- [Tailwind utility-first styling](https://tailwindcss.com/docs/utility-first)
|
||||
- [Quasar components](https://quasar.dev/vue-components)
|
||||
|
||||
## Persistence
|
||||
|
||||
!!! info "Persistence sources"
|
||||
- [SQLAlchemy engine configuration and pooling](https://docs.sqlalchemy.org/en/20/core/engines.html)
|
||||
- [SQLAlchemy session lifecycle basics](https://docs.sqlalchemy.org/en/20/orm/session_basics.html)
|
||||
- [SQLAlchemy session lifecycle](https://docs.sqlalchemy.org/en/20/orm/session_basics.html)
|
||||
- [Alembic tutorial](https://alembic.sqlalchemy.org/en/latest/tutorial.html)
|
||||
|
||||
## Pydantic
|
||||
## Configuration And Dataclasses
|
||||
|
||||
!!! info "Pydantic source"
|
||||
- [Pydantic settings management](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/)
|
||||
|
||||
## NiceGUI
|
||||
|
||||
!!! info "NiceGUI sources"
|
||||
- [Pages, routing, and FastAPI integration](https://www.nicegui.io/documentation/section_pages_routing)
|
||||
- [Binding properties and bindable dataclass](https://www.nicegui.io/documentation/section_binding_properties)
|
||||
- [Security best practices](https://www.nicegui.io/documentation/section_security)
|
||||
|
||||
## Python Dataclasses
|
||||
|
||||
!!! info "Python sources"
|
||||
- [dataclasses module reference](https://docs.python.org/3/library/dataclasses.html)
|
||||
!!! info "Python and Pydantic sources"
|
||||
- [Pydantic settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)
|
||||
- [Python dataclasses](https://docs.python.org/3/library/dataclasses.html)
|
||||
- [PEP 557: Data Classes](https://peps.python.org/pep-0557/)
|
||||
|
||||
## LangGraph
|
||||
|
||||
!!! info "LangGraph sources"
|
||||
- [Overview](https://docs.langchain.com/oss/python/langgraph/overview)
|
||||
- [Quickstart](https://docs.langchain.com/oss/python/langgraph/quickstart)
|
||||
- [Workflows and agents](https://docs.langchain.com/oss/python/langgraph/workflows-agents)
|
||||
- [Persistence](https://docs.langchain.com/oss/python/langgraph/persistence)
|
||||
- [Memory concepts](https://docs.langchain.com/oss/python/concepts/memory)
|
||||
- [Streaming](https://docs.langchain.com/oss/python/langgraph/streaming)
|
||||
- [Interrupts and human-in-the-loop](https://docs.langchain.com/oss/python/langgraph/interrupts)
|
||||
@@ -0,0 +1,39 @@
|
||||
# Troubleshooting and Quality Gates
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Upload Errors
|
||||
|
||||
- Validate extension and size before storage.
|
||||
- Catch expected exceptions and return negative notifications.
|
||||
- Log unexpected exceptions with request context.
|
||||
|
||||
### UI Race Conditions
|
||||
|
||||
- Disable triggering controls during async work.
|
||||
- Remove duplicate timers and listeners targeting the same state.
|
||||
- Ensure service call ordering is deterministic before render updates.
|
||||
|
||||
### Asset Caching
|
||||
|
||||
- Confirm static mount and proxy rewrite correctness.
|
||||
- Add cache-busting query strings for changed assets.
|
||||
- Avoid per-page CSS injection.
|
||||
|
||||
### Navigation and State Drift
|
||||
|
||||
- Avoid global mutable UI state.
|
||||
- Keep state request-scoped or service-managed.
|
||||
- Rehydrate page data during route load.
|
||||
|
||||
## Production Readiness Gate
|
||||
|
||||
Pass all checks before shipping:
|
||||
|
||||
- Structure: one-way dependencies between pages, components, and services.
|
||||
- Responsiveness: UI validated at both small and large viewport widths.
|
||||
- Accessibility: labels and actions are clear and readable.
|
||||
- Reliability: validation and exception paths surface user feedback.
|
||||
- Maintainability: repeated UI patterns are extracted; business logic remains in services.
|
||||
|
||||
If any check fails, return to the workflow step that owns that concern.
|
||||
Reference in New Issue
Block a user