graphiti-core 0.21.0rc2__py3-none-any.whl → 0.21.0rc4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphiti-core might be problematic. Click here for more details.
- graphiti_core/driver/driver.py +9 -0
- graphiti_core/driver/falkordb_driver.py +111 -0
- graphiti_core/graph_queries.py +35 -6
- graphiti_core/graphiti.py +2 -2
- graphiti_core/helpers.py +2 -2
- graphiti_core/search/search_utils.py +2 -0
- graphiti_core/utils/bulk_utils.py +19 -7
- {graphiti_core-0.21.0rc2.dist-info → graphiti_core-0.21.0rc4.dist-info}/METADATA +1 -1
- {graphiti_core-0.21.0rc2.dist-info → graphiti_core-0.21.0rc4.dist-info}/RECORD +11 -11
- {graphiti_core-0.21.0rc2.dist-info → graphiti_core-0.21.0rc4.dist-info}/WHEEL +0 -0
- {graphiti_core-0.21.0rc2.dist-info → graphiti_core-0.21.0rc4.dist-info}/licenses/LICENSE +0 -0
graphiti_core/driver/driver.py
CHANGED
|
@@ -311,3 +311,12 @@ class GraphDriver(ABC):
|
|
|
311
311
|
return success if failed == 0 else success
|
|
312
312
|
|
|
313
313
|
return 0
|
|
314
|
+
|
|
315
|
+
def build_fulltext_query(
|
|
316
|
+
self, query: str, group_ids: list[str] | None = None, max_query_length: int = 128
|
|
317
|
+
) -> str:
|
|
318
|
+
"""
|
|
319
|
+
Specific fulltext query builder for database providers.
|
|
320
|
+
Only implemented by providers that need custom fulltext query building.
|
|
321
|
+
"""
|
|
322
|
+
raise NotImplementedError(f'build_fulltext_query not implemented for {self.provider}')
|
|
@@ -36,6 +36,42 @@ from graphiti_core.utils.datetime_utils import convert_datetimes_to_strings
|
|
|
36
36
|
|
|
37
37
|
logger = logging.getLogger(__name__)
|
|
38
38
|
|
|
39
|
+
STOPWORDS = [
|
|
40
|
+
'a',
|
|
41
|
+
'is',
|
|
42
|
+
'the',
|
|
43
|
+
'an',
|
|
44
|
+
'and',
|
|
45
|
+
'are',
|
|
46
|
+
'as',
|
|
47
|
+
'at',
|
|
48
|
+
'be',
|
|
49
|
+
'but',
|
|
50
|
+
'by',
|
|
51
|
+
'for',
|
|
52
|
+
'if',
|
|
53
|
+
'in',
|
|
54
|
+
'into',
|
|
55
|
+
'it',
|
|
56
|
+
'no',
|
|
57
|
+
'not',
|
|
58
|
+
'of',
|
|
59
|
+
'on',
|
|
60
|
+
'or',
|
|
61
|
+
'such',
|
|
62
|
+
'that',
|
|
63
|
+
'their',
|
|
64
|
+
'then',
|
|
65
|
+
'there',
|
|
66
|
+
'these',
|
|
67
|
+
'they',
|
|
68
|
+
'this',
|
|
69
|
+
'to',
|
|
70
|
+
'was',
|
|
71
|
+
'will',
|
|
72
|
+
'with',
|
|
73
|
+
]
|
|
74
|
+
|
|
39
75
|
|
|
40
76
|
class FalkorDriverSession(GraphDriverSession):
|
|
41
77
|
provider = GraphProvider.FALKORDB
|
|
@@ -167,3 +203,78 @@ class FalkorDriver(GraphDriver):
|
|
|
167
203
|
cloned = FalkorDriver(falkor_db=self.client, database=database)
|
|
168
204
|
|
|
169
205
|
return cloned
|
|
206
|
+
|
|
207
|
+
def sanitize(self, query: str) -> str:
|
|
208
|
+
"""
|
|
209
|
+
Replace FalkorDB special characters with whitespace.
|
|
210
|
+
Based on FalkorDB tokenization rules: ,.<>{}[]"':;!@#$%^&*()-+=~
|
|
211
|
+
"""
|
|
212
|
+
# FalkorDB separator characters that break text into tokens
|
|
213
|
+
separator_map = str.maketrans(
|
|
214
|
+
{
|
|
215
|
+
',': ' ',
|
|
216
|
+
'.': ' ',
|
|
217
|
+
'<': ' ',
|
|
218
|
+
'>': ' ',
|
|
219
|
+
'{': ' ',
|
|
220
|
+
'}': ' ',
|
|
221
|
+
'[': ' ',
|
|
222
|
+
']': ' ',
|
|
223
|
+
'"': ' ',
|
|
224
|
+
"'": ' ',
|
|
225
|
+
':': ' ',
|
|
226
|
+
';': ' ',
|
|
227
|
+
'!': ' ',
|
|
228
|
+
'@': ' ',
|
|
229
|
+
'#': ' ',
|
|
230
|
+
'$': ' ',
|
|
231
|
+
'%': ' ',
|
|
232
|
+
'^': ' ',
|
|
233
|
+
'&': ' ',
|
|
234
|
+
'*': ' ',
|
|
235
|
+
'(': ' ',
|
|
236
|
+
')': ' ',
|
|
237
|
+
'-': ' ',
|
|
238
|
+
'+': ' ',
|
|
239
|
+
'=': ' ',
|
|
240
|
+
'~': ' ',
|
|
241
|
+
'?': ' ',
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
sanitized = query.translate(separator_map)
|
|
245
|
+
# Clean up multiple spaces
|
|
246
|
+
sanitized = ' '.join(sanitized.split())
|
|
247
|
+
return sanitized
|
|
248
|
+
|
|
249
|
+
def build_fulltext_query(
|
|
250
|
+
self, query: str, group_ids: list[str] | None = None, max_query_length: int = 128
|
|
251
|
+
) -> str:
|
|
252
|
+
"""
|
|
253
|
+
Build a fulltext query string for FalkorDB using RedisSearch syntax.
|
|
254
|
+
FalkorDB uses RedisSearch-like syntax where:
|
|
255
|
+
- Field queries use @ prefix: @field:value
|
|
256
|
+
- Multiple values for same field: (@field:value1|value2)
|
|
257
|
+
- Text search doesn't need @ prefix for content fields
|
|
258
|
+
- AND is implicit with space: (@group_id:value) (text)
|
|
259
|
+
- OR uses pipe within parentheses: (@group_id:value1|value2)
|
|
260
|
+
"""
|
|
261
|
+
if group_ids is None or len(group_ids) == 0:
|
|
262
|
+
group_filter = ''
|
|
263
|
+
else:
|
|
264
|
+
group_values = '|'.join(group_ids)
|
|
265
|
+
group_filter = f'(@group_id:{group_values})'
|
|
266
|
+
|
|
267
|
+
sanitized_query = self.sanitize(query)
|
|
268
|
+
|
|
269
|
+
# Remove stopwords from the sanitized query
|
|
270
|
+
query_words = sanitized_query.split()
|
|
271
|
+
filtered_words = [word for word in query_words if word.lower() not in STOPWORDS]
|
|
272
|
+
sanitized_query = ' | '.join(filtered_words)
|
|
273
|
+
|
|
274
|
+
# If the query is too long return no query
|
|
275
|
+
if len(sanitized_query.split(' ')) + len(group_ids or '') >= max_query_length:
|
|
276
|
+
return ''
|
|
277
|
+
|
|
278
|
+
full_query = group_filter + ' (' + sanitized_query + ')'
|
|
279
|
+
|
|
280
|
+
return full_query
|
graphiti_core/graph_queries.py
CHANGED
|
@@ -71,12 +71,41 @@ def get_range_indices(provider: GraphProvider) -> list[LiteralString]:
|
|
|
71
71
|
|
|
72
72
|
def get_fulltext_indices(provider: GraphProvider) -> list[LiteralString]:
|
|
73
73
|
if provider == GraphProvider.FALKORDB:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
from typing import cast
|
|
75
|
+
|
|
76
|
+
from graphiti_core.driver.falkordb_driver import STOPWORDS
|
|
77
|
+
|
|
78
|
+
# Convert to string representation for embedding in queries
|
|
79
|
+
stopwords_str = str(STOPWORDS)
|
|
80
|
+
|
|
81
|
+
# Use type: ignore to satisfy LiteralString requirement while maintaining single source of truth
|
|
82
|
+
return cast(
|
|
83
|
+
list[LiteralString],
|
|
84
|
+
[
|
|
85
|
+
f"""CALL db.idx.fulltext.createNodeIndex(
|
|
86
|
+
{{
|
|
87
|
+
label: 'Episodic',
|
|
88
|
+
stopwords: {stopwords_str}
|
|
89
|
+
}},
|
|
90
|
+
'content', 'source', 'source_description', 'group_id'
|
|
91
|
+
)""",
|
|
92
|
+
f"""CALL db.idx.fulltext.createNodeIndex(
|
|
93
|
+
{{
|
|
94
|
+
label: 'Entity',
|
|
95
|
+
stopwords: {stopwords_str}
|
|
96
|
+
}},
|
|
97
|
+
'name', 'summary', 'group_id'
|
|
98
|
+
)""",
|
|
99
|
+
f"""CALL db.idx.fulltext.createNodeIndex(
|
|
100
|
+
{{
|
|
101
|
+
label: 'Community',
|
|
102
|
+
stopwords: {stopwords_str}
|
|
103
|
+
}},
|
|
104
|
+
'name', 'group_id'
|
|
105
|
+
)""",
|
|
106
|
+
"""CREATE FULLTEXT INDEX FOR ()-[e:RELATES_TO]-() ON (e.name, e.fact, e.group_id)""",
|
|
107
|
+
],
|
|
108
|
+
)
|
|
80
109
|
|
|
81
110
|
if provider == GraphProvider.KUZU:
|
|
82
111
|
return [
|
graphiti_core/graphiti.py
CHANGED
|
@@ -456,12 +456,12 @@ class Graphiti:
|
|
|
456
456
|
start = time()
|
|
457
457
|
now = utc_now()
|
|
458
458
|
|
|
459
|
-
# if group_id is None, use the default group id by the provider
|
|
460
|
-
group_id = group_id or get_default_group_id(self.driver.provider)
|
|
461
459
|
validate_entity_types(entity_types)
|
|
462
460
|
|
|
463
461
|
validate_excluded_entity_types(excluded_entity_types, entity_types)
|
|
464
462
|
validate_group_id(group_id)
|
|
463
|
+
# if group_id is None, use the default group id by the provider
|
|
464
|
+
group_id = group_id or get_default_group_id(self.driver.provider)
|
|
465
465
|
|
|
466
466
|
previous_episodes = (
|
|
467
467
|
await self.retrieve_episodes(
|
graphiti_core/helpers.py
CHANGED
|
@@ -54,7 +54,7 @@ def get_default_group_id(provider: GraphProvider) -> str:
|
|
|
54
54
|
For most databases, the default group id is an empty string, while there are database types that require a specific default group id.
|
|
55
55
|
"""
|
|
56
56
|
if provider == GraphProvider.FALKORDB:
|
|
57
|
-
return '_'
|
|
57
|
+
return '\\_'
|
|
58
58
|
else:
|
|
59
59
|
return ''
|
|
60
60
|
|
|
@@ -116,7 +116,7 @@ async def semaphore_gather(
|
|
|
116
116
|
return await asyncio.gather(*(_wrap_coroutine(coroutine) for coroutine in coroutines))
|
|
117
117
|
|
|
118
118
|
|
|
119
|
-
def validate_group_id(group_id: str) -> bool:
|
|
119
|
+
def validate_group_id(group_id: str | None) -> bool:
|
|
120
120
|
"""
|
|
121
121
|
Validate that a group_id contains only ASCII alphanumeric characters, dashes, and underscores.
|
|
122
122
|
|
|
@@ -92,6 +92,8 @@ def fulltext_query(query: str, group_ids: list[str] | None, driver: GraphDriver)
|
|
|
92
92
|
if len(query.split(' ')) > MAX_QUERY_LENGTH:
|
|
93
93
|
return ''
|
|
94
94
|
return query
|
|
95
|
+
elif driver.provider == GraphProvider.FALKORDB:
|
|
96
|
+
return driver.build_fulltext_query(query, group_ids, MAX_QUERY_LENGTH)
|
|
95
97
|
group_ids_filter_list = (
|
|
96
98
|
[driver.fulltext_syntax + f'group_id:"{g}"' for g in group_ids]
|
|
97
99
|
if group_ids is not None
|
|
@@ -136,12 +136,14 @@ async def add_nodes_and_edges_bulk_tx(
|
|
|
136
136
|
entity_data: dict[str, Any] = {
|
|
137
137
|
'uuid': node.uuid,
|
|
138
138
|
'name': node.name,
|
|
139
|
-
'name_embedding': node.name_embedding,
|
|
140
139
|
'group_id': node.group_id,
|
|
141
140
|
'summary': node.summary,
|
|
142
141
|
'created_at': node.created_at,
|
|
143
142
|
}
|
|
144
143
|
|
|
144
|
+
if not bool(driver.aoss_client):
|
|
145
|
+
entity_data['name_embedding'] = node.name_embedding
|
|
146
|
+
|
|
145
147
|
entity_data['labels'] = list(set(node.labels + ['Entity']))
|
|
146
148
|
if driver.provider == GraphProvider.KUZU:
|
|
147
149
|
attributes = convert_datetimes_to_strings(node.attributes) if node.attributes else {}
|
|
@@ -161,7 +163,6 @@ async def add_nodes_and_edges_bulk_tx(
|
|
|
161
163
|
'target_node_uuid': edge.target_node_uuid,
|
|
162
164
|
'name': edge.name,
|
|
163
165
|
'fact': edge.fact,
|
|
164
|
-
'fact_embedding': edge.fact_embedding,
|
|
165
166
|
'group_id': edge.group_id,
|
|
166
167
|
'episodes': edge.episodes,
|
|
167
168
|
'created_at': edge.created_at,
|
|
@@ -170,6 +171,9 @@ async def add_nodes_and_edges_bulk_tx(
|
|
|
170
171
|
'invalid_at': edge.invalid_at,
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
if not bool(driver.aoss_client):
|
|
175
|
+
edge_data['fact_embedding'] = edge.fact_embedding
|
|
176
|
+
|
|
173
177
|
if driver.provider == GraphProvider.KUZU:
|
|
174
178
|
attributes = convert_datetimes_to_strings(edge.attributes) if edge.attributes else {}
|
|
175
179
|
edge_data['attributes'] = json.dumps(attributes)
|
|
@@ -195,21 +199,29 @@ async def add_nodes_and_edges_bulk_tx(
|
|
|
195
199
|
else:
|
|
196
200
|
await tx.run(get_episode_node_save_bulk_query(driver.provider), episodes=episodes)
|
|
197
201
|
await tx.run(
|
|
198
|
-
get_entity_node_save_bulk_query(
|
|
202
|
+
get_entity_node_save_bulk_query(
|
|
203
|
+
driver.provider, nodes, has_aoss=bool(driver.aoss_client)
|
|
204
|
+
),
|
|
199
205
|
nodes=nodes,
|
|
200
|
-
has_aoss=bool(driver.aoss_client),
|
|
201
206
|
)
|
|
202
207
|
await tx.run(
|
|
203
208
|
get_episodic_edge_save_bulk_query(driver.provider),
|
|
204
209
|
episodic_edges=[edge.model_dump() for edge in episodic_edges],
|
|
205
210
|
)
|
|
206
211
|
await tx.run(
|
|
207
|
-
get_entity_edge_save_bulk_query(driver.provider),
|
|
212
|
+
get_entity_edge_save_bulk_query(driver.provider, has_aoss=bool(driver.aoss_client)),
|
|
208
213
|
entity_edges=edges,
|
|
209
|
-
has_aoss=bool(driver.aoss_client),
|
|
210
214
|
)
|
|
211
215
|
|
|
212
|
-
if driver.aoss_client:
|
|
216
|
+
if bool(driver.aoss_client):
|
|
217
|
+
for node_data, entity_node in zip(nodes, entity_nodes, strict=True):
|
|
218
|
+
if node_data.get('uuid') == entity_node.uuid:
|
|
219
|
+
node_data['name_embedding'] = entity_node.name_embedding
|
|
220
|
+
|
|
221
|
+
for edge_data, entity_edge in zip(edges, entity_edges, strict=True):
|
|
222
|
+
if edge_data.get('uuid') == entity_edge.uuid:
|
|
223
|
+
edge_data['fact_embedding'] = entity_edge.fact_embedding
|
|
224
|
+
|
|
213
225
|
await driver.save_to_aoss(EPISODE_INDEX_NAME, episodes)
|
|
214
226
|
await driver.save_to_aoss(ENTITY_INDEX_NAME, nodes)
|
|
215
227
|
await driver.save_to_aoss(ENTITY_EDGE_INDEX_NAME, edges)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphiti-core
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.0rc4
|
|
4
4
|
Summary: A temporal graph building library
|
|
5
5
|
Project-URL: Homepage, https://help.getzep.com/graphiti/graphiti/overview
|
|
6
6
|
Project-URL: Repository, https://github.com/getzep/graphiti
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
graphiti_core/__init__.py,sha256=e5SWFkRiaUwfprYIeIgVIh7JDedNiloZvd3roU-0aDY,55
|
|
2
2
|
graphiti_core/edges.py,sha256=PhJm_s28cHLEaIqcw66wP16hOq4P4bVQbC_sESHQkXU,20919
|
|
3
3
|
graphiti_core/errors.py,sha256=cH_v9TPgEPeQE6GFOHIg5TvejpUCBddGarMY2Whxbwc,2707
|
|
4
|
-
graphiti_core/graph_queries.py,sha256=
|
|
5
|
-
graphiti_core/graphiti.py,sha256=
|
|
4
|
+
graphiti_core/graph_queries.py,sha256=ZWMqAo5pwb8PO5ddg4zZ0ArhHWuWV42g3R9ULIxsHOs,8058
|
|
5
|
+
graphiti_core/graphiti.py,sha256=Uxppvzjc-jFO6JCRE3PUlU5B5zUo-jBrC02uETb0-x0,42072
|
|
6
6
|
graphiti_core/graphiti_types.py,sha256=C_p2XwScQlCzo7ets097TrSLs9ATxPZQ4WCsxDS7QHc,1066
|
|
7
|
-
graphiti_core/helpers.py,sha256=
|
|
7
|
+
graphiti_core/helpers.py,sha256=q8kbL9gz8igdlh-oMUS-ylUyeMlXZb-ccf-HQkrES_0,5184
|
|
8
8
|
graphiti_core/nodes.py,sha256=wYLQcVEXvQMxTpTc9LWSoPTzzaoUOm0rl07c9wS1XSY,30323
|
|
9
9
|
graphiti_core/py.typed,sha256=vlmmzQOt7bmeQl9L3XJP4W6Ry0iiELepnOrinKz5KQg,79
|
|
10
10
|
graphiti_core/cross_encoder/__init__.py,sha256=hry59vz21x-AtGZ0MJ7ugw0HTwJkXiddpp_Yqnwsen0,723
|
|
@@ -13,8 +13,8 @@ graphiti_core/cross_encoder/client.py,sha256=KLsbfWKOEaAV3adFe3XZlAeb-gje9_sVKCV
|
|
|
13
13
|
graphiti_core/cross_encoder/gemini_reranker_client.py,sha256=hmITG5YIib52nrKvINwRi4xTfAO1U4jCCaEVIwImHw0,6208
|
|
14
14
|
graphiti_core/cross_encoder/openai_reranker_client.py,sha256=WHMl6Q6gEslR2EzjwpFSZt2Kh6bnu8alkLvzmi0MDtg,4674
|
|
15
15
|
graphiti_core/driver/__init__.py,sha256=kCWimqQU19airu5gKwCmZtZuXkDfaQfKSUhMDoL-rTA,626
|
|
16
|
-
graphiti_core/driver/driver.py,sha256=
|
|
17
|
-
graphiti_core/driver/falkordb_driver.py,sha256=
|
|
16
|
+
graphiti_core/driver/driver.py,sha256=EO9Aj5O2vpH7iyvQQcE5uJGQ8eA-_i6f8NwfAlW8r74,10831
|
|
17
|
+
graphiti_core/driver/falkordb_driver.py,sha256=Q-dImfK4O2bkikqFzo0Wg2g7iFFRSuzy_c6u82tX6-M,9361
|
|
18
18
|
graphiti_core/driver/kuzu_driver.py,sha256=RcWu8E0CCdofrFe34NmCeqfuhaZr_7ZN5jqDkI3VQMI,5453
|
|
19
19
|
graphiti_core/driver/neo4j_driver.py,sha256=E93PdOZaH7wzEbIfoiDSYht49jr6zSzvMMyo1INGEOw,4096
|
|
20
20
|
graphiti_core/driver/neptune_driver.py,sha256=akNLHhFHPEeQu-xO3PM51RomklntT6k5eA2CQ4AFbCc,10311
|
|
@@ -60,11 +60,11 @@ graphiti_core/search/search_config.py,sha256=v_rUHsu1yo5OuPfEm21lSuXexQs-o8qYwSS
|
|
|
60
60
|
graphiti_core/search/search_config_recipes.py,sha256=4GquRphHhJlpXQhAZOySYnCzBWYoTwxlJj44eTOavZQ,7443
|
|
61
61
|
graphiti_core/search/search_filters.py,sha256=DOAmYkc6A0z20EZId5fJZj1RvLz4WeQcoPANk9k-Sh8,10304
|
|
62
62
|
graphiti_core/search/search_helpers.py,sha256=wj3ARlCNnZixNNntgCdAqzGoE4de4lW3r4rSG-3WyGw,2877
|
|
63
|
-
graphiti_core/search/search_utils.py,sha256=
|
|
63
|
+
graphiti_core/search/search_utils.py,sha256=ak1aBeKNuxS7szydNHwva2ABWSRlQ0S_v8ZOx7k0wc4,76958
|
|
64
64
|
graphiti_core/telemetry/__init__.py,sha256=5kALLDlU9bb2v19CdN7qVANsJWyfnL9E60J6FFgzm3o,226
|
|
65
65
|
graphiti_core/telemetry/telemetry.py,sha256=47LrzOVBCcZxsYPsnSxWFiztHoxYKKxPwyRX0hnbDGc,3230
|
|
66
66
|
graphiti_core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
|
-
graphiti_core/utils/bulk_utils.py,sha256=
|
|
67
|
+
graphiti_core/utils/bulk_utils.py,sha256=9XWXqjxiu2ydKMLKQRTbvzO6cO1o1HRjjpmaf5Ym51k,17633
|
|
68
68
|
graphiti_core/utils/datetime_utils.py,sha256=J-zYSq7-H-2n9hYOXNIun12kM10vNX9mMATGR_egTmY,1806
|
|
69
69
|
graphiti_core/utils/maintenance/__init__.py,sha256=vW4H1KyapTl-OOz578uZABYcpND4wPx3Vt6aAPaXh78,301
|
|
70
70
|
graphiti_core/utils/maintenance/community_operations.py,sha256=XMiokEemn96GlvjkOvbo9hIX04Fea3eVj408NHG5P4o,11042
|
|
@@ -74,7 +74,7 @@ graphiti_core/utils/maintenance/node_operations.py,sha256=r9ilkA01eq1z-nF8P_s1EX
|
|
|
74
74
|
graphiti_core/utils/maintenance/temporal_operations.py,sha256=IIaVtShpVkOYe6haxz3a1x3v54-MzaEXG8VsxFUNeoY,3582
|
|
75
75
|
graphiti_core/utils/maintenance/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
76
|
graphiti_core/utils/ontology_utils/entity_types_utils.py,sha256=4eVgxLWY6Q8k9cRJ5pW59IYF--U4nXZsZIGOVb_yHfQ,1285
|
|
77
|
-
graphiti_core-0.21.
|
|
78
|
-
graphiti_core-0.21.
|
|
79
|
-
graphiti_core-0.21.
|
|
80
|
-
graphiti_core-0.21.
|
|
77
|
+
graphiti_core-0.21.0rc4.dist-info/METADATA,sha256=W_bFyM6HCQ8N7-tFNyjGHuRafGDYj89EtQ4tngZPUKc,26933
|
|
78
|
+
graphiti_core-0.21.0rc4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
79
|
+
graphiti_core-0.21.0rc4.dist-info/licenses/LICENSE,sha256=KCUwCyDXuVEgmDWkozHyniRyWjnWUWjkuDHfU6o3JlA,11325
|
|
80
|
+
graphiti_core-0.21.0rc4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|