Skip to main content

A fluent graph query library for Python with ElementStore and graph operations

Project description

Graph Elements Python Library

A Python library for graph-based data structures and queries, providing TypeScript-equivalent functionality for managing BaseElement, Node, Edge, MetaNode, and ElementStore classes with a powerful fluent GraphQuery API.

Features

  • 🧩 Complete Graph Elements: BaseElement, Node, Edge, MetaNode classes with full TypeScript parity
  • 🔍 Powerful Query API: Fluent GraphQuery interface with comprehensive filtering operators
  • Clean API: Simple addNode(), createNode(), addEdge() methods with Props class
  • 🔗 Shorter Query Syntax: classId(), where(), gte(), order_by(), first() aliases
  • �🗄️ Flexible Storage: ElementStore with pluggable storage backends (memory, custom implementations)
  • 📊 Rich Filtering: Support for EQ, GT, LT, GTE, LTE, BETWEEN, CONTAINS, STARTS_WITH, ENDS_WITH, REGEX, IN operators
  • 🔄 Method Chaining: Intuitive fluent API for complex query composition
  • 📈 Aggregation Functions: count, sum, mean/avg, median, min, max operations
  • 🎯 Type Safe: Full typing support with TypeScript-equivalent interfaces
  • Async Support: Async versions of node and edge creation methods
  • Well Tested: Comprehensive test suite with 297 test cases

Installation

For End Users

# Install from PyPI (recommended)
pip install graph-api-python

# Or install from GitHub (latest development version)
pip install git+https://github.com/damylen/graph-api-python.git@main

# Install specific version from GitHub
pip install git+https://github.com/damylen/graph-api-python.git@v0.1.0

For Development

This project uses uv for fast, reliable Python package management.

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Clone and set up the project
git clone <repository-url>
cd graph-api
uv sync

Quick Start

from graph_api import GraphQuery, ElementStore, Props

# Create an element store
store = ElementStore()

# Add nodes using the clean API
alice = store.addNode('person', name="Alice", age=30, tags=["developer", "senior"])
bob = store.addNode('person', name="Bob", age=28, tags=["designer"])

# Or create with Props object
props = Props(name="Carol", age=32, department="Engineering")
carol = store.addNode('person', props)

# Create edges between nodes
friendship = store.addEdge('friendship', alice, bob, strength=0.9, type="close_friends")

# Create queries with intuitive syntax
query = GraphQuery(store)

# Basic filtering
people = query.classId('person').r()

# Advanced filtering with method chaining
senior_devs = (query
    .classId('person')
    .gte('age', 25)
    .contains('tags', 'senior')
    .r())

# Aggregations
total_people = query.classId('person').count()
avg_age = query.classId('person').avg('age')

# Sorting and limiting
youngest = (query
    .classId('person')
    .order_by('age', 'asc')
    .first(5)
    .r())

API Usage

The library provides a clean, intuitive API for graph operations:

Node Operations

from graph_api import ElementStore, Props

store = ElementStore()

# Add nodes with keyword arguments
person = store.addNode('person', name="John", age=30, city="Boston")

# Add nodes with Props object
props = Props(name="Alice", age=28, job="Engineer")
alice = store.addNode('person', props)

# Create nodes without adding to store
node = store.createNode('person', name="Bob", age=25)
# Later add to store
store.addNode(node)

# Async versions available
async def add_user():
    user = await store.addNodeAsync('user', name="Async User", active=True)
    return user

Edge Operations

# Create relationships between nodes
alice = store.addNode('person', name="Alice")
bob = store.addNode('person', name="Bob")

# Add edge with properties
friendship = store.addEdge('friendship', alice, bob, 
                          strength=0.9, type="close_friends")

# Create edge without adding to store
edge = store.createEdge('relationship', alice, bob, 
                       Props(type="colleague", department="Engineering"))

# Async edge creation
async def create_relationship():
    rel = await store.addEdgeAsync('follows', alice, bob, since="2023")
    return rel

Props Class

The Props class provides a simple way to define element properties:

