Metadata-Version: 2.4
Name: graphdb-client
Version: 0.0.1
Summary: Python client for graphdb — an in-memory graph database with a Cypher subset over HTTP/JSON
Project-URL: Homepage, https://pmuston.github.io/graphdb
Project-URL: Documentation, https://pmuston.github.io/graphdb/guide/
Project-URL: Source, https://github.com/pmuston/graphdb-client-py
Project-URL: Issues, https://github.com/pmuston/graphdb-client-py/issues
Author-email: Paul Muston <paul.muston@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: client,cypher,database,driver,graph,graphdb
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database :: Front-Ends
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Provides-Extra: pandas
Requires-Dist: pandas>=1.5; extra == 'pandas'
Description-Content-Type: text/markdown

# graphdb-client

Python client for [graphdb](https://pmuston.github.io/graphdb) — an in-memory
graph database serving a subset of openCypher over HTTP/JSON.

> **Status: 0.0.1 reserves the name.** There is no client in this release. The
> interface below is the design being built; `GraphDB` arrives in 0.1.0.

```bash
pip install graphdb-client
```

## The shape it is heading for

```python
from graphdb_client import GraphDB, ConstraintViolation

db = GraphDB("http://localhost:8080", token=...)
db.wait_ready(timeout=30)

for rec in db.run("MATCH (p:Person)-[:KNOWS]->(f) WHERE p.city = $city RETURN p, f",
                  city="Berlin"):
    print(rec["p"]["name"], "->", rec["f"]["name"])
```

`rec["p"]` is a `Node` — `.labels`, `.id`, `.element_id`, and mapping access
going straight to properties. Writes report what they changed, and failures are
ordinary Python exceptions:

```python
res = db.run("CREATE (p:Person {name: $name}) RETURN p", name="Zoe")
res.stats.nodes_created          # 1

try:
    db.run("MATCH (p:Person {name:'Zoe'}) DELETE p")
except ConstraintViolation as e:
    e.code                       # Neo.ClientError.Schema.ConstraintValidationFailed
```

## Design notes

**No session or transaction object.** graphdb runs one statement per
transaction, so a session layer would wrap a single POST in ceremony. If the
server grows an explicit transaction endpoint, that is when a context manager
arrives — not before.

**Graph values are materialised from the server's `kind` discriminator**, never
by guessing from which keys are present. A user map stays a plain `dict`, which
is what makes the discriminator worth having.

**Retries are opt-in and read-only.** graphdb writes are not idempotent —
`CREATE` duplicates on re-run — so `run()` never retries. `read()` is the
retrying variant, and choosing it for a write is an explicit caller decision.

**Parameters are bound, never interpolated.** `run(query, **params)` keeps the
safe path the shortest one.

**Loading `.cypher` files is out of scope.** Splitting a multi-statement file
correctly requires the Cypher tokeniser, because a `;` inside a string literal
or a backtick-quoted identifier is not a separator. Use `graphdb import`, which
owns that rule.

## Compatibility

Targets graphdb interface version 1 (server 0.18.0+, which added the `kind`
discriminator). The client feature-detects on connect against the `features`
list published by `GET /`.

## Licence

MIT.
