Metadata-Version: 2.4
Name: networkx-graphql
Version: 0.1.2
Summary: NetworkX GraphQL
Project-URL: Homepage, https://erivlis.github.io/networkx-graphql
Project-URL: Documentation, https://erivlis.github.io/networkx-graphql
Project-URL: Bug Tracker, https://github.com/erivlis/networkx-graphql/issues
Project-URL: Source, https://github.com/erivlis/networkx-graphql
Author-email: Eran Rivlis <eran@rivlis.info>
License-File: LICENSE
Keywords: graph,graphql,networkx
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: <3.15,>=3.11
Requires-Dist: graphinate
Requires-Dist: networkx>=3.5
Provides-Extra: server
Requires-Dist: starlette-prometheus; extra == 'server'
Requires-Dist: uvicorn[standard]; extra == 'server'
Description-Content-Type: text/markdown

# networkx-graphql

> The QL in the nx.Graph

---

<table>
  <tr style="vertical-align: middle;">
    <td>Package</td>
    <td>
      <img alt="PyPI - Version" class="off-glb" loading="lazy" src="https://img.shields.io/pypi/v/networkx-graphql.svg?logo=pypi&logoColor=lightblue">
      <img alt="PyPI - Status" class="off-glb" loading="lazy" src="https://img.shields.io/pypi/status/networkx-graphql.svg?logo=pypi&logoColor=lightblue">
      <img alt="PyPI - Python Version" class="off-glb" loading="lazy" src="https://img.shields.io/pypi/pyversions/networkx-graphql.svg?logo=python&label=Python&logoColor=lightblue">
      <img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dd/networkx-graphql.svg?logo=pypi&logoColor=lightblue">
      <img alt="Libraries.io SourceRank" src="https://img.shields.io/librariesio/sourcerank/pypi/networkx-graphql.svg?logo=Libraries.io&label=SourceRank">
    </td>
  </tr>
  <tr>
    <td>Code</td>
    <td>
      <img alt="GitHub" src="https://img.shields.io/github/license/erivlis/networkx-graphql">
      <img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/erivlis/networkx-graphql.svg?label=Size&logo=git">
      <img alt="GitHub last commit (by committer)" src="https://img.shields.io/github/last-commit/erivlis/networkx-graphql.svg?&logo=git">
      <a href="https://github.com/erivlis/networkx-graphql/graphs/contributors"><img alt="Contributors" src="https://img.shields.io/github/contributors/erivlis/networkx-graphql.svg?&logo=git"></a>
    </td>
  </tr>
  <tr>
    <td>Tools</td>
    <td>
      <a href="https://www.jetbrains.com/pycharm/"><img alt="PyCharm" src="https://img.shields.io/badge/PyCharm-FCF84A.svg?logo=PyCharm&logoColor=black&labelColor=21D789&color=FCF84A"></a>
      <a href="https://github.com/astral-sh/uv"><img alt="uv" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" style="max-width:100%;"></a>
      <a href="https://github.com/astral-sh/ruff"><img alt="Ruff" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" style="max-width:100%;"></a>
      <!--a href="https://squidfunk.github.io/mkdocs-material/"><img src="https://img.shields.io/badge/Material_for_MkDocs-526CFE?&logo=MaterialForMkDocs&logoColor=white&labelColor=grey"></a-->
      <a href="https://hatch.pypa.io"><img alt="Hatch project" class="off-glb" loading="lazy" src="https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg"></a>
    </td>
  </tr>
  <tr>
    <td>CI/CD</td>
    <td>
      <a href="https://github.com/erivlis/networkx-graphql/actions/workflows/test.yml"><img alt="Test" src="https://github.com/erivlis/networkx-graphql/actions/workflows/test.yml/badge.svg"></a>
      <a href="https://github.com/erivlis/networkx-graphql/actions/workflows/publish.yml"><img alt="Publish" src="https://github.com/erivlis/networkx-graphql/actions/workflows/test-beta.yml/badge.svg"></a>
      <a href="https://github.com/erivlis/networkx-graphql/actions/workflows/publish.yml"><img alt="Publish" src="https://github.com/erivlis/networkx-graphql/actions/workflows/publish.yml/badge.svg"></a>
      <!--a href="https://github.com/erivlis/networkx-graphql/actions/workflows/publish-docs.yaml"><img alt="Publish Docs" src="https://github.com/erivlis/networkx-graphql/actions/workflows/publish-docs.yaml/badge.svg"></a-->
    </td>
  </tr>
  <tr>
    <td>Scans</td>
    <td>
      <a href="https://codecov.io/gh/erivlis/networkx-graphql"><img alt="Codecov Coverage" src="https://codecov.io/gh/erivlis/networkx-graphql/graph/badge.svg?token=deEsZ3pJD7"/></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Quality Gate Status" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=alert_status"></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Security Rating" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=security_rating"></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Maintainability Rating" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=sqale_rating"></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Reliability Rating" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=reliability_rating"></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Lines of Code" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=ncloc"></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Vulnerabilities" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=vulnerabilities"></a>
      <a href="https://sonarcloud.io/summary/new_code?id=erivlis_networkx-graphql"><img alt="Bugs" src="https://sonarcloud.io/api/project_badges/measure?project=erivlis_networkx-graphql&metric=bugs"></a>
      <a href="https://app.codacy.com/gh/erivlis/networkx-graphql/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img alt="Codacy Quality" src="https://app.codacy.com/project/badge/Grade/eeb375c023a9425f995e44eae66e41f0"></a>
      <a href="https://app.codacy.com/gh/erivlis/networkx-graphql/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage"><img alt="Codacy Coverage" src="https://app.codacy.com/project/badge/Coverage/eeb375c023a9425f995e44eae66e41f0"/></a>
      <a href="https://www.codefactor.io/repository/github/erivlis/networkx-graphql/overview/main"><img src="https://www.codefactor.io/repository/github/erivlis/networkx-graphql/badge/main" alt="CodeFactor" /></a>
      <a href="https://app.deepsource.com/gh/erivlis/networkx-graphql/" target="_blank"><img alt="DeepSource" title="DeepSource" src="https://app.deepsource.com/gh/erivlis/networkx-graphql.svg/?label=active+issues&show_trend=true&token=uyl1AJLBqgkY7MsVbtjPnf9j"/></a>
      <a href="https://app.deepsource.com/gh/erivlis/networkx-graphql/" target="_blank"><img alt="DeepSource" title="DeepSource" src="https://app.deepsource.com/gh/erivlis/networkx-graphql.svg/?label=resolved+issues&show_trend=true&token=uyl1AJLBqgkY7MsVbtjPnf9j"/></a>
      <a href="https://snyk.io/test/github/erivlis/networkx-graphql"><img alt="Snyk" src="https://snyk.io/test/github/erivlis/networkx-graphql/badge.svg"></a>
    </td>
  </tr>
