Skip to content

Quickstart

Get Purple8 Graph running and execute your first hybrid query in under 5 minutes.

Prerequisites

  • Python 3.9 or later
  • pip

1. Install

bash
pip install purple8-graph

Optional extras

bash
# On-disk ANN index for vectors larger than RAM
pip install "purple8-graph[diskann]"

# Production: Prometheus metrics + OpenTelemetry tracing
pip install "purple8-graph[prod]"

# SAML 2.0 / SSO (Okta, Auth0, Azure AD, Google)
pip install "purple8-graph[saml]"

# AWS S3 backups
pip install "purple8-graph[s3]"

2. Create a graph and add data

python
from purple8_graph import GraphEngine
import numpy as np

# Open (or create) a database — no schema required, no config needed
engine = GraphEngine("./my_graph")

# Add some nodes — any labels, any properties
engine.add_node("doc1", labels=["Document"], properties={
    "title": "Attention is all you need",
    "year": 2017,
    "region": "Global",
})
engine.add_node("doc2", labels=["Document"], properties={
    "title": "BERT: Pre-training of Deep Bidirectional Transformers",
    "year": 2018,
    "region": "Global",
})
engine.add_node("vaswani", labels=["Person"], properties={"name": "Ashish Vaswani"})
engine.add_node("devlin",  labels=["Person"], properties={"name": "Jacob Devlin"})
engine.add_node("ml",      labels=["Topic"],  properties={"name": "Machine Learning"})

# Add relationships
engine.add_edge("doc1", "vaswani", "AUTHORED_BY")
engine.add_edge("doc2", "devlin",  "AUTHORED_BY")
engine.add_edge("doc1", "ml",      "BELONGS_TO")
engine.add_edge("doc2", "ml",      "BELONGS_TO")

3. Add vector embeddings

For real usage, use your embedding model of choice. For this quickstart, random vectors stand in:

python
# In production, replace with: openai.embeddings.create(...) or sentence_transformers.encode(...)
DIMS = 384
engine.add_node("doc1", labels=["Document"], properties={
    "title": "Attention is all you need",
    "year": 2017,
    "region": "Global",
    "embedding": np.random.rand(DIMS).tolist(),
})
engine.add_node("doc2", labels=["Document"], properties={
    "title": "BERT: Pre-training of Deep Bidirectional Transformers",
    "year": 2018,
    "region": "Global",
    "embedding": np.random.rand(DIMS).tolist(),
})

# Create the HNSW index over the 'embedding' property of Document nodes
engine.create_vector_index("Document", "embedding", dim=DIMS)

4. Run a hybrid query

python
# Simulate a query embedding
query_vec = np.random.rand(DIMS).tolist()

# Vector search + graph traversal — one Cypher statement
results = engine.execute_cypher("""
    CALL db.vector.search('Document', $vec, 10) YIELD node, score
    WHERE score > 0.5
    MATCH (node)-[:AUTHORED_BY]->(author:Person)
    MATCH (node)-[:BELONGS_TO]->(topic:Topic)
    RETURN node.title, author.name, topic.name, score
    ORDER BY score DESC
""", {"vec": query_vec})

for row in results:
    print(f"{row['node.title']}  (score={row['score']:.4f})")
    print(f"  Author: {row['author.name']}  Topic: {row['topic.name']}")

5. Query without vectors

Cypher also works without vector search — standard graph queries:

python
# Find all documents from a specific author
results = engine.execute_cypher("""
    MATCH (p:Person {name: 'Ashish Vaswani'})<-[:AUTHORED_BY]-(doc:Document)
    RETURN doc.title, doc.year
    ORDER BY doc.year
""")

# Multi-hop — find co-authors (people who share a topic)
results = engine.execute_cypher("""
    MATCH (p1:Person)<-[:AUTHORED_BY]-(doc:Document)-[:BELONGS_TO]->(t:Topic)
    MATCH (doc2:Document)-[:BELONGS_TO]->(t)<-[:BELONGS_TO]-(doc3:Document)
    MATCH (doc3)-[:AUTHORED_BY]->(p2:Person)
    WHERE p1 <> p2
    RETURN p1.name, p2.name, t.name
    LIMIT 10
""")

6. Start the REST API server (optional)

You don't need a server for embedded usage. But if you want a REST/GraphQL API:

bash
purple8-graph serve --db ./my_graph --port 8010

The server starts at http://localhost:8010. Interactive API docs at http://localhost:8010/docs.

bash
# Create an auth token
curl -s -X POST http://localhost:8010/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Purple8Admin!"}' \
  | jq .access_token

# Execute a Cypher query via REST
curl -s -X POST http://localhost:8010/v1/cypher \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{"query": "MATCH (n:Document) RETURN n.title LIMIT 5"}'

What's next?

Purple8 Graph is proprietary software. All rights reserved.