from graph_api import Props

# Create props with keyword arguments
props = Props(name="Alice", age=30, job="Engineer")

# Props behaves like a dictionary
props['department'] = "Engineering"
assert props['name'] == "Alice"
assert 'age' in props

Query Methods

Filtering Methods

  • classId(class_id): Filter by element class ID
  • where(key, operator, value): Filter by property with operator
  • where(key, value): Filter by property equality (shorthand)
  • prop(key, value): Alias for property equality
  • gt(key, value), lt(key, value), gte(key, value), lte(key, value): Comparison operators
  • contains(key, value): Check if property contains value
  • startsWith(key, value), endsWith(key, value): String matching

Sorting and Limiting

  • order_by(property, direction): Sort by property ('asc' or 'desc')
  • first(n): Limit to first N results
  • last(n): Limit to last N results

Aggregation Methods

  • count(): Count results
  • sum(property): Sum numeric property
  • avg(property): Average of numeric property
  • median(property): Median of numeric property
  • min(property): Minimum of numeric property
  • max(property): Maximum of numeric property

Example Usage

# Chain methods for complex queries
young_engineers = (query
    .classId('person')
    .where('department', 'Engineering')
    .lt('age', 35)
    .order_by('age', 'desc')
    .first(10)
    .r())

# Use comparison operators
seniors = query.classId('person').gte('age', 30).r()

# Aggregations
avg_age = query.classId('person').avg('age')
total_people = query.classId('person').count()

Development

This project uses uv for dependency management and development workflows.

Prerequisites

  • Python 3.12+
  • uv

Setup

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Clone the repository
git clone <repository-url>
cd graph-api

# Create virtual environment and install dependencies
uv sync

# Install in development mode
uv pip install -e .

Running Tests

# Run all tests
uv run pytest tests/ -v

# Run tests with coverage
uv run pytest tests/ -v --cov=graph_api --cov-report=html

# Run specific test file
uv run pytest tests/test_graph_query.py -v

Code Quality

# Run linting
uv run ruff check .

# Format code
uv run black .

# Sort imports
uv run isort .

# Type checking
uv run mypy graph_api/

# All quality checks
uv run ruff check . && uv run black --check . && uv run isort --check-only . && uv run mypy graph_api/

Adding Dependencies

# Add runtime dependency
uv add requests

# Add development dependency
uv add --dev pytest-mock

# Update dependencies
uv lock --upgrade

Using Makefile (Optional)

For convenience, common development tasks are available via Makefile:

# Set up development environment
make dev

# Run all quality checks and tests
make qa

# Run tests with coverage
make test

# Format code and fix linting
make lint-fix

# Build package
make build

# See all available commands
make help

Test Coverage

  • ✅ 297 tests passing
  • ✅ All filtering operators tested
  • ✅ Method chaining validated
  • ✅ Edge cases covered
  • ✅ Aggregation functions verified
  • ✅ Clean API methods tested
  • ✅ Async operations validated

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

graph_api_python-0.2.0.tar.gz (264.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

graph_api_python-0.2.0-py3-none-any.whl (38.2 kB view details)

Uploaded Python 3

File details

Details for the file graph_api_python-0.2.0.tar.gz.

File metadata

  • Download URL: graph_api_python-0.2.0.tar.gz
  • Upload date:
  • Size: 264.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for graph_api_python-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9677f3f8db894cdab5503ac5726edf761dcb5633dc09355521611280c5c91fa6
MD5 ce1b95dce143b15dc3ef35e083232512
BLAKE2b-256 46b5c9bacf10ca7d69b54c3f8e2f124f71a950b1fda1ab50dcbbe3bda17f7ae8

See more details on using hashes here.

File details

Details for the file graph_api_python-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for graph_api_python-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1820d7193d19474bde46683a4d69684a4095e53777592bb46ba1ad730643b541
MD5 b3fd3f09b8b689545cfd929ff18c0cf7
BLAKE2b-256 6f2792135649b624355c842980bb2990acaf2a3be7f69674a4a04ea5f3a0c684

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page