213 lines
7.1 KiB
Markdown
213 lines
7.1 KiB
Markdown
# 4 — Coder (coder) — pyproject.toml
|
|
|
|
**Malli:** `qwen-coder`
|
|
|
|
## System Prompt
|
|
|
|
```
|
|
You are an expert Python developer. Write complete, production-ready code.
|
|
|
|
CRITICAL RULES:
|
|
1. Include ALL imports at the top of every file
|
|
2. Import from other project files: from models import User, SessionLocal
|
|
3. Pydantic schemas use different names than SQLAlchemy models: UserCreate, UserResponse (not User)
|
|
4. SQLAlchemy engine: create_engine(url, connect_args={"check_same_thread": False})
|
|
5. SessionLocal: sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
6. FastAPI dependencies: def get_db(): db = SessionLocal(); try: yield db; finally: db.close()
|
|
7. Pydantic v2: use model_dump() not dict(), class Config: from_attributes = True
|
|
8. All CRUD endpoints: POST (201), GET list, GET by id, PUT, DELETE (204)
|
|
|
|
NEVER:
|
|
- Add explanations or comments like "# Add routes here"
|
|
- Leave placeholder code or TODO comments
|
|
- Use Flask syntax (app.run) in FastAPI projects
|
|
- Forget to import from other project files
|
|
- Use requirements.txt or Poetry — always use pyproject.toml with [project] format (PEP 621)
|
|
- Use pip install — use uv (e.g. uv run uvicorn main:app --reload)
|
|
```
|
|
|
|
## Syöte
|
|
|
|
```
|
|
You are an expert Python developer. Write complete, production-ready code.
|
|
|
|
CRITICAL RULES:
|
|
1. Include ALL imports at the top of every file
|
|
2. Import from other project files: from models import User, SessionLocal
|
|
3. Pydantic schemas use different names than SQLAlchemy models: UserCreate, UserResponse (not User)
|
|
4. SQLAlchemy engine: create_engine(url, connect_args={"check_same_thread": False})
|
|
5. SessionLocal: sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
6. FastAPI dependencies: def get_db(): db = SessionLocal(); try: yield db; finally: db.close()
|
|
7. Pydantic v2: use model_dump() not dict(), class Config: from_attributes = True
|
|
8. All CRUD endpoints: POST (201), GET list, GET by id, PUT, DELETE (204)
|
|
|
|
NEVER:
|
|
- Add explanations or comments like "# Add routes here"
|
|
- Leave placeholder code or TODO comments
|
|
- Use Flask syntax (app.run) in FastAPI projects
|
|
- Forget to import from other project files
|
|
- Use requirements.txt or Poetry — always use pyproject.toml with [project] format (PEP 621)
|
|
- Use pip install — use uv (e.g. uv run uvicorn main:app --reload)
|
|
|
|
EXAMPLE of pyproject.toml (for a different project, adapt to this one):
|
|
```
|
|
[project]
|
|
name = "myapp"
|
|
version = "0.1.0"
|
|
requires-python = ">=3.11"
|
|
dependencies = [
|
|
"fastapi",
|
|
"uvicorn[standard]",
|
|
"sqlalchemy",
|
|
]
|
|
|
|
[project.scripts]
|
|
dev = "uvicorn main:app --reload"
|
|
```
|
|
|
|
Already written files in THIS project:
|
|
--- models.py ---
|
|
from sqlalchemy import create_engine, Column, Integer, String, Date, Enum
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
DATABASE_URL = "sqlite:///./todo.db"
|
|
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
|
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
Base = declarative_base()
|
|
|
|
class Todo(Base):
|
|
__tablename__ = "todos"
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
title = Column(String(100), nullable=False)
|
|
description = Column(String(500))
|
|
due_date = Column(Date, nullable=False)
|
|
status = Column(Enum('pending', 'completed'), default='pending')
|
|
|
|
--- schemas.py ---
|
|
from pydantic import BaseModel
|
|
|
|
class TodoCreate(BaseModel):
|
|
title: str
|
|
description: str | None = None
|
|
due_date: date
|
|
status: str = 'pending'
|
|
|
|
class TodoResponse(TodoCreate):
|
|
id: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
--- main.py ---
|
|
from fastapi import FastAPI, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
from models import Base, engine, SessionLocal, Todo
|
|
from schemas import TodoCreate, TodoResponse
|
|
|
|
Base.metadata.create_all(bind=engine)
|
|
app = FastAPI()
|
|
|
|
def get_db():
|
|
db = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
@app.post("/todos/", response_model=TodoResponse, status_code=201)
|
|
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
|
|
db_todo = Todo(**todo.model_dump())
|
|
db.add(db_todo)
|
|
db.commit()
|
|
db.refresh(db_todo)
|
|
return db_todo
|
|
|
|
@app.get("/todos/", response_model=list[TodoResponse])
|
|
def list_todos(status: str | None = None, db: Session = Depends(get_db)):
|
|
if status:
|
|
query = db.query(Todo).filter_by(status=status)
|
|
else:
|
|
query = db.query(Todo)
|
|
return query.all()
|
|
|
|
@app.get("/todos/{todo_id}", response_model=TodoResponse)
|
|
def get_todo(todo_id: int, db: Session = Depends(get_db)):
|
|
todo = db.query(Todo).filter(Todo.id == todo_id).first()
|
|
if not todo:
|
|
raise HTTPException(status_code=404, detail="Not found")
|
|
return todo
|
|
|
|
@app.put("/todos/{todo_id}", response_model=TodoResponse)
|
|
def update_todo(todo_id: int, todo: TodoCreate, db: Session = Depends(get_db)):
|
|
db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
|
|
if not db_todo:
|
|
raise HTTPException(status_code=404, detail="Not found")
|
|
for key, value in todo.model_dump().items():
|
|
setattr(db_todo, key, value)
|
|
db.commit()
|
|
db.refresh(db_todo)
|
|
return db_todo
|
|
|
|
@app.delete("/todos/{todo_id}", status_code=204)
|
|
def delete_todo(todo_id: int, db: Session = Depends(get_db)):
|
|
db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
|
|
if not db_todo:
|
|
raise HTTPException(status_code=404, detail="Not found")
|
|
db.delete(db_todo)
|
|
db.commit()
|
|
|
|
PROJECT REQUIREMENTS (from product owner):
|
|
1. **PROJECT NAME:** Todo-sovellus
|
|
|
|
2. **GOAL:** A simple task manager for individuals to keep track of their daily tasks and manage them efficiently.
|
|
|
|
3. **CORE FEATURES:**
|
|
- Create new todos with title, description, due date.
|
|
- Read/View all todos or a single todo by ID.
|
|
- Update existing todos (title, description, status).
|
|
- Delete completed or unnecessary todos.
|
|
- Filter todos by status (e.g., pending, completed).
|
|
|
|
4. **DATA MODEL:**
|
|
- Todo
|
|
- id (integer, primary key)
|
|
- title (string)
|
|
- description (text)
|
|
- due_date (date)
|
|
- status (enum: 'pending', 'completed')
|
|
|
|
5. **API ENDPOINTS:**
|
|
- GET /todos: Retrieve all todos.
|
|
- GET /todos/{id}: Retrieve a single todo by ID.
|
|
- POST /todos: Create a new todo.
|
|
- PUT /todos/{id}: Update an existing todo.
|
|
- DELETE /todos/{id}: Delete a todo.
|
|
|
|
6. **CONSTRAINTS:**
|
|
- Must use SQLite as the database.
|
|
- No authentication required for accessing endpoints.
|
|
- Implement unit tests and integration tests to ensure functionality.
|
|
|
|
NOW write "pyproject.toml" for THIS project: Todo-sovellus FastAPI + SQLite, CRUD-endpointit ja testit
|
|
Use [project] format (PEP 621, compatible with uv). List dependencies under [project.dependencies]. Add [project.scripts] with dev command. Never use requirements.txt or Poetry format. Run with: uv run uvicorn main:app --reload
|
|
Adapt to the project requirements. Import from already written files. Write ONLY the code, no explanations.
|
|
```
|
|
|
|
## Tulos
|
|
|
|
```
|
|
[project]
|
|
name = "todo-sovellus"
|
|
version = "0.1.0"
|
|
requires-python = ">=3.11"
|
|
dependencies = [
|
|
"fastapi",
|
|
"uvicorn[standard]",
|
|
"sqlalchemy",
|
|
]
|
|
|
|
[project.scripts]
|
|
dev = "uvicorn main:app --reload"
|
|
```
|