cognee 0.5.1.dev0__py3-none-any.whl → 0.5.2__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 +2 -0
- cognee/alembic/README +1 -0
- cognee/alembic/env.py +107 -0
- cognee/alembic/script.py.mako +26 -0
- cognee/alembic/versions/1a58b986e6e1_enable_delete_for_old_tutorial_notebooks.py +52 -0
- cognee/alembic/versions/1d0bb7fede17_add_pipeline_run_status.py +33 -0
- cognee/alembic/versions/1daae0df1866_incremental_loading.py +48 -0
- cognee/alembic/versions/211ab850ef3d_add_sync_operations_table.py +118 -0
- cognee/alembic/versions/45957f0a9849_add_notebook_table.py +46 -0
- cognee/alembic/versions/46a6ce2bd2b2_expand_dataset_database_with_json_.py +333 -0
- cognee/alembic/versions/482cd6517ce4_add_default_user.py +30 -0
- cognee/alembic/versions/76625596c5c3_expand_dataset_database_for_multi_user.py +98 -0
- cognee/alembic/versions/8057ae7329c2_initial_migration.py +25 -0
- cognee/alembic/versions/9e7a3cb85175_loader_separation.py +104 -0
- cognee/alembic/versions/a1b2c3d4e5f6_add_label_column_to_data.py +38 -0
- cognee/alembic/versions/ab7e313804ae_permission_system_rework.py +236 -0
- cognee/alembic/versions/b9274c27a25a_kuzu_11_migration.py +75 -0
- cognee/alembic/versions/c946955da633_multi_tenant_support.py +137 -0
- cognee/alembic/versions/e1ec1dcb50b6_add_last_accessed_to_data.py +51 -0
- cognee/alembic/versions/e4ebee1091e7_expand_data_model_info.py +140 -0
- cognee/alembic.ini +117 -0
- cognee/api/v1/add/routers/get_add_router.py +2 -0
- cognee/api/v1/cognify/cognify.py +11 -6
- cognee/api/v1/cognify/routers/get_cognify_router.py +8 -0
- cognee/api/v1/config/config.py +60 -0
- cognee/api/v1/datasets/routers/get_datasets_router.py +45 -3
- cognee/api/v1/memify/routers/get_memify_router.py +2 -0
- cognee/api/v1/search/routers/get_search_router.py +21 -6
- cognee/api/v1/search/search.py +25 -5
- cognee/api/v1/sync/routers/get_sync_router.py +3 -3
- cognee/cli/commands/add_command.py +1 -1
- cognee/cli/commands/cognify_command.py +6 -0
- cognee/cli/commands/config_command.py +1 -1
- cognee/context_global_variables.py +5 -1
- cognee/eval_framework/answer_generation/answer_generation_executor.py +7 -8
- cognee/infrastructure/databases/cache/cache_db_interface.py +38 -1
- cognee/infrastructure/databases/cache/config.py +6 -0
- cognee/infrastructure/databases/cache/fscache/FsCacheAdapter.py +21 -0
- cognee/infrastructure/databases/cache/get_cache_engine.py +9 -3
- cognee/infrastructure/databases/cache/redis/RedisAdapter.py +60 -1
- cognee/infrastructure/databases/dataset_database_handler/supported_dataset_database_handlers.py +7 -0
- cognee/infrastructure/databases/graph/get_graph_engine.py +29 -1
- cognee/infrastructure/databases/graph/neo4j_driver/Neo4jAuraDevDatasetDatabaseHandler.py +62 -27
- cognee/infrastructure/databases/hybrid/neptune_analytics/NeptuneAnalyticsAdapter.py +17 -4
- cognee/infrastructure/databases/relational/sqlalchemy/SqlAlchemyAdapter.py +2 -1
- cognee/infrastructure/databases/vector/chromadb/ChromaDBAdapter.py +2 -0
- cognee/infrastructure/databases/vector/config.py +6 -0
- cognee/infrastructure/databases/vector/create_vector_engine.py +69 -22
- cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +64 -9
- cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +13 -2
- cognee/infrastructure/databases/vector/lancedb/LanceDBAdapter.py +16 -3
- cognee/infrastructure/databases/vector/models/ScoredResult.py +3 -3
- cognee/infrastructure/databases/vector/pgvector/PGVectorAdapter.py +16 -3
- cognee/infrastructure/databases/vector/pgvector/PGVectorDatasetDatabaseHandler.py +86 -0
- cognee/infrastructure/databases/vector/pgvector/create_db_and_tables.py +81 -2
- cognee/infrastructure/databases/vector/vector_db_interface.py +8 -0
- cognee/infrastructure/files/utils/get_data_file_path.py +33 -27
- cognee/infrastructure/llm/prompts/extract_query_time.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_event_entity_prompt.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_event_graph_prompt.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_graph_prompt.txt +2 -2
- cognee/infrastructure/llm/prompts/generate_graph_prompt_guided.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_graph_prompt_oneshot.txt +2 -2
- cognee/infrastructure/llm/prompts/generate_graph_prompt_simple.txt +1 -1
- cognee/infrastructure/llm/prompts/generate_graph_prompt_strict.txt +1 -1
- cognee/infrastructure/llm/prompts/search_type_selector_prompt.txt +6 -6
- cognee/infrastructure/llm/prompts/test.txt +1 -1
- cognee/infrastructure/llm/prompts/translate_content.txt +19 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +24 -0
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/llama_cpp/adapter.py +191 -0
- cognee/modules/chunking/models/DocumentChunk.py +0 -1
- cognee/modules/cognify/config.py +2 -0
- cognee/modules/data/models/Data.py +1 -0
- cognee/modules/engine/models/Entity.py +0 -1
- cognee/modules/engine/operations/setup.py +6 -0
- cognee/modules/graph/cognee_graph/CogneeGraph.py +150 -37
- cognee/modules/graph/cognee_graph/CogneeGraphElements.py +48 -2
- cognee/modules/graph/utils/__init__.py +1 -0
- cognee/modules/graph/utils/get_entity_nodes_from_triplets.py +12 -0
- cognee/modules/notebooks/methods/__init__.py +1 -0
- cognee/modules/notebooks/methods/create_notebook.py +0 -34
- cognee/modules/notebooks/methods/create_tutorial_notebooks.py +191 -0
- cognee/modules/notebooks/methods/get_notebooks.py +12 -8
- cognee/modules/notebooks/tutorials/cognee-basics/cell-1.md +3 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-2.md +10 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-3.md +7 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-4.py +28 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-5.py +3 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-6.py +9 -0
- cognee/modules/notebooks/tutorials/cognee-basics/cell-7.py +17 -0
- cognee/modules/notebooks/tutorials/cognee-basics/config.json +4 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-1.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-10.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-11.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-12.py +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-13.md +7 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-14.py +6 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-15.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-16.py +7 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-2.md +9 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-3.md +7 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-4.md +9 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-5.md +5 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-6.py +13 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-7.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-8.md +3 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/cell-9.py +31 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/config.json +4 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/copilot_conversations.json +107 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/guido_contributions.json +976 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/my_developer_rules.md +79 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/pep_style_guide.md +74 -0
- cognee/modules/notebooks/tutorials/python-development-with-cognee/data/zen_principles.md +74 -0
- cognee/modules/retrieval/EntityCompletionRetriever.py +51 -38
- cognee/modules/retrieval/__init__.py +0 -1
- cognee/modules/retrieval/base_retriever.py +66 -10
- cognee/modules/retrieval/chunks_retriever.py +57 -49
- cognee/modules/retrieval/coding_rules_retriever.py +12 -5
- cognee/modules/retrieval/completion_retriever.py +29 -28
- cognee/modules/retrieval/cypher_search_retriever.py +25 -20
- cognee/modules/retrieval/graph_completion_context_extension_retriever.py +42 -46
- cognee/modules/retrieval/graph_completion_cot_retriever.py +68 -51
- cognee/modules/retrieval/graph_completion_retriever.py +78 -63
- cognee/modules/retrieval/graph_summary_completion_retriever.py +2 -0
- cognee/modules/retrieval/lexical_retriever.py +34 -12
- cognee/modules/retrieval/natural_language_retriever.py +18 -15
- cognee/modules/retrieval/summaries_retriever.py +51 -34
- cognee/modules/retrieval/temporal_retriever.py +59 -49
- cognee/modules/retrieval/triplet_retriever.py +31 -32
- cognee/modules/retrieval/utils/access_tracking.py +88 -0
- cognee/modules/retrieval/utils/brute_force_triplet_search.py +99 -85
- cognee/modules/retrieval/utils/node_edge_vector_search.py +174 -0
- cognee/modules/search/methods/__init__.py +1 -0
- cognee/modules/search/methods/get_retriever_output.py +53 -0
- cognee/modules/search/methods/get_search_type_retriever_instance.py +252 -0
- cognee/modules/search/methods/search.py +90 -215
- cognee/modules/search/models/SearchResultPayload.py +67 -0
- cognee/modules/search/types/SearchResult.py +1 -8
- cognee/modules/search/types/SearchType.py +1 -2
- cognee/modules/search/types/__init__.py +1 -1
- cognee/modules/search/utils/__init__.py +1 -2
- cognee/modules/search/utils/transform_insights_to_graph.py +2 -2
- cognee/modules/search/utils/{transform_context_to_graph.py → transform_triplets_to_graph.py} +2 -2
- cognee/modules/users/authentication/default/default_transport.py +11 -1
- cognee/modules/users/authentication/get_api_auth_backend.py +2 -1
- cognee/modules/users/authentication/get_client_auth_backend.py +2 -1
- cognee/modules/users/methods/create_user.py +0 -9
- cognee/modules/users/permissions/methods/has_user_management_permission.py +29 -0
- cognee/modules/visualization/cognee_network_visualization.py +1 -1
- cognee/run_migrations.py +48 -0
- cognee/shared/exceptions/__init__.py +1 -3
- cognee/shared/exceptions/exceptions.py +11 -1
- cognee/shared/usage_logger.py +332 -0
- cognee/shared/utils.py +12 -5
- cognee/tasks/chunks/__init__.py +9 -0
- cognee/tasks/cleanup/cleanup_unused_data.py +172 -0
- cognee/tasks/graph/__init__.py +7 -0
- cognee/tasks/memify/__init__.py +8 -0
- cognee/tasks/memify/extract_usage_frequency.py +613 -0
- cognee/tasks/summarization/models.py +0 -2
- cognee/tasks/temporal_graph/__init__.py +0 -1
- cognee/tasks/translation/__init__.py +96 -0
- cognee/tasks/translation/config.py +110 -0
- cognee/tasks/translation/detect_language.py +190 -0
- cognee/tasks/translation/exceptions.py +62 -0
- cognee/tasks/translation/models.py +72 -0
- cognee/tasks/translation/providers/__init__.py +44 -0
- cognee/tasks/translation/providers/azure_provider.py +192 -0
- cognee/tasks/translation/providers/base.py +85 -0
- cognee/tasks/translation/providers/google_provider.py +158 -0
- cognee/tasks/translation/providers/llm_provider.py +143 -0
- cognee/tasks/translation/translate_content.py +282 -0
- cognee/tasks/web_scraper/default_url_crawler.py +6 -2
- cognee/tests/cli_tests/cli_unit_tests/test_cli_commands.py +1 -0
- cognee/tests/cli_tests/cli_unit_tests/test_cli_edge_cases.py +3 -0
- cognee/tests/integration/retrieval/test_brute_force_triplet_search_with_cognify.py +62 -0
- cognee/tests/integration/retrieval/test_chunks_retriever.py +115 -16
- cognee/tests/integration/retrieval/test_graph_completion_retriever.py +13 -5
- cognee/tests/integration/retrieval/test_graph_completion_retriever_context_extension.py +22 -20
- cognee/tests/integration/retrieval/test_graph_completion_retriever_cot.py +23 -24
- cognee/tests/integration/retrieval/test_rag_completion_retriever.py +70 -5
- cognee/tests/integration/retrieval/test_structured_output.py +62 -18
- cognee/tests/integration/retrieval/test_summaries_retriever.py +20 -9
- cognee/tests/integration/retrieval/test_temporal_retriever.py +38 -8
- cognee/tests/integration/retrieval/test_triplet_retriever.py +13 -4
- cognee/tests/integration/shared/test_usage_logger_integration.py +255 -0
- cognee/tests/tasks/translation/README.md +147 -0
- cognee/tests/tasks/translation/__init__.py +1 -0
- cognee/tests/tasks/translation/config_test.py +93 -0
- cognee/tests/tasks/translation/detect_language_test.py +118 -0
- cognee/tests/tasks/translation/providers_test.py +151 -0
- cognee/tests/tasks/translation/translate_content_test.py +213 -0
- cognee/tests/test_chromadb.py +1 -1
- cognee/tests/test_cleanup_unused_data.py +165 -0
- cognee/tests/test_delete_by_id.py +6 -6
- cognee/tests/test_extract_usage_frequency.py +308 -0
- cognee/tests/test_kuzu.py +17 -7
- cognee/tests/test_lancedb.py +3 -1
- cognee/tests/test_library.py +1 -1
- cognee/tests/test_neo4j.py +17 -7
- cognee/tests/test_neptune_analytics_vector.py +3 -1
- cognee/tests/test_permissions.py +172 -187
- cognee/tests/test_pgvector.py +3 -1
- cognee/tests/test_relational_db_migration.py +15 -1
- cognee/tests/test_remote_kuzu.py +3 -1
- cognee/tests/test_s3_file_storage.py +1 -1
- cognee/tests/test_search_db.py +97 -110
- cognee/tests/test_usage_logger_e2e.py +268 -0
- cognee/tests/unit/api/test_get_raw_data_endpoint.py +206 -0
- cognee/tests/unit/eval_framework/answer_generation_test.py +4 -3
- cognee/tests/unit/infrastructure/databases/cache/test_cache_config.py +2 -0
- cognee/tests/unit/modules/graph/cognee_graph_elements_test.py +42 -2
- cognee/tests/unit/modules/graph/cognee_graph_test.py +329 -31
- cognee/tests/unit/modules/retrieval/chunks_retriever_test.py +31 -59
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_context_extension_test.py +70 -33
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py +72 -52
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_test.py +27 -33
- cognee/tests/unit/modules/retrieval/rag_completion_retriever_test.py +28 -15
- cognee/tests/unit/modules/retrieval/summaries_retriever_test.py +37 -42
- cognee/tests/unit/modules/retrieval/temporal_retriever_test.py +48 -64
- cognee/tests/unit/modules/retrieval/test_brute_force_triplet_search.py +263 -24
- cognee/tests/unit/modules/retrieval/test_node_edge_vector_search.py +273 -0
- cognee/tests/unit/modules/retrieval/triplet_retriever_test.py +30 -16
- cognee/tests/unit/modules/search/test_get_search_type_retriever_instance.py +125 -0
- cognee/tests/unit/modules/search/test_search.py +176 -0
- cognee/tests/unit/modules/search/test_search_prepare_search_result_contract.py +190 -0
- cognee/tests/unit/modules/users/test_tutorial_notebook_creation.py +511 -297
- cognee/tests/unit/shared/test_usage_logger.py +241 -0
- cognee/tests/unit/users/permissions/test_has_user_management_permission.py +46 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dist-info}/METADATA +22 -17
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dist-info}/RECORD +235 -147
- cognee/api/.env.example +0 -5
- cognee/modules/retrieval/base_graph_retriever.py +0 -24
- cognee/modules/search/methods/get_search_type_tools.py +0 -223
- cognee/modules/search/methods/no_access_control_search.py +0 -62
- cognee/modules/search/utils/prepare_search_result.py +0 -63
- cognee/tests/test_feedback_enrichment.py +0 -174
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dist-info}/WHEEL +0 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dist-info}/entry_points.txt +0 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dist-info}/licenses/LICENSE +0 -0
- {cognee-0.5.1.dev0.dist-info → cognee-0.5.2.dist-info}/licenses/NOTICE.md +0 -0
cognee/tests/test_permissions.py
CHANGED
|
@@ -1,227 +1,212 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import os
|
|
2
|
-
import cognee
|
|
3
3
|
import pathlib
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import pytest
|
|
6
|
+
import pytest_asyncio
|
|
7
|
+
from unittest.mock import AsyncMock, patch
|
|
8
|
+
|
|
9
|
+
import cognee
|
|
10
|
+
from cognee.context_global_variables import backend_access_control_enabled
|
|
11
|
+
from cognee.modules.engine.operations.setup import setup as engine_setup
|
|
7
12
|
from cognee.modules.search.types import SearchType
|
|
8
|
-
from cognee.modules.users.
|
|
13
|
+
from cognee.modules.users.exceptions import PermissionDeniedError
|
|
14
|
+
from cognee.modules.users.methods import create_user, get_user
|
|
9
15
|
from cognee.modules.users.permissions.methods import authorized_give_permission_on_datasets
|
|
10
|
-
from cognee.modules.
|
|
16
|
+
from cognee.modules.users.roles.methods import add_user_to_role, create_role
|
|
17
|
+
from cognee.modules.users.tenants.methods import (
|
|
18
|
+
add_user_to_tenant,
|
|
19
|
+
create_tenant,
|
|
20
|
+
select_tenant,
|
|
21
|
+
)
|
|
11
22
|
|
|
12
|
-
|
|
23
|
+
pytestmark = pytest.mark.asyncio
|
|
13
24
|
|
|
14
25
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
def _extract_dataset_id_from_cognify(cognify_result: dict):
|
|
27
|
+
"""Extract dataset_id from cognify output dictionary."""
|
|
28
|
+
for dataset_id, _pipeline_result in cognify_result.items():
|
|
29
|
+
return dataset_id
|
|
30
|
+
return None
|
|
18
31
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
|
|
33
|
+
async def _reset_engines_and_prune() -> None:
|
|
34
|
+
"""Reset db engine caches and prune data/system."""
|
|
35
|
+
try:
|
|
36
|
+
from cognee.infrastructure.databases.vector import get_vector_engine
|
|
37
|
+
|
|
38
|
+
vector_engine = get_vector_engine()
|
|
39
|
+
if hasattr(vector_engine, "engine") and hasattr(vector_engine.engine, "dispose"):
|
|
40
|
+
await vector_engine.engine.dispose(close=True)
|
|
41
|
+
except Exception:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
from cognee.infrastructure.databases.relational.create_relational_engine import (
|
|
45
|
+
create_relational_engine,
|
|
29
46
|
)
|
|
47
|
+
from cognee.infrastructure.databases.vector.create_vector_engine import _create_vector_engine
|
|
48
|
+
from cognee.infrastructure.databases.graph.get_graph_engine import _create_graph_engine
|
|
30
49
|
|
|
31
|
-
|
|
32
|
-
|
|
50
|
+
_create_graph_engine.cache_clear()
|
|
51
|
+
_create_vector_engine.cache_clear()
|
|
52
|
+
create_relational_engine.cache_clear()
|
|
33
53
|
|
|
34
54
|
await cognee.prune.prune_data()
|
|
35
55
|
await cognee.prune.prune_system(metadata=True)
|
|
36
56
|
|
|
37
|
-
explanation_file_path_nlp = os.path.join(
|
|
38
|
-
pathlib.Path(__file__).parent, "test_data/Natural_language_processing.txt"
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
# Add document for default user
|
|
42
|
-
await cognee.add([explanation_file_path_nlp], dataset_name="NLP")
|
|
43
|
-
default_user = await get_default_user()
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
)
|
|
58
|
+
@pytest.fixture(scope="module")
|
|
59
|
+
def event_loop():
|
|
60
|
+
"""Single event loop for this module (avoids cross-loop futures)."""
|
|
61
|
+
loop = asyncio.new_event_loop()
|
|
62
|
+
try:
|
|
63
|
+
yield loop
|
|
64
|
+
finally:
|
|
65
|
+
loop.close()
|
|
48
66
|
|
|
49
|
-
# Add document for test user
|
|
50
|
-
test_user = await create_user("user@example.com", "example")
|
|
51
|
-
await cognee.add([explanation_file_path_quantum], dataset_name="QUANTUM", user=test_user)
|
|
52
|
-
|
|
53
|
-
nlp_cognify_result = await cognee.cognify(["NLP"], user=default_user)
|
|
54
|
-
quantum_cognify_result = await cognee.cognify(["QUANTUM"], user=test_user)
|
|
55
|
-
|
|
56
|
-
# Extract dataset_ids from cognify results
|
|
57
|
-
def extract_dataset_id_from_cognify(cognify_result):
|
|
58
|
-
"""Extract dataset_id from cognify output dictionary"""
|
|
59
|
-
for dataset_id, pipeline_result in cognify_result.items():
|
|
60
|
-
return dataset_id # Return the first (and likely only) dataset_id
|
|
61
|
-
return None
|
|
62
|
-
|
|
63
|
-
# Get dataset IDs from cognify results
|
|
64
|
-
default_user_dataset_id = extract_dataset_id_from_cognify(nlp_cognify_result)
|
|
65
|
-
print("User is", default_user_dataset_id)
|
|
66
|
-
test_user_dataset_id = extract_dataset_id_from_cognify(quantum_cognify_result)
|
|
67
|
-
|
|
68
|
-
# Check if default_user can only see information from the NLP dataset
|
|
69
|
-
search_results = await cognee.search(
|
|
70
|
-
query_type=SearchType.GRAPH_COMPLETION,
|
|
71
|
-
query_text="What is in the document?",
|
|
72
|
-
user=default_user,
|
|
73
|
-
)
|
|
74
|
-
assert len(search_results) == 1, "The search results list lenght is not one."
|
|
75
|
-
print("\n\nExtracted sentences are:\n")
|
|
76
|
-
for result in search_results:
|
|
77
|
-
print(f"{result}\n")
|
|
78
|
-
assert search_results[0]["dataset_name"] == "NLP", (
|
|
79
|
-
f"Dict must contain dataset name 'NLP': {search_results[0]}"
|
|
80
|
-
)
|
|
81
67
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
88
|
-
assert len(search_results) == 1, "The search results list lenght is not one."
|
|
89
|
-
print("\n\nExtracted sentences are:\n")
|
|
90
|
-
for result in search_results:
|
|
91
|
-
print(f"{result}\n")
|
|
92
|
-
assert search_results[0]["dataset_name"] == "QUANTUM", (
|
|
93
|
-
f"Dict must contain dataset name 'QUANTUM': {search_results[0]}"
|
|
94
|
-
)
|
|
68
|
+
@pytest_asyncio.fixture(scope="module")
|
|
69
|
+
async def permissions_example_env(tmp_path_factory):
|
|
70
|
+
"""One-time environment setup for the permissions example test."""
|
|
71
|
+
# Ensure permissions feature is enabled (example requires it), but don't override if caller set it already.
|
|
72
|
+
os.environ.setdefault("ENABLE_BACKEND_ACCESS_CONTROL", "True")
|
|
95
73
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
await cognee.add(
|
|
100
|
-
[explanation_file_path_nlp],
|
|
101
|
-
dataset_name="QUANTUM",
|
|
102
|
-
dataset_id=test_user_dataset_id,
|
|
103
|
-
user=default_user,
|
|
104
|
-
)
|
|
105
|
-
except PermissionDeniedError:
|
|
106
|
-
add_error = True
|
|
107
|
-
assert add_error, "PermissionDeniedError was not raised during add as expected"
|
|
74
|
+
root = tmp_path_factory.mktemp("permissions_example")
|
|
75
|
+
cognee.config.data_root_directory(str(root / "data"))
|
|
76
|
+
cognee.config.system_root_directory(str(root / "system"))
|
|
108
77
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
try:
|
|
112
|
-
await cognee.cognify(datasets=[test_user_dataset_id], user=default_user)
|
|
113
|
-
except PermissionDeniedError:
|
|
114
|
-
cognify_error = True
|
|
115
|
-
assert cognify_error, "PermissionDeniedError was not raised during cognify as expected"
|
|
78
|
+
await _reset_engines_and_prune()
|
|
79
|
+
await engine_setup()
|
|
116
80
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
try:
|
|
120
|
-
await authorized_give_permission_on_datasets(
|
|
121
|
-
default_user.id,
|
|
122
|
-
[test_user_dataset_id],
|
|
123
|
-
"write",
|
|
124
|
-
default_user.id,
|
|
125
|
-
)
|
|
126
|
-
except PermissionDeniedError:
|
|
127
|
-
give_permission_error = True
|
|
128
|
-
assert give_permission_error, (
|
|
129
|
-
"PermissionDeniedError was not raised during assignment of permission as expected"
|
|
81
|
+
assert backend_access_control_enabled(), (
|
|
82
|
+
"Expected permissions to be enabled via ENABLE_BACKEND_ACCESS_CONTROL=True"
|
|
130
83
|
)
|
|
131
84
|
|
|
132
|
-
|
|
133
|
-
await authorized_give_permission_on_datasets(
|
|
134
|
-
default_user.id,
|
|
135
|
-
[test_user_dataset_id],
|
|
136
|
-
"write",
|
|
137
|
-
test_user.id,
|
|
138
|
-
)
|
|
85
|
+
yield
|
|
139
86
|
|
|
140
|
-
|
|
141
|
-
await cognee.add(
|
|
142
|
-
[explanation_file_path_nlp],
|
|
143
|
-
dataset_name="QUANTUM",
|
|
144
|
-
dataset_id=test_user_dataset_id,
|
|
145
|
-
user=default_user,
|
|
146
|
-
)
|
|
147
|
-
await cognee.cognify(datasets=[test_user_dataset_id], user=default_user)
|
|
148
|
-
|
|
149
|
-
# Actually give permission to default_user to read on test_users dataset
|
|
150
|
-
await authorized_give_permission_on_datasets(
|
|
151
|
-
default_user.id,
|
|
152
|
-
[test_user_dataset_id],
|
|
153
|
-
"read",
|
|
154
|
-
test_user.id,
|
|
155
|
-
)
|
|
87
|
+
await _reset_engines_and_prune()
|
|
156
88
|
|
|
157
|
-
# Check if default_user can see from test_users datasets now
|
|
158
|
-
search_results = await cognee.search(
|
|
159
|
-
query_type=SearchType.GRAPH_COMPLETION,
|
|
160
|
-
query_text="What is in the document?",
|
|
161
|
-
user=default_user,
|
|
162
|
-
dataset_ids=[test_user_dataset_id],
|
|
163
|
-
)
|
|
164
|
-
assert len(search_results) == 1, "The search results list length is not one."
|
|
165
|
-
print("\n\nExtracted sentences are:\n")
|
|
166
|
-
for result in search_results:
|
|
167
|
-
print(f"{result}\n")
|
|
168
89
|
|
|
169
|
-
|
|
170
|
-
|
|
90
|
+
async def test_permissions_example_flow(permissions_example_env):
|
|
91
|
+
"""Pytest version of `examples/python/permissions_example.py` (same scenarios, asserts instead of prints)."""
|
|
92
|
+
# Patch LLM calls so GRAPH_COMPLETION can run without external API keys.
|
|
93
|
+
llm_patch = patch(
|
|
94
|
+
"cognee.infrastructure.llm.LLMGateway.LLMGateway.acreate_structured_output",
|
|
95
|
+
new_callable=AsyncMock,
|
|
96
|
+
return_value="MOCK_ANSWER",
|
|
171
97
|
)
|
|
172
98
|
|
|
173
|
-
#
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
99
|
+
# Resolve example data file path (repo-shipped PDF).
|
|
100
|
+
repo_root = pathlib.Path(__file__).resolve().parent
|
|
101
|
+
explanation_file_path = str(repo_root / "test_data" / "artificial-intelligence.pdf")
|
|
102
|
+
assert pathlib.Path(explanation_file_path).exists(), (
|
|
103
|
+
f"Expected example PDF to exist at {explanation_file_path}"
|
|
178
104
|
)
|
|
179
|
-
assert len(search_results) == 2, "The search results list length is not two."
|
|
180
|
-
print("\n\nExtracted sentences are:\n")
|
|
181
|
-
for result in search_results:
|
|
182
|
-
print(f"{result}\n")
|
|
183
105
|
|
|
184
|
-
#
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
106
|
+
# Same QUANTUM text as in the example.
|
|
107
|
+
text = """A quantum computer is a computer that takes advantage of quantum mechanical phenomena.
|
|
108
|
+
At small scales, physical matter exhibits properties of both particles and waves, and quantum computing leverages
|
|
109
|
+
this behavior, specifically quantum superposition and entanglement, using specialized hardware that supports the
|
|
110
|
+
preparation and manipulation of quantum states.
|
|
111
|
+
"""
|
|
190
112
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
except PermissionDeniedError:
|
|
195
|
-
delete_error = True
|
|
113
|
+
# Create user_1, add AI dataset.
|
|
114
|
+
user_1 = await create_user("user_1@example.com", "example")
|
|
115
|
+
await cognee.add([explanation_file_path], dataset_name="AI", user=user_1)
|
|
196
116
|
|
|
197
|
-
|
|
117
|
+
# Create user_2, add QUANTUM dataset.
|
|
118
|
+
user_2 = await create_user("user_2@example.com", "example")
|
|
119
|
+
await cognee.add([text], dataset_name="QUANTUM", user=user_2)
|
|
198
120
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
test_user_dataset_data = await get_dataset_data(test_user_dataset_id)
|
|
202
|
-
text_data_id = test_user_dataset_data[0].id
|
|
121
|
+
ai_cognify_result = await cognee.cognify(["AI"], user=user_1)
|
|
122
|
+
quantum_cognify_result = await cognee.cognify(["QUANTUM"], user=user_2)
|
|
203
123
|
|
|
204
|
-
|
|
124
|
+
ai_dataset_id = _extract_dataset_id_from_cognify(ai_cognify_result)
|
|
125
|
+
quantum_dataset_id = _extract_dataset_id_from_cognify(quantum_cognify_result)
|
|
126
|
+
assert ai_dataset_id is not None
|
|
127
|
+
assert quantum_dataset_id is not None
|
|
205
128
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
129
|
+
with llm_patch:
|
|
130
|
+
# user_1 can read own dataset.
|
|
131
|
+
search_results = await cognee.search(
|
|
132
|
+
query_type=SearchType.GRAPH_COMPLETION,
|
|
133
|
+
query_text="What is in the document?",
|
|
134
|
+
user=user_1,
|
|
135
|
+
datasets=[ai_dataset_id],
|
|
136
|
+
)
|
|
137
|
+
assert isinstance(search_results, list) and len(search_results) == 1
|
|
138
|
+
assert search_results[0]["dataset_name"] == "AI"
|
|
139
|
+
assert search_results[0]["search_result"] == ["MOCK_ANSWER"]
|
|
140
|
+
|
|
141
|
+
# user_1 can't read dataset owned by user_2.
|
|
142
|
+
with pytest.raises(PermissionDeniedError):
|
|
143
|
+
await cognee.search(
|
|
144
|
+
query_type=SearchType.GRAPH_COMPLETION,
|
|
145
|
+
query_text="What is in the document?",
|
|
146
|
+
user=user_1,
|
|
147
|
+
datasets=[quantum_dataset_id],
|
|
148
|
+
)
|
|
213
149
|
|
|
214
|
-
#
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
explanation_file_data_id = test_user_dataset_data[0].id
|
|
150
|
+
# user_1 can't add to user_2's dataset.
|
|
151
|
+
with pytest.raises(PermissionDeniedError):
|
|
152
|
+
await cognee.add([explanation_file_path], dataset_id=quantum_dataset_id, user=user_1)
|
|
218
153
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
154
|
+
# user_2 grants read permission to user_1 for QUANTUM dataset.
|
|
155
|
+
await authorized_give_permission_on_datasets(
|
|
156
|
+
user_1.id, [quantum_dataset_id], "read", user_2.id
|
|
157
|
+
)
|
|
222
158
|
|
|
159
|
+
with llm_patch:
|
|
160
|
+
# Now user_1 can read QUANTUM dataset via dataset_id.
|
|
161
|
+
search_results = await cognee.search(
|
|
162
|
+
query_type=SearchType.GRAPH_COMPLETION,
|
|
163
|
+
query_text="What is in the document?",
|
|
164
|
+
user=user_1,
|
|
165
|
+
dataset_ids=[quantum_dataset_id],
|
|
166
|
+
)
|
|
167
|
+
assert isinstance(search_results, list) and len(search_results) == 1
|
|
168
|
+
assert search_results[0]["dataset_name"] == "QUANTUM"
|
|
169
|
+
assert search_results[0]["search_result"] == ["MOCK_ANSWER"]
|
|
170
|
+
|
|
171
|
+
# Tenant + role scenario.
|
|
172
|
+
tenant_id = await create_tenant("CogneeLab", user_2.id)
|
|
173
|
+
await select_tenant(user_id=user_2.id, tenant_id=tenant_id)
|
|
174
|
+
role_id = await create_role(role_name="Researcher", owner_id=user_2.id)
|
|
175
|
+
|
|
176
|
+
user_3 = await create_user("user_3@example.com", "example")
|
|
177
|
+
await add_user_to_tenant(user_id=user_3.id, tenant_id=tenant_id, owner_id=user_2.id)
|
|
178
|
+
await add_user_to_role(user_id=user_3.id, role_id=role_id, owner_id=user_2.id)
|
|
179
|
+
await select_tenant(user_id=user_3.id, tenant_id=tenant_id)
|
|
180
|
+
|
|
181
|
+
# Can't grant role permission on a dataset that isn't part of the active tenant.
|
|
182
|
+
with pytest.raises(PermissionDeniedError):
|
|
183
|
+
await authorized_give_permission_on_datasets(
|
|
184
|
+
role_id, [quantum_dataset_id], "read", user_2.id
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Re-create QUANTUM dataset in CogneeLab tenant so role permissions can be assigned.
|
|
188
|
+
user_2 = await get_user(user_2.id) # refresh tenant context
|
|
189
|
+
await cognee.add([text], dataset_name="QUANTUM_COGNEE_LAB", user=user_2)
|
|
190
|
+
quantum_cognee_lab_cognify_result = await cognee.cognify(
|
|
191
|
+
["QUANTUM_COGNEE_LAB"], user=user_2
|
|
192
|
+
)
|
|
193
|
+
quantum_cognee_lab_dataset_id = _extract_dataset_id_from_cognify(
|
|
194
|
+
quantum_cognee_lab_cognify_result
|
|
195
|
+
)
|
|
196
|
+
assert quantum_cognee_lab_dataset_id is not None
|
|
223
197
|
|
|
224
|
-
|
|
225
|
-
|
|
198
|
+
await authorized_give_permission_on_datasets(
|
|
199
|
+
role_id, [quantum_cognee_lab_dataset_id], "read", user_2.id
|
|
200
|
+
)
|
|
226
201
|
|
|
227
|
-
|
|
202
|
+
with llm_patch:
|
|
203
|
+
# user_3 can read via role permission.
|
|
204
|
+
search_results = await cognee.search(
|
|
205
|
+
query_type=SearchType.GRAPH_COMPLETION,
|
|
206
|
+
query_text="What is in the document?",
|
|
207
|
+
user=user_3,
|
|
208
|
+
dataset_ids=[quantum_cognee_lab_dataset_id],
|
|
209
|
+
)
|
|
210
|
+
assert isinstance(search_results, list) and len(search_results) == 1
|
|
211
|
+
assert search_results[0]["dataset_name"] == "QUANTUM_COGNEE_LAB"
|
|
212
|
+
assert search_results[0]["search_result"] == ["MOCK_ANSWER"]
|
cognee/tests/test_pgvector.py
CHANGED
|
@@ -163,7 +163,9 @@ async def main():
|
|
|
163
163
|
await test_getting_of_documents(dataset_name_1)
|
|
164
164
|
|
|
165
165
|
vector_engine = get_vector_engine()
|
|
166
|
-
random_node = (
|
|
166
|
+
random_node = (
|
|
167
|
+
await vector_engine.search("Entity_name", "Quantum computer", include_payload=True)
|
|
168
|
+
)[0]
|
|
167
169
|
random_node_name = random_node.payload["text"]
|
|
168
170
|
|
|
169
171
|
search_results = await cognee.search(
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import pathlib
|
|
2
2
|
import os
|
|
3
3
|
from cognee.infrastructure.databases.graph import get_graph_engine
|
|
4
|
+
from cognee.modules.data.methods.create_authorized_dataset import create_authorized_dataset
|
|
5
|
+
from cognee.modules.users.methods import get_default_user
|
|
4
6
|
from cognee.infrastructure.databases.relational import (
|
|
5
7
|
get_migration_relational_engine,
|
|
6
8
|
create_db_and_tables as create_relational_db_and_tables,
|
|
@@ -12,6 +14,8 @@ from cognee.tasks.ingestion import migrate_relational_database
|
|
|
12
14
|
from cognee.modules.search.types import SearchType
|
|
13
15
|
import cognee
|
|
14
16
|
|
|
17
|
+
TEST_DATASET_NAME = "migration_test_dataset"
|
|
18
|
+
|
|
15
19
|
|
|
16
20
|
def nodes_dict(nodes):
|
|
17
21
|
return {n_id: data for (n_id, data) in nodes}
|
|
@@ -35,6 +39,9 @@ async def setup_test_db():
|
|
|
35
39
|
await create_relational_db_and_tables()
|
|
36
40
|
await create_pgvector_db_and_tables()
|
|
37
41
|
|
|
42
|
+
user = await get_default_user()
|
|
43
|
+
await create_authorized_dataset(TEST_DATASET_NAME, user)
|
|
44
|
+
|
|
38
45
|
migration_engine = get_migration_relational_engine()
|
|
39
46
|
return migration_engine
|
|
40
47
|
|
|
@@ -48,7 +55,9 @@ async def relational_db_migration():
|
|
|
48
55
|
|
|
49
56
|
# 1. Search the graph
|
|
50
57
|
search_results = await cognee.search(
|
|
51
|
-
query_type=SearchType.GRAPH_COMPLETION,
|
|
58
|
+
query_type=SearchType.GRAPH_COMPLETION,
|
|
59
|
+
query_text="Tell me about the artist AC/DC",
|
|
60
|
+
datasets=[TEST_DATASET_NAME],
|
|
52
61
|
)
|
|
53
62
|
print("Search results:", search_results)
|
|
54
63
|
|
|
@@ -215,6 +224,7 @@ async def test_schema_only_migration():
|
|
|
215
224
|
query_text="How many tables are there in this database",
|
|
216
225
|
query_type=cognee.SearchType.GRAPH_COMPLETION,
|
|
217
226
|
top_k=30,
|
|
227
|
+
datasets=[TEST_DATASET_NAME],
|
|
218
228
|
)
|
|
219
229
|
assert any("11" in r for r in search_results), (
|
|
220
230
|
"Number of tables in the database reported in search_results is either None or not equal to 11"
|
|
@@ -278,6 +288,9 @@ async def test_search_result_quality():
|
|
|
278
288
|
get_migration_relational_engine,
|
|
279
289
|
)
|
|
280
290
|
|
|
291
|
+
user = await get_default_user()
|
|
292
|
+
await create_authorized_dataset(TEST_DATASET_NAME, user)
|
|
293
|
+
|
|
281
294
|
# Get relational database with original data
|
|
282
295
|
migration_engine = get_migration_relational_engine()
|
|
283
296
|
from sqlalchemy import text
|
|
@@ -308,6 +321,7 @@ async def test_search_result_quality():
|
|
|
308
321
|
query_text=f"List me all the invoices of Customer:{row.FirstName} {row.LastName}.",
|
|
309
322
|
top_k=50,
|
|
310
323
|
system_prompt="Just return me the invoiceID as a number without any text. This is an example output: ['1', '2', '3']. Where 1, 2, 3 are invoiceIDs of an invoice",
|
|
324
|
+
datasets=[TEST_DATASET_NAME],
|
|
311
325
|
)
|
|
312
326
|
print(f"Cognee search result: {search_results}")
|
|
313
327
|
|
cognee/tests/test_remote_kuzu.py
CHANGED
|
@@ -58,7 +58,9 @@ async def main():
|
|
|
58
58
|
from cognee.infrastructure.databases.vector import get_vector_engine
|
|
59
59
|
|
|
60
60
|
vector_engine = get_vector_engine()
|
|
61
|
-
random_node = (
|
|
61
|
+
random_node = (
|
|
62
|
+
await vector_engine.search("Entity_name", "Quantum computer", include_payload=True)
|
|
63
|
+
)[0]
|
|
62
64
|
random_node_name = random_node.payload["text"]
|
|
63
65
|
|
|
64
66
|
search_results = await cognee.search(
|
|
@@ -43,7 +43,7 @@ async def main():
|
|
|
43
43
|
from cognee.infrastructure.databases.vector import get_vector_engine
|
|
44
44
|
|
|
45
45
|
vector_engine = get_vector_engine()
|
|
46
|
-
random_node = (await vector_engine.search("Entity_name", "AI"))[0]
|
|
46
|
+
random_node = (await vector_engine.search("Entity_name", "AI", include_payload=True))[0]
|
|
47
47
|
random_node_name = random_node.payload["text"]
|
|
48
48
|
|
|
49
49
|
search_results = await cognee.search(
|