feat(avocet): POST /api/label endpoint

This commit is contained in:
pyr0ball 2026-03-03 15:14:04 -08:00
parent c1a6dd4fc5
commit ff27053aa9
2 changed files with 45 additions and 1 deletions

View file

@ -8,7 +8,10 @@ from __future__ import annotations
import json import json
from pathlib import Path from pathlib import Path
from fastapi import FastAPI, Query from datetime import datetime, timezone
from fastapi import FastAPI, HTTPException, Query
from pydantic import BaseModel
_ROOT = Path(__file__).parent.parent _ROOT = Path(__file__).parent.parent
_DATA_DIR: Path = _ROOT / "data" # overridable in tests via set_data_dir() _DATA_DIR: Path = _ROOT / "data" # overridable in tests via set_data_dir()
@ -67,3 +70,23 @@ _last_action: dict | None = None
def get_queue(limit: int = Query(default=10, ge=1, le=50)): def get_queue(limit: int = Query(default=10, ge=1, le=50)):
items = _read_jsonl(_queue_file()) items = _read_jsonl(_queue_file())
return {"items": items[:limit], "total": len(items)} return {"items": items[:limit], "total": len(items)}
class LabelRequest(BaseModel):
id: str
label: str
@app.post("/api/label")
def post_label(req: LabelRequest):
global _last_action
items = _read_jsonl(_queue_file())
match = next((x for x in items if x["id"] == req.id), None)
if not match:
raise HTTPException(404, f"Item {req.id!r} not found in queue")
record = {**match, "label": req.label,
"labeled_at": datetime.now(timezone.utc).isoformat()}
_append_jsonl(_score_file(), record)
_write_jsonl(_queue_file(), [x for x in items if x["id"] != req.id])
_last_action = {"type": "label", "item": record}
return {"ok": True}

View file

@ -52,3 +52,24 @@ def test_queue_empty_when_no_file(client):
r = client.get("/api/queue") r = client.get("/api/queue")
assert r.status_code == 200 assert r.status_code == 200
assert r.json() == {"items": [], "total": 0} assert r.json() == {"items": [], "total": 0}
def test_label_appends_to_score(client, queue_with_items):
from app import api as api_module
r = client.post("/api/label", json={"id": "id0", "label": "interview_scheduled"})
assert r.status_code == 200
records = api_module._read_jsonl(api_module._score_file())
assert len(records) == 1
assert records[0]["id"] == "id0"
assert records[0]["label"] == "interview_scheduled"
assert "labeled_at" in records[0]
def test_label_removes_from_queue(client, queue_with_items):
from app import api as api_module
client.post("/api/label", json={"id": "id0", "label": "rejected"})
queue = api_module._read_jsonl(api_module._queue_file())
assert not any(x["id"] == "id0" for x in queue)
def test_label_unknown_id_returns_404(client, queue_with_items):
r = client.post("/api/label", json={"id": "unknown", "label": "neutral"})
assert r.status_code == 404