From 84ddb7f637f654e4a1214eebe433ae4f918d18ec Mon Sep 17 00:00:00 2001 From: phernandez Date: Mon, 23 Dec 2024 09:37:52 -0600 Subject: [PATCH] Use KnowledgeService in /knowledge routes --- src/basic_memory/api/routers/knowledge.py | 29 +++++++------- src/basic_memory/deps.py | 39 +++++++++++++++++++ .../services/knowledge/entities.py | 7 ++-- .../services/observation_service.py | 7 ---- 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/basic_memory/api/routers/knowledge.py b/src/basic_memory/api/routers/knowledge.py index 6b0ccade..d6d0b82d 100644 --- a/src/basic_memory/api/routers/knowledge.py +++ b/src/basic_memory/api/routers/knowledge.py @@ -3,7 +3,10 @@ from fastapi import APIRouter, HTTPException from loguru import logger -from basic_memory.deps import EntityServiceDep, RelationServiceDep, ObservationServiceDep +from basic_memory.deps import ( + EntityServiceDep, + KnowledgeServiceDep, +) from basic_memory.schemas import ( CreateEntityRequest, CreateEntityResponse, @@ -34,10 +37,10 @@ router = APIRouter(prefix="/knowledge", tags=["knowledge"]) @router.post("/entities", response_model=CreateEntityResponse) async def create_entities( - data: CreateEntityRequest, entity_service: EntityServiceDep + data: CreateEntityRequest, knowledge_service: KnowledgeServiceDep ) -> CreateEntityResponse: """Create new entities in the knowledge graph.""" - entities = await entity_service.create_entities(data.entities) + entities = await knowledge_service.create_entities(data.entities) return CreateEntityResponse( entities=[EntityResponse.model_validate(entity) for entity in entities] ) @@ -45,10 +48,10 @@ async def create_entities( @router.post("/relations", response_model=CreateRelationsResponse) async def create_relations( - data: CreateRelationsRequest, relation_service: RelationServiceDep + data: CreateRelationsRequest, knowledge_service: KnowledgeServiceDep ) -> CreateRelationsResponse: """Create relations between entities.""" - relations = await relation_service.create_relations(data.relations) + relations = await knowledge_service.create_relations(data.relations) return CreateRelationsResponse( relations=[RelationResponse.model_validate(relation) for relation in relations] ) @@ -56,11 +59,11 @@ async def create_relations( @router.post("/observations", response_model=AddObservationsResponse) async def add_observations( - data: AddObservationsRequest, observation_service: ObservationServiceDep + data: AddObservationsRequest, knowledge_service: KnowledgeServiceDep ) -> AddObservationsResponse: """Add observations to an entity.""" logger.debug(f"Adding observations to entity: {data.entity_id}") - observations = await observation_service.add_observations( + observations = await knowledge_service.add_observations( data.entity_id, data.observations, data.context ) return AddObservationsResponse( @@ -112,26 +115,26 @@ async def open_nodes(data: OpenNodesRequest, entity_service: EntityServiceDep) - @router.post("/entities/delete", response_model=DeleteEntitiesResponse) async def delete_entity( - data: DeleteEntitiesRequest, entity_service: EntityServiceDep + data: DeleteEntitiesRequest, knowledge_service: KnowledgeServiceDep ) -> DeleteEntitiesResponse: """Delete a specific entity by ID.""" - deleted = await entity_service.delete_entities(data.entity_ids) + deleted = await knowledge_service.delete_entities(data.entity_ids) return DeleteEntitiesResponse(deleted=deleted) @router.post("/observations/delete", response_model=DeleteObservationsResponse) async def delete_observations( - data: DeleteObservationsRequest, observation_service: ObservationServiceDep + data: DeleteObservationsRequest, knowledge_service: KnowledgeServiceDep ) -> DeleteObservationsResponse: """Delete observations from an entity.""" entity_id = data.entity_id - deleted = await observation_service.delete_observations(entity_id, data.deletions) + deleted = await knowledge_service.delete_observations(entity_id, data.deletions) return DeleteObservationsResponse(deleted=deleted) @router.post("/relations/delete", response_model=DeleteRelationsResponse) async def delete_relations( - data: DeleteRelationsRequest, relation_service: RelationServiceDep + data: DeleteRelationsRequest, knowledge_service: KnowledgeServiceDep ) -> DeleteRelationsResponse: """Delete relations between entities.""" to_delete = [ @@ -142,5 +145,5 @@ async def delete_relations( } for relation in data.relations ] - deleted = await relation_service.delete_relations(to_delete) + deleted = await knowledge_service.delete_relations(to_delete) return DeleteRelationsResponse(deleted=deleted) diff --git a/src/basic_memory/deps.py b/src/basic_memory/deps.py index 52727d42..650d15f7 100644 --- a/src/basic_memory/deps.py +++ b/src/basic_memory/deps.py @@ -13,6 +13,7 @@ from sqlalchemy.ext.asyncio import ( from basic_memory import db from basic_memory.config import ProjectConfig, config from basic_memory.db import DatabaseType +from basic_memory.markdown.knowledge_writer import KnowledgeWriter from basic_memory.repository.document_repository import DocumentRepository from basic_memory.repository.entity_repository import EntityRepository from basic_memory.repository.observation_repository import ObservationRepository @@ -23,6 +24,8 @@ from basic_memory.services import ( RelationService, DocumentService, ) +from basic_memory.services.file_service import FileService +from basic_memory.services.knowledge import KnowledgeService ## project @@ -144,3 +147,39 @@ async def get_document_service(document_repository: DocumentRepositoryDep) -> Do DocumentServiceDep = Annotated[DocumentService, Depends(get_document_service)] + + +async def get_file_service() -> FileService: + return FileService() + + +FileServiceDep = Annotated[FileService, Depends(get_file_service)] + + +async def get_knowledge_writer() -> KnowledgeWriter: + return KnowledgeWriter() + + +KnowledgeWriterDep = Annotated[KnowledgeWriter, Depends(get_knowledge_writer)] + + +async def get_knowledge_service( + entity_service: EntityServiceDep, + observation_service: ObservationServiceDep, + relation_service: RelationServiceDep, + file_service: FileServiceDep, + knowledge_writer: KnowledgeWriterDep, + test_project_path: ProjectPathDep, +) -> KnowledgeService: + """Create KnowledgeService with dependencies.""" + return KnowledgeService( + entity_service=entity_service, + observation_service=observation_service, + relation_service=relation_service, + file_service=file_service, + knowledge_writer=knowledge_writer, + base_path=test_project_path, + ) + + +KnowledgeServiceDep = Annotated[KnowledgeService, Depends(get_knowledge_service)] diff --git a/src/basic_memory/services/knowledge/entities.py b/src/basic_memory/services/knowledge/entities.py index c2589594..6e318b0a 100644 --- a/src/basic_memory/services/knowledge/entities.py +++ b/src/basic_memory/services/knowledge/entities.py @@ -1,6 +1,5 @@ """Entity operations for knowledge service.""" -from pathlib import Path from typing import Sequence, List from loguru import logger @@ -31,9 +30,9 @@ class EntityOperations(FileOperations): except Exception as e: # Clean up on any failure if "db_entity" in locals(): - await self.entity_service.delete_entity(db_entity.id) + await self.entity_service.delete_entity(db_entity.id) # pyright: ignore [reportPossiblyUnboundVariable] if "path" in locals(): - await self.file_service.delete_file(path) + await self.file_service.delete_file(path) # pyright: ignore [reportUndefinedVariable] # noqa: F821 logger.error(f"Failed to create entity: {e}") raise @@ -86,4 +85,4 @@ class EntityOperations(FileOperations): success = False continue - return success \ No newline at end of file + return success diff --git a/src/basic_memory/services/observation_service.py b/src/basic_memory/services/observation_service.py index 2bd2b409..689d10e1 100644 --- a/src/basic_memory/services/observation_service.py +++ b/src/basic_memory/services/observation_service.py @@ -18,19 +18,12 @@ class ObservationService(BaseService[ObservationRepository]): def __init__(self, observation_repository: ObservationRepository): super().__init__(observation_repository) - # self.entity_service = entity_service async def add_observations( self, entity_id: int, observations: List[str], context: str | None = None ) -> List[ObservationModel]: """Add multiple observations to an entity.""" logger.debug(f"Adding {len(observations)} observations to entity: {entity_id}") - - # # Check if entity exists first - # entity = await self.entity_service.get_entity(entity_id) - # if not entity: - # raise EntityNotFoundError(f"Entity not found: {entity_id}") - return await self.repository.create_all( [ dict(entity_id=entity_id, content=observation, context=context)