Graph Examples

This page provides practical examples of working with knowledge graphs using the Graphora client library.

Retrieving a Graph

After a successful merge operation, you can retrieve the resulting knowledge graph:

from graphora import GraphoraClient

# Initialize the client with user ID (required)
client = GraphoraClient(
    base_url="https://api.graphora.io",
    user_id="your-user-id",  # Required for all API calls
    api_key="your-api-key"
)

# Get the merged graph using the merge ID and transform ID
merge_id = "merge_123456789"
transform_id = "transform_123456789"
graph = client.get_merged_graph(merge_id, transform_id)

# Print basic graph statistics
print(f"Graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")

# Explore node types
node_types = {}
for node in graph.nodes:
    for label in node.labels:
        if label in node_types:
            node_types[label] += 1
        else:
            node_types[label] = 1

print("Node types distribution:")
for node_type, count in node_types.items():
    print(f"  {node_type}: {count} nodes")

# Explore edge types
edge_types = {}
for edge in graph.edges:
    if edge.type in edge_types:
        edge_types[edge.type] += 1
    else:
        edge_types[edge.type] = 1

print("Edge types distribution:")
for edge_type, count in edge_types.items():
    print(f"  {edge_type}: {count} edges")

Retrieving a Transformed Graph

You can also retrieve the graph directly from a transformation before merging:

from graphora import GraphoraClient

# Initialize the client with user ID (required)
client = GraphoraClient(
    base_url="https://api.graphora.io",
    user_id="your-user-id",  # Required for all API calls
    api_key="your-api-key"
)

# Get the transformed graph using just the transform ID
transform_id = "transform_123456789"
graph = client.get_transformed_graph(transform_id=transform_id)

# Print basic graph statistics
print(f"Transformed graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")

# Examine the first few nodes
for i, node in enumerate(graph.nodes[:5]):
    print(f"Node {i+1}: {node.id}")
    print(f"  Labels: {node.labels}")
    print(f"  Properties: {node.properties}")

Querying Specific Nodes

You can query for specific nodes in the graph:

from graphora import GraphoraClient

# Initialize the client with user ID (required)
client = GraphoraClient(
    base_url="https://api.graphora.io",
    user_id="your-user-id",  # Required for all API calls
    api_key="your-api-key"
)

# Get the merged graph
merge_id = "merge_123456789"
transform_id = "transform_123456789"
graph = client.get_merged_graph(merge_id, transform_id)

# Find all Person nodes
person_nodes = [node for node in graph.nodes if "Person" in node.labels]
print(f"Found {len(person_nodes)} Person nodes")

# Find a specific person by name
target_name = "John Doe"
john_nodes = [node for node in person_nodes if node.properties.get("name") == target_name]

if john_nodes:
    john = john_nodes[0]
    print(f"Found {target_name}:")
    print(f"  ID: {john.id}")
    print(f"  Labels: {john.labels}")
    print(f"  Properties: {john.properties}")
    
    # Find all edges connected to this node
    john_edges = [edge for edge in graph.edges if edge.source == john.id or edge.target == john.id]
    print(f"  Connected through {len(john_edges)} relationships")
    
    for edge in john_edges:
        # Determine if John is the source or target
        if edge.source == john.id:
            # Find the target node
            target_nodes = [node for node in graph.nodes if node.id == edge.target]
            if target_nodes:
                target = target_nodes[0]
                print(f"  {target_name} {edge.type} {target.labels[0] if target.labels else 'Unknown'} ({target.properties.get('name', 'Unknown')})")
        else:
            # Find the source node
            source_nodes = [node for node in graph.nodes if node.id == edge.source]
            if source_nodes:
                source = source_nodes[0]
                print(f"  {source.labels[0] if source.labels else 'Unknown'} ({source.properties.get('name', 'Unknown')}) {edge.type} {target_name}")
else:
    print(f"No nodes found with name {target_name}")

Modifying Graph Data

You can modify the graph data and save changes back:

from graphora import GraphoraClient, SaveGraphRequest, NodeChange, EdgeChange

# Initialize the client with user ID (required)
client = GraphoraClient(
    base_url="https://api.graphora.io",
    user_id="your-user-id",  # Required for all API calls
    api_key="your-api-key"
)

# Get the current graph
transform_id = "transform_123456789"
graph = client.get_transformed_graph(transform_id=transform_id)

# Prepare changes
changes = SaveGraphRequest()

# Add a new node
new_node = NodeChange(
    labels=["Person"],
    properties={
        "name": "Jane Smith",
        "age": 30,
        "email": "[email protected]"
    }
)
changes.nodes.append(new_node)

# Modify an existing node (assuming we know its ID)
if graph.nodes:
    existing_node_id = graph.nodes[0].id
    modified_node = NodeChange(
        id=existing_node_id,
        labels=graph.nodes[0].labels,
        properties={
            **graph.nodes[0].properties,
            "last_updated": "2024-01-01"
        }
    )
    changes.nodes.append(modified_node)

# Add a new edge
if len(graph.nodes) >= 2:
    new_edge = EdgeChange(
        type="KNOWS",
        source=graph.nodes[0].id,
        target=graph.nodes[1].id,
        properties={"since": "2024"}
    )
    changes.edges.append(new_edge)

# Save the changes
response = client.update_transform_graph(transform_id, changes)
print(f"Graph updated successfully. New graph has {len(response.data.nodes)} nodes and {len(response.data.edges)} edges")

Converting to NetworkX for Advanced Analysis

You can convert the Graphora graph to a NetworkX graph for advanced analysis:

from graphora import GraphoraClient
import networkx as nx

# Initialize the client with user ID (required)
client = GraphoraClient(
    base_url="https://api.graphora.io",
    user_id="your-user-id",  # Required for all API calls
    api_key="your-api-key"
)

# Get the merged graph
merge_id = "merge_123456789"
transform_id = "transform_123456789"
graph = client.get_merged_graph(merge_id, transform_id)

# Convert to NetworkX graph
G = nx.Graph()

# Add nodes with their properties
for node in graph.nodes:
    G.add_node(node.id, labels=node.labels, **node.properties)

# Add edges with their properties
for edge in graph.edges:
    G.add_edge(edge.source, edge.target, type=edge.type, **edge.properties)

# Now you can use NetworkX algorithms
# Calculate centrality measures
degree_centrality = nx.degree_centrality(G)
betweenness_centrality = nx.betweenness_centrality(G)

# Find the most central nodes
top_degree_nodes = sorted(degree_centrality.items(), key=lambda x: x[1], reverse=True)[:5]
print("Top 5 nodes by degree centrality:")
for node_id, centrality in top_degree_nodes:
    node_labels = G.nodes[node_id]['labels']
    node_name = G.nodes[node_id].get('name', 'Unknown')
    print(f"  {node_name} ({node_labels[0] if node_labels else 'Unknown'}): {centrality:.4f}")

# Calculate basic graph metrics
print(f"Graph density: {nx.density(G):.4f}")
print(f"Number of connected components: {nx.number_connected_components(G)}")

if nx.is_connected(G):
    print(f"Average shortest path length: {nx.average_shortest_path_length(G):.4f}")
    print(f"Graph diameter: {nx.diameter(G)}")

These examples demonstrate the basic operations for working with knowledge graphs using the Graphora client library. For more detailed information about graph concepts and operations, see the Graph Concepts page.