mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
change document api to uset get by id
This commit is contained in:
@@ -49,21 +49,21 @@ async def list_documents(
|
||||
return [DocumentCreateResponse.model_validate(doc.__dict__) for doc in documents]
|
||||
|
||||
|
||||
@router.get("/{path:path}", response_model=DocumentResponse)
|
||||
@router.get("/{id:int}", response_model=DocumentResponse)
|
||||
async def get_document(
|
||||
path: str,
|
||||
id: int,
|
||||
service: DocumentServiceDep,
|
||||
) -> DocumentResponse:
|
||||
"""Get a document by path."""
|
||||
"""Get a document by ID."""
|
||||
try:
|
||||
document, content = await service.read_document(path)
|
||||
document, content = await service.read_document_by_id(id)
|
||||
doc_dict = document.__dict__ | {"content": content}
|
||||
response = DocumentResponse.model_validate(doc_dict)
|
||||
return response
|
||||
except DocumentNotFoundError:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Document not found: {path}"
|
||||
detail=f"Document not found: {id}"
|
||||
)
|
||||
except DocumentWriteError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import hashlib
|
||||
from datetime import datetime, UTC
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict, Any, List
|
||||
from typing import Optional, Dict, Any, List, Tuple
|
||||
|
||||
import yaml
|
||||
from loguru import logger
|
||||
@@ -60,18 +60,16 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
except Exception as e:
|
||||
raise DocumentWriteError(f"Failed to create directory: {parent}: {e}")
|
||||
|
||||
async def add_frontmatter(self, content: str, doc_id: int, metadata: Optional[Dict[str, Any]] = None) -> str:
|
||||
async def add_frontmatter(
|
||||
self, content: str, doc_id: int, metadata: Optional[Dict[str, Any]] = None
|
||||
) -> str:
|
||||
"""Add frontmatter to document content."""
|
||||
# Generate frontmatter with timestamps
|
||||
now = datetime.now(UTC).isoformat()
|
||||
frontmatter = {
|
||||
"id": doc_id,
|
||||
"created": now,
|
||||
"modified": now
|
||||
}
|
||||
frontmatter = {"id": doc_id, "created": now, "modified": now}
|
||||
if metadata:
|
||||
frontmatter.update(metadata)
|
||||
|
||||
|
||||
yaml_fm = yaml.dump(frontmatter, sort_keys=False)
|
||||
return f"---\n{yaml_fm}---\n\n{content}"
|
||||
|
||||
@@ -104,10 +102,7 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
|
||||
try:
|
||||
# 1. Create initial DB record to get ID
|
||||
doc = await self.repository.create({
|
||||
"path": str(path),
|
||||
"doc_metadata": metadata
|
||||
})
|
||||
doc = await self.repository.create({"path": str(path), "doc_metadata": metadata})
|
||||
|
||||
# 2. Add frontmatter with DB-generated ID
|
||||
content_with_frontmatter = await self.add_frontmatter(content, doc.id, metadata)
|
||||
@@ -122,11 +117,41 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
|
||||
except Exception as e:
|
||||
# Clean up on any failure
|
||||
if 'doc' in locals(): # DB record was created
|
||||
if "doc" in locals(): # DB record was created
|
||||
await self.repository.delete(doc.id)
|
||||
file_path.unlink(missing_ok=True)
|
||||
raise DocumentWriteError(f"Failed to create document: {e}")
|
||||
|
||||
async def read_document_by_id(self, id: int) -> Tuple[Document, str]:
|
||||
"""
|
||||
Read a document and its content by ID.
|
||||
|
||||
Args:
|
||||
id: Document ID
|
||||
|
||||
Returns:
|
||||
Tuple of (document record, content)
|
||||
|
||||
Raises:
|
||||
DocumentNotFoundError: If document doesn't exist
|
||||
DocumentError: If file read fails
|
||||
"""
|
||||
logger.debug(f"Reading document with ID {id}")
|
||||
|
||||
# Get document record
|
||||
query = select(Document).where(Document.id == id)
|
||||
doc = await self.repository.find_one(query)
|
||||
if not doc:
|
||||
raise DocumentNotFoundError(f"Document not found: {id}")
|
||||
|
||||
# Read content since file is source of truth
|
||||
try:
|
||||
file_path = Path(doc.path)
|
||||
content = file_path.read_text()
|
||||
return doc, content
|
||||
except Exception as e:
|
||||
raise DocumentError(f"Failed to read document {id}: {e}")
|
||||
|
||||
async def read_document(self, path: str) -> tuple[Document, str]:
|
||||
"""
|
||||
Read a document and its content.
|
||||
@@ -167,15 +192,15 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
) -> Document:
|
||||
"""
|
||||
Update a document using its ID.
|
||||
|
||||
|
||||
Args:
|
||||
id: Document ID
|
||||
content: New content
|
||||
metadata: Optional new metadata
|
||||
|
||||
|
||||
Returns:
|
||||
Updated document record
|
||||
|
||||
|
||||
Raises:
|
||||
DocumentNotFoundError: If document doesn't exist
|
||||
DocumentWriteError: If update fails
|
||||
@@ -189,11 +214,7 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
raise DocumentNotFoundError(f"Document not found: {id}")
|
||||
|
||||
# Use existing path to update file
|
||||
return await self.update_document(
|
||||
path=document.path,
|
||||
content=content,
|
||||
metadata=metadata
|
||||
)
|
||||
return await self.update_document(path=document.path, content=content, metadata=metadata)
|
||||
|
||||
async def update_document(
|
||||
self, path: str, content: str, metadata: Optional[Dict[str, Any]] = None
|
||||
@@ -239,7 +260,7 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
checksum = await self.compute_checksum(content)
|
||||
update_data = {"checksum": checksum}
|
||||
if metadata is not None:
|
||||
update_data["doc_metadata"] = metadata
|
||||
update_data["doc_metadata"] = metadata # pyright: ignore [reportArgumentType]
|
||||
|
||||
updated_document = await self.repository.update(doc.id, update_data)
|
||||
assert updated_document is not None, f"Could not update document {doc.id}"
|
||||
@@ -272,4 +293,4 @@ class DocumentService(BaseService[DocumentRepository]):
|
||||
# Delete database record if it exists
|
||||
doc = await self.repository.find_by_path(str(path))
|
||||
if doc:
|
||||
await self.repository.delete(doc.id)
|
||||
await self.repository.delete(doc.id)
|
||||
|
||||
Reference in New Issue
Block a user