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.3.1.tar.gz (169.0 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.3.1-py3-none-any.whl (38.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: graph_api_python-0.3.1.tar.gz
  • Upload date:
  • Size: 169.0 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.3.1.tar.gz
Algorithm Hash digest
SHA256 f67b4d4e00056818bd0107506389efd883b2c789b0e695294bdf4bb153fe487d
MD5 2935b6350df2d95f6ecb5290d9d7122f
BLAKE2b-256 5fd2845916daf3952b15144dd0b919da747ce1bc3da9a7e90f5b6242cd79625f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for graph_api_python-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 18e282983cfa153e018283ce58a595f20660bbaae07ef295cc41912a2bc059bf
MD5 ba27039efe9a04fee147d6143204f19d
BLAKE2b-256 770be96852efb63bd1975a530aa8b327bfb1671791468ae5d1afa8e13f5f3360

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