Metadata-Version: 2.4
Name: aioorient
Version: 1.0.0
Summary: Async-native Python client for the OrientDB binary protocol
Author-email: Ivona Obonova <ivonaobonova@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/obonovai/aioorient
Project-URL: Repository, https://github.com/obonovai/aioorient
Project-URL: Documentation, https://github.com/obonovai/aioorient/tree/master/docs
Project-URL: Issues, https://github.com/obonovai/aioorient/issues
Project-URL: Changelog, https://github.com/obonovai/aioorient/blob/master/CHANGELOG.md
Keywords: orientdb,async,asyncio,database,graph,ogm,binary-protocol
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Database :: Front-Ends
Classifier: Typing :: Typed
Requires-Python: >=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# aioorient

[![PyPI](https://img.shields.io/pypi/v/aioorient.svg)](https://pypi.org/project/aioorient/)
[![Python](https://img.shields.io/pypi/pyversions/aioorient.svg)](https://pypi.org/project/aioorient/)
[![CI](https://github.com/obonovai/aioorient/workflows/CI/badge.svg)](https://github.com/obonovai/aioorient/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Async-native Python client for the OrientDB binary protocol. Typed, tested,
pooled, and dependency-free. Targets OrientDB 3.0+ (v37/v38 wire protocol) on
Python 3.13+.

## Quickstart

```python
import asyncio
from aioorient import Client

async def main() -> None:
    async with await Client.connect(
        "localhost", 2424, user="root", password="rootpw"
    ) as client:
        async with client.database("demo", user="admin", password="adminpw") as db:
            rows = await db.query("SELECT FROM Person WHERE age > :min", params={"min": 18})
            for row in rows:
                print(row["name"], row.rid)

asyncio.run(main())
```

## Install

```shell
pip install aioorient
```

Zero runtime dependencies. An optional C extension accelerates record decoding and
ships in the binary wheels; without it, a pure-Python decoder is used
transparently.

## Features

- **Async-only.** Everything is `await`-ed; no sync wrapper, no blocking I/O.
- **Typed.** `mypy --strict` clean, ships `py.typed`; `dict[str, Any]` only where
  OrientDB values are genuinely polymorphic.
- **Pooled by default.** One `Client` → a server-level pool plus per-database
  query and batch pools, with health checks and back-pressure. No socket wrangling.
- **v38 transactions.** `async with db.transaction() as tx:` with MVCC-enforced
  `expected_version`.
- **Streaming queries.** `async for row in db.query_stream(sql):` pages under the
  hood without leaking server-side cursors.
- **Live queries.** `async with db.live_query(sql) as sub:` with a bounded buffer
  and clean three-way teardown.
- **Binary v37 codec.** Full document encode/decode with varint + zigzag
  primitives and an optional C fast path.
- **Object-graph mapper.** Declarative vertices/edges, property descriptors, a
  chainable query DSL, atomic batches, and per-class brokers.

## Documentation

Full guides live in [`docs/`](docs/index.md):

- [Getting started](docs/getting-started.md)
- [Connections & pooling](docs/connections.md)
- [Queries](docs/queries.md) · [Transactions](docs/transactions.md) · [Live queries](docs/live-queries.md)
- [Object-graph mapper](docs/ogm.md)
- [Records & types](docs/records-and-types.md) · [Exceptions](docs/exceptions.md)
- [TinkerPop / Gremlin](docs/gremlin.md)
- [Evaluation](docs/evaluation.md) — benchmarks vs. other OrientDB Python clients

## Object-graph mapper at a glance

```python
from aioorient.ogm import Graph, declarative_node, String, Integer

Node = declarative_node()

class Person(Node):
    element_type = "Person"
    name = String()
    age = Integer()

async with Graph(db, bases=[Node]) as g:
    await g.init_schema()
    alice = await g.create_vertex(Person, name="Alice", age=30)
    adults = await g.query(Person).where(Person.age >= 18).order_by(Person.name).all()
```

See the [OGM guide](docs/ogm.md) for the query DSL, batches, brokers, and
traversals.

## Gremlin traversals at a glance

OrientDB can execute TinkerPop 3 Gremlin traversals server-side; aioorient sends
them over the same binary connection via `db.script(language="gremlin")`. The
server binds `g = graph.traversal()`, so you write standard Gremlin directly
(needs the `orientdb:3.2-tp3` image):

```python
rows = await db.script(
    "g.V().hasLabel('Person').has('age', gte(18)).valueMap('name', 'age')",
    language="gremlin",
    params={},
)
for row in rows:
    print(row.fields)
```

Gremlin support is **experimental**. See the [Gremlin guide](docs/gremlin.md) for
prerequisites, result shapes, and caveats.

## Development

```shell
uv sync
uv run ruff check . && uv run ruff format --check .
uv run mypy src/aioorient tests
uv run pytest -m "not integration"          # unit tier
```

Integration tests require Docker (the suite starts/stops OrientDB itself):

```shell
uv run pytest -m integration
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for the commit conventions that drive
automated releases.

## License

[MIT](LICENSE)
