nicegui prompt

This commit is contained in:
John Lancaster
2026-06-16 21:33:29 -05:00
commit ece3e68915
5 changed files with 1044 additions and 0 deletions
+244
View File
@@ -0,0 +1,244 @@
# NiceGUI
Build a production-ready, multi-page NiceGUI application that follows modern FastAPI project layout and architecture practices.
## Goal
Create a clean, maintainable app structure where:
- FastAPI is the underlying ASGI app.
- NiceGUI is mounted/initialized in a way that aligns with FastAPI best practices.
- Each page is implemented as a separate module in `pages/`.
- The project is easy to test, extend, and deploy.
## Requirements
- Prefer Pydantic settings with a `.env` example.
- Consider adding structured logging configuration.
- Use a `src/`-style layout with clear package boundaries.
- Use an app factory (`create_app`) and avoid global side effects at import time.
- Register NiceGUI pages from modules in `pages/`.
- Keep UI logic in page modules and shared UI helpers/components in a separate package.
- Include at least these pages:
- Home (`/`)
- Dashboard (`/dashboard`)
- About (`/about`)
- Include a health endpoint (`/healthz`) on the FastAPI side.
- Provide minimal test examples for FastAPI routes and page registration.
- Use FastAPI lifespan for startup/shutdown resource management.
## Recommendations
- Consider a shared navigation/header component and left drawer used by all pages.
- Consider including dev tooling basics (formatting/lint/test commands).
- Prefer clear separation of concerns:
- `db/` for engine/session/base/models/repositories (if needed)
- `api/` for HTTP endpoints
- `ui/` for NiceGUI pages/components
- `services/` for business logic
- If you need database access, a solid pattern is to use FastAPI + SQLAlchemy best practices:
- Use one engine per application process (do not create per request).
- Prefer a request-scoped session dependency using `yield`.
- Keep transaction boundaries explicit (commit/rollback) in service/repository flows.
- Avoid sharing a session across concurrent tasks.
- Consider production-minded pool settings (`pool_pre_ping=True` and sensible recycle/timeout values).
- Prefer Alembic for schema migrations.
## Extending This Pattern with LangGraph (Optional)
If your app needs multi-step AI workflows, tool-calling loops, or human-in-the-loop approvals, a clean extension is to add a dedicated LangGraph domain layer.
### Recommended architecture shape
- Keep LangGraph logic out of `ui/pages/` and out of HTTP route handlers.
- Add an `ai/` package (or similar) and keep graph definition, state schema, tools, and orchestration there.
- Call the graph from `services/` so your UI and API both use the same orchestration entry points.
- Continue using FastAPI lifespan for shared resources (models, clients, stores/checkpointers).
### Suggested project extension
```text
.
└─ src/
└─ app/
├─ ai/
│ ├─ __init__.py
│ ├─ state.py # TypedDict / Pydantic state schemas + reducers
│ ├─ nodes/
│ │ ├─ __init__.py
│ │ ├─ llm.py
│ │ ├─ tools.py
│ │ └─ review.py # optional interrupt/human-review nodes
│ ├─ graphs/
│ │ ├─ __init__.py
│ │ └─ assistant_graph.py
│ ├─ runtime.py # compile() + checkpointer/store wiring
│ └─ contracts.py # input/output DTOs between services and graph
├─ services/
│ └─ ai_service.py # invoke/stream/resume wrappers
└─ api/
└─ ai.py # optional HTTP endpoints for run/stream/resume
```
### Idiomatic LangGraph practices to request
- Define explicit graph state schema (`TypedDict` or Pydantic) and use reducers for append/merge behavior where needed.
- Compile graphs with persistence primitives appropriate to environment:
- dev/testing: in-memory checkpointer/store
- production: durable checkpointer/store
- Always pass a stable `thread_id` in `configurable` for resumable sessions and conversation continuity.
- For interactive UX, prefer event streaming APIs and project-specific streaming adapters in service code.
- Use `interrupt()` for human approvals/reviews; resume with `Command(resume=...)` using the same `thread_id`.
- Keep interrupt payloads JSON-serializable.
- Place non-idempotent side effects after interrupts (or isolate them in separate nodes), because interrupted nodes re-run from the start.
- If using tools, prefer LangGraphs `ToolNode` (or an equivalent centralized tool-execution node) for consistent execution/error handling.
- Keep graph nodes deterministic and narrow in scope (single responsibility per node).
- Add observability with LangSmith tracing for graph runs, transitions, and latency debugging.
### Integration guidance for NiceGUI + FastAPI
- UI pages should call `ai_service` methods, not graph internals.
- If the UX needs live token/progress updates, expose streaming from service -> UI in a transport-appropriate way.
- For approval workflows, surface interrupt payloads in UI, collect user response, then resume via service with `Command(resume=...)`.
- Keep graph invocation boundaries typed (request/response contracts) so changes in graph internals do not leak into page modules.
### Testing recommendations for LangGraph additions
- Unit test node functions as pure transformations where possible.
- Integration test graph routes (happy path, tool path, interrupt/resume path).
- Add tests ensuring `thread_id` reuse resumes correctly and new IDs start fresh sessions.
- Add regression tests for state-schema evolution and serialization compatibility.
## Suggested Project Structure
Base structure (no database required):
```text
.
├─ pyproject.toml
├─ .env.example
├─ README.md
├─ src/
│ └─ app/
│ ├─ __init__.py
│ ├─ main.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
│ └─ bootstrap.py
└─ tests/
├─ test_health.py
└─ test_pages_registration.py
```
If database access is needed, extend with:
```text
.
├─ alembic.ini
├─ alembic/
│ ├─ env.py
│ └─ versions/
├─ src/
│ └─ app/
│ └─ db/
│ ├─ __init__.py
│ ├─ base.py
│ ├─ session.py
│ ├─ models/
│ │ ├─ __init__.py
│ │ └─ example.py
│ └─ repositories/
│ ├─ __init__.py
│ └─ example_repo.py
└─ tests/
└─ test_db_session_dependency.py
```
## Implementation Notes
- Prefer an explicit page registration function pattern, for example:
- `register_pages()` in `ui/pages/__init__.py`
- Each page module exports `register_page()`
- Keep imports one-way to avoid circular dependencies.
- Keep page modules cohesive: route declaration + page layout for that route.
- Prefer FastAPI lifespan hooks where appropriate for startup/shutdown behavior.
- Prefer type hints throughout.
### Database-specific notes (only if your app needs a DB)
- Prefer settings via `pydantic-settings` and read `DATABASE_URL` from environment/dotenv.
- Configure the SQLAlchemy engine once at app setup level; avoid creating engine/sessionmaker in endpoint functions.
- Provide `get_db_session()` via `yield` so sessions are consistently closed.
- Prefer a repository/service boundary to keep SQL details out of page modules.
- Prefer Alembic for schema changes and include commands for `revision --autogenerate` and `upgrade head`.
- Avoid `metadata.create_all()` in production startup flow; reserve it for optional local/dev bootstrap paths.
- Consider a light DB readiness check in health reporting (or a dedicated `/readyz`) when relevant.
- Ensure logs do not leak secrets (for example, avoid unsafe SQL echo in production).
## Output Format
Return:
1. A short architecture explanation.
2. Full file tree.
3. Complete contents for each file.
4. Run instructions (dev and prod).
5. A brief section explaining how to add a new page module in `pages/`.
## Guardrails
- Prefer not to put all pages in one file.
- Avoid relying on implicit globals for app setup.
- Keep code minimal but production-minded.
- Prefer clarity and maintainability over clever abstractions.
## Source Documentation (recommended references)
- FastAPI lifespan events:
- https://fastapi.tiangolo.com/advanced/events/
- FastAPI settings and environment variables:
- https://fastapi.tiangolo.com/advanced/settings/
- FastAPI dependencies with `yield` (session lifecycle pattern):
- https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/
- FastAPI SQL databases tutorial (when using a DB):
- https://fastapi.tiangolo.com/tutorial/sql-databases/
- SQLAlchemy engine configuration and pooling (when using a DB):
- https://docs.sqlalchemy.org/en/20/core/engines.html
- SQLAlchemy session basics and lifecycle guidance (when using a DB):
- https://docs.sqlalchemy.org/en/20/orm/session_basics.html
- Alembic tutorial and migration environment (when using a DB):
- https://alembic.sqlalchemy.org/en/latest/tutorial.html
- Pydantic settings management:
- https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/
- NiceGUI pages/routing and FastAPI integration:
- https://www.nicegui.io/documentation/section_pages_routing
- NiceGUI security best practices:
- https://www.nicegui.io/documentation/section_security
- LangGraph overview:
- https://docs.langchain.com/oss/python/langgraph/overview
- LangGraph quickstart:
- https://docs.langchain.com/oss/python/langgraph/quickstart
- LangGraph workflows and agents:
- https://docs.langchain.com/oss/python/langgraph/workflows-agents
- LangGraph persistence (checkpointer vs store):
- https://docs.langchain.com/oss/python/langgraph/persistence
- LangGraph memory concepts:
- https://docs.langchain.com/oss/python/concepts/memory
- LangGraph streaming:
- https://docs.langchain.com/oss/python/langgraph/streaming
- LangGraph interrupts / human-in-the-loop:
- https://docs.langchain.com/oss/python/langgraph/interrupts