Metadata-Version: 2.5
Name: vibedata-odcs
Version: 0.2.4
Summary: VibeData data-contract tooling: check, generate, reverse, diff, profile and results for Open Data Contract Standard (ODCS v3.2.0) contracts at a Domain's boundary. One library and one `odcs` command shared by the Build agent's skills, Domain CI and Studio.
Project-URL: Repository, https://github.com/accelerate-data/vibedata-python-packages
Project-URL: Changelog, https://github.com/accelerate-data/vibedata-python-packages/blob/main/packages/vibedata-odcs/CHANGELOG.md
Author-email: Vibedata <eng@acceleratedata.ai>
License: MIT
Requires-Python: >=3.11
Requires-Dist: datacontract-cli<1.3,>=1.2.9
Requires-Dist: jsonschema>=4.18
Requires-Dist: pyyaml>=6
Requires-Dist: typer>=0.13
Provides-Extra: dev
Requires-Dist: datacontract-cli[duckdb]<1.3,>=1.2.9; extra == 'dev'
Requires-Dist: duckdb; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: engine-databricks
Requires-Dist: datacontract-cli[databricks]<1.3,>=1.2.9; extra == 'engine-databricks'
Provides-Extra: engine-duckdb
Requires-Dist: datacontract-cli[duckdb]<1.3,>=1.2.9; extra == 'engine-duckdb'
Provides-Extra: engine-redshift
Requires-Dist: datacontract-cli[redshift]<1.3,>=1.2.9; extra == 'engine-redshift'
Provides-Extra: engine-sqlserver
Requires-Dist: datacontract-cli[sqlserver]<1.3,>=1.2.9; extra == 'engine-sqlserver'
Provides-Extra: warehouse
Requires-Dist: duckdb; extra == 'warehouse'
Description-Content-Type: text/markdown

# vibedata-odcs

Data-contract tooling for [Open Data Contract Standard](https://github.com/bitol-io/open-data-contract-standard) (ODCS v3.2.0) contracts at a VibeData Domain's boundary.
One library and one `vibedata-odcs` command, shared by the Build agent's `data-contract` skills, Domain CI's logical-model gate, and Studio. It replaces the `odcs.py` script that was copied into each of them.

```bash
pip install vibedata-odcs                      # check, generate, diff, results, version
pip install "vibedata-odcs[engine-duckdb]"     # adds the DuckDB driver: profile, check --relations, reverse, export on a local file
pip install "vibedata-odcs[engine-databricks]" # the same on Databricks (engine-sqlserver for a Fabric warehouse, engine-redshift for Redshift)
pip install "vibedata-odcs[warehouse]"         # adds duckdb for reverse and the undeclared-columns check on a local file
```

`datacontract-cli` (MIT) is a core dependency: `diff` and the engine adapter (`vibedata.odcs.engine`) use it. The `engine-*` extras add the driver for the platform the checks run against.

Run from the Domain's repository root:

| Command | What it does | Reads a warehouse |
| --- | --- | --- |
| `vibedata-odcs check` | schema and structure of the committed contracts, one per boundary relation, agreement with the canonical model | no |
| `vibedata-odcs check --relations` | adds the comparison against the built relation: the engine's presence and type checks, plus the columns the contract does not declare (or names only, against dbt's `catalog.json`) | yes |
| `vibedata-odcs reverse [--force]` | drafts the boundary's contracts from a built warehouse (a local file, or Databricks, Fabric and Redshift through the engine's importers), with the open questions as findings | yes |
| `vibedata-odcs generate` | writes the dbt keys and the dlt `COLUMNS` hints from the contracts | no |
| `vibedata-odcs diff <base-ref>` | classifies each changed contract against a git base and requires the version bump it needs | no |
| `vibedata-odcs profile [--relation S.T]` | tests each contract's checks (key, `required`, library rules, relationships) against the built relation, through the engine | yes |
| `vibedata-odcs export <format> --out DIR` | renders each contract as `sql`, `jsonschema`, `avro`, `html` or `mermaid`, through the engine | no |
| `vibedata-odcs results <run_results.json>` | maps a dbt run's test results to the contract assertions they enforce (JSON lines) | no |
| `vibedata-odcs version` | package, standard and pinned-schema versions | no |

Diagnostics are JSON on stdout. The exit code is 0 when there are no errors (warnings are allowed) and 1 otherwise. That JSON, its diagnostic `code` values and the exit codes are the public API this package versions (see `CHANGELOG.md`).

The console script is `vibedata-odcs`, prefixed so it cannot collide with another tool's `odcs` in a shared environment; `python -m vibedata.odcs` is the same command.

## The warehouse

`--catalog PATH` names the local database file (or dbt's `catalog.json` for `check --relations`).
Without it, the command asks the installed destination resolver. The library ships none, because it knows no platform. A caller that knows the Intent's platform passes one:

```python
from vibedata.odcs.cli import main

main(destination_resolver=lambda repo_map: {"family": "duckdb", "path": "/sandbox.duckdb", "platform": "duckdb_local"})
```

The resolver returns the platform's coordinates; the engine builds its native server block from them at run time, so a committed contract keeps `type: custom` and carries no environment coordinate. `family` (or the platform's leading word) picks the engine: `duckdb` (`path`), `databricks` (`host`, `catalog`) `sqlserver`, which is how a Fabric warehouse is read (`host`, `database`, optional `authentication`, set as `DATACONTRACT_SQLSERVER_AUTHENTICATION`), or `redshift` (`host`, `database`, optional `port`; an optional `user`, `sslmode` and `authentication` become `DATACONTRACT_REDSHIFT_USERNAME`, `_SSLMODE` and `_AUTHENTICATION`, and the password stays in `DATACONTRACT_REDSHIFT_PASSWORD`, or IAM mints one). The schema is the relation's own. Credentials stay in the environment, as datacontract-cli reads them. A `physicalType` is dropped before testing when the run's platform is not the contract's, so a contract written on DuckDB compares logical types on Databricks.

With no resolver and no `--catalog`, a warehouse command refuses with `catalog/missing` rather than passing silently.

The resolver is process-wide state: every `main()` call sets it, `None` included, so a long-lived process that calls `main()` repeatedly passes the resolver it wants on each call.

## Vendored schema

`src/vibedata/odcs/schemas/` holds the pinned ODCS JSON schema; see its README for provenance. Validation never fetches, so `check` runs offline.
