Installation status
The SDKs are not yet published to PyPI or npm. Install them from the repository (packages/sdk/python, packages/sdk/ts) or from release assets when they are provided. Publishing is a separate owner decision.
Both helpers call the ordinary, authorized operations — the server decides and enforces the profile's bounds — and return metadata only.
Python — datanivra_sdk.testdata
import os
from datanivra_sdk import DataNivraClient
from datanivra_sdk.manifests import load_manifest, checksum
from datanivra_sdk.testdata import TestDataClient
manifest = load_manifest("test-data/pr-regression.yaml") # safe YAML/JSON, strict validation
print(manifest.kind, checksum(manifest)) # canonical SHA-256 of the spec
with DataNivraClient(os.environ["DATANIVRA_BASE_URL"], token=os.environ["DATANIVRA_TOKEN"]) as api:
td = TestDataClient(api)
print([p.name for p in td.profiles()])
print(td.plan(manifest).decision) # dry run
with td.acquire(manifest, idempotency_key="ci-4242-1") as request:
run_integration_tests(request.environment_id) # released afterwards, even on failure| Helper | Does |
|---|---|
TestDataClient.profiles() | approved profile versions you may invoke |
plan(source) | the decision now, no side effects |
request(source, idempotency_key=…) | create, or return the live request of the same key / CI run |
wait(id, until=READY, timeout_seconds=900, poll_seconds=2) | bounded back-off; raises TestDataError with REQUEST_FAILED, REQUEST_REJECTED, PENDING_APPROVAL_TIMEOUT or WAIT_TIMEOUT |
release(id, reason_code=…) | release what the request holds (idempotent) |
acquire(source, …) | context manager: request, wait, yield, always release (keep_on_error=True keeps it for debugging) |
exchange_workload_token(base_url, tenant_slug=…, workload_identity_id=…, id_token=…) | CI OIDC token → workload session |
ci_id_token(audience) | the running GitHub Actions job's OIDC token, or DATANIVRA_ID_TOKEN (GitLab) |
source may be a manifest path, manifest text, a parsed manifest, a mapping or a TestDataRequestCreate.
TypeScript — @datanivra/sdk/testdata
The manifest parser uses js-yaml as an optional peer dependency: install js-yaml@5.4.2 next to the SDK when you parse YAML manifests (JSON bodies need nothing extra).
import { readFileSync } from 'node:fs';
import { createDataNivraClient } from '@datanivra/sdk';
import { TestDataClient, parseManifest } from '@datanivra/sdk/testdata';
const manifest = parseManifest(readFileSync('test-data/pr-regression.yaml', 'utf8'));
const api = createDataNivraClient({
baseUrl: process.env.DATANIVRA_BASE_URL!,
getAccessToken: () => process.env.DATANIVRA_TOKEN,
});
const td = new TestDataClient(api);
await td.withTestData(
readFileSync('test-data/pr-regression.yaml', 'utf8'),
async (request) => runIntegrationTests(request.environment_id),
{ idempotencyKey: 'ci-4242-1', timeoutMs: 900_000 },
);parseManifest, validateTestDataRequest, toTestDataRequest and TestDataClient (profiles, plan, request, get, wait, release, withTestData) are exported from the ./testdata entry, which is kept out of the main entry so browser bundles do not load the YAML parser. Waiting honours an AbortSignal. Node 20 or later.
Validation in TypeScript is strict for TestDataRequest manifests; TestDataProfile manifests are checked structurally — their full validation, checksum and approval happen in DataNivra (or with the Python helper and datanivra test-data validate).
Errors
A denied request raises the SDK's API error with code TEST_DATA_REQUEST_DENIED and the reason codes in details. Manifest problems raise ManifestError with value-free issues (path, code).