Skip to content

Tutorial: from an empty folder to an API and an admin

This takes about 10 minutes. You need uv (or pip) and Docker.

1. Install fyro and create a project

mkdir fyro-tutorial && cd fyro-tutorial
uv venv && source .venv/bin/activate
uv pip install fyro

fyro new mysite
cd mysite

fyro new writes:

mysite/
  manage.py           # runs fyro's commands for this project
  asgi.py             # the app: fyro.create_app()
  .env                # development settings (never commit it)
  .gitignore
  compose.yaml        # Postgres for this project
  mysite/
    settings.py

2. Start Postgres

docker compose up -d --wait

Port 5432 already taken?

Run FYRO_DB_PORT=5433 docker compose up -d --wait and change the port in FYRO_DATABASE_URL in .env to 5433.

3. Create an app with a model

python manage.py startapp blog

Write blog/models.py:

from fyro import Field, Model


class Post(Model):
    title: str = Field(max_length=200)
    body: str
    published: bool = False

Add the app (and fyro's built-in auth) to mysite/settings.py:

from fyro import Settings


class ProjectSettings(Settings):
    installed_apps: list[str] = ["fyro.auth", "blog"]

4. Create the tables

python manage.py makemigrations
python manage.py migrate

makemigrations writes a file to migrations/; migrate applies it.

5. Create an admin user and run the server

python manage.py createsuperuser
python manage.py runserver

Open:

6. Use the API

Reading is public; writing needs a login (the default once fyro.auth is installed):

curl -s http://127.0.0.1:8000/api/blog/post
TOKEN=$(curl -s -X POST http://127.0.0.1:8000/api/auth/login \
  -H 'content-type: application/json' \
  -d '{"username": "admin", "password": "your-password"}' | python -c 'import sys,json; print(json.load(sys.stdin)["token"])')
curl -s -X POST http://127.0.0.1:8000/api/blog/post \
  -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{"title": "Hello", "body": "First post"}'

7. Change the model

Add a field, then migrate again:

    views: int = 0
python manage.py makemigrations
python manage.py migrate

Existing posts get views = 0. Next: the guides.