</table>

## Overview

**networkx-graphql** brings GraphQL querying to [NetworkX](https://networkx.org/) graph structures in Python. By
leveraging [Strawberry GraphQL](https://strawberry.rocks/) and [Graphinate](https://github.com/erivlis/graphinate), it
automatically generates strongly-typed GraphQL schemas directly from NetworkX graph instances and serves them via an
interactive GraphQL web interface.

Whether you are working with simple undirected graphs, complex directed networks, or multi-edge graphs,
`networkx-graphql` allows you to explore and query node relationships with zero GraphQL boilerplate.

---

## Features

- ⚡ **Instant Schema Generation**: Automatically derive Strawberry GraphQL schemas from NetworkX graphs in a single line
  of code.
- 🕸️ **Full NetworkX Compatibility**: Seamlessly supports `nx.Graph`, `nx.DiGraph`, `nx.MultiGraph`, and
  `nx.MultiDiGraph`.
- 🏷️ **Custom Node Classification**: Supply custom extractor functions to dynamically extract node types and structure
  GraphQL schemas accordingly.
- 🌐 **Embedded GraphQL Server**: Built-in HTTP server with an interactive GraphiQL playground powered by Uvicorn and
  Starlette.
- 🐍 **Fully Typed**: Written with Python 3.11+ type annotations for maximum IDE support and type safety.

---

## Installation

Install `networkx-graphql` using `pip`:

```bash
pip install networkx-graphql
```

Or using [`uv`](https://github.com/astral-sh/uv):

```bash
uv add networkx-graphql
```

### Server Extra

To include web server dependencies (`uvicorn`, `starlette-prometheus`), install with the `server` extra:

```bash
pip install "networkx-graphql[server]"
# or with uv
uv add "networkx-graphql[server]"
```

---

## Quickstart

Spin up a GraphQL server for a NetworkX graph in 3 lines:

```python
import networkx as nx
import networkx_graphql as nxg

# 1. Create any NetworkX graph
graph = nx.ladder_graph(5)

# 2. Generate the GraphQL schema
schema = nxg.schema(graph)

# 3. Start the GraphQL server (default port: 8073)
nxg.run(schema, port=8073)
```

Now navigate in your browser to `http://localhost:8073` (which will redirect to `http://localhost:8073/viewer'), to view
the graph using 3D force-directed graph visualizer for the underlying NetworkX graph.
The viewer is powered by [Graphinate](https://github.com/graphinate/graphinate).

Explore the GraphQL schema and run queries using the built-in GraphiQL interface at `http://localhost:8073/graphiql`.



---

## Usage Examples

### Custom Node Type Extractor

By default, all nodes are categorized under a generic type (`'node'`). You can provide a custom `node_type_extractor`
function to map graph nodes to distinct GraphQL types:

```python
import networkx as nx
import networkx_graphql as nxg

# Create a graph with different node types
graph = nx.DiGraph(name="CompanyNetwork")
graph.add_node("alice", role="manager")
graph.add_node("bob", role="developer")
graph.add_edge("alice", "bob", relationship="manages")


# Define a custom node type extractor
def extract_node_type(node: str) -> str:
    role = graph.nodes[node].get("role", "employee")
    return role.capitalize()


# Generate schema with custom node types
schema = nxg.schema(graph, node_type_extractor=extract_node_type)

# Serve the GraphQL schema
nxg.run(schema, port=8073)
```

---

## API Reference

### `networkx_graphql.schema(graph, node_type_extractor=None)`

Generates a [`strawberry.Schema`](https://strawberry.rocks/) from a NetworkX graph instance.

| Parameter             | Type                | Description                                                                         | Default    |
|:----------------------|:--------------------|:------------------------------------------------------------------------------------|:-----------|
| `graph`               | `nx.Graph`          | Any NetworkX graph instance (`Graph`, `DiGraph`, `MultiGraph`, `MultiDiGraph`).     | *Required* |
| `node_type_extractor` | `Extractor \| None` | A function or callable `(node) -> str` that returns a GraphQL type name for a node. | `None`     |

**Returns**: `strawberry.Schema` - The generated Strawberry GraphQL schema object.

---

### `networkx_graphql.server(graphql_schema, port=8073)`

Launches an HTTP server to serve the Strawberry GraphQL schema. Alias: `networkx_graphql.run`.

| Parameter        | Type                | Description                             | Default    |
|:-----------------|:--------------------|:----------------------------------------|:-----------|
| `graphql_schema` | `strawberry.Schema` | The Strawberry GraphQL schema to serve. | *Required* |
| `port`           | `int`               | The HTTP port to run the server on.     | `8073`     |

---

## Development & Testing

This project uses [`uv`](https://github.com/astral-sh/uv) for dependency management and [
`pytest`](https://docs.pytest.org/) for testing.

### Setup Development Environment

```bash
# Clone the repository
git clone https://github.com/erivlis/networkx-graphql.git
cd networkx-graphql

# Install dependencies with uv
uv sync --all-extras
```

### Running Tests & Linting

```bash
# Run pytest test suite
uv run pytest

# Run linter checks
uv run ruff check .
```

---

## License

Distributed under the terms of the [GNU Lesser General Public License v3.0 or later (LGPLv3+)](LICENSE).
