Skip to content

Latest commit

 

History

History
274 lines (184 loc) · 9.69 KB

File metadata and controls

274 lines (184 loc) · 9.69 KB

AI Implementation Guide

This guide is written for coding agents and fast-moving builders who want to extend this repository without redesigning the architecture from scratch.

Core Idea

This repository does not require an API wrapper for normal UI work.

Use this flow first:

  1. Add UI in a page module under template-basic/view/.
  2. Load data directly in Python when the page is rendered.
  3. Keep visible labels and dummy content in template-basic/config.json.
  4. Add a small API route only when external clients need it.

Use a separated frontend/backend architecture only if you actually need independent deployment, a public API surface, or a JavaScript-heavy app.

Architecture At A Glance

Co-located Python UI

flowchart LR
    A[Python logic] --> B[NiceGUI page]
    B --> C[Shared shell]
    C --> D[Browser UI]
    A --> E[CSV / local files / local state]
Loading

Use this when one Python app owns the logic and the UI.

Split Frontend And Backend

flowchart LR
    A[Python backend] --> B[REST / WebSocket API]
    B --> C[React / Vue frontend]
    C --> D[Browser UI]
    A --> E[DB / services]
Loading

Use this only when the separation solves a real deployment or integration problem.

Project Shape

Fastest Safe Extension Pattern

When adding a new feature, follow this order.

  1. Add a new page file under template-basic/view/.
  2. Register it in template-basic/main.py.
  3. Add a navigation entry in template-basic/config.json.
  4. Reuse render_shell from template-basic/view/layout.py.
  5. Put labels, section names, and fake content in template-basic/config.json instead of hardcoding them.
  6. Add only the minimum CSS needed in template-basic/static/custom.css.

Example: Add A New Page

Use this shape.

from nicegui import ui

from .layout import render_shell


def create_example_page(*, app_title: str, shell_content: dict, example_content: dict) -> None:
    @ui.page('/example')
    def example_page() -> None:
        ui.page_title(f'{app_title} - Example')

        def workspace() -> None:
            with ui.element('section').classes('ark-console-card w-full'):
                ui.label(example_content.get('title', 'Example')).classes('ark-section-title')
                ui.label(example_content.get('copy', '')).classes('ark-console-copy')

        render_shell(
            app_title=app_title,
            active='example',
            shell_content=shell_content,
            workspace_builder=workspace,
        )

Then register it in template-basic/main.py and add a nav entry in template-basic/config.json.

Example: Add Data Without Building An API

If the data is local and only used by this app, load it directly in the page module.

That is what template-basic/view/dashboard.py already does:

  1. Reads CSV with Python.
  2. Filters rows for the requested symbol and timeframe.
  3. Builds chart options in Python.
  4. Passes the result straight into NiceGUI.

This is the right choice for local tools, personal dashboards, prototypes, internal utilities, and offline or single-user workflows.

When You Actually Need An API

Add an API layer only if one of these is true.

  1. Another application needs to consume the same data.
  2. You want a JavaScript frontend deployed separately from Python.
  3. You need mobile, desktop, or third-party clients to call the backend.
  4. You need strict service boundaries for scaling or security.

If none of those are true, direct Python-driven UI is usually faster and easier to maintain.

Start From Intent, Not Tools

Most people do not begin with a technical request.

They begin with something like this:

  • I want something like a personal chat workspace.
  • I want a screen like LM Studio, but simpler.
  • I want a dashboard like a trading monitor.
  • I want a local tool that remembers my notes and prompts.
  • I want a page where I can load files, ask questions, and keep the results.

That is the right starting point.

The job of the AI is to translate that intent into concrete edits.

Translate "I Want Something Like..." Into Work

Use this mapping.

  1. "I want something like a local chat app" Result:
  1. "I want something like a market dashboard" Result:
  1. "I want something like my personal AI workspace" Result:
  • combine chat, notes, prompts, and file views
  • add new pages under template-basic/view/
  • keep labels and card content in template-basic/config.json
  1. "I want something like LM Studio, but for my workflow" Result:
  • do not begin by cloning LM Studio features
  • define the actual workflow first: chat, file search, evaluation, notes, export, dashboard
  • implement the workflow in this shell one page at a time
  1. "I want a tool that remembers things" Result:
  • first define what must be remembered
  • if simple, store local files or JSON
  • only add a DB after the memory model is clear

Ask The Right Question First

Before building, force the request into this sentence:

"I want to build a tool that helps me do X, by showing Y, storing Z, and letting me trigger W."

Once that sentence is clear, implementation becomes much easier.

What People Usually Actually Want

They usually do not want:

  • a raw model loader
  • a generic API server
  • a blank GUI shell

They usually want:

  • a screen that feels like their workbench
  • a repeatable workflow
  • a place where chat, files, prompts, and results live together
  • a tool that fits their own process instead of a public demo checklist

State Management Rule

Default to local page state first.

  • use local lists and values for chat demos
  • derive dashboard data from files or config on render
  • store reusable copy and display knobs in template-basic/config.json

Only introduce shared state when multiple pages truly need the same live data.

Styling Rule

Keep the visual language stable.

  1. Prefer CSS variables over hardcoded colors and widths.
  2. Reuse the existing shell cards and spacing.
  3. Add new classes only when the current classes cannot express the new component.
  4. Avoid page-specific one-off hacks if the pattern may repeat.

Dashboard Rule

For charts, start with the built-in NiceGUI ECharts path used in template-basic/view/dashboard.py.

This avoids extra dependencies for common cases like line charts, candlesticks, bar charts, and volume overlays.

Only add another charting package if ECharts genuinely blocks a required feature.

AI Agent Checklist

Before editing:

  1. Read template-basic/main.py, template-basic/config.json, and the target page in template-basic/view/.
  2. Check whether the requested text already belongs in config.json.
  3. Reuse render_shell unless the request explicitly replaces the shell.

While editing:

  1. Keep changes narrow.
  2. Do not split the app into frontend plus API unless the user asked for that architecture.
  3. Use the existing naming and page registration pattern.

After editing:

  1. Check Python errors.
  2. Start the app on the configured port.
  3. Confirm the new route is reachable.

Good First Extensions

If another AI needs a clear next task, these are safe.

  1. Add symbol and timeframe selectors to template-basic/view/dashboard.py.
  2. Add file upload and preview pages using the same shell.
  3. Replace dummy preview content in template-basic/config.json with project-specific controls.
  4. Add a second dashboard card for moving averages or volatility.
  5. Add export buttons that work locally before introducing APIs.

Prompting Another AI

If you hand this repo to another AI, give it constraints that match the template instead of asking for a generic webapp.

Good prompt shape:

  1. name the page to edit
  2. name the data source
  3. say whether copy belongs in config.json
  4. say whether the shared shell must stay intact
  5. explicitly forbid unnecessary API separation

See AI_PROMPT_TEMPLATES.md for copy-paste prompts.

Bottom Line

For this repository, the fastest path is:

Python logic -> NiceGUI page -> shared shell -> config-driven copy

Not:

Python backend -> custom API wrapper -> separate frontend -> extra complexity

Start simple, keep the architecture close to the actual problem, and only add boundaries when they solve a real deployment need.