Files
wehub-resource-sync c889a57b6b
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:02:24 +08:00

208 lines
8.0 KiB
Python

import asyncio
from uuid import UUID
from typing import Optional
from cognee.context_global_variables import set_database_global_context_variables
from cognee.modules.users.models import User
from cognee.modules.users.methods import get_default_user
from cognee.modules.users.exceptions import PermissionDeniedError
from cognee.modules.data.methods import get_dataset_data, has_dataset_data
from cognee.modules.data.methods import get_authorized_dataset, get_authorized_existing_datasets
from cognee.modules.data.exceptions.exceptions import UnauthorizedDataAccessError
from cognee.modules.graph.methods import (
delete_data_nodes_and_edges,
delete_dataset_nodes_and_edges,
has_data_related_nodes,
legacy_delete,
try_delete_data_by_graph_provenance,
)
from cognee.modules.ingestion import discover_directory_datasets
from cognee.modules.pipelines.operations.get_pipeline_status import get_pipeline_status
from cognee.shared.logging_utils import get_logger
logger = get_logger()
class datasets:
"""
Dataset management namespace for Cognee.
All methods are static and provide operations for listing, inspecting,
and deleting datasets and the data items within them.
Example:
```python
import cognee
# List all accessible datasets
all_datasets = await cognee.datasets.list_datasets()
# Check cognify processing status for datasets
status = await cognee.datasets.get_status([dataset_id])
# Delete a specific data item from a dataset
await cognee.datasets.delete_data(dataset_id=dataset_id, data_id=data_id)
```
"""
@staticmethod
async def list_datasets(user: Optional[User] = None):
if user is None:
user = await get_default_user()
return await get_authorized_existing_datasets([], "read", user)
@staticmethod
def discover_datasets(directory_path: str):
return list(discover_directory_datasets(directory_path).keys())
@staticmethod
async def list_data(dataset_id: UUID, user: Optional[User] = None):
from cognee.modules.data.methods import get_dataset_data
if not user:
user = await get_default_user()
dataset = await get_authorized_dataset(user, dataset_id)
return await get_dataset_data(dataset.id)
@staticmethod
async def has_data(dataset_id: str, user: Optional[User] = None) -> bool:
if not user:
user = await get_default_user()
dataset = await get_authorized_dataset(user, dataset_id)
return await has_dataset_data(dataset.id)
@staticmethod
async def get_status(
dataset_ids: list[UUID], pipeline_names: Optional[list[str]] = None
) -> dict:
# Backward-compatible default behavior: cognify-only flat map.
if not pipeline_names:
return await get_pipeline_status(dataset_ids, pipeline_name="cognify_pipeline")
# Preserve order while removing duplicates.
requested_pipelines = list(dict.fromkeys(pipeline_names))
# For one pipeline, keep flat shape.
if len(requested_pipelines) == 1:
return await get_pipeline_status(dataset_ids, pipeline_name=requested_pipelines[0])
# For multiple pipelines, return nested shape.
statuses_by_dataset = {str(dataset_id): {} for dataset_id in dataset_ids}
for pipeline_name in requested_pipelines:
pipeline_status = await get_pipeline_status(dataset_ids, pipeline_name=pipeline_name)
for dataset_id, status in pipeline_status.items():
statuses_by_dataset.setdefault(dataset_id, {})[pipeline_name] = status
return statuses_by_dataset
@staticmethod
async def empty_dataset(dataset_id: UUID, user: Optional[User] = None):
from cognee.modules.data.methods import delete_data, delete_dataset
if not user:
user = await get_default_user()
dataset = await get_authorized_dataset(user, dataset_id, "delete")
if not dataset:
raise UnauthorizedDataAccessError(f"Dataset {dataset_id} not accessible.")
async with set_database_global_context_variables(dataset.id, dataset.owner_id):
await delete_dataset_nodes_and_edges(dataset_id, user.id)
dataset_data = await get_dataset_data(dataset.id)
# Delete dataset record first while DatasetData junction rows still exist,
# so pipeline_status cleanup can find related Data records.
result = await delete_dataset(dataset)
# Delete individual data records; use return_exceptions so all are attempted
# even if some fail.
if dataset_data:
results = await asyncio.gather(
*[delete_data(data, dataset_id) for data in dataset_data],
return_exceptions=True,
)
deletion_errors = [r for r in results if isinstance(r, Exception)]
if deletion_errors:
logger.error(
"Failed to delete %d/%d data items from dataset %s: %s",
len(deletion_errors),
len(dataset_data),
dataset_id,
deletion_errors,
)
return result
@staticmethod
async def delete_data(
dataset_id: UUID,
data_id: UUID,
user: Optional[User] = None,
mode: str = "soft", # mode is there for backwards compatibility. Don't use "hard", it is dangerous.
delete_dataset_if_empty: bool = False, # if this flag is True, delete the whole dataset if it is left empty after data deletion
):
from cognee.modules.data.methods import delete_data, get_data, delete_dataset
if not user:
user = await get_default_user()
try:
dataset = await get_authorized_dataset(user, dataset_id, "delete")
except PermissionDeniedError:
raise UnauthorizedDataAccessError(f"Dataset {dataset_id} not accessible.")
if not dataset:
raise UnauthorizedDataAccessError(f"Dataset {dataset_id} not accessible.")
dataset_data = [data for data in await get_dataset_data(dataset.id) if data.id == data_id]
data = dataset_data[0] if len(dataset_data) > 0 else None
if not data:
# If data is not found in the system, user is using a custom graph model.
async with set_database_global_context_variables(dataset_id, dataset.owner_id):
await delete_data_nodes_and_edges(dataset_id, data_id, user.id)
dataset_data = await get_dataset_data(dataset.id)
if not dataset_data and delete_dataset_if_empty:
await delete_dataset(dataset)
return {"status": "success"}
if not any(ds.id == dataset_id for ds in data.datasets):
raise UnauthorizedDataAccessError(f"Data {data_id} not accessible.")
async with set_database_global_context_variables(dataset_id, dataset.owner_id):
# Delete mode is exclusive: ledger rows imply the relational-ledger
# path; only ledger-free data probes the graph marker to distinguish
# graph-provenance data from legacy data without graph ownership.
if await has_data_related_nodes(dataset_id, data_id):
await delete_data_nodes_and_edges(dataset_id, data_id, user.id)
elif not await try_delete_data_by_graph_provenance(dataset_id, data_id):
await legacy_delete(data, "soft")
await delete_data(data, dataset_id)
dataset_data = await get_dataset_data(dataset.id)
if not dataset_data and delete_dataset_if_empty:
await delete_dataset(dataset)
return {"status": "success"}
@staticmethod
async def delete_all(user: Optional[User] = None):
if not user:
user = await get_default_user()
user_datasets = await get_authorized_existing_datasets([], "delete", user)
for dataset in user_datasets:
await datasets.empty_dataset(dataset.id, user)