Metadata-Version: 2.5
Name: datanivra-cli
Version: 0.1.0
Summary: The `datanivra` command line (metadata/orchestration only).
Project-URL: Homepage, https://www.datanivra.com
Project-URL: Documentation, https://www.datanivra.com/docs/cli
Project-URL: Examples, https://github.com/DataNivra/datanivra-examples
License: Proprietary
License-File: LICENSE
Keywords: api-client,datanivra,test-data-management
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: <3.14,>=3.12
Requires-Dist: cryptography>=43
Requires-Dist: datanivra-contracts<2,>=1.0.0
Requires-Dist: datanivra-sdk<0.2,>=0.1.0
Requires-Dist: httpx>=0.27
Description-Content-Type: text/markdown

# datanivra-cli

The `datanivra` command line (DX-01): metadata and orchestration only.

```bash
datanivra login --url https://api.example.test --device --tenant acme-qa   # identity provider (RFC 8628)
datanivra login --url https://api.example.test --id-token-stdin --tenant acme-qa < id_token.txt  # CI
datanivra login --url https://api.example.test --token-stdin < token.txt
datanivra jobs list --state FAILED -o json
datanivra datasets request create request.json --idempotency-key "$CI_PIPELINE_ID"
```

* `src/datanivra_cli/app.py` — argparse command tree (login, org, roles, users, agents [enroll],
  sources, discover [review], policies [lifecycle], environments, datasets [request, provision,
  rollback, revoke], jobs, certify, refresh, packs, billing, audit, capacity) and exit codes.
  Every `auth='user'` operation of `API_ROUTES` has a command — `tests/test_cli_coverage.py`
  runs each one against a recording fake and fails for a new operation without a command.
* `config.py` — profiles in `profiles.json` (0600, atomic writes, refuses group/world-readable
  files, token never printed, only sent to the URL it was issued for).
* `device.py` — OAuth 2.0 device authorization grant against the identity provider the control
  plane advertises (`GET /v1/auth/oidc/config`): https-only IdP URLs (http only to loopback),
  issuer check, `slow_down`/denial/expiry handling; the ID token is exchanged at
  `POST /v1/auth/oidc/exchange` and never printed. `logout` revokes the session server-side
  (`POST /v1/auth/logout`) before forgetting it.
* Transport security: the control-plane URL must be `https://`; plain `http://` is accepted only
  for a loopback host (`localhost`, `127.0.0.0/8`, `[::1]`), so neither a stored nor a
  `DATANIVRA_TOKEN` session token is ever sent in clear text across a network. `--insecure-http`
  is the explicit opt-in for a trusted private network.
* `output.py` — egress guard (only `CONTROL_METADATA` / `AGGREGATE_METRIC` /
  `EVIDENCE_METADATA` / `SECRET_REFERENCE` fields are printed), stable JSON, tables.

The CLI talks only to the control plane via `datanivra_sdk`; it imports no connectors, engine
or agent code (enforced by `tests/contract/test_import_boundaries.py` and
`tests/test_cli_unit.py`). User guide: `apps/docs/content/cli.md`.

Tests: `uv run pytest packages/cli -q` (unit + end-to-end against the composed control plane
on embedded PostgreSQL).
