cognee 0.3.5__py3-none-any.whl → 0.3.7__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.
- cognee/__init__.py +1 -0
- cognee/api/health.py +2 -12
- cognee/api/v1/add/add.py +46 -6
- cognee/api/v1/add/routers/get_add_router.py +5 -1
- cognee/api/v1/cognify/cognify.py +29 -9
- cognee/api/v1/datasets/datasets.py +11 -0
- cognee/api/v1/responses/default_tools.py +0 -1
- cognee/api/v1/responses/dispatch_function.py +1 -1
- cognee/api/v1/responses/routers/default_tools.py +0 -1
- cognee/api/v1/search/search.py +11 -9
- cognee/api/v1/settings/routers/get_settings_router.py +7 -1
- cognee/api/v1/ui/ui.py +47 -16
- cognee/api/v1/update/routers/get_update_router.py +1 -1
- cognee/api/v1/update/update.py +3 -3
- cognee/cli/_cognee.py +61 -10
- cognee/cli/commands/add_command.py +3 -3
- cognee/cli/commands/cognify_command.py +3 -3
- cognee/cli/commands/config_command.py +9 -7
- cognee/cli/commands/delete_command.py +3 -3
- cognee/cli/commands/search_command.py +3 -7
- cognee/cli/config.py +0 -1
- cognee/context_global_variables.py +5 -0
- cognee/exceptions/exceptions.py +1 -1
- cognee/infrastructure/databases/cache/__init__.py +2 -0
- cognee/infrastructure/databases/cache/cache_db_interface.py +79 -0
- cognee/infrastructure/databases/cache/config.py +44 -0
- cognee/infrastructure/databases/cache/get_cache_engine.py +67 -0
- cognee/infrastructure/databases/cache/redis/RedisAdapter.py +243 -0
- cognee/infrastructure/databases/exceptions/__init__.py +1 -0
- cognee/infrastructure/databases/exceptions/exceptions.py +18 -2
- cognee/infrastructure/databases/graph/get_graph_engine.py +1 -1
- cognee/infrastructure/databases/graph/graph_db_interface.py +5 -0
- cognee/infrastructure/databases/graph/kuzu/adapter.py +67 -44
- cognee/infrastructure/databases/graph/neo4j_driver/adapter.py +13 -3
- cognee/infrastructure/databases/graph/neo4j_driver/deadlock_retry.py +1 -1
- cognee/infrastructure/databases/graph/neptune_driver/neptune_utils.py +1 -1
- cognee/infrastructure/databases/relational/sqlalchemy/SqlAlchemyAdapter.py +1 -1
- cognee/infrastructure/databases/vector/embeddings/FastembedEmbeddingEngine.py +21 -3
- cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +17 -10
- cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +17 -4
- cognee/infrastructure/databases/vector/embeddings/config.py +2 -3
- cognee/infrastructure/databases/vector/exceptions/exceptions.py +1 -1
- cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +0 -1
- cognee/infrastructure/files/exceptions.py +1 -1
- cognee/infrastructure/files/storage/LocalFileStorage.py +9 -9
- cognee/infrastructure/files/storage/S3FileStorage.py +11 -11
- cognee/infrastructure/files/utils/guess_file_type.py +6 -0
- cognee/infrastructure/llm/prompts/search_type_selector_prompt.txt +0 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/anthropic/adapter.py +19 -9
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/gemini/adapter.py +17 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/generic_llm_api/adapter.py +17 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +32 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/mistral/__init__.py +0 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/mistral/adapter.py +109 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/ollama/adapter.py +33 -8
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/openai/adapter.py +40 -18
- cognee/infrastructure/loaders/LoaderEngine.py +27 -7
- cognee/infrastructure/loaders/external/__init__.py +7 -0
- cognee/infrastructure/loaders/external/advanced_pdf_loader.py +2 -8
- cognee/infrastructure/loaders/external/beautiful_soup_loader.py +310 -0
- cognee/infrastructure/loaders/supported_loaders.py +7 -0
- cognee/modules/data/exceptions/exceptions.py +1 -1
- cognee/modules/data/methods/__init__.py +3 -0
- cognee/modules/data/methods/get_dataset_data.py +4 -1
- cognee/modules/data/methods/has_dataset_data.py +21 -0
- cognee/modules/engine/models/TableRow.py +0 -1
- cognee/modules/ingestion/save_data_to_file.py +9 -2
- cognee/modules/pipelines/exceptions/exceptions.py +1 -1
- cognee/modules/pipelines/operations/pipeline.py +12 -1
- cognee/modules/pipelines/operations/run_tasks.py +25 -197
- cognee/modules/pipelines/operations/run_tasks_data_item.py +260 -0
- cognee/modules/pipelines/operations/run_tasks_distributed.py +121 -38
- cognee/modules/retrieval/EntityCompletionRetriever.py +48 -8
- cognee/modules/retrieval/base_graph_retriever.py +3 -1
- cognee/modules/retrieval/base_retriever.py +3 -1
- cognee/modules/retrieval/chunks_retriever.py +5 -1
- cognee/modules/retrieval/code_retriever.py +20 -2
- cognee/modules/retrieval/completion_retriever.py +50 -9
- cognee/modules/retrieval/cypher_search_retriever.py +11 -1
- cognee/modules/retrieval/graph_completion_context_extension_retriever.py +47 -8
- cognee/modules/retrieval/graph_completion_cot_retriever.py +32 -1
- cognee/modules/retrieval/graph_completion_retriever.py +54 -10
- cognee/modules/retrieval/lexical_retriever.py +20 -2
- cognee/modules/retrieval/natural_language_retriever.py +10 -1
- cognee/modules/retrieval/summaries_retriever.py +5 -1
- cognee/modules/retrieval/temporal_retriever.py +62 -10
- cognee/modules/retrieval/user_qa_feedback.py +3 -2
- cognee/modules/retrieval/utils/completion.py +5 -0
- cognee/modules/retrieval/utils/description_to_codepart_search.py +1 -1
- cognee/modules/retrieval/utils/session_cache.py +156 -0
- cognee/modules/search/methods/get_search_type_tools.py +0 -5
- cognee/modules/search/methods/no_access_control_search.py +12 -1
- cognee/modules/search/methods/search.py +34 -2
- cognee/modules/search/types/SearchType.py +0 -1
- cognee/modules/settings/get_settings.py +23 -0
- cognee/modules/users/methods/get_authenticated_user.py +3 -1
- cognee/modules/users/methods/get_default_user.py +1 -6
- cognee/modules/users/roles/methods/create_role.py +2 -2
- cognee/modules/users/tenants/methods/create_tenant.py +2 -2
- cognee/shared/exceptions/exceptions.py +1 -1
- cognee/tasks/codingagents/coding_rule_associations.py +1 -2
- cognee/tasks/documents/exceptions/exceptions.py +1 -1
- cognee/tasks/graph/extract_graph_from_data.py +2 -0
- cognee/tasks/ingestion/data_item_to_text_file.py +3 -3
- cognee/tasks/ingestion/ingest_data.py +11 -5
- cognee/tasks/ingestion/save_data_item_to_storage.py +12 -1
- cognee/tasks/storage/add_data_points.py +3 -10
- cognee/tasks/storage/index_data_points.py +19 -14
- cognee/tasks/storage/index_graph_edges.py +25 -11
- cognee/tasks/web_scraper/__init__.py +34 -0
- cognee/tasks/web_scraper/config.py +26 -0
- cognee/tasks/web_scraper/default_url_crawler.py +446 -0
- cognee/tasks/web_scraper/models.py +46 -0
- cognee/tasks/web_scraper/types.py +4 -0
- cognee/tasks/web_scraper/utils.py +142 -0
- cognee/tasks/web_scraper/web_scraper_task.py +396 -0
- cognee/tests/cli_tests/cli_unit_tests/test_cli_utils.py +0 -1
- cognee/tests/integration/web_url_crawler/test_default_url_crawler.py +13 -0
- cognee/tests/integration/web_url_crawler/test_tavily_crawler.py +19 -0
- cognee/tests/integration/web_url_crawler/test_url_adding_e2e.py +344 -0
- cognee/tests/subprocesses/reader.py +25 -0
- cognee/tests/subprocesses/simple_cognify_1.py +31 -0
- cognee/tests/subprocesses/simple_cognify_2.py +31 -0
- cognee/tests/subprocesses/writer.py +32 -0
- cognee/tests/tasks/descriptive_metrics/metrics_test_utils.py +0 -2
- cognee/tests/tasks/descriptive_metrics/neo4j_metrics_test.py +8 -3
- cognee/tests/tasks/entity_extraction/entity_extraction_test.py +89 -0
- cognee/tests/tasks/web_scraping/web_scraping_test.py +172 -0
- cognee/tests/test_add_docling_document.py +56 -0
- cognee/tests/test_chromadb.py +7 -11
- cognee/tests/test_concurrent_subprocess_access.py +76 -0
- cognee/tests/test_conversation_history.py +240 -0
- cognee/tests/test_kuzu.py +27 -15
- cognee/tests/test_lancedb.py +7 -11
- cognee/tests/test_library.py +32 -2
- cognee/tests/test_neo4j.py +24 -16
- cognee/tests/test_neptune_analytics_vector.py +7 -11
- cognee/tests/test_permissions.py +9 -13
- cognee/tests/test_pgvector.py +4 -4
- cognee/tests/test_remote_kuzu.py +8 -11
- cognee/tests/test_s3_file_storage.py +1 -1
- cognee/tests/test_search_db.py +6 -8
- cognee/tests/unit/infrastructure/databases/cache/test_cache_config.py +89 -0
- cognee/tests/unit/modules/retrieval/conversation_history_test.py +154 -0
- {cognee-0.3.5.dist-info → cognee-0.3.7.dist-info}/METADATA +22 -7
- {cognee-0.3.5.dist-info → cognee-0.3.7.dist-info}/RECORD +155 -128
- {cognee-0.3.5.dist-info → cognee-0.3.7.dist-info}/entry_points.txt +1 -0
- distributed/Dockerfile +0 -3
- distributed/entrypoint.py +21 -9
- distributed/signal.py +5 -0
- distributed/workers/data_point_saving_worker.py +64 -34
- distributed/workers/graph_saving_worker.py +71 -47
- cognee/infrastructure/databases/graph/memgraph/memgraph_adapter.py +0 -1116
- cognee/modules/retrieval/insights_retriever.py +0 -133
- cognee/tests/test_memgraph.py +0 -109
- cognee/tests/unit/modules/retrieval/insights_retriever_test.py +0 -251
- distributed/poetry.lock +0 -12238
- distributed/pyproject.toml +0 -185
- {cognee-0.3.5.dist-info → cognee-0.3.7.dist-info}/WHEEL +0 -0
- {cognee-0.3.5.dist-info → cognee-0.3.7.dist-info}/licenses/LICENSE +0 -0
- {cognee-0.3.5.dist-info → cognee-0.3.7.dist-info}/licenses/NOTICE.md +0 -0
distributed/Dockerfile
CHANGED
distributed/entrypoint.py
CHANGED
|
@@ -10,6 +10,7 @@ from distributed.app import app
|
|
|
10
10
|
from distributed.queues import add_nodes_and_edges_queue, add_data_points_queue
|
|
11
11
|
from distributed.workers.graph_saving_worker import graph_saving_worker
|
|
12
12
|
from distributed.workers.data_point_saving_worker import data_point_saving_worker
|
|
13
|
+
from distributed.signal import QueueSignal
|
|
13
14
|
|
|
14
15
|
logger = get_logger()
|
|
15
16
|
|
|
@@ -23,13 +24,14 @@ async def main():
|
|
|
23
24
|
await add_nodes_and_edges_queue.clear.aio()
|
|
24
25
|
await add_data_points_queue.clear.aio()
|
|
25
26
|
|
|
26
|
-
number_of_graph_saving_workers = 1 # Total number of graph_saving_worker to spawn
|
|
27
|
-
number_of_data_point_saving_workers =
|
|
27
|
+
number_of_graph_saving_workers = 1 # Total number of graph_saving_worker to spawn (MAX 1)
|
|
28
|
+
number_of_data_point_saving_workers = (
|
|
29
|
+
10 # Total number of graph_saving_worker to spawn (MAX 10)
|
|
30
|
+
)
|
|
28
31
|
|
|
29
|
-
results = []
|
|
30
32
|
consumer_futures = []
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
await prune.prune_data() # This prunes the data from the file storage
|
|
33
35
|
# Delete DBs and saved files from metastore
|
|
34
36
|
await prune.prune_system(metadata=True)
|
|
35
37
|
|
|
@@ -45,16 +47,28 @@ async def main():
|
|
|
45
47
|
worker_future = data_point_saving_worker.spawn()
|
|
46
48
|
consumer_futures.append(worker_future)
|
|
47
49
|
|
|
50
|
+
""" Example: Setting and adding S3 path as input
|
|
48
51
|
s3_bucket_path = os.getenv("S3_BUCKET_PATH")
|
|
49
52
|
s3_data_path = "s3://" + s3_bucket_path
|
|
50
53
|
|
|
51
54
|
await cognee.add(s3_data_path, dataset_name="s3-files")
|
|
55
|
+
"""
|
|
56
|
+
await cognee.add(
|
|
57
|
+
[
|
|
58
|
+
"Audi is a German car manufacturer",
|
|
59
|
+
"The Netherlands is next to Germany",
|
|
60
|
+
"Berlin is the capital of Germany",
|
|
61
|
+
"The Rhine is a major European river",
|
|
62
|
+
"BMW produces luxury vehicles",
|
|
63
|
+
],
|
|
64
|
+
dataset_name="s3-files",
|
|
65
|
+
)
|
|
52
66
|
|
|
53
67
|
await cognee.cognify(datasets=["s3-files"])
|
|
54
68
|
|
|
55
|
-
#
|
|
56
|
-
await add_nodes_and_edges_queue.put.aio(
|
|
57
|
-
await add_data_points_queue.put.aio(
|
|
69
|
+
# Put Processing end signal into the queues to stop the consumers
|
|
70
|
+
await add_nodes_and_edges_queue.put.aio(QueueSignal.STOP)
|
|
71
|
+
await add_data_points_queue.put.aio(QueueSignal.STOP)
|
|
58
72
|
|
|
59
73
|
for consumer_future in consumer_futures:
|
|
60
74
|
try:
|
|
@@ -64,8 +78,6 @@ async def main():
|
|
|
64
78
|
except Exception as e:
|
|
65
79
|
logger.error(e)
|
|
66
80
|
|
|
67
|
-
print(results)
|
|
68
|
-
|
|
69
81
|
|
|
70
82
|
if __name__ == "__main__":
|
|
71
83
|
asyncio.run(main())
|
distributed/signal.py
ADDED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import modal
|
|
2
3
|
import asyncio
|
|
3
4
|
from sqlalchemy.exc import OperationalError, DBAPIError
|
|
4
5
|
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential
|
|
5
6
|
|
|
6
7
|
from distributed.app import app
|
|
8
|
+
from distributed.signal import QueueSignal
|
|
7
9
|
from distributed.modal_image import image
|
|
8
10
|
from distributed.queues import add_data_points_queue
|
|
9
11
|
|
|
10
12
|
from cognee.shared.logging_utils import get_logger
|
|
11
13
|
from cognee.infrastructure.databases.vector import get_vector_engine
|
|
12
14
|
|
|
13
|
-
|
|
14
15
|
logger = get_logger("data_point_saving_worker")
|
|
15
16
|
|
|
16
17
|
|
|
@@ -39,54 +40,83 @@ def is_deadlock_error(error):
|
|
|
39
40
|
return False
|
|
40
41
|
|
|
41
42
|
|
|
43
|
+
secret_name = os.environ.get("MODAL_SECRET_NAME", "distributed_cognee")
|
|
44
|
+
|
|
45
|
+
|
|
42
46
|
@app.function(
|
|
43
47
|
retries=3,
|
|
44
48
|
image=image,
|
|
45
49
|
timeout=86400,
|
|
46
|
-
max_containers=
|
|
47
|
-
secrets=[modal.Secret.from_name(
|
|
50
|
+
max_containers=10,
|
|
51
|
+
secrets=[modal.Secret.from_name(secret_name)],
|
|
48
52
|
)
|
|
49
53
|
async def data_point_saving_worker():
|
|
50
54
|
print("Started processing of data points; starting vector engine queue.")
|
|
51
55
|
vector_engine = get_vector_engine()
|
|
56
|
+
# Defines how many data packets do we glue together from the modal queue before embedding call and ingestion
|
|
57
|
+
BATCH_SIZE = 25
|
|
58
|
+
stop_seen = False
|
|
52
59
|
|
|
53
60
|
while True:
|
|
61
|
+
if stop_seen:
|
|
62
|
+
print("Finished processing all data points; stopping vector engine queue consumer.")
|
|
63
|
+
return True
|
|
64
|
+
|
|
54
65
|
if await add_data_points_queue.len.aio() != 0:
|
|
55
66
|
try:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
print("Remaining elements in queue:")
|
|
68
|
+
print(await add_data_points_queue.len.aio())
|
|
69
|
+
|
|
70
|
+
# collect batched requests
|
|
71
|
+
batched_points = {}
|
|
72
|
+
for _ in range(min(BATCH_SIZE, await add_data_points_queue.len.aio())):
|
|
73
|
+
add_data_points_request = await add_data_points_queue.get.aio(block=False)
|
|
74
|
+
|
|
75
|
+
if not add_data_points_request:
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
if add_data_points_request == QueueSignal.STOP:
|
|
79
|
+
await add_data_points_queue.put.aio(QueueSignal.STOP)
|
|
80
|
+
stop_seen = True
|
|
81
|
+
break
|
|
82
|
+
|
|
83
|
+
if len(add_data_points_request) == 2:
|
|
84
|
+
collection_name, data_points = add_data_points_request
|
|
85
|
+
if collection_name not in batched_points:
|
|
86
|
+
batched_points[collection_name] = []
|
|
87
|
+
batched_points[collection_name].extend(data_points)
|
|
88
|
+
else:
|
|
89
|
+
print("NoneType or invalid request detected.")
|
|
90
|
+
|
|
91
|
+
if batched_points:
|
|
92
|
+
for collection_name, data_points in batched_points.items():
|
|
93
|
+
print(
|
|
94
|
+
f"Adding {len(data_points)} data points to '{collection_name}' collection."
|
|
79
95
|
)
|
|
80
|
-
except DBAPIError as error:
|
|
81
|
-
if is_deadlock_error(error):
|
|
82
|
-
raise VectorDatabaseDeadlockError()
|
|
83
|
-
except OperationalError as error:
|
|
84
|
-
if is_deadlock_error(error):
|
|
85
|
-
raise VectorDatabaseDeadlockError()
|
|
86
96
|
|
|
87
|
-
|
|
97
|
+
@retry(
|
|
98
|
+
retry=retry_if_exception_type(VectorDatabaseDeadlockError),
|
|
99
|
+
stop=stop_after_attempt(3),
|
|
100
|
+
wait=wait_exponential(multiplier=2, min=1, max=6),
|
|
101
|
+
)
|
|
102
|
+
async def add_data_points():
|
|
103
|
+
try:
|
|
104
|
+
await vector_engine.create_data_points(
|
|
105
|
+
collection_name, data_points, distributed=False
|
|
106
|
+
)
|
|
107
|
+
except DBAPIError as error:
|
|
108
|
+
if is_deadlock_error(error):
|
|
109
|
+
raise VectorDatabaseDeadlockError()
|
|
110
|
+
except OperationalError as error:
|
|
111
|
+
if is_deadlock_error(error):
|
|
112
|
+
raise VectorDatabaseDeadlockError()
|
|
113
|
+
|
|
114
|
+
await add_data_points()
|
|
115
|
+
print(f"Finished adding data points to '{collection_name}'.")
|
|
88
116
|
|
|
89
|
-
|
|
117
|
+
except modal.exception.DeserializationError as error:
|
|
118
|
+
logger.error(f"Deserialization error: {str(error)}")
|
|
119
|
+
continue
|
|
90
120
|
|
|
91
121
|
else:
|
|
92
122
|
print("No jobs, go to sleep.")
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import modal
|
|
2
3
|
import asyncio
|
|
3
4
|
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential
|
|
4
5
|
|
|
5
6
|
from distributed.app import app
|
|
7
|
+
from distributed.signal import QueueSignal
|
|
6
8
|
from distributed.modal_image import image
|
|
7
9
|
from distributed.queues import add_nodes_and_edges_queue
|
|
8
10
|
|
|
@@ -10,7 +12,6 @@ from cognee.shared.logging_utils import get_logger
|
|
|
10
12
|
from cognee.infrastructure.databases.graph import get_graph_engine
|
|
11
13
|
from cognee.infrastructure.databases.graph.config import get_graph_config
|
|
12
14
|
|
|
13
|
-
|
|
14
15
|
logger = get_logger("graph_saving_worker")
|
|
15
16
|
|
|
16
17
|
|
|
@@ -37,68 +38,91 @@ def is_deadlock_error(error):
|
|
|
37
38
|
return False
|
|
38
39
|
|
|
39
40
|
|
|
41
|
+
secret_name = os.environ.get("MODAL_SECRET_NAME", "distributed_cognee")
|
|
42
|
+
|
|
43
|
+
|
|
40
44
|
@app.function(
|
|
41
45
|
retries=3,
|
|
42
46
|
image=image,
|
|
43
47
|
timeout=86400,
|
|
44
|
-
max_containers=
|
|
45
|
-
secrets=[modal.Secret.from_name(
|
|
48
|
+
max_containers=1,
|
|
49
|
+
secrets=[modal.Secret.from_name(secret_name)],
|
|
46
50
|
)
|
|
47
51
|
async def graph_saving_worker():
|
|
48
52
|
print("Started processing of nodes and edges; starting graph engine queue.")
|
|
49
53
|
graph_engine = await get_graph_engine()
|
|
54
|
+
# Defines how many data packets do we glue together from the queue before ingesting them into the graph database
|
|
55
|
+
BATCH_SIZE = 25
|
|
56
|
+
stop_seen = False
|
|
50
57
|
|
|
51
58
|
while True:
|
|
59
|
+
if stop_seen:
|
|
60
|
+
print("Finished processing all data points; stopping graph engine queue consumer.")
|
|
61
|
+
return True
|
|
62
|
+
|
|
52
63
|
if await add_nodes_and_edges_queue.len.aio() != 0:
|
|
53
64
|
try:
|
|
54
|
-
|
|
65
|
+
print("Remaining elements in queue:")
|
|
66
|
+
print(await add_nodes_and_edges_queue.len.aio())
|
|
67
|
+
|
|
68
|
+
all_nodes, all_edges = [], []
|
|
69
|
+
for _ in range(min(BATCH_SIZE, await add_nodes_and_edges_queue.len.aio())):
|
|
70
|
+
nodes_and_edges = await add_nodes_and_edges_queue.get.aio(block=False)
|
|
71
|
+
|
|
72
|
+
if not nodes_and_edges:
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
if nodes_and_edges == QueueSignal.STOP:
|
|
76
|
+
await add_nodes_and_edges_queue.put.aio(QueueSignal.STOP)
|
|
77
|
+
stop_seen = True
|
|
78
|
+
break
|
|
79
|
+
|
|
80
|
+
if len(nodes_and_edges) == 2:
|
|
81
|
+
nodes, edges = nodes_and_edges
|
|
82
|
+
all_nodes.extend(nodes)
|
|
83
|
+
all_edges.extend(edges)
|
|
84
|
+
else:
|
|
85
|
+
print("None Type detected.")
|
|
86
|
+
|
|
87
|
+
if all_nodes or all_edges:
|
|
88
|
+
print(f"Adding {len(all_nodes)} nodes and {len(all_edges)} edges.")
|
|
89
|
+
|
|
90
|
+
@retry(
|
|
91
|
+
retry=retry_if_exception_type(GraphDatabaseDeadlockError),
|
|
92
|
+
stop=stop_after_attempt(3),
|
|
93
|
+
wait=wait_exponential(multiplier=2, min=1, max=6),
|
|
94
|
+
)
|
|
95
|
+
async def save_graph_nodes(new_nodes):
|
|
96
|
+
try:
|
|
97
|
+
await graph_engine.add_nodes(new_nodes, distributed=False)
|
|
98
|
+
except Exception as error:
|
|
99
|
+
if is_deadlock_error(error):
|
|
100
|
+
raise GraphDatabaseDeadlockError()
|
|
101
|
+
|
|
102
|
+
@retry(
|
|
103
|
+
retry=retry_if_exception_type(GraphDatabaseDeadlockError),
|
|
104
|
+
stop=stop_after_attempt(3),
|
|
105
|
+
wait=wait_exponential(multiplier=2, min=1, max=6),
|
|
106
|
+
)
|
|
107
|
+
async def save_graph_edges(new_edges):
|
|
108
|
+
try:
|
|
109
|
+
await graph_engine.add_edges(new_edges, distributed=False)
|
|
110
|
+
except Exception as error:
|
|
111
|
+
if is_deadlock_error(error):
|
|
112
|
+
raise GraphDatabaseDeadlockError()
|
|
113
|
+
|
|
114
|
+
if all_nodes:
|
|
115
|
+
await save_graph_nodes(all_nodes)
|
|
116
|
+
|
|
117
|
+
if all_edges:
|
|
118
|
+
await save_graph_edges(all_edges)
|
|
119
|
+
|
|
120
|
+
print("Finished adding nodes and edges.")
|
|
121
|
+
|
|
55
122
|
except modal.exception.DeserializationError as error:
|
|
56
123
|
logger.error(f"Deserialization error: {str(error)}")
|
|
57
124
|
continue
|
|
58
125
|
|
|
59
|
-
if len(nodes_and_edges) == 0:
|
|
60
|
-
print("Finished processing all nodes and edges; stopping graph engine queue.")
|
|
61
|
-
return True
|
|
62
|
-
|
|
63
|
-
if len(nodes_and_edges) == 2:
|
|
64
|
-
print(
|
|
65
|
-
f"Adding {len(nodes_and_edges[0])} nodes and {len(nodes_and_edges[1])} edges."
|
|
66
|
-
)
|
|
67
|
-
nodes = nodes_and_edges[0]
|
|
68
|
-
edges = nodes_and_edges[1]
|
|
69
|
-
|
|
70
|
-
@retry(
|
|
71
|
-
retry=retry_if_exception_type(GraphDatabaseDeadlockError),
|
|
72
|
-
stop=stop_after_attempt(3),
|
|
73
|
-
wait=wait_exponential(multiplier=2, min=1, max=6),
|
|
74
|
-
)
|
|
75
|
-
async def save_graph_nodes(new_nodes):
|
|
76
|
-
try:
|
|
77
|
-
await graph_engine.add_nodes(new_nodes, distributed=False)
|
|
78
|
-
except Exception as error:
|
|
79
|
-
if is_deadlock_error(error):
|
|
80
|
-
raise GraphDatabaseDeadlockError()
|
|
81
|
-
|
|
82
|
-
@retry(
|
|
83
|
-
retry=retry_if_exception_type(GraphDatabaseDeadlockError),
|
|
84
|
-
stop=stop_after_attempt(3),
|
|
85
|
-
wait=wait_exponential(multiplier=2, min=1, max=6),
|
|
86
|
-
)
|
|
87
|
-
async def save_graph_edges(new_edges):
|
|
88
|
-
try:
|
|
89
|
-
await graph_engine.add_edges(new_edges, distributed=False)
|
|
90
|
-
except Exception as error:
|
|
91
|
-
if is_deadlock_error(error):
|
|
92
|
-
raise GraphDatabaseDeadlockError()
|
|
93
|
-
|
|
94
|
-
if nodes:
|
|
95
|
-
await save_graph_nodes(nodes)
|
|
96
|
-
|
|
97
|
-
if edges:
|
|
98
|
-
await save_graph_edges(edges)
|
|
99
|
-
|
|
100
|
-
print("Finished adding nodes and edges.")
|
|
101
|
-
|
|
102
126
|
else:
|
|
103
127
|
print("No jobs, go to sleep.")
|
|
104
128
|
await asyncio.sleep(5)
|