Metadata-Version: 2.4
Name: dataceen-client
Version: 0.0.2
Summary: Python client for Dataceen GraphQL + gRPC subscription APIs
Author: Dataceen
License: Apache-2.0
Project-URL: Source, https://github.com/dataceen/dataceen-client-python
Project-URL: Issues, https://github.com/dataceen/dataceen-client-python/issues
Keywords: dataceen,graphql,grpc,client,azure-ad
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: msal>=1.28
Requires-Dist: grpcio>=1.60
Requires-Dist: protobuf>=4.25
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: python-dotenv>=1.0; extra == "dev"
Requires-Dist: grpcio-tools>=1.60; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Dynamic: license-file

# dataceen-client (Python)

Python client for the Dataceen GraphQL + gRPC subscription APIs. Parallel to
the C# (`DataceenClient/`) and TypeScript (`DataceenClientTs/`) reference
clients — feature-parity verified against the same `Thomas/CandyShopModel/All`
fixtures.

> **Status:** 0.0.1 alpha. 88 unit tests green. Not yet on PyPI.

## Install

```sh
python -m venv .venv
.venv\Scripts\activate            # PowerShell
pip install -e ".[dev]"
```

Requires Python 3.11+ (`typing.NotRequired`, generic `TypedDict`).

## Configure

Copy `.env.example` to `.env` at the repo root and fill in real Azure AD
credentials. The example matches the C# `appsettings.json`'s `AllClient`
section.

## Quick start

```python
import asyncio
from dataceen_client import DataceenClient, load_config_from_env
from dataceen_client.runtime import do_find

async def main():
    cfg = load_config_from_env()
    async with DataceenClient(cfg) as client:
        result = await do_find(
            client,
            "Customer",
            size=5,
            filter={"CustomerId": {"like": "cst"}},
            fields={
                "_id": True,
                "CustomerId": True,
                "CustomerPlacedOrder": {"Order": {"OrderId": True}},
            },
            order_by=[{"CustomerId": "Ascending"}],
        )
        for item in result["Items"]:
            print(item)

asyncio.run(main())
```

After running codegen, replace `do_find(client, "Customer", ...)` with the
typed `AllClient(client).Customer.find(...)`.

## Subscriptions

```python
async with DataceenClient(cfg) as client:
    sub = client.create_subscription(
        topics=["Customer"],
        baseload_topics=["Customer"],
        start_mode="POSITION_BEGINNING",
        include_complete=True,
    )

    async def on_customer(evt):
        if evt.event_type == "BASELOAD_EVENT":
            ...  # evt.complete is parsed JSON
        elif evt.event_type == "SUBSCRIPTION_EVENT":
            ...  # live event

    sub.on("Customer", on_customer)
    await client.subscribe(sub)   # blocks until sub.cancel()
```

## Codegen

```sh
python -m tools.codegen.src.cli fetch          # cache schema.json
python -m tools.codegen.src.cli emit Customer  # Customer + everything it references
python -m tools.codegen.src.cli emit-all       # whole model
```

Output → `src/dataceen_client/generated/` (gitignored). Per entity you get
typed `TypedDict`s for read/create/filter/fields, a change-tracked `Update`
class, and an `<Entity>Client` wrapping the runtime helpers; `AllClient`
aggregates the top-level entities.

Codegen runs from a source checkout — it is intentionally not part of the
published wheel (only the runtime `dataceen_client` package is shipped).

## Tests

```sh
pytest                       # 88 unit tests, ~1.7s
RUN_INTEGRATION=1 pytest     # also run live-backend integration tests (needs .env)
```

## Example app

End-to-end example against the live backend:

```sh
python -m examples.candy_shop.find
python -m examples.candy_shop.search_and_aggregate
python -m examples.candy_shop.subscriber
python -m examples.candy_shop.program                    # full read-only orchestrator
RUN_DESTRUCTIVE=1 python -m examples.candy_shop.program  # also create/update/delete
```

## Docs

- `docs/plan.md` — phase plan
- `docs/decisions.md` — decisions and motivation
- `docs/progress.md` — live status
- `docs/dsl-comparison.md` — why pure-dict DSL for Python
- `docs/porting-guide.md` — Python-specific amendments to the canonical guide
- `docs/release.md` — version-bump and publish runbook

## License

Proprietary — see [LICENSE](LICENSE).
