Skip to content

Latest commit

 

History

214 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rio Boilerplate

Production-ready Rio web application template featuring session-based authentication, optional TOTP multi-factor security, FastAPI endpoints, and a reusable component library.

Highlights

  • Auth & security: login, password reset, role-based guards, MFA toggles, recovery codes, admin-only operations.
  • API layer: FastAPI routers for profile data, shared validation in app/app/validation.py, and SQLite persistence helpers. Protected external HTTP clients are not supported until a credential model is designed for a concrete consumer.
  • UI experience: Rio pages for public marketing routes and protected app area, shared layout elements, and Plotly chart support.
  • Built-in primary currency system with configurable naming, precision, admin tooling, and ledger history.
  • Developer ergonomics: Example scripts, bundled Rio documentation, and deployment playbooks for quick onboarding.

Using as a Template

There are two ways to use this boilerplate:

Option A: Clone (simple, no upstream updates)

git clone git@github.com:azidancorp/RioBoilerplate.git my-project
cd my-project
rm -rf .git && git init  # Start fresh git history

Option B: Add as Remote (recommended - enables upstream updates)

If you already have a git project and want to pull in this boilerplate while keeping the ability to get future updates:

# From your existing project directory
git remote add boilerplate git@github.com:azidancorp/RioBoilerplate.git
git fetch boilerplate
git merge boilerplate/main --allow-unrelated-histories -m "Merge RioBoilerplate template"

This merges the boilerplate into your project. Later, to pull updates:

git fetch boilerplate
git merge boilerplate/main

For detailed merge instructions and conflict resolution, see UPSTREAM_MERGE_GUIDE.md.

Quick Start

  1. Set up the boilerplate using Option A or B above.
  2. Create and activate a virtual environment: python -m venv venv then source venv/bin/activate (or venv\Scripts\activate on Windows).
  3. Install the hashed development lock: python -m pip install --require-hashes -r requirements-dev.txt.
  4. Copy .env.example to .env and set any provider/session secrets your deployment uses.
  5. From the repository root, initialize the first verified root account: ./bootstrap.sh.
  6. Start the development server: ./dev.sh (or ./dev.sh 8888 to pick a port).
  7. The app stores its local SQLite database at app/app/data/app.db. This file is ignored by git and should remain a local runtime artifact.

Access the dev server at http://localhost:8181. Use ./dev.sh 8181 --release to mirror production settings. Replace 8181 with the port you actually chose when checking a different local run.

Local configuration

The values tracked in app/app/config.py describe production — a canonical HTTPS APP_URL, Secure/__Host- cookies, real email delivery, and enforced email verification. That way a missing or unread configuration fails closed with a broken localhost login instead of failing open with insecure cookies on a public site.

./dev.sh creates app/app/config_local.py (git-ignored) from app/app/config_local.example.py on first run, which overrides those values for localhost. Edit that file freely; dev.sh never rewrites it. If you start the server without it — plain cd app && rio run on a fresh clone — login appears to succeed but a red banner reports that the sign-in state could not be saved, because cookie writes are pinned to the production origin.

Overrides are ignored under pytest, so tests and CI always run against the tracked production configuration.

Public password signup and OAuth registration cannot initialize an empty database. With no arguments, bootstrap_root prompts for email and password. You can also pass values directly, for example python -m app.scripts.bootstrap_root --email owner@example.com --password '<strong-password>'. --username owner is optional; if you provide --username without --email, that username becomes the root login identifier. The command creates one verified root user only when the database is empty.

Railway First Deployment

Warning: not production-ready on Railway yet. As shipped, railway.toml deploys with no volume attached, and Railway's container filesystem is ephemeral — the SQLite database is erased on every deploy and restart. Do not put real users on a Railway deployment until the runtime-data relocation described below is complete and a volume is mounted. The supported production path today is the VPS guide in DEPLOYMENT_INSTRUCTIONS.md; the outstanding Railway work and the root-bootstrap procedure are tracked in docs/railway-readiness.md.

railway.toml runs strict prestart checks before starting the public server. On a fresh database, the deployment exits with a bootstrap error rather than exposing an unclaimed root slot. It also refuses to start until secure cookies, a canonical HTTPS APP_URL, and an external resend or verified-STARTTLS smtp email method are configured. These non-secret values are code-configured, so set, test, and commit them in app/app/config.py before deploying; provider secrets remain in the environment. These fail-closed results are expected.

Do not expose a Railway domain until the initial root has been created against the same persistent database the service will use. railway run and railway shell execute locally with Railway variables and do not modify the deployed SQLite volume.

The current app/app/data/ directory mixes mutable runtime state with tracked sample data, so it does not yet have a safe Railway volume mount target. Complete the runtime-data relocation tracked in docs/railway-readiness.md before treating this SQLite configuration as Railway-ready; mounting a volume over the whole directory would hide tracked application files.

Everyday Development

  • ./dev.sh – hot-reloading dev server with the local configuration override in place.
  • ./dev.sh 8181 --release – release-mode smoke test.
  • curl -fsS http://127.0.0.1:8181/api/health – machine-readable health check for the running app and local SQLite schema.

Runtime dependencies are declared in requirements.in and compiled with hashes into requirements.txt. Development and supply-chain tools use the corresponding requirements-dev.in and requirements-dev.txt files. After changing an input, regenerate both locks with the pinned pip-compile from the development lock; never hand-edit the generated files.

Configuration

  • .env is for secrets only, such as SESSION_SECRET_KEY or provider credentials.
  • Non-secret behavior stays code-configured in app/app/config.py, whose tracked values describe production. Edit that file directly for app-specific defaults such as email validation, username login, password policy, and currency naming/precision.
  • Machine-local development values belong in the git-ignored app/app/config_local.py, never in a commit. See “Local configuration” above.
  • EMAIL_METHOD="outbox" is for local development and is set by the local override file. Production must select resend or secure smtp; delivery failures never fall back to local files.
  • Email validation and username-login behavior are documented in docs/configuration/email-validation.md.
  • Root initialization is intentionally not configurable: public registration never assigns a privileged role.
  • The runtime SQLite database file app/app/data/app.db is created locally on first run and is ignored by git.
  • Before going to production, replace the placeholder branding in app/app/assets/ (favicon.ico, logo.png, og_image.png) with your own. The source script at app/assets_src/build_brand_assets.py shows how they were generated and can be adapted; run it from the outer app/ directory with python assets_src/build_brand_assets.py.

Currency System

  • SQLite schema stores a single minor-unit balance per user plus an audited user_currency_ledger.
  • Admin UI (/app/admin) now surfaces balances, allows grants/deductions, and shows success/error feedback.
  • FastAPI endpoints (/api/currency/*) expose balance, ledger, and privileged adjustment APIs.
  • CLI helper python app/app/scripts/currency_admin.py supports list, ledger, adjust, and set operations from the terminal.

HTTP API

  • Protected profile operations and /api/currency/balance, /api/currency/ledger, /api/currency/adjust, and /api/currency/set require Authorization: Bearer <session token>. /api/health, /api/test, /api/contact, and /api/currency/config are public.
  • The bearer requirement is declared in OpenAPI as SessionBearer. Interactive Swagger UI lives at /docs; reference documentation lives at /redoc. The schema describes how to send an existing credential but does not provide or issue one.
  • The stock Rio UI does not depend on protected REST operations over HTTP. app/app/pages/app_page/currency_playground.py invokes currency route handlers directly as a manual QA exception, not as the general UI/service sharing pattern.
  • There is intentionally no supported external token issuance or browser-cookie extraction flow. Production sessions are created through the web login/OAuth paths; tests create sessions directly with Persistence.create_session() only as setup.
  • Before adding a browser, mobile, CLI, or integration client, read docs/api-client-authentication.md and design a credential lifecycle for that concrete consumer.

Project Layout

RioBoilerplate/
├── app/
│   ├── rio.toml               # Rio app configuration
│   ├── JSPages/               # Prototype HTML/JS demos
│   └── app/
│       ├── __init__.py        # App bootstrap + FastAPI bridge
│       ├── api/               # FastAPI routers (profiles, examples)
│       ├── assets/            # Branding assets (favicon, logo, og_image) — replace before production
│       ├── components/        # Reusable Rio UI widgets
│       ├── data/              # Runtime SQLite DB (local/ignored) and sample data
│       ├── pages/             # Public pages
│       │   └── app_page/      # Protected app pages
│       ├── scripts/           # Utilities and MFA helper scripts
│       ├── permissions.py     # Role checks and guard helpers
│       ├── persistence.py     # Database access layer
│       └── validation.py      # Input validation & Pydantic models
├── RioDocumentation/          # Bundled Rio reference material
├── DEPLOYMENT_INSTRUCTIONS.md # Production rollout guide
├── requirements.in            # Direct runtime dependencies
├── requirements.txt           # Hashed runtime lock
├── requirements-dev.in        # Direct development/tooling dependencies
├── requirements-dev.txt       # Hashed development lock
└── README.md

Testing & QA

Focus release verification on:

  • Registration, login, and role-based routing.
  • Enabling/disabling MFA and using recovery codes.
  • Profile update via the UI and profile CRUD via /api/profiles.
  • Error handling across contact flows and API responses.
  • Currency adjustments: verify admin operations, ledger history, and /api/currency/* behaviour (positive & negative paths).
  • Release health check: curl -fsS http://127.0.0.1:8181/api/health against the port used for that run.

Further Reading

  • AGENTS.md – contributor workflow and coding standards.
  • CLAUDE.md – extended architecture and assistant notes.
  • DEPLOYMENT_INSTRUCTIONS.md – step-by-step deployment guidance.
  • RioDocumentation/ – offline Rio framework reference.

License

Distributed under the terms of the included LICENSE.

About

A simple web app boilerplate template that can be used as a base for projects using the python Rio framework.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages