Getting Started with Python
This tutorial walks you through installing GraphQLite and building a small social network graph from scratch. By the end you will know how to create nodes and relationships, query the graph with Cypher, explore the graph using built-in API methods, run a graph algorithm, and persist your work to a file.
What You Will Learn
- Install GraphQLite for Python
- Create nodes and relationships using the
Graphclass - Inspect graph statistics and explore connections
- Run Cypher queries with parameters
- Compute PageRank to find influential nodes
- Save the graph to a file and reopen it
Prerequisites
- Python 3.8 or later
pippackage manager
Step 1: Install GraphQLite
pip install graphqlite
Verify the installation:
import graphqlite
print(graphqlite.__version__) # 0.4.3
Step 2: Create an In-Memory Graph
from graphqlite import Graph
# ':memory:' creates a temporary in-memory database
g = Graph(":memory:")
print(g.stats())
# {'nodes': 0, 'edges': 0}
The Graph class is the high-level API. It manages the SQLite connection, loads the extension, and initialises the schema for you.
Step 3: Add Person Nodes
Add three people. Each node has a unique string ID, a dictionary of properties, and an optional label.
g.upsert_node("alice", {"name": "Alice", "age": 30, "city": "London"}, label="Person")
g.upsert_node("bob", {"name": "Bob", "age": 25, "city": "Paris"}, label="Person")
g.upsert_node("carol", {"name": "Carol", "age": 35, "city": "London"}, label="Person")
print(g.stats())
# {'nodes': 3, 'edges': 0}
upsert_node creates the node if the ID is new, or updates its properties if it already exists (merge semantics). This makes it safe to call repeatedly.
Verify a node was stored:
node = g.get_node("alice")
print(node)
# {'id': 'alice', 'label': 'Person', 'properties': {'name': 'Alice', 'age': 30, 'city': 'London'}}
Step 4: Add KNOWS Relationships
Connect the people:
g.upsert_edge("alice", "bob", {"since": 2020, "strength": "close"}, rel_type="KNOWS")
g.upsert_edge("alice", "carol", {"since": 2018, "strength": "close"}, rel_type="KNOWS")
g.upsert_edge("bob", "carol", {"since": 2021, "strength": "casual"}, rel_type="KNOWS")
print(g.stats())
# {'nodes': 3, 'edges': 3}
Relationships are directed. alice -> bob is not the same as bob -> alice.
Step 5: Inspect the Graph
Use built-in methods to explore the graph without writing Cypher:
# Check if specific connections exist
print(g.has_edge("alice", "bob")) # True
print(g.has_edge("bob", "alice")) # False (directed)
# Get Alice's outgoing neighbors
neighbors = g.get_neighbors("alice")
print([n["id"] for n in neighbors])
# ['bob', 'carol']
# Get degree (total connected edges, both directions)
print(g.node_degree("alice")) # 2
print(g.node_degree("carol")) # 2 (one in, one out)
List all nodes filtered by label:
people = g.get_all_nodes(label="Person")
for p in people:
print(p["id"], p["properties"]["name"])
# alice Alice
# bob Bob
# carol Carol
Step 6: Query with Cypher
The query() method runs a Cypher string and returns a list of dictionaries. For queries without user-supplied data, this is convenient:
results = g.query("""
MATCH (a:Person)-[:KNOWS]->(b:Person)
RETURN a.name AS from, b.name AS to, a.city AS city
ORDER BY a.name
""")
for row in results:
print(f"{row['from']} ({row['city']}) knows {row['to']}")
# Alice (London) knows Bob
# Alice (London) knows Carol
# Bob (Paris) knows Carol
Step 7: Parameterized Queries
When any part of the query comes from user input, use parameterized queries. Access the underlying Connection object via g.connection:
# Find everyone in a specific city — city name comes from user input
city = "London"
results = g.connection.cypher(
"MATCH (p:Person {city: $city}) RETURN p.name AS name, p.age AS age ORDER BY p.age",
{"city": city}
)
for row in results:
print(f"{row['name']}, age {row['age']}")
# Alice, age 30
# Carol, age 35
Parameters are passed as a Python dictionary and serialised to JSON internally. This protects against injection and handles special characters cleanly. See the parameterized queries guide for more detail.
Multi-hop traversal using parameters:
# Who does a given person know transitively (up to 2 hops)?
results = g.connection.cypher(
"""
MATCH (start:Person {name: $name})-[:KNOWS*1..2]->(other:Person)
RETURN DISTINCT other.name AS name
""",
{"name": "Alice"}
)
print([r["name"] for r in results])
# ['Bob', 'Carol']
Step 8: Run PageRank
Load the graph into the algorithm cache, then run PageRank. PageRank scores nodes by how many high-scoring nodes point to them.
# Load the graph cache (required before algorithms)
g.connection.cypher("RETURN gql_load_graph()")
results = g.pagerank(damping=0.85, iterations=20)
print("PageRank scores:")
for r in sorted(results, key=lambda x: x["score"], reverse=True):
print(f" {r['user_id']}: {r['score']:.4f}")
# PageRank scores:
# carol: 0.2282
# bob: 0.1847
# alice: 0.1471
Carol scores highest because two people point to her. See Graph Analytics for a full walkthrough of all 15+ algorithms.
Step 9: Persist to a File
Switching from :memory: to a file path makes the graph persistent:
# Save to a file
g_file = Graph("social.db")
g_file.upsert_node("alice", {"name": "Alice", "age": 30, "city": "London"}, label="Person")
g_file.upsert_node("bob", {"name": "Bob", "age": 25, "city": "Paris"}, label="Person")
g_file.upsert_node("carol", {"name": "Carol", "age": 35, "city": "London"}, label="Person")
g_file.upsert_edge("alice", "bob", {"since": 2020}, rel_type="KNOWS")
g_file.upsert_edge("alice", "carol", {"since": 2018}, rel_type="KNOWS")
g_file.upsert_edge("bob", "carol", {"since": 2021}, rel_type="KNOWS")
print(f"Saved: {g_file.stats()}")
# Saved: {'nodes': 3, 'edges': 3}
Reopen it later:
g_reopen = Graph("social.db")
print(g_reopen.stats())
# {'nodes': 3, 'edges': 3}
node = g_reopen.get_node("alice")
print(node["properties"]["name"])
# Alice
The database is a standard SQLite file. You can inspect it with any SQLite tool.
Summary
In this tutorial you:
- Installed GraphQLite with
pip install graphqlite - Created an in-memory graph using the
Graphclass - Added Person nodes with
upsert_node() - Added KNOWS relationships with
upsert_edge() - Explored the graph with
get_neighbors(),node_degree(), andstats() - Queried with Cypher via
g.query()andg.connection.cypher() - Used parameterized queries to safely handle user input
- Ran PageRank with
g.pagerank() - Persisted the graph to a
.dbfile
Next Steps
- Building a Knowledge Graph — A more complex domain with multiple node and relationship types
- Graph Analytics — All 15+ algorithms with worked examples
- Query Patterns (SQL) — Advanced Cypher patterns: UNWIND, WITH pipelines, CASE, UNION
- Python API Reference — Complete method documentation for
Graph,Connection, andGraphManager - Parameterized Queries Guide — Best practices for safe query construction