cognee 0.5.0__py3-none-any.whl → 0.5.0.dev0__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.
Files changed (131) hide show
  1. cognee/api/client.py +5 -1
  2. cognee/api/v1/add/add.py +1 -2
  3. cognee/api/v1/cognify/code_graph_pipeline.py +119 -0
  4. cognee/api/v1/cognify/cognify.py +16 -24
  5. cognee/api/v1/cognify/routers/__init__.py +1 -0
  6. cognee/api/v1/cognify/routers/get_code_pipeline_router.py +90 -0
  7. cognee/api/v1/cognify/routers/get_cognify_router.py +1 -3
  8. cognee/api/v1/datasets/routers/get_datasets_router.py +3 -3
  9. cognee/api/v1/ontologies/ontologies.py +37 -12
  10. cognee/api/v1/ontologies/routers/get_ontology_router.py +25 -27
  11. cognee/api/v1/search/search.py +0 -4
  12. cognee/api/v1/ui/ui.py +68 -38
  13. cognee/context_global_variables.py +16 -61
  14. cognee/eval_framework/answer_generation/answer_generation_executor.py +0 -10
  15. cognee/eval_framework/answer_generation/run_question_answering_module.py +1 -1
  16. cognee/eval_framework/corpus_builder/task_getters/get_cascade_graph_tasks.py +2 -0
  17. cognee/eval_framework/corpus_builder/task_getters/get_default_tasks_by_indices.py +4 -4
  18. cognee/eval_framework/eval_config.py +2 -2
  19. cognee/eval_framework/modal_run_eval.py +28 -16
  20. cognee/infrastructure/databases/graph/config.py +0 -3
  21. cognee/infrastructure/databases/graph/get_graph_engine.py +0 -1
  22. cognee/infrastructure/databases/graph/graph_db_interface.py +0 -15
  23. cognee/infrastructure/databases/graph/kuzu/adapter.py +0 -228
  24. cognee/infrastructure/databases/graph/neo4j_driver/adapter.py +1 -80
  25. cognee/infrastructure/databases/utils/__init__.py +0 -3
  26. cognee/infrastructure/databases/utils/get_or_create_dataset_database.py +48 -62
  27. cognee/infrastructure/databases/vector/config.py +0 -2
  28. cognee/infrastructure/databases/vector/create_vector_engine.py +0 -1
  29. cognee/infrastructure/databases/vector/embeddings/FastembedEmbeddingEngine.py +6 -8
  30. cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +7 -9
  31. cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +10 -11
  32. cognee/infrastructure/databases/vector/embeddings/embedding_rate_limiter.py +544 -0
  33. cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +0 -2
  34. cognee/infrastructure/databases/vector/vector_db_interface.py +0 -35
  35. cognee/infrastructure/files/storage/s3_config.py +0 -2
  36. cognee/infrastructure/llm/LLMGateway.py +2 -5
  37. cognee/infrastructure/llm/config.py +0 -35
  38. cognee/infrastructure/llm/extraction/knowledge_graph/extract_content_graph.py +2 -2
  39. cognee/infrastructure/llm/structured_output_framework/baml/baml_src/extraction/acreate_structured_output.py +8 -23
  40. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/anthropic/adapter.py +16 -17
  41. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/gemini/adapter.py +37 -40
  42. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/generic_llm_api/adapter.py +36 -39
  43. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +1 -19
  44. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/mistral/adapter.py +9 -11
  45. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/ollama/adapter.py +21 -23
  46. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/openai/adapter.py +34 -42
  47. cognee/modules/cognify/config.py +0 -2
  48. cognee/modules/data/deletion/prune_system.py +2 -52
  49. cognee/modules/data/methods/delete_dataset.py +0 -26
  50. cognee/modules/engine/models/__init__.py +0 -1
  51. cognee/modules/graph/cognee_graph/CogneeGraph.py +37 -85
  52. cognee/modules/graph/cognee_graph/CogneeGraphElements.py +3 -8
  53. cognee/modules/memify/memify.py +7 -1
  54. cognee/modules/pipelines/operations/pipeline.py +2 -18
  55. cognee/modules/retrieval/__init__.py +1 -1
  56. cognee/modules/retrieval/code_retriever.py +232 -0
  57. cognee/modules/retrieval/graph_completion_context_extension_retriever.py +0 -4
  58. cognee/modules/retrieval/graph_completion_cot_retriever.py +0 -4
  59. cognee/modules/retrieval/graph_completion_retriever.py +0 -10
  60. cognee/modules/retrieval/graph_summary_completion_retriever.py +0 -4
  61. cognee/modules/retrieval/temporal_retriever.py +0 -4
  62. cognee/modules/retrieval/utils/brute_force_triplet_search.py +10 -42
  63. cognee/modules/run_custom_pipeline/run_custom_pipeline.py +1 -8
  64. cognee/modules/search/methods/get_search_type_tools.py +8 -54
  65. cognee/modules/search/methods/no_access_control_search.py +0 -4
  66. cognee/modules/search/methods/search.py +0 -21
  67. cognee/modules/search/types/SearchType.py +1 -1
  68. cognee/modules/settings/get_settings.py +0 -19
  69. cognee/modules/users/methods/get_authenticated_user.py +2 -2
  70. cognee/modules/users/models/DatasetDatabase.py +3 -15
  71. cognee/shared/logging_utils.py +0 -4
  72. cognee/tasks/code/enrich_dependency_graph_checker.py +35 -0
  73. cognee/tasks/code/get_local_dependencies_checker.py +20 -0
  74. cognee/tasks/code/get_repo_dependency_graph_checker.py +35 -0
  75. cognee/tasks/documents/__init__.py +1 -0
  76. cognee/tasks/documents/check_permissions_on_dataset.py +26 -0
  77. cognee/tasks/graph/extract_graph_from_data.py +10 -9
  78. cognee/tasks/repo_processor/__init__.py +2 -0
  79. cognee/tasks/repo_processor/get_local_dependencies.py +335 -0
  80. cognee/tasks/repo_processor/get_non_code_files.py +158 -0
  81. cognee/tasks/repo_processor/get_repo_file_dependencies.py +243 -0
  82. cognee/tasks/storage/add_data_points.py +2 -142
  83. cognee/tests/test_cognee_server_start.py +4 -2
  84. cognee/tests/test_conversation_history.py +1 -23
  85. cognee/tests/test_delete_bmw_example.py +60 -0
  86. cognee/tests/test_search_db.py +1 -37
  87. cognee/tests/unit/api/test_ontology_endpoint.py +89 -77
  88. cognee/tests/unit/infrastructure/mock_embedding_engine.py +7 -3
  89. cognee/tests/unit/infrastructure/test_embedding_rate_limiting_realistic.py +5 -0
  90. cognee/tests/unit/modules/graph/cognee_graph_elements_test.py +2 -2
  91. cognee/tests/unit/modules/graph/cognee_graph_test.py +0 -406
  92. {cognee-0.5.0.dist-info → cognee-0.5.0.dev0.dist-info}/METADATA +89 -76
  93. {cognee-0.5.0.dist-info → cognee-0.5.0.dev0.dist-info}/RECORD +97 -118
  94. {cognee-0.5.0.dist-info → cognee-0.5.0.dev0.dist-info}/WHEEL +1 -1
  95. cognee/api/v1/ui/node_setup.py +0 -360
  96. cognee/api/v1/ui/npm_utils.py +0 -50
  97. cognee/eval_framework/Dockerfile +0 -29
  98. cognee/infrastructure/databases/dataset_database_handler/__init__.py +0 -3
  99. cognee/infrastructure/databases/dataset_database_handler/dataset_database_handler_interface.py +0 -80
  100. cognee/infrastructure/databases/dataset_database_handler/supported_dataset_database_handlers.py +0 -18
  101. cognee/infrastructure/databases/dataset_database_handler/use_dataset_database_handler.py +0 -10
  102. cognee/infrastructure/databases/graph/kuzu/KuzuDatasetDatabaseHandler.py +0 -81
  103. cognee/infrastructure/databases/graph/neo4j_driver/Neo4jAuraDevDatasetDatabaseHandler.py +0 -168
  104. cognee/infrastructure/databases/utils/get_graph_dataset_database_handler.py +0 -10
  105. cognee/infrastructure/databases/utils/get_vector_dataset_database_handler.py +0 -10
  106. cognee/infrastructure/databases/utils/resolve_dataset_database_connection_info.py +0 -30
  107. cognee/infrastructure/databases/vector/lancedb/LanceDBDatasetDatabaseHandler.py +0 -50
  108. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/bedrock/__init__.py +0 -5
  109. cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/bedrock/adapter.py +0 -153
  110. cognee/memify_pipelines/create_triplet_embeddings.py +0 -53
  111. cognee/modules/engine/models/Triplet.py +0 -9
  112. cognee/modules/retrieval/register_retriever.py +0 -10
  113. cognee/modules/retrieval/registered_community_retrievers.py +0 -1
  114. cognee/modules/retrieval/triplet_retriever.py +0 -182
  115. cognee/shared/rate_limiting.py +0 -30
  116. cognee/tasks/memify/get_triplet_datapoints.py +0 -289
  117. cognee/tests/integration/retrieval/test_triplet_retriever.py +0 -84
  118. cognee/tests/integration/tasks/test_add_data_points.py +0 -139
  119. cognee/tests/integration/tasks/test_get_triplet_datapoints.py +0 -69
  120. cognee/tests/test_dataset_database_handler.py +0 -137
  121. cognee/tests/test_dataset_delete.py +0 -76
  122. cognee/tests/test_edge_centered_payload.py +0 -170
  123. cognee/tests/test_pipeline_cache.py +0 -164
  124. cognee/tests/unit/infrastructure/llm/test_llm_config.py +0 -46
  125. cognee/tests/unit/modules/memify_tasks/test_get_triplet_datapoints.py +0 -214
  126. cognee/tests/unit/modules/retrieval/test_brute_force_triplet_search.py +0 -608
  127. cognee/tests/unit/modules/retrieval/triplet_retriever_test.py +0 -83
  128. cognee/tests/unit/tasks/storage/test_add_data_points.py +0 -288
  129. {cognee-0.5.0.dist-info → cognee-0.5.0.dev0.dist-info}/entry_points.txt +0 -0
  130. {cognee-0.5.0.dist-info → cognee-0.5.0.dev0.dist-info}/licenses/LICENSE +0 -0
  131. {cognee-0.5.0.dist-info → cognee-0.5.0.dev0.dist-info}/licenses/NOTICE.md +0 -0
@@ -1,28 +1,17 @@
1
1
  import pytest
2
2
  import uuid
3
3
  from fastapi.testclient import TestClient
4
- from unittest.mock import Mock
4
+ from unittest.mock import patch, Mock, AsyncMock
5
5
  from types import SimpleNamespace
6
+ import importlib
6
7
  from cognee.api.client import app
7
- from cognee.modules.users.methods import get_authenticated_user
8
8
 
9
-
10
- @pytest.fixture(scope="session")
11
- def test_client():
12
- # Keep a single TestClient (and event loop) for the whole module.
13
- # Re-creating TestClient repeatedly can break async DB connections (asyncpg loop mismatch).
14
- with TestClient(app) as c:
15
- yield c
9
+ gau_mod = importlib.import_module("cognee.modules.users.methods.get_authenticated_user")
16
10
 
17
11
 
18
12
  @pytest.fixture
19
- def client(test_client, mock_default_user):
20
- async def override_get_authenticated_user():
21
- return mock_default_user
22
-
23
- app.dependency_overrides[get_authenticated_user] = override_get_authenticated_user
24
- yield test_client
25
- app.dependency_overrides.pop(get_authenticated_user, None)
13
+ def client():
14
+ return TestClient(app)
26
15
 
27
16
 
28
17
  @pytest.fixture
@@ -36,15 +25,16 @@ def mock_user():
36
25
  def mock_default_user():
37
26
  """Mock default user for testing."""
38
27
  return SimpleNamespace(
39
- id=str(uuid.uuid4()),
40
- email="default@example.com",
41
- is_active=True,
42
- tenant_id=str(uuid.uuid4()),
28
+ id=uuid.uuid4(), email="default@example.com", is_active=True, tenant_id=uuid.uuid4()
43
29
  )
44
30
 
45
31
 
46
- def test_upload_ontology_success(client):
32
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
33
+ def test_upload_ontology_success(mock_get_default_user, client, mock_default_user):
47
34
  """Test successful ontology upload"""
35
+ import json
36
+
37
+ mock_get_default_user.return_value = mock_default_user
48
38
  ontology_content = (
49
39
  b"<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'></rdf:RDF>"
50
40
  )
@@ -53,7 +43,7 @@ def test_upload_ontology_success(client):
53
43
  response = client.post(
54
44
  "/api/v1/ontologies",
55
45
  files=[("ontology_file", ("test.owl", ontology_content, "application/xml"))],
56
- data={"ontology_key": unique_key, "description": "Test"},
46
+ data={"ontology_key": json.dumps([unique_key]), "description": json.dumps(["Test"])},
57
47
  )
58
48
 
59
49
  assert response.status_code == 200
@@ -62,8 +52,10 @@ def test_upload_ontology_success(client):
62
52
  assert "uploaded_at" in data["uploaded_ontologies"][0]
63
53
 
64
54
 
65
- def test_upload_ontology_invalid_file(client):
55
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
56
+ def test_upload_ontology_invalid_file(mock_get_default_user, client, mock_default_user):
66
57
  """Test 400 response for non-.owl files"""
58
+ mock_get_default_user.return_value = mock_default_user
67
59
  unique_key = f"test_ontology_{uuid.uuid4().hex[:8]}"
68
60
  response = client.post(
69
61
  "/api/v1/ontologies",
@@ -73,10 +65,14 @@ def test_upload_ontology_invalid_file(client):
73
65
  assert response.status_code == 400
74
66
 
75
67
 
76
- def test_upload_ontology_missing_data(client):
68
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
69
+ def test_upload_ontology_missing_data(mock_get_default_user, client, mock_default_user):
77
70
  """Test 400 response for missing file or key"""
71
+ import json
72
+
73
+ mock_get_default_user.return_value = mock_default_user
78
74
  # Missing file
79
- response = client.post("/api/v1/ontologies", data={"ontology_key": "test"})
75
+ response = client.post("/api/v1/ontologies", data={"ontology_key": json.dumps(["test"])})
80
76
  assert response.status_code == 400
81
77
 
82
78
  # Missing key
@@ -86,25 +82,33 @@ def test_upload_ontology_missing_data(client):
86
82
  assert response.status_code == 400
87
83
 
88
84
 
89
- def test_upload_ontology_without_auth_header(client):
90
- """Test behavior when no explicit authentication header is provided."""
85
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
86
+ def test_upload_ontology_unauthorized(mock_get_default_user, client, mock_default_user):
87
+ """Test behavior when default user is provided (no explicit authentication)"""
88
+ import json
89
+
91
90
  unique_key = f"test_ontology_{uuid.uuid4().hex[:8]}"
91
+ mock_get_default_user.return_value = mock_default_user
92
92
  response = client.post(
93
93
  "/api/v1/ontologies",
94
94
  files=[("ontology_file", ("test.owl", b"<rdf></rdf>", "application/xml"))],
95
- data={"ontology_key": unique_key},
95
+ data={"ontology_key": json.dumps([unique_key])},
96
96
  )
97
97
 
98
+ # The current system provides a default user when no explicit authentication is given
99
+ # This test verifies the system works with conditional authentication
98
100
  assert response.status_code == 200
99
101
  data = response.json()
100
102
  assert data["uploaded_ontologies"][0]["ontology_key"] == unique_key
101
103
  assert "uploaded_at" in data["uploaded_ontologies"][0]
102
104
 
103
105
 
104
- def test_upload_multiple_ontologies_in_single_request_is_rejected(client):
105
- """Uploading multiple ontology files in a single request should fail."""
106
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
107
+ def test_upload_multiple_ontologies(mock_get_default_user, client, mock_default_user):
108
+ """Test uploading multiple ontology files in single request"""
106
109
  import io
107
110
 
111
+ # Create mock files
108
112
  file1_content = b"<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'></rdf:RDF>"
109
113
  file2_content = b"<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'></rdf:RDF>"
110
114
 
@@ -112,16 +116,24 @@ def test_upload_multiple_ontologies_in_single_request_is_rejected(client):
112
116
  ("ontology_file", ("vehicles.owl", io.BytesIO(file1_content), "application/xml")),
113
117
  ("ontology_file", ("manufacturers.owl", io.BytesIO(file2_content), "application/xml")),
114
118
  ]
115
- data = {"ontology_key": "vehicles", "description": "Base vehicles"}
119
+ data = {
120
+ "ontology_key": '["vehicles", "manufacturers"]',
121
+ "descriptions": '["Base vehicles", "Car manufacturers"]',
122
+ }
116
123
 
117
124
  response = client.post("/api/v1/ontologies", files=files, data=data)
118
125
 
119
- assert response.status_code == 400
120
- assert "Only one ontology_file is allowed" in response.json()["error"]
126
+ assert response.status_code == 200
127
+ result = response.json()
128
+ assert "uploaded_ontologies" in result
129
+ assert len(result["uploaded_ontologies"]) == 2
130
+ assert result["uploaded_ontologies"][0]["ontology_key"] == "vehicles"
131
+ assert result["uploaded_ontologies"][1]["ontology_key"] == "manufacturers"
121
132
 
122
133
 
123
- def test_upload_endpoint_rejects_array_style_fields(client):
124
- """Array-style form values should be rejected (no backwards compatibility)."""
134
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
135
+ def test_upload_endpoint_accepts_arrays(mock_get_default_user, client, mock_default_user):
136
+ """Test that upload endpoint accepts array parameters"""
125
137
  import io
126
138
  import json
127
139
 
@@ -130,16 +142,18 @@ def test_upload_endpoint_rejects_array_style_fields(client):
130
142
  files = [("ontology_file", ("single.owl", io.BytesIO(file_content), "application/xml"))]
131
143
  data = {
132
144
  "ontology_key": json.dumps(["single_key"]),
133
- "description": json.dumps(["Single ontology"]),
145
+ "descriptions": json.dumps(["Single ontology"]),
134
146
  }
135
147
 
136
148
  response = client.post("/api/v1/ontologies", files=files, data=data)
137
149
 
138
- assert response.status_code == 400
139
- assert "ontology_key must be a string" in response.json()["error"]
150
+ assert response.status_code == 200
151
+ result = response.json()
152
+ assert result["uploaded_ontologies"][0]["ontology_key"] == "single_key"
140
153
 
141
154
 
142
- def test_cognify_with_multiple_ontologies(client):
155
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
156
+ def test_cognify_with_multiple_ontologies(mock_get_default_user, client, mock_default_user):
143
157
  """Test cognify endpoint accepts multiple ontology keys"""
144
158
  payload = {
145
159
  "datasets": ["test_dataset"],
@@ -153,11 +167,13 @@ def test_cognify_with_multiple_ontologies(client):
153
167
  assert response.status_code in [200, 400, 409] # May fail for other reasons, not type
154
168
 
155
169
 
156
- def test_complete_multifile_workflow(client):
157
- """Test workflow: upload ontologies one-by-one → cognify with multiple keys"""
170
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
171
+ def test_complete_multifile_workflow(mock_get_default_user, client, mock_default_user):
172
+ """Test complete workflow: upload multiple ontologies → cognify with multiple keys"""
158
173
  import io
174
+ import json
159
175
 
160
- # Step 1: Upload two ontologies (one-by-one)
176
+ # Step 1: Upload multiple ontologies
161
177
  file1_content = b"""<?xml version="1.0"?>
162
178
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
163
179
  xmlns:owl="http://www.w3.org/2002/07/owl#">
@@ -170,21 +186,17 @@ def test_complete_multifile_workflow(client):
170
186
  <owl:Class rdf:ID="Manufacturer"/>
171
187
  </rdf:RDF>"""
172
188
 
173
- upload_response_1 = client.post(
174
- "/api/v1/ontologies",
175
- files=[("ontology_file", ("vehicles.owl", io.BytesIO(file1_content), "application/xml"))],
176
- data={"ontology_key": "vehicles", "description": "Vehicle ontology"},
177
- )
178
- assert upload_response_1.status_code == 200
189
+ files = [
190
+ ("ontology_file", ("vehicles.owl", io.BytesIO(file1_content), "application/xml")),
191
+ ("ontology_file", ("manufacturers.owl", io.BytesIO(file2_content), "application/xml")),
192
+ ]
193
+ data = {
194
+ "ontology_key": json.dumps(["vehicles", "manufacturers"]),
195
+ "descriptions": json.dumps(["Vehicle ontology", "Manufacturer ontology"]),
196
+ }
179
197
 
180
- upload_response_2 = client.post(
181
- "/api/v1/ontologies",
182
- files=[
183
- ("ontology_file", ("manufacturers.owl", io.BytesIO(file2_content), "application/xml"))
184
- ],
185
- data={"ontology_key": "manufacturers", "description": "Manufacturer ontology"},
186
- )
187
- assert upload_response_2.status_code == 200
198
+ upload_response = client.post("/api/v1/ontologies", files=files, data=data)
199
+ assert upload_response.status_code == 200
188
200
 
189
201
  # Step 2: Verify ontologies are listed
190
202
  list_response = client.get("/api/v1/ontologies")
@@ -205,41 +217,41 @@ def test_complete_multifile_workflow(client):
205
217
  assert cognify_response.status_code != 400 # Not a validation error
206
218
 
207
219
 
208
- def test_upload_error_handling(client):
209
- """Test error handling for invalid uploads (single-file endpoint)."""
220
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
221
+ def test_multifile_error_handling(mock_get_default_user, client, mock_default_user):
222
+ """Test error handling for invalid multifile uploads"""
210
223
  import io
211
224
  import json
212
225
 
213
- # Array-style key should be rejected
226
+ # Test mismatched array lengths
214
227
  file_content = b"<rdf:RDF></rdf:RDF>"
215
228
  files = [("ontology_file", ("test.owl", io.BytesIO(file_content), "application/xml"))]
216
229
  data = {
217
- "ontology_key": json.dumps(["key1", "key2"]),
218
- "description": "desc1",
230
+ "ontology_key": json.dumps(["key1", "key2"]), # 2 keys, 1 file
231
+ "descriptions": json.dumps(["desc1"]),
219
232
  }
220
233
 
221
234
  response = client.post("/api/v1/ontologies", files=files, data=data)
222
235
  assert response.status_code == 400
223
- assert "ontology_key must be a string" in response.json()["error"]
236
+ assert "Number of keys must match number of files" in response.json()["error"]
224
237
 
225
- # Duplicate key should be rejected
226
- response_1 = client.post(
227
- "/api/v1/ontologies",
228
- files=[("ontology_file", ("test1.owl", io.BytesIO(file_content), "application/xml"))],
229
- data={"ontology_key": "duplicate", "description": "desc1"},
230
- )
231
- assert response_1.status_code == 200
238
+ # Test duplicate keys
239
+ files = [
240
+ ("ontology_file", ("test1.owl", io.BytesIO(file_content), "application/xml")),
241
+ ("ontology_file", ("test2.owl", io.BytesIO(file_content), "application/xml")),
242
+ ]
243
+ data = {
244
+ "ontology_key": json.dumps(["duplicate", "duplicate"]),
245
+ "descriptions": json.dumps(["desc1", "desc2"]),
246
+ }
232
247
 
233
- response_2 = client.post(
234
- "/api/v1/ontologies",
235
- files=[("ontology_file", ("test2.owl", io.BytesIO(file_content), "application/xml"))],
236
- data={"ontology_key": "duplicate", "description": "desc2"},
237
- )
238
- assert response_2.status_code == 400
239
- assert "already exists" in response_2.json()["error"]
248
+ response = client.post("/api/v1/ontologies", files=files, data=data)
249
+ assert response.status_code == 400
250
+ assert "Duplicate ontology keys not allowed" in response.json()["error"]
240
251
 
241
252
 
242
- def test_cognify_missing_ontology_key(client):
253
+ @patch.object(gau_mod, "get_default_user", new_callable=AsyncMock)
254
+ def test_cognify_missing_ontology_key(mock_get_default_user, client, mock_default_user):
243
255
  """Test cognify with non-existent ontology key"""
244
256
  payload = {
245
257
  "datasets": ["test_dataset"],
@@ -4,7 +4,10 @@ from typing import List
4
4
  from cognee.infrastructure.databases.vector.embeddings.LiteLLMEmbeddingEngine import (
5
5
  LiteLLMEmbeddingEngine,
6
6
  )
7
- from cognee.shared.rate_limiting import embedding_rate_limiter_context_manager
7
+ from cognee.infrastructure.databases.vector.embeddings.embedding_rate_limiter import (
8
+ embedding_rate_limit_async,
9
+ embedding_sleep_and_retry_async,
10
+ )
8
11
 
9
12
 
10
13
  class MockEmbeddingEngine(LiteLLMEmbeddingEngine):
@@ -31,6 +34,8 @@ class MockEmbeddingEngine(LiteLLMEmbeddingEngine):
31
34
  self.fail_every_n_requests = fail_every_n_requests
32
35
  self.add_delay = add_delay
33
36
 
37
+ @embedding_sleep_and_retry_async()
38
+ @embedding_rate_limit_async
34
39
  async def embed_text(self, text: List[str]) -> List[List[float]]:
35
40
  """
36
41
  Mock implementation that returns fixed embeddings and can
@@ -47,5 +52,4 @@ class MockEmbeddingEngine(LiteLLMEmbeddingEngine):
47
52
  raise Exception(f"Mock failure on request #{self.request_count}")
48
53
 
49
54
  # Return mock embeddings of the correct dimension
50
- async with embedding_rate_limiter_context_manager():
51
- return [[0.1] * self.dimensions for _ in text]
55
+ return [[0.1] * self.dimensions for _ in text]
@@ -6,6 +6,9 @@ import logging
6
6
  from cognee.infrastructure.llm.config import (
7
7
  get_llm_config,
8
8
  )
9
+ from cognee.infrastructure.databases.vector.embeddings.embedding_rate_limiter import (
10
+ EmbeddingRateLimiter,
11
+ )
9
12
  from cognee.tests.unit.infrastructure.mock_embedding_engine import MockEmbeddingEngine
10
13
 
11
14
  # Configure logging
@@ -30,6 +33,7 @@ async def test_embedding_rate_limiting_realistic():
30
33
 
31
34
  # Clear the config and rate limiter caches to ensure our settings are applied
32
35
  get_llm_config.cache_clear()
36
+ EmbeddingRateLimiter.reset_instance()
33
37
 
34
38
  # Create a fresh config instance and verify settings
35
39
  config = get_llm_config()
@@ -166,6 +170,7 @@ async def test_with_mock_failures():
166
170
 
167
171
  # Clear caches
168
172
  get_llm_config.cache_clear()
173
+ EmbeddingRateLimiter.reset_instance()
169
174
 
170
175
  # Create a mock engine configured to fail every 3rd request
171
176
  engine = MockEmbeddingEngine()
@@ -9,7 +9,7 @@ def test_node_initialization():
9
9
  """Test that a Node is initialized correctly."""
10
10
  node = Node("node1", {"attr1": "value1"}, dimension=2)
11
11
  assert node.id == "node1"
12
- assert node.attributes == {"attr1": "value1", "vector_distance": 3.5}
12
+ assert node.attributes == {"attr1": "value1", "vector_distance": np.inf}
13
13
  assert len(node.status) == 2
14
14
  assert np.all(node.status == 1)
15
15
 
@@ -96,7 +96,7 @@ def test_edge_initialization():
96
96
  edge = Edge(node1, node2, {"weight": 10}, directed=False, dimension=2)
97
97
  assert edge.node1 == node1
98
98
  assert edge.node2 == node2
99
- assert edge.attributes == {"vector_distance": 3.5, "weight": 10}
99
+ assert edge.attributes == {"vector_distance": np.inf, "weight": 10}
100
100
  assert edge.directed is False
101
101
  assert len(edge.status) == 2
102
102
  assert np.all(edge.status == 1)