Metadata-Version: 2.4
Name: garphield
Version: 0.1.7
Summary: Validated Python round-trip primitives for Garphield projects
Author: Garphield contributors
License-Expression: LicenseRef-Proprietary
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES.md
Requires-Python: <3.15,>=3.10
Requires-Dist: anywidget<1,>=0.9
Requires-Dist: jsonschema<5,>=4.23
Requires-Dist: jupyter-ui-poll<2,>=1.0
Requires-Dist: rfc8785<0.2,>=0.1.4
Provides-Extra: networkx
Requires-Dist: networkx<3.5,>=3.4.2; (python_version == '3.10') and extra == 'networkx'
Requires-Dist: networkx<4,>=3.6.1; (python_version >= '3.11') and extra == 'networkx'
Requires-Dist: pandas<4,>=2.2; extra == 'networkx'
Provides-Extra: tables
Requires-Dist: pandas<3,>=2.2; extra == 'tables'
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://raw.githubusercontent.com/ammil-industries/garphield/develop/python/logo.png" alt="garphield" width="360">
</p>

# garphield for Python

Explore graphs visually from a notebook. Pass a NetworkX graph or pandas
DataFrame to `show()` and get an interactive Garphield view inline - then
open the full workbench to build stories, apply layouts, and return the
result to Python.

```python
import garphield as gph
import networkx as nx

G = nx.karate_club_graph()
view = gph.show(
    G,
    node_color="club",
    node_size=G.degree,
    node_label=str,
)
```

Once the view is displayed, drive it from Python:

```python
view.select([0, 1, 2]).fit()
view.bind("node_color", gph.algorithm("louvain", resolution=1.1))
edited = view.to_project()
```

## Install

```bash
pip install garphield
```

With NetworkX and pandas adapters:

```bash
pip install 'garphield[tables,networkx]'
```

## From pandas

```python
import pandas as pd
import garphield as gph

edges = pd.DataFrame({"source": ["a"], "target": ["b"], "weight": [1.5]})
project = gph.Project.from_pandas(edges)
tables = project.to_pandas()
```

## Project files

Read, validate, and write `.gph` project files:

```python
import garphield as gph

project = gph.Project.load("project.gph")
print(project.semantic_fingerprint())
project.save("project-copy.gph")
```

`Project.save()` writes deterministic, human-readable JSON. Semantic and
project fingerprints use RFC 8785/JCS canonical bytes.

## Notebook round-trip

The wheel carries a version-matched notebook renderer, so the view works
without a hosted renderer or CDN. Use **Open in Garphield** to continue
in the full workbench at [garphield.com](https://garphield.com), then
**Return to notebook** to bring the result back to Python.

The handoff waits for **Send project** before the remote
frame is created or the project is sent to it. The transport uses a
10 s acknowledgement timeout.

Use `chrome=["minimap"]` or `chrome=["toolbar"]` to keep embeds
lightweight. `project.save_html("graph.html", chrome=["minimap"])` writes
a standalone interactive HTML file.

## Environments

Local Jupyter, VS Code notebooks, JupyterHub, Google Colab, and Snowflake
Snowpark notebooks are resolved automatically. For Snowpark, use
`show_snowpark()` which materializes selected tables in the kernel before
handoff.

## Links

- [garphield.com](https://garphield.com)
- [GitHub](https://github.com/ammil-industries/garphield)
