Skip to content

Commit 10e910a

Browse files
feat+fix(changelogs+relationships&retrieve): added changelogs and fixed duplicated relationships creation with change to lowercase node properties instead of capitalized
1 parent a0d1d64 commit 10e910a

File tree

22 files changed

+728
-61
lines changed

22 files changed

+728
-61
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "brainapi2"
3-
version = "1.6.16-dev"
3+
version = "1.7.0-dev"
44
description = "Version 1.x.x of the BrainAPI memory layer."
55
authors = [
66
{name = "Christian",email = "[email protected]"}

src/adapters/data.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from typing import List, Tuple
1212
from src.adapters.interfaces.data import DataClient, SearchResult
13-
from src.constants.data import Brain, Observation, StructuredData, TextChunk
13+
from src.constants.data import Brain, KGChanges, Observation, StructuredData, TextChunk
1414

1515

1616
class DataAdapter:
@@ -82,3 +82,11 @@ def get_brains_list(self) -> List[Brain]:
8282
Get the list of brains from the data client.
8383
"""
8484
return self.data.get_brains_list()
85+
86+
def save_kg_changes(
87+
self, kg_changes: KGChanges, brain_id: str = "default"
88+
) -> KGChanges:
89+
"""
90+
Save a KG changes to the data client.
91+
"""
92+
return self.data.save_kg_changes(kg_changes, brain_id)

src/adapters/embeddings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,16 @@ def get_by_ids(
6868
def search_similar_by_ids(
6969
self,
7070
vector_ids: list[str],
71+
brain_id: str,
7172
store: str,
7273
min_similarity: float,
7374
limit: int = 10,
74-
brain_id: str = "default",
7575
) -> list[Vector]:
7676
"""
7777
Search similar vectors by their IDs.
7878
"""
7979
return self.vector_store.search_similar_by_ids(
80-
vector_ids, store, min_similarity, limit, brain_id
80+
vector_ids, brain_id, store, min_similarity, limit
8181
)
8282

8383

src/adapters/graph.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
-----
99
"""
1010

11-
from typing import Optional, Tuple
11+
from typing import Literal, Optional, Tuple
1212
from src.adapters.interfaces.graph import GraphClient
1313
from src.constants.kg import (
1414
IdentificationParams,
@@ -247,5 +247,32 @@ def search_entities(
247247
brain_id, limit, skip, node_labels, node_uuids, query_text
248248
)
249249

250+
def deprecate_relationship(
251+
self,
252+
subject: Node,
253+
predicate: Predicate,
254+
object: Node,
255+
brain_id: str = "default",
256+
) -> Tuple[Node, Predicate, Node] | None:
257+
"""
258+
Deprecate a relationship from the graph.
259+
"""
260+
return self.graph.deprecate_relationship(subject, predicate, object, brain_id)
261+
262+
def update_properties(
263+
self,
264+
uuid: str,
265+
updating: Literal["node", "relationship"],
266+
brain_id: str = "default",
267+
new_properties: dict = {},
268+
properties_to_remove: list[str] = [],
269+
) -> Node | Predicate | None:
270+
"""
271+
Update the properties of a node or relationship in the graph.
272+
"""
273+
return self.graph.update_properties(
274+
uuid, updating, brain_id, new_properties, properties_to_remove
275+
)
276+
250277

251278
_graph_adapter = GraphAdapter()

src/adapters/interfaces/data.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from pydantic import BaseModel
1515

16-
from src.constants.data import Brain, Observation, StructuredData, TextChunk
16+
from src.constants.data import Brain, KGChanges, Observation, StructuredData, TextChunk
1717

1818

1919
class SearchResult(BaseModel):
@@ -91,3 +91,10 @@ def get_brains_list(self) -> List[Brain]:
9191
Get the list of brains from the data client.
9292
"""
9393
raise NotImplementedError("get_brains_list method not implemented")
94+
95+
@abstractmethod
96+
def save_kg_changes(self, kg_changes: KGChanges, brain_id: str) -> KGChanges:
97+
"""
98+
Save a KG changes to the data client.
99+
"""
100+
raise NotImplementedError("save_kg_changes method not implemented")

src/adapters/interfaces/graph.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"""
1010

1111
from abc import ABC, abstractmethod
12-
from typing import Optional, Tuple
12+
from typing import Literal, Optional, Tuple
1313

1414
from src.constants.kg import (
1515
IdentificationParams,
@@ -245,3 +245,30 @@ def search_entities(
245245
Search the entities of the graph.
246246
"""
247247
raise NotImplementedError("search_entities method not implemented")
248+
249+
@abstractmethod
250+
def deprecate_relationship(
251+
self,
252+
subject: Node,
253+
predicate: Predicate,
254+
object: Node,
255+
brain_id: str,
256+
) -> Tuple[Node, Predicate, Node] | None:
257+
"""
258+
Deprecate a relationship from the graph.
259+
"""
260+
raise NotImplementedError("deprecate_relationship method not implemented")
261+
262+
@abstractmethod
263+
def update_properties(
264+
self,
265+
uuid: str,
266+
updating: Literal["node", "relationship"],
267+
brain_id: str,
268+
new_properties: dict,
269+
properties_to_remove: list[str],
270+
) -> Node | Predicate | None:
271+
"""
272+
Update the properties of a node or relationship in the graph.
273+
"""
274+
raise NotImplementedError("update_properties method not implemented")

src/constants/data.py

Lines changed: 126 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"""
1010

1111
from datetime import datetime
12-
from typing import List, Optional
12+
from enum import Enum
13+
from typing import Annotated, Any, List, Literal, Optional, Union
1314
import uuid
1415
from pydantic import BaseModel, Field
1516

@@ -62,24 +63,138 @@ class Observation(BaseModel):
6263
)
6364

6465

65-
class KGChanges(BaseModel):
66+
class KGChangesType(Enum):
6667
"""
67-
KG changes model.
68+
KG changes type.
6869
"""
6970

70-
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
71+
RELATIONSHIP_CREATED = "relationship_created"
72+
RELATIONSHIP_DEPRECATED = "relationship_deprecated"
73+
NODE_PROPERTIES_UPDATED = "node_properties_updated"
74+
RELATIONSHIP_PROPERTIES_UPDATED = "relationship_properties_updated"
75+
76+
77+
class PartialNode(BaseModel):
78+
"""
79+
Partial node model.
80+
"""
7181

72-
node_ids: Optional[List[str]] = Field(
73-
default=None, description="The id of the node that was changed."
82+
uuid: str = Field(description="The id of the node.")
83+
name: str = Field(description="The name of the node.")
84+
labels: List[str] = Field(description="The labels of the node.")
85+
description: Optional[str] = Field(description="The description of the node.")
86+
properties: dict = Field(description="The properties of the node.")
87+
88+
89+
class PartialPredicate(BaseModel):
90+
"""
91+
Partial relationship model.
92+
"""
93+
94+
uuid: str = Field(description="The id of the relationship.")
95+
name: str = Field(description="The name of the relationship.")
96+
description: Optional[str] = Field(
97+
description="The description of the relationship."
98+
)
99+
properties: Optional[dict] = Field(
100+
default=None, description="The properties of the relationship."
101+
)
102+
103+
104+
class KGChangeLogRelationshipCreated(BaseModel):
105+
"""
106+
KG change log relationship created model.
107+
"""
108+
109+
type: Literal[KGChangesType.RELATIONSHIP_CREATED] = Field(
110+
default=KGChangesType.RELATIONSHIP_CREATED,
111+
description="The type of the change.",
112+
)
113+
subject: PartialNode = Field(description="The subject of the relationship.")
114+
predicate: PartialPredicate = Field(
115+
description="The predicate of the relationship."
116+
)
117+
object: PartialNode = Field(description="The object of the relationship.")
118+
119+
120+
class KGChangeLogRelationshipDeprecated(BaseModel):
121+
"""
122+
KG change log relationship deprecated model.
123+
"""
124+
125+
type: Literal[KGChangesType.RELATIONSHIP_DEPRECATED] = Field(
126+
default=KGChangesType.RELATIONSHIP_DEPRECATED,
127+
description="The type of the change.",
128+
)
129+
subject: PartialNode = Field(description="The subject of the relationship.")
130+
predicate: PartialPredicate = Field(
131+
description="The predicate of the relationship."
74132
)
75-
predicate_id: Optional[str] = Field(
76-
default=None, description="The id of the predicate that was changed."
133+
object: PartialNode = Field(description="The object of the relationship.")
134+
new_predicate: Optional[PartialPredicate] = Field(
135+
description="The new predicate of the relationship."
77136
)
78137

79-
changelog: List[dict] = Field(description="The changelog of the changes.")
80-
date: datetime = Field(
138+
139+
class KGChangeLogPredicateUpdatedProperty(BaseModel):
140+
"""
141+
KG change log relationship updated property model.
142+
"""
143+
144+
property: str = Field(description="The property that was updated.")
145+
previous_value: Any = Field(description="The previous value of the property.")
146+
new_value: Any = Field(description="The new value of the property.")
147+
148+
149+
class KGChangeLogNodePropertiesUpdated(BaseModel):
150+
"""
151+
KG change log node properties updated model.
152+
"""
153+
154+
type: Literal[KGChangesType.NODE_PROPERTIES_UPDATED] = Field(
155+
default=KGChangesType.NODE_PROPERTIES_UPDATED,
156+
description="The type of the change.",
157+
)
158+
node: PartialNode = Field(description="The node that was updated.")
159+
properties: List[KGChangeLogPredicateUpdatedProperty] = Field(
160+
description="The properties that were updated."
161+
)
162+
163+
164+
class KGChangeLogPredicatePropertiesUpdated(BaseModel):
165+
"""
166+
KG change log relationship properties updated model.
167+
"""
168+
169+
type: Literal[KGChangesType.RELATIONSHIP_PROPERTIES_UPDATED] = Field(
170+
default=KGChangesType.RELATIONSHIP_PROPERTIES_UPDATED,
171+
description="The type of the change.",
172+
)
173+
predicate: PartialPredicate = Field(description="The predicate that was updated.")
174+
properties: List[KGChangeLogPredicateUpdatedProperty] = Field(
175+
description="The properties that were updated."
176+
)
177+
178+
179+
class KGChanges(BaseModel):
180+
"""
181+
KG changes model.
182+
"""
183+
184+
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
185+
type: KGChangesType = Field(description="The type of the changes.")
186+
change: Annotated[
187+
Union[
188+
KGChangeLogRelationshipCreated,
189+
KGChangeLogRelationshipDeprecated,
190+
KGChangeLogNodePropertiesUpdated,
191+
KGChangeLogPredicatePropertiesUpdated,
192+
],
193+
Field(discriminator="type"),
194+
] = Field(description="The change data, discriminated by type.")
195+
timestamp: datetime = Field(
81196
default_factory=datetime.now,
82-
description="The date and time the changes were made.",
197+
description="The timestamp of the changes.",
83198
)
84199

85200

src/constants/kg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Predicate(BaseModel):
4848
Predicate model.
4949
"""
5050

51+
uuid: str = Field(default_factory=lambda: str(uuid.uuid4()))
5152
name: str
5253
description: str
5354
last_updated: datetime = Field(

0 commit comments

Comments
 (0)