Download app/api/batches.py from nvikou/Sheetly: direct link, hf CLI and curl.
- Browser
- Download file 3.14 kB
-
https://huggingface.co/spaces/nvikou/Sheetly/resolve/main/app/api/batches.py
- Command line
-
hf download hf://spaces/nvikou/Sheetly/app/api/batches.py
-
curl -L -o batches.py https://huggingface.co/spaces/nvikou/Sheetly/resolve/main/app/api/batches.py
3.14 kB
| """Batch upload API.""" | |
| from __future__ import annotations | |
| import uuid | |
| from pathlib import Path | |
| from fastapi import APIRouter, Depends, File, HTTPException, UploadFile | |
| from sqlalchemy import select | |
| from sqlalchemy.ext.asyncio import AsyncSession | |
| from app.api.serializers import batch_out, document_out | |
| from app.db import get_session | |
| from app.models import Batch, Document | |
| from app.schemas import BatchOut, DocStatus, DocumentOut | |
| from app.services.ingest import ensure_upload_dir, save_upload | |
| from app.services.paths import resolve_stored_path, to_stored_path | |
| from app.services.queue import enqueue_batch | |
| router = APIRouter(prefix="/api/batches", tags=["batches"]) | |
| async def create_batch( | |
| files: list[UploadFile] = File(...), | |
| session: AsyncSession = Depends(get_session), | |
| ) -> BatchOut: | |
| """Upload one or more files / ZIPs as a batch.""" | |
| if not files: | |
| raise HTTPException(400, "No files uploaded") | |
| batch_id = str(uuid.uuid4()) | |
| root = ensure_upload_dir() | |
| batch_dir = root / batch_id | |
| batch_dir.mkdir(parents=True, exist_ok=True) | |
| saved: list[tuple[str, Path, str]] = [] | |
| errors: list[str] = [] | |
| for upload in files: | |
| try: | |
| saved.extend(await save_upload(upload, batch_dir)) | |
| except ValueError as exc: | |
| errors.append(str(exc)) | |
| if not saved: | |
| raise HTTPException( | |
| 400, | |
| "; ".join(errors) or "No valid files", | |
| ) | |
| batch = Batch( | |
| id=batch_id, | |
| status="pending", | |
| total=len(saved), | |
| processed=0, | |
| failed=0, | |
| ) | |
| session.add(batch) | |
| for name, path, mime in saved: | |
| session.add( | |
| Document( | |
| id=str(uuid.uuid4()), | |
| batch_id=batch_id, | |
| filename=name, | |
| file_path=to_stored_path(path), | |
| mime_type=mime, | |
| status=DocStatus.QUEUED.value, | |
| ) | |
| ) | |
| await session.commit() | |
| await session.refresh(batch) | |
| enqueue_batch(batch_id) | |
| return batch_out(batch) | |
| async def get_batch( | |
| batch_id: str, | |
| session: AsyncSession = Depends(get_session), | |
| ) -> BatchOut: | |
| """Batch status and progress.""" | |
| batch = await session.get(Batch, batch_id) | |
| if not batch: | |
| raise HTTPException(404, "Batch not found") | |
| return batch_out(batch) | |
| async def list_batch_documents( | |
| batch_id: str, | |
| session: AsyncSession = Depends(get_session), | |
| ) -> list[DocumentOut]: | |
| """Documents belonging to a batch.""" | |
| batch = await session.get(Batch, batch_id) | |
| if not batch: | |
| raise HTTPException(404, "Batch not found") | |
| result = await session.execute( | |
| select(Document).where(Document.batch_id == batch_id) | |
| ) | |
| out = [] | |
| for d in result.scalars().all(): | |
| try: | |
| if resolve_stored_path(d.file_path).is_file(): | |
| out.append(document_out(d)) | |
| except FileNotFoundError: | |
| continue | |
| return out | |