update
This commit is contained in:
@@ -7,32 +7,40 @@ from fastapi import APIRouter, HTTPException
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from agents import provider_available
|
||||
from config import FORMAT_META, PROJECTS_DIR, PROVIDERS
|
||||
from config import PROJECTS_DIR, PROVIDERS
|
||||
from database import (
|
||||
create_guide, delete_guide, get_guide, list_guides,
|
||||
list_progress, set_progress, delete_progress,
|
||||
)
|
||||
from generator import generate_guide, cancel_guide, chat_with_guide
|
||||
from generator import (
|
||||
generate_guide, cancel_guide, chat_with_guide,
|
||||
generate_bausteine, bausteine_status, active_bausteine, reset_bausteine,
|
||||
)
|
||||
from models import (
|
||||
GuideCreateRequest, GuideResponse,
|
||||
BausteineCreateRequest, BausteineStatusResponse,
|
||||
GuideChatRequest, GuideChatResponse,
|
||||
ProgressUpdate, ProgressResponse, ProjectResponse, ProviderInfo,
|
||||
)
|
||||
from paths import final_html_path, project_dir
|
||||
from paths import bausteine_path, bausteine_topics, guide_content_path, project_dir
|
||||
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
|
||||
@router.get("/formats")
|
||||
async def get_formats():
|
||||
return FORMAT_META
|
||||
|
||||
|
||||
@router.get("/providers", response_model=list[ProviderInfo])
|
||||
async def get_providers():
|
||||
return [{"id": pid, "available": provider_available(pid)} for pid in PROVIDERS]
|
||||
|
||||
|
||||
@router.get("/topics")
|
||||
async def list_topics():
|
||||
guides = await list_guides()
|
||||
topics = {g["topic"] for g in guides}
|
||||
topics.update(bausteine_topics())
|
||||
topics.update(job["topic"] for job in active_bausteine())
|
||||
return sorted(topics)
|
||||
|
||||
|
||||
def _safe_project_name(name: str) -> str:
|
||||
if not name or "/" in name or "\\" in name or ".." in name or "\x00" in name:
|
||||
raise HTTPException(400, "Ungültiger Projektname")
|
||||
@@ -56,8 +64,39 @@ async def remove_project(name: str):
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
# --- Bausteine ---
|
||||
|
||||
@router.get("/bausteine/status", response_model=BausteineStatusResponse)
|
||||
async def get_bausteine_status(topic: str):
|
||||
return bausteine_status(topic)
|
||||
|
||||
|
||||
@router.get("/bausteine/active")
|
||||
async def get_active_bausteine():
|
||||
return active_bausteine()
|
||||
|
||||
|
||||
@router.post("/bausteine")
|
||||
async def create_bausteine(req: BausteineCreateRequest):
|
||||
topic = req.topic.strip()
|
||||
if bausteine_status(topic)["generating"]:
|
||||
return {"ok": True, "status": "already_generating"}
|
||||
asyncio.create_task(generate_bausteine(topic, req.instructions.strip(), req.provider))
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.delete("/bausteine")
|
||||
async def remove_bausteine(topic: str):
|
||||
reset_bausteine(topic)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
# --- Guides ---
|
||||
|
||||
@router.post("/guides", response_model=GuideResponse)
|
||||
async def create(req: GuideCreateRequest):
|
||||
if not bausteine_path(req.topic.strip()).exists():
|
||||
raise HTTPException(400, "Erst Bausteine erstellen")
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
guide = {
|
||||
"id": str(uuid.uuid4()),
|
||||
@@ -87,17 +126,17 @@ async def get_one(guide_id: str):
|
||||
return guide
|
||||
|
||||
|
||||
@router.get("/guides/{guide_id}/html")
|
||||
async def download_html(guide_id: str):
|
||||
@router.get("/guides/{guide_id}/content")
|
||||
async def guide_content(guide_id: str):
|
||||
guide = await get_guide(guide_id)
|
||||
if guide is None:
|
||||
raise HTTPException(404, "Guide nicht gefunden")
|
||||
if guide["status"] != "done":
|
||||
raise HTTPException(404, "HTML nicht verfügbar")
|
||||
html_path = final_html_path(guide["topic"], guide["format"])
|
||||
if not html_path.exists():
|
||||
raise HTTPException(404, "Inhalt nicht verfügbar")
|
||||
path = guide_content_path(guide["topic"], guide["format"])
|
||||
if not path.exists():
|
||||
raise HTTPException(404, "Datei nicht gefunden")
|
||||
return FileResponse(html_path, media_type="text/html", content_disposition_type="inline")
|
||||
return FileResponse(path, media_type="application/json")
|
||||
|
||||
|
||||
@router.post("/guides/{guide_id}/chat", response_model=GuideChatResponse)
|
||||
@@ -126,9 +165,7 @@ async def remove(guide_id: str):
|
||||
guide = await get_guide(guide_id)
|
||||
if guide is None:
|
||||
raise HTTPException(404, "Guide nicht gefunden")
|
||||
html_path = final_html_path(guide["topic"], guide["format"])
|
||||
html_path.unlink(missing_ok=True)
|
||||
html_path.with_suffix(".bausteine.md").unlink(missing_ok=True)
|
||||
guide_content_path(guide["topic"], guide["format"]).unlink(missing_ok=True)
|
||||
await delete_progress(guide_id)
|
||||
await delete_guide(guide_id)
|
||||
return {"ok": True}
|
||||
|
||||
Reference in New Issue
Block a user