import asynciofrom typing import Anyfrom pydantic import SkipValidationimport cogneefrom cognee.infrastructure.engine import DataPointfrom cognee.infrastructure.engine.models.Edge import Edgefrom cognee.tasks.storage import add_data_pointsclass Person(DataPoint): name: str # Keep it simple for forward refs / mixed values knows: SkipValidation[Any] = None # single Person or list[Person] # Recommended: specify which fields to index for search metadata: dict = {"index_fields": ["name"]}async def main(): # Start clean (optional in your app) await cognee.prune.prune_data() await cognee.prune.prune_system(metadata=True) alice = Person(name="Alice") bob = Person(name="Bob") charlie = Person(name="Charlie") # Create relationships - field name becomes edge label alice.knows = bob # You can also do lists: alice.knows = [bob, charlie] # Optional: add weights and custom relationship types bob.knows = (Edge(weight=0.9, relationship_type="friend_of"), charlie) await add_data_points([alice, bob, charlie])if __name__ == "__main__": asyncio.run(main())
This example shows the complete workflow with metadata for indexing and optional edge weights. In practice, you can create complex nested models with multiple relationships and sophisticated data structures.
class Person(DataPoint): name: str knows: SkipValidation[Any] = None # Recommended: specify which fields to index for search metadata: dict = {"index_fields": ["name"]}
Create a Pydantic model that inherits from DataPoint. Use SkipValidation[Any] for fields that will hold other DataPoints to avoid forward reference issues. Metadata is recommended - it tells Cognee which fields to embed and store in the vector database for search.
Assign DataPoint instances to fields to create edges. The field name becomes the relationship label by default. Weights are optional - you can use Edge to add weights, custom relationship types, or other metadata to your relationships.
This converts your DataPoint instances into nodes and edges in the knowledge graph, automatically handling the graph structure and indexing. The name field gets embedded and stored in the vector database for search.