A tiny FastAPI-powered todo list with a clean web UI. Use the Pinokio launcher to install dependencies, start the server, update packages, or reset the environment in one click.
- Install: Run
install.jsto create a virtual environment and install dependencies withuv pip install -r requirements.txt. - Start: Run
start.jsto launch the FastAPI server (daemonized). The launcher captures the printed URL and exposes an Open Web UI button once the server is ready. - Update: Run
update.jsto upgrade dependencies to the latest versions fromrequirements.txt. - Reset: Run
reset.jsto remove the virtual environment and Python caches if you need a clean slate.
- The web UI lives at
/and talks to a simple JSON API. - Todos are stored in memory for simplicity; restarting the app clears the list.
- The server binds to
127.0.0.1on the next available port chosen by Pinokio. - UI supports a light/dark toggle that remembers your choice in local storage.
All endpoints are relative to the server base URL returned by start.js (for example http://127.0.0.1:8000).
GET /api/todos
Response:
[{"id":1,"title":"Example","completed":false}]POST /api/todos
Body:
{"title": "Buy milk"}Response: 201 Created with the new todo object.
PATCH /api/todos/{id}
Body (all fields optional):
{"title": "Buy oat milk", "completed": true}DELETE /api/todos/{id} → 204 No Content
Replace BASE_URL with the URL captured by start.js.
const BASE_URL = "http://127.0.0.1:8000";
async function addTodo(title) {
const res = await fetch(`${BASE_URL}/api/todos`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title }),
});
return res.json();
}import requests
BASE_URL = "http://127.0.0.1:8000"
resp = requests.post(f"{BASE_URL}/api/todos", json={"title": "Read docs"})
resp.raise_for_status()
print(resp.json())curl -X POST "%BASE_URL%/api/todos" ^
-H "Content-Type: application/json" ^
-d "{\"title\":\"Finish tasks\"}"On macOS/Linux:
curl -X POST "$BASE_URL/api/todos" \
-H "Content-Type: application/json" \
-d '{"title":"Finish tasks"}'