Quickstart¶
The default is a page with a form, not an API-only file. FastAPI leaves HTML, forms, and a panel as homework; pyron init does not.
It asks the project name, what it is about, and what people add (dishes, kits, classes…). You get a unique app: home form, /docs, /admin, and 10 starter records for that topic — not a copy of the bookstore example.
- http://127.0.0.1:8000 — HTML form (creates a row)
- http://127.0.0.1:8000/docs — the same row as JSON
- http://127.0.0.1:8000/admin — the same row in the panel (first visit creates root)
- http://127.0.0.1:8000/p/about — a CMS page; add more under Pages in
/admin. Jinja2 renders them. - http://127.0.0.1:8000/admin/settings — site name, phone, hours
from pyron import Form, redirect
@app.post("/")
async def add_item(title: str = Form(), description: str = Form("")):
...
return redirect("/", message=f"Added “{title}”.")
API only¶
from pydantic import BaseModel, Field
from pyron import Pyron
app = Pyron(title="Harbor API")
class BookIn(BaseModel):
title: str = Field(min_length=1)
price: float = Field(ge=0)
@app.get("/health")
async def health() -> dict[str, str]:
return {"status": "ok"}
@app.post("/books", status_code=201)
async def create_book(book: BookIn) -> BookIn:
return book
Open:
- http://127.0.0.1:8000/docs — Swagger
- http://127.0.0.1:8000/redoc
- http://127.0.0.1:8000/openapi.json
Pydantic models on the handler are the contract: validation, types, and OpenAPI come from the same class.
Scaffold¶
pyron init shop # default ssr: form + API + admin
pyron init shop --template api # JSON + docs
pyron init shop --template desk # same as ssr
pyron init shop --template fullstack
Then cd shop, pyron dev.
Server-rendered pages¶
from starlette.requests import Request
from pyron import Pyron
app = Pyron(templates="templates", static_dir="static")
@app.get("/")
async def home(request: Request):
return await app.render(request, "index.html", {"title": "Harbor"})
Pages that should not appear in Swagger: include_in_schema=False.
With the admin panel on, Pages in /admin are CMS views (Markdown + preview). You do not write a route: Jinja2 renders /p/{slug} from page.html. Settings is the shop name, phone, and hours. Details: Admin — Pages · Settings.
Example¶
Shop at /, API at /api/books, admin panel at /admin, CMS pages at /p/about.