124 lines
3.4 KiB
Markdown
124 lines
3.4 KiB
Markdown
# Golden Examples — referenssitoteutukset
|
||
|
||
Kultaiset esimerkit ovat **täydellisiä, testattuja** FastAPI-projekteja joita LLM käyttää mallina koodigeneroinnissa. Malli näkee esimerkin ja tuottaa vastaavan rakenteen uudelle projektille.
|
||
|
||
## Uuden esimerkin luominen
|
||
|
||
### 1. Luo hakemisto
|
||
|
||
```bash
|
||
mkdir golden-examples/shop
|
||
```
|
||
|
||
Nimeä hakemisto skenaarion mukaan (todo, blog, shop, booking...).
|
||
|
||
### 2. Luo 4 tiedostoa
|
||
|
||
| Tiedosto | Sisältö |
|
||
|----------|---------|
|
||
| `models.py` | SQLAlchemy 2.0 -mallit (DeclarativeBase, Mapped, mapped_column) |
|
||
| `schemas.py` | Pydantic v2 -skeemat (ConfigDict, `str \| None` -syntaksi) |
|
||
| `main.py` | FastAPI CRUD -endpointit (POST 201, GET, GET/:id 404, PUT, DELETE 204) |
|
||
| `test_main.py` | Pytest + TestClient, erillinen test.db, uniikki data per testi |
|
||
|
||
### 3. Noudata konventioita
|
||
|
||
**Python-versio:** >=3.14
|
||
|
||
**SQLAlchemy 2.0** (ei legacy):
|
||
```python
|
||
# Oikein
|
||
class Base(DeclarativeBase):
|
||
pass
|
||
|
||
class Todo(Base):
|
||
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
||
title: Mapped[str] = mapped_column(String(255))
|
||
status: Mapped[str] = mapped_column(String(20), default="pending")
|
||
|
||
# Väärin
|
||
Base = declarative_base()
|
||
id = Column(Integer, primary_key=True)
|
||
```
|
||
|
||
**Pydantic v2** (ei v1):
|
||
```python
|
||
# Oikein
|
||
class TodoResponse(TodoCreate):
|
||
id: int
|
||
model_config = ConfigDict(from_attributes=True)
|
||
|
||
# Väärin
|
||
class Config:
|
||
orm_mode = True
|
||
```
|
||
|
||
**Tyypitys:**
|
||
```python
|
||
# Oikein
|
||
description: Mapped[str | None] = mapped_column(Text, default=None)
|
||
|
||
# Väärin
|
||
description: Mapped[Optional[str]]
|
||
```
|
||
|
||
**Dokumentointi (zensical):**
|
||
```python
|
||
"""Tietokantamallit — SQLAlchemy 2.0, Mapped-tyypitys, SQLite."""
|
||
|
||
class Todo(Base):
|
||
"""Tehtävä — otsikko, kuvaus, deadline, prioriteetti ja status."""
|
||
```
|
||
|
||
Yksi rivi riittää. Kerro mitä asia ON, älä mitä se tekee. Katso [DOCUMENTATION.md](DOCUMENTATION.md).
|
||
|
||
**Testidata — uniikki ja kuvaava:**
|
||
```python
|
||
# Oikein
|
||
def test_create_todo():
|
||
response = client.post("/todos/", json={"title": "Osta maitoa", "priority": 2})
|
||
|
||
def test_update_todo():
|
||
created = client.post("/todos/", json={"title": "Vanha otsikko"}).json()
|
||
|
||
# Väärin — geneerinen data
|
||
def test_create_todo():
|
||
response = client.post("/todos/", json={"title": "test", "priority": 1})
|
||
```
|
||
|
||
### 4. Testaa Docker-kontissa
|
||
|
||
```bash
|
||
rm -rf /tmp/golden-test && mkdir /tmp/golden-test
|
||
cp golden-examples/shop/*.py /tmp/golden-test/
|
||
docker run --rm -v /tmp/golden-test:/src:ro kipina-pytest
|
||
```
|
||
|
||
**Kaikkien testien pitää mennä läpi.** Ei varoituksia, ei deprecation-viestejä.
|
||
|
||
### 5. Vaikeustasot
|
||
|
||
| Taso | Esimerkit | Haaste |
|
||
|------|-----------|--------|
|
||
| 1 — Perus-CRUD | `todo/`, `users/`, `notes/` | Yksi entiteetti |
|
||
| 2 — Relaatiot | `blog/`, `library/`, `school/` | Foreign key, 2–3 entiteettiä |
|
||
| 3 — Liiketoimintalogiikka | `shop/`, `booking/` | Custom endpointit, validointi |
|
||
|
||
Aloita tasosta 1 ja etene. Tason 1 esimerkkien pitää olla yksinkertaisia — ne opettavat mallille perusrakenteen.
|
||
|
||
## Miten esimerkit vaikuttavat
|
||
|
||
Benchmark lataa `todo/`-esimerkin ja syöttää sen LLM:lle osana koodingenerointipromptia:
|
||
|
||
```
|
||
REFERENCE IMPLEMENTATION (todo project — follow this exact structure):
|
||
|
||
=== models.py ===
|
||
<todo/models.py sisältö>
|
||
|
||
=== schemas.py ===
|
||
...
|
||
```
|
||
|
||
Malli näkee tarkan esimerkin ja tuottaa vastaavan rakenteen uudelle projektille. Mitä parempi esimerkki, sitä parempi tulos.
|