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
199 lines
6.6 KiB
Python
199 lines
6.6 KiB
Python
from typing import get_args
|
|
|
|
import pytest
|
|
from pydantic import BaseModel
|
|
|
|
from cognee.infrastructure.engine import DataPoint
|
|
from cognee.shared.graph_model_utils import (
|
|
datapoint_model_to_basemodel,
|
|
graph_model_to_graph_schema,
|
|
)
|
|
|
|
DATAPOINT_INFRA_FIELDS = {
|
|
"id",
|
|
"created_at",
|
|
"updated_at",
|
|
"ontology_valid",
|
|
"version",
|
|
"topological_rank",
|
|
"type",
|
|
"belongs_to_set",
|
|
"source_pipeline",
|
|
"source_task",
|
|
"source_node_set",
|
|
"source_user",
|
|
"source_content_hash",
|
|
"feedback_weight",
|
|
"importance_weight",
|
|
}
|
|
|
|
|
|
def assert_dump_has_no_infra(data):
|
|
"""Recursively assert model_dump output contains no DataPoint infra keys."""
|
|
if isinstance(data, dict):
|
|
assert DATAPOINT_INFRA_FIELDS.isdisjoint(data)
|
|
for value in data.values():
|
|
assert_dump_has_no_infra(value)
|
|
elif isinstance(data, list):
|
|
for item in data:
|
|
assert_dump_has_no_infra(item)
|
|
|
|
|
|
@pytest.fixture
|
|
def programming_language_models():
|
|
class FieldType(DataPoint):
|
|
name: str = "Field"
|
|
metadata: dict = {"index_fields": ["name"]}
|
|
|
|
class Field(DataPoint):
|
|
name: str
|
|
is_type: FieldType
|
|
metadata: dict = {"index_fields": ["name"]}
|
|
|
|
class ProgrammingLanguageType(DataPoint):
|
|
name: str = "Programming Language"
|
|
|
|
class ProgrammingLanguage(DataPoint):
|
|
name: str
|
|
used_in: list[Field] = []
|
|
is_type: ProgrammingLanguageType
|
|
metadata: dict = {"index_fields": ["name"]}
|
|
|
|
return {
|
|
"FieldType": FieldType,
|
|
"Field": Field,
|
|
"ProgrammingLanguageType": ProgrammingLanguageType,
|
|
"ProgrammingLanguage": ProgrammingLanguage,
|
|
}
|
|
|
|
|
|
def test_graph_model_to_graph_schema_supports_datapoint_subclasses():
|
|
class FieldType(DataPoint):
|
|
name: str = "Field"
|
|
|
|
class Field(DataPoint):
|
|
name: str
|
|
is_type: FieldType
|
|
|
|
schema = graph_model_to_graph_schema(Field)
|
|
|
|
assert schema["title"] == "Field"
|
|
assert "name" in schema["properties"]
|
|
assert "is_type" in schema["properties"]
|
|
assert "id" not in schema["properties"]
|
|
assert "version" not in schema["properties"]
|
|
|
|
field_type_schema = schema["$defs"]["FieldType"]
|
|
assert "id" not in field_type_schema["properties"]
|
|
assert "version" not in field_type_schema["properties"]
|
|
|
|
|
|
def test_graph_model_to_graph_schema_keeps_basemodel_behavior():
|
|
class FieldType(BaseModel):
|
|
name: str = "Field"
|
|
|
|
class Field(BaseModel):
|
|
name: str
|
|
is_type: FieldType
|
|
|
|
schema = graph_model_to_graph_schema(Field)
|
|
|
|
assert schema["title"] == "Field"
|
|
assert "name" in schema["properties"]
|
|
assert "is_type" in schema["properties"]
|
|
|
|
|
|
def test_datapoint_model_to_basemodel_simplifies_single_class(programming_language_models):
|
|
Field = programming_language_models["Field"]
|
|
|
|
simplified = datapoint_model_to_basemodel(Field)
|
|
|
|
assert issubclass(simplified, BaseModel)
|
|
assert not issubclass(simplified, DataPoint)
|
|
assert set(simplified.model_fields) == {"name", "is_type", "metadata"}
|
|
assert DATAPOINT_INFRA_FIELDS.isdisjoint(simplified.model_fields)
|
|
|
|
field_type = simplified.model_fields["is_type"].annotation
|
|
assert field_type().name == "Field"
|
|
|
|
instance = simplified(name="numpy", is_type=field_type())
|
|
assert instance.name == "numpy"
|
|
|
|
|
|
def test_datapoint_model_to_basemodel_recurses_nested_types(programming_language_models):
|
|
ProgrammingLanguage = programming_language_models["ProgrammingLanguage"]
|
|
|
|
simplified = datapoint_model_to_basemodel(ProgrammingLanguage)
|
|
field_type = simplified.model_fields["is_type"].annotation
|
|
field_model = get_args(simplified.model_fields["used_in"].annotation)[0]
|
|
nested_field_type = field_model.model_fields["is_type"].annotation
|
|
|
|
assert set(simplified.model_fields) == {"name", "used_in", "is_type", "metadata"}
|
|
assert not issubclass(field_model, DataPoint)
|
|
assert set(field_model.model_fields) == {"name", "is_type", "metadata"}
|
|
assert not issubclass(field_type, DataPoint)
|
|
assert set(field_type.model_fields) == {"name"}
|
|
assert not issubclass(nested_field_type, DataPoint)
|
|
assert set(nested_field_type.model_fields) == {"name", "metadata"}
|
|
|
|
instance = simplified(
|
|
name="Python",
|
|
is_type=field_type(),
|
|
used_in=[field_model(name="data analysis", is_type=nested_field_type())],
|
|
)
|
|
dump = instance.model_dump()
|
|
|
|
assert dump["name"] == "Python"
|
|
assert dump["used_in"][0]["name"] == "data analysis"
|
|
assert_dump_has_no_infra(dump)
|
|
|
|
|
|
def test_datapoint_model_to_basemodel_passthrough():
|
|
class PlainModel(BaseModel):
|
|
name: str
|
|
|
|
assert datapoint_model_to_basemodel(PlainModel) is PlainModel
|
|
|
|
|
|
def test_strip_metadata_flag(programming_language_models):
|
|
Field = programming_language_models["Field"]
|
|
ProgrammingLanguage = programming_language_models["ProgrammingLanguage"]
|
|
|
|
default_simplified = datapoint_model_to_basemodel(Field)
|
|
assert "metadata" in default_simplified.model_fields
|
|
|
|
stripped = datapoint_model_to_basemodel(ProgrammingLanguage, strip_metadata=True)
|
|
field_model = get_args(stripped.model_fields["used_in"].annotation)[0]
|
|
field_type = stripped.model_fields["is_type"].annotation
|
|
nested_field_type = field_model.model_fields["is_type"].annotation
|
|
|
|
assert "metadata" not in stripped.model_fields
|
|
assert "metadata" not in field_model.model_fields
|
|
assert "metadata" not in field_type.model_fields
|
|
assert "metadata" not in nested_field_type.model_fields
|
|
|
|
|
|
def test_rehydration_with_strip_metadata(programming_language_models):
|
|
ProgrammingLanguage = programming_language_models["ProgrammingLanguage"]
|
|
|
|
simplified = datapoint_model_to_basemodel(ProgrammingLanguage, strip_metadata=True)
|
|
field_model = get_args(simplified.model_fields["used_in"].annotation)[0]
|
|
field_type = simplified.model_fields["is_type"].annotation
|
|
nested_field_type = field_model.model_fields["is_type"].annotation
|
|
|
|
simplified_tree = simplified(
|
|
name="Python",
|
|
is_type=field_type(),
|
|
used_in=[field_model(name="data analysis", is_type=nested_field_type())],
|
|
)
|
|
|
|
rehydrated = ProgrammingLanguage.model_validate(simplified_tree.model_dump())
|
|
|
|
assert isinstance(rehydrated, ProgrammingLanguage)
|
|
assert rehydrated.name == "Python"
|
|
assert isinstance(rehydrated.is_type, programming_language_models["ProgrammingLanguageType"])
|
|
assert isinstance(rehydrated.used_in[0], programming_language_models["Field"])
|
|
assert rehydrated.used_in[0].name == "data analysis"
|
|
assert rehydrated.metadata["index_fields"] == ["name"]
|
|
assert rehydrated.used_in[0].metadata["index_fields"] == ["name"]
|