Spaces:
Running
Running
| import logging | |
| from fastapi import APIRouter, BackgroundTasks, HTTPException | |
| from pydantic import BaseModel | |
| from typing import List, Optional, Dict | |
| from app.services.note_store import create_note, get_note | |
| from app.jobs.async_enrichment_job import enrich_note | |
| from app.models.enums import NoteType, NoteStatus | |
| from app.utils.time import now_ts | |
| router = APIRouter(prefix="/internal/notes", tags=["internal"]) | |
| logger = logging.getLogger(__name__) | |
| class NoteTextInternalCreateRequest(BaseModel): | |
| note_id: str | |
| raw_text: str | |
| folder_id: Optional[str] = None | |
| generate: List[str] = [] | |
| async def create_text_note_internal(req: NoteTextInternalCreateRequest, bg: BackgroundTasks): | |
| """ | |
| Idempotent create for text notes: | |
| - If note exists -> return current status | |
| - Else create note with provided `note_id` and optionally enqueue enrichment | |
| """ | |
| now = now_ts() | |
| allowed = {"normalize", "keywords", "summary", "mindmap"} | |
| if not set(req.generate).issubset(allowed): | |
| raise HTTPException(400, "Invalid generate task") | |
| # IDEMPOTENT CHECK | |
| existing = get_note(req.note_id) | |
| if existing: | |
| logger.info("Note already exists, skip create note_id=%s", req.note_id) | |
| return { | |
| "note_id": req.note_id, | |
| "status": existing.get("status"), | |
| } | |
| has_enrichment = bool(req.generate) | |
| note = { | |
| "note_id": req.note_id, | |
| "type": NoteType.text, | |
| "raw_text": req.raw_text, | |
| "folder_id": req.folder_id, | |
| "status": NoteStatus.processing if has_enrichment else NoteStatus.created, | |
| "created_at": now, | |
| "updated_at": now, | |
| } | |
| # Prepare fields for enrichment if requested | |
| if req.generate: | |
| note.update({ | |
| "normalized_text": None, | |
| "title": None, | |
| "keywords": [], | |
| "summary": None, | |
| "mindmap": None, | |
| "generate": req.generate, | |
| }) | |
| try: | |
| create_note(note) | |
| except ValueError: | |
| # race: another worker created it first | |
| logger.warning("Race create_note, ignore note_id=%s", req.note_id) | |
| existing = get_note(req.note_id) | |
| return { | |
| "note_id": req.note_id, | |
| "status": existing.get("status") if existing else NoteStatus.created, | |
| } | |
| # enqueue enrichment if requested | |
| if req.generate: | |
| try: | |
| bg.add_task(enrich_note, req.note_id, req.generate) | |
| except Exception: | |
| # don't fail the request if enqueue fails; log and continue | |
| logger.exception("Failed to enqueue enrich_note for %s", req.note_id) | |
| return {"note_id": req.note_id, "status": note["status"]} | |