> For the complete documentation index, see [llms.txt](https://docs.soda.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.soda.io/reference/soda-apis/python-api.md).

# Python API

This reference explains how to use the Soda Core Python API to generate, test, publish, and verify data contracts using local execution (Soda Core) or remote execution (Soda Runner).

## Installation

{% content-ref url="/pages/xbHoaBtcgajPRYZQ1UoX" %}
[Soda Python Libraries](/deployment-options/soda-python-libraries.md)
{% endcontent-ref %}

## Publish a local Contract to Soda Cloud

{% hint style="warning" %}
Publishing a new version of a contract to Soda Cloud requires additional permissions in Soda Cloud.

* If you are publishing a new version for an **existing dataset**, you must have the **Managed contract** permission for that dataset.
* If you are publishing a **new dataset**, you must have the global permission **Create new datasets and data sources with Soda Library**.

Learn more about permissions in Soda Cloud [Global and Dataset Roles](/organization-and-admin-settings/global-and-dataset-roles.md)
{% endhint %}

Use `publish_contract` to publish a contract to Soda Cloud:

```python
from soda_core.contracts import publish_contract

result = publish_contract(
    contract_file_path="contract1.yaml",
    soda_cloud_file_path="path/to/soda_cloud.yml"
)
```

<table><thead><tr><th width="199.44921875">Parameter</th><th width="112.70703125">Required</th><th width="100.5234375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>contract_file_path</code></td><td>Yes</td><td>str</td><td>Path to local contract file</td></tr><tr><td><code>soda_cloud_file_path</code></td><td>yes</td><td>str</td><td>Path to Soda Cloud config file</td></tr></tbody></table>

When the contract has parse or validation errors, the result has `has_errors` set to `True` and its logs list the errors. Check `has_errors` before you read the contract:

```python
if result.has_errors:
    print(result.logs.get_errors_str())
else:
    print(result[0].contract.dataset_id)
```

A YAML syntax error in the contract or the Soda Cloud config file raises a `YamlParserException`, from `soda_core.common.exceptions`.

### **Configure Logging**

To enable logging for contract operations, use:

```python
from soda_core import configure_logging

# Enable or disable verbose logging
configure_logging(verbose=True)
```

To access logs **after** a verification run:

```python
from soda_core.contracts import publish_contract

result = publish_contract(
    contract_file_path="contract1.yaml",
    soda_cloud_file_path="path/to/soda_cloud.yml"
)

result.logs.get_logs()
```

### Publish Result Object

#### Publish Verification Session Result

Represents the overall publication session (may include multiple contracts).

**Attributes**

* `items: list[ContractPublicationResult]` : all per-contract publication results. The result also indexes them directly, as in `result[0]`. See [#contractpublicationresult](#contractpublicationresult "mention")
* `has_errors: bool` : true if the publication logged an error.
* `logs: Logs` : publication logs across all contracts. Read them with `logs.get_logs()`, and the errors with `logs.get_errors()`.

***

#### **ContractPublicationResult**

Immutable outcome for a **single** contract publishing.

**Attributes**

* `contract: Optional[Contract]` : See [#contract](#contract "mention"). `None` when the contract was not published.

***

#### Contract

Describes the published contract (dataset identity and source info).

**Attributes**

* `data_source_name str` : name of the data source (as configured in Soda).
* `dataset_prefix: str[]` : hierarchical prefix (e.g., db, schema).
* `dataset_name: str` : name of the dataset (table/view).
* `soda_qualified_dataset_name: str` : full qualified dataset identifier.
* `source: YamlFileContentInfo` : reference to YAML source definition. See [#yamlfilecontentinfo](#yamlfilecontentinfo "mention")
* `dataset_id: Optional[str]`: the unique identifier of the dataset (only filled in when results are sent to Soda Cloud).

#### YamlFileContentInfo

Describes the published YAML.

**Attributes**

* `source_content_str: Optional[str]` : YAML provided inline.
* `local_path: Optional[str]` : local file path to the YAML.

## Verify a Contract

{% hint style="info" %}
Soda Library can verify contracts either locally (Soda Core) or remotely (Soda Runner). The returned session result objects share a common structure, but log/diagnostics availability differs by execution context.
{% endhint %}

{% hint style="warning" %}
Publishing verification results to Soda Cloud with `publish=True` requires additional permissions in Soda Cloud.

* If you are publishing to an **existing dataset**, you must have the **Managed contract** permission for that dataset.
* If you are publishing a **new dataset**, you must have the global permission **Create new datasets and data sources with Soda Library**.

Learn more about permissions in Soda Cloud [Global and Dataset Roles](/organization-and-admin-settings/global-and-dataset-roles.md)
{% endhint %}

### With Soda Core

Use `verify_contract_locally` to run the verification using **local configuration and execution**:

```python
from soda_core.contracts import verify_contract_locally

result = verify_contract_locally(
    data_source_file_path="path/to/data_source.yml",
    contract_file_path="contract1.yaml", ## OR dataset_identifier="datasource/db/schema/dataset"
    soda_cloud_file_path="path/to/soda_cloud.yml",
    variables={"START_DATE": "2024-01-01"},
    publish=False,
)
```

<table><thead><tr><th width="199.44921875">Parameter</th><th width="236.28515625">Required</th><th width="85.89453125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>data_source_file_path</code></td><td>Yes (or <code>data_source_file_paths</code> is required)</td><td>str</td><td>Path to data source file <a data-mention href="/reference/data-source-reference-for-soda-core.md">Data source reference for Soda Core</a></td></tr><tr><td><code>data_source_file_paths</code></td><td>Yes (or <code>data_source_file_path</code> is required)</td><td>[str]</td><td><p>Paths to data source files <a data-mention href="/reference/data-source-reference-for-soda-core.md">Data source reference for Soda Core</a> .</p><p>Required when using reconciliation checks to compare with a source dataset located in another data source.</p></td></tr><tr><td><code>contract_file_path</code></td><td>Yes (or <code>dataset_identifier</code> is required)</td><td>str</td><td>Path to local contract file</td></tr><tr><td><code>dataset_identifier</code></td><td>Yes (or <code>contract_file_path</code> is required)</td><td>str</td><td>Dataset identifier to fetch contracts from Soda Cloud <a data-mention href="/reference/contract-language-reference.md#dataset-fully-qualified-name">Contract Language reference</a></td></tr><tr><td><code>variables</code></td><td>No</td><td>dict</td><td>Variables to override in contract</td></tr><tr><td><code>publish</code></td><td>No</td><td>bool</td><td>Push results to Soda Cloud.</td></tr><tr><td><code>soda_cloud_file_path</code></td><td>No (unless publish is True)</td><td>str</td><td>Path to Soda Cloud config file</td></tr><tr><td><code>check_paths</code></td><td>No</td><td>[str]</td><td>Check paths of the checks to run, like <code>--check-paths</code> in the CLI. The other checks come back with the outcome <code>EXCLUDED</code>. <a data-mention href="/reference/cli-reference.md#check-paths">Core CLI reference</a></td></tr></tbody></table>

With `dataset_identifier`, a contract that Soda Cloud cannot return raises a `ContractFetchFailedException`, whose message names the dataset and the reason. Nothing is verified. `verify_contract_on_runner` does the same.

```python
from soda_core.common.exceptions import ContractFetchFailedException

try:
    result = verify_contract_locally(
        data_source_file_path="path/to/data_source.yml",
        dataset_identifier="datasource/db/schema/dataset",
        soda_cloud_file_path="path/to/soda_cloud.yml",
    )
except ContractFetchFailedException as e:
    # For example: Could not fetch the contract for dataset 'datasource/db/schema/dataset':
    # the dataset has no published contract in Soda Cloud
    print(e)
```

### With Soda Runner

Use `verify_contract_on_runner` to run verification **remotely via Soda Runner**.

```python
from soda_core.contracts import verify_contract_on_runner

result = verify_contract_on_runner(
    contract_file_path="path/to/contract.yaml", ## OR dataset_identifier="datasource/db/schema/dataset"
    soda_cloud_file_path="path/to/soda_cloud.yml",
    variables={"COUNTRY": "US"},
    publish=True,
)
```

<table><thead><tr><th width="199.44921875">Parameter</th><th width="207.40625">Required</th><th width="87.14453125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>contract_file_path</code></td><td>Yes (or <code>dataset_identifier</code> is required)</td><td>str</td><td>Path to local contract file</td></tr><tr><td><code>dataset_identifier</code></td><td>Yes (or <code>contract_file_path</code> is required)</td><td>str</td><td>Dataset identifier to fetch contract from Soda Cloud <a data-mention href="/reference/contract-language-reference.md#dataset-fully-qualified-name">Contract Language reference</a></td></tr><tr><td><code>variables</code></td><td>No</td><td>dict</td><td>Variables to override in contract</td></tr><tr><td><code>publish</code></td><td>No</td><td>bool</td><td>Push results to Soda Cloud.</td></tr><tr><td><code>soda_cloud_file_path</code></td><td>Yes</td><td>str</td><td>Path to Soda Cloud config file</td></tr><tr><td><code>blocking_timeout_in_minutes</code></td><td>No</td><td>int</td><td>How long to wait for the runner to return results (default: 60 minutes)</td></tr><tr><td><code>check_paths</code></td><td>No</td><td>[str]</td><td>Check paths of the checks to run on Soda Runner, like <code>--check-paths</code> with <code>--use-runner</code> in the CLI. <a data-mention href="/reference/cli-reference.md#run-a-subset-of-checks">Core CLI reference</a></td></tr></tbody></table>

Running a subset of checks with `check_paths` requires partial contract execution to be enabled for your organization. Contact <support@soda.io> to enable it. Without it, Soda Cloud rejects the request and no checks run. The call returns a result with `has_errors` set to `True` instead of raising, and `get_errors()` includes the message from Soda Cloud. On the contract result, `sending_results_to_soda_cloud_failed` is `True`.

***

### **Configure Logging**

To enable logging for contract operations, use:

```python
from soda_core import configure_logging

# Enable or disable verbose logging
configure_logging(verbose=True)
```

To access logs **after** a verification run:

```python
from soda_core.contracts import verify_contract_on_runner

result = verify_contract_on_runner(
    contract_file_path="path/to/contract.yaml", 
    soda_cloud_file_path="path/to/soda_cloud.yml",
)

result.get_logs()
```

{% hint style="warning" %}
If you call `verify_contract_locally(...)` or `verify_contract_on_runner(...)` in a loop, you should invoke `configure_logging(...)` **inside the loop before each verification call**.

The logging setup is not automatically reset between iterations, so placing `configure_logging(...)` only once outside the loop may lead to missing or inconsistent log output for subsequent runs.
{% endhint %}

### Verification Result Object

Running a verification returns a **`ContractVerificationSessionResult`** that aggregates results for one or more contracts verified in a single session. Use it to read logs and errors across contracts and to compute aggregate pass/fail counts. Each contract gets a **`ContractVerificationResult`** per-check **`CheckResult`** entries and derived counters.

***

#### Contract Verification Session Result

Represents the overall verification session (may include multiple contracts).

**Attributes available for Soda Core and Soda Runner scans**

* `contract_verification_results: list[ContractVerificationResult]` : all per-contract results. See [#contractverificationresult](#contractverificationresult "mention")
* `has_errors: bool` : true if any contract has execution errors.
* `has_excluded_checks: bool` : true if any contract has any excluded checks.
* `is_failed: bool` : true if any contract has failed checks. Ignores execution errors.
* `is_passed: bool` : true if all contracts have no failed checks. Ignores execution errors.
* `is_warned: bool` : true if any contract has warned checks. Ignores execution errors.
* `is_ok: bool` : true if all contracts are both not failed and have no errors.

**Attributes only available for Soda Core scans**

* `number_of_checks: int` : sum across contract.
* `number_of_checks_excluded`: sum across contract.
* `number_of_checks_passed: int` : sum across contract.
* `number_of_checks_failed: int` : sum across contract.
* `started_timestamp: timestamp` : verification start timestamp
* `data_timestamp: timestamp` : Effective timestamp of the contract. In the future, It will be possible to overwrite the value for backfilling use case.
* `ended_timestamp: timestamp` : verification end timestamp

**Methods**

* `get_logs() -> list[str]` : concatenated logs from all contracts.
* `get_logs_str() -> str` : newline-joined logs.
* `get_errors() -> list[str]` / `get_errors_str() -> str` : aggregated error lines from logs.

***

#### ContractVerificationResult

Immutable outcome for a **single** contract: status, timing, measurements, and per-check results.

**Attributes available for Soda Core and Soda Runner scans**

* `contract: Contract` : See [#contract](#contract "mention")
* `status: ContractVerificationStatus` : `FAILED`, `PASSED`, `WARNED`, `ERROR`, or `UNKNOWN`. See [#contractverificationstatus](#contractverificationstatus "mention")
* `sending_results_to_soda_cloud_failed: bool` : whether publishing failed.
* `log_records: Optional[list[logging.LogRecord]]` : detailed logs.
* `has_errors: bool` : true if status is `ERROR`.
* `has_excluded_checks: bool` : true if any check is excluded.
* `error: Optional[BaseException]` : the exception that stopped the contract before it was verified. `None` for a contract that was verified.
* `is_failed: bool` : true if status is `FAILED`. (Only checks, not execution errors.)
* `is_warned: bool` : true if status is `WARNED`. (Ignores execution errors.)
* `is_passed: bool` : true if status is `PASSED`. (Ignores execution errors.)
* `is_ok: bool` : not failed and not in error.
* `number_of_checks: int` / `number_of_checks_passed: int` / `number_of_checks_failed: int` : counts derived from `check_results`.

**Attributes only available for Soda Core scans**

* `data_source: DataSource` : See [#datasource](#datasource "mention")
* `data_timestamp: Optional[datetime]` : data time context (if any).
* `started_timestamp: datetime` / `ended_timestamp: datetime` : execution window.
* `measurements: list[Measurement]` — See [#measurement](#measurement "mention")
* `check_results: list[CheckResult]` — See [#checkresult](#checkresult "mention")
* `scan_id: Optional[str]`: the id of the scan (filled in when results are sent to soda-cloud)

**Methods**

* `get_logs() -> list[str]` / `get_logs_str() -> str` : pull message text from log records.
* `get_errors() -> list[str]` / `get_errors_str() -> str` : log lines at error level or higher.

***

#### CheckResult

Represents the outcome of a single check in the contract.

**Attributes**

* `check: Check` : See [#check](#check "mention")
* `outcome: CheckOutcome` : `PASSED`, `WARN`, `FAILED`, `NOT_EVALUATED`, or `EXCLUDED`. See [#checkoutcome](#checkoutcome "mention")
* `threshold_value: Optional[float|int]` : threshold applied.
* `diagnostic_metric_values: Optional[dict[str, float|int|str]]` : diagnostic metrics.
* `is_passed: bool` / `is_warned: bool` / `is_failed: bool` / `is_not_evaluated: bool` / `is_excluded: bool` : convenience flags, read as properties: `check_result.is_excluded`, not `check_result.is_excluded()`.
* `outcome_emoticon: str` : Unicode for quick visual status.

**Methods**

* `log_table_row() -> dict` : compact, user-friendly log row (includes diagnostics).
* `log_table_row_diagnostics(verbose: bool=True) -> str` : formatted diagnostic string; uses `_log_console_format(...)` for short form.

***

#### CheckOutcome

`PASSED`, `WARN`, `FAILED`, `NOT_EVALUATED`, `EXCLUDED`.

`EXCLUDED` marks a check the run did not select, for example with `check_paths` or a check filter. A check in a [contract scope](/reference/contract-language-reference.md#contract-scopes) is also `EXCLUDED` when the `soda-scopes` package is not installed.

***

#### Measurement

Metric container captured during verification.

**Attributes**

* `metric_id: str` : unique identifier of the metric.
* `metric_name: Optional[str]` : name of the metric.
* `value: Any` : captured value of the metric.

***

#### ContractVerificationStatus

Execution status of a contract. Drives `is_failed`, `is_passed`, and `has_errors`.

**Values**

* `UNKNOWN` : status not determined.
* `FAILED` : contract executed and one or more checks failed.
* `WARNED`: contract executed and one or more checks warned.
* `PASSED` : contract executed and all checks passed.
* `ERROR` : execution error occurred.

***

#### Check

Represents the executed check definition (identity, type, threshold, etc.).

**Attributes**

* `type: str` : check type (e.g., `missing`, `row_count`).
* `name: Optional[str]` : ame of the check.
* `qualifier: Optional[str]` : string to distinguish multiple checks of same type.
* `identity: str` : unique identifier of the check, **used to correlate results in Soda Cloud**. It is **automatically generated based on the check path** in the contract.
* `column_name: Optional[str]` : column the check applies to (if applicable).
* `threshold: Optional[Threshold]` : threshold configuration for this check.
* `attributes: dict[str, Any]` : metadata attributes (for Soda Cloud, routing, etc.).
* `scope: Optional[str]` : key of the [contract scope](/reference/contract-language-reference.md#contract-scopes) the check is in, or `None` for a check without a scope.
* `location: str` : where in the contract YAML the check is defined.

***

#### Threshold

Configured numeric boundaries for a check outcome.

**Attributes**

* `must_be: Optional[float|int]` : value must equal the configured number.
* `must_not_be: Optional[float|int]` : value must not equal the configured number.
* `must_be_greater_than: Optional[float|int]` : value must be strictly greater than.
* `must_be_greater_than_or_equal: Optional[float|int]` : value must be greater than or equal.
* `must_be_less_than: Optional[float|int]` : value must be strictly less than.
* `must_be_less_than_or_equal: Optional[float|int]` : value must be less than or equal.
* `must_be_between: Optional[dict]` : value must be within the specified range.
* `must_be_not_between: Optional[dict]` : value must not be within the specified range.

***

#### Contract

Describes the verified contract (dataset identity and source info).

**Attributes**

* `data_source_name str` : name of the data source (as configured in Soda).
* `dataset_prefix: str[]` : hierarchical prefix (e.g., db, schema).
* `dataset_name: str` : name of the dataset (table/view).
* `source: YamlFileContentInfo` : reference to YAML source definition. See [#yamlfilecontentinfo](#yamlfilecontentinfo "mention")
* `dataset_id: Optional[str]`: the unique identifier of the dataset (only filled in when results are sent to Soda Cloud).

***

#### YamlFileContentInfo

Describes where the YAML was loaded from.

**Attributes**

* `source_content_str: Optional[str]` : YAML provided inline.
* `local_path: Optional[str]` : local file path to the YAML.

***

#### DataSource

Represents the data source used for verification.

**Attributes**

* `name: str` : logical name of the data source.
* `type: str` : type of the data source (e.g., Postgres, Snowflake, BigQuery).

<br>

***

{% hint style="info" %}
You are **not logged in to Soda** and are viewing the default public documentation. Learn more about [Licensing & documentation access](/reference/documentation-access-and-licensing.md).
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.soda.io/reference/soda-apis/python-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
