Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/models/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ class DocumentDeleteResponse(BaseModel):
status: str
message: str

class BatchDeleteResponse(BaseModel):
"""Response for batch document deletion endpoint"""
deleted: List[str]
errors: List[Dict[str, str]]


class DocumentDownloadUrlResponse(BaseModel):
"""Response for document download URL endpoint"""
Expand Down
28 changes: 27 additions & 1 deletion core/routes/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Any, Dict, List, Optional, Union

import arq
from fastapi import APIRouter, Depends, Form, HTTPException, Query, Request, UploadFile
from fastapi import APIRouter, Body, Depends, Form, HTTPException, Query, Request, UploadFile

from core.auth_utils import verify_token
from core.database.postgres_database import InvalidMetadataFilterError
Expand All @@ -12,6 +12,7 @@
from core.models.documents import Document
from core.models.request import DocumentPagesRequest, IngestTextRequest, ListDocsRequest, MetadataUpdateRequest
from core.models.responses import (
BatchDeleteResponse,
DocumentDeleteResponse,
DocumentDownloadUrlResponse,
DocumentPagesResponse,
Expand Down Expand Up @@ -254,7 +255,32 @@ async def delete_document(document_id: str, auth: AuthContext = Depends(verify_t
raise HTTPException(status_code=403, detail=str(e))
except TypedMetadataError as exc:
raise HTTPException(status_code=400, detail=str(exc))


@router.delete("/batch", response_model=BatchDeleteResponse)
async def batch_delete_documents(
document_ids: List[str] = Body(..., embed=True),
auth: AuthContext = Depends(verify_token),
):
if not document_ids:
raise HTTPException(status_code=400, detail="No document_ids provided for batch deletion")

deleted: List[str] = []
errors: List[Dict[str, str]] = []

for doc_id in document_ids:
try:
success = await document_service.delete_document(doc_id, auth)
if success:
deleted.append(doc_id)
else:
errors.append({"document_id": doc_id, "error": "Document not found or delete failed"})
except PermissionError as e:
errors.append({"document_id": doc_id, "error": str(e)})
except TypedMetadataError as exc:
errors.append({"document_id": doc_id, "error": str(exc)})

return BatchDeleteResponse(deleted=deleted, errors=errors)

@router.get("/filename/{filename}", response_model=Document)
async def get_document_by_filename(
Expand Down
Loading