Manage data contracts via SDKs
Data contracts can currently only be managed for tables, views, and materialized views.
Create new contract
To create a contract for an existing asset in Atlan:
- Java
- Python
- Kotlin
- Raw REST API
Table asset = Table.updater("default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN", "SALE_TXN")
.build();
String spec = client
.contracts.generateInitialSpec(asset); // (1)
DataContractSpec dcs = DataContractSpec.fromString(spec) // (2)
.toBuilder()
.description("Changed description.")
.extraProperty("something", "extra")
.build();
DataContract contract = DataContract.creator(spec, asset) // (3)
.build();
AssetMutationResponse response = contract.save(client); // (4)
-
Start by initializing a data contract. You can use the
.contracts.generateInitialSpec()on any Atlan client to generate the initial YAML data contract specification for a given asset. -
(Optional) You can translate the YAML string representation into a specification object that you can then programmatically extend, without needing to do direct string manipulations.
Loses all comments
Be aware that doing this conversion will remove any comments in the YAML.
:::
3. You need to provide the contract specification (YAML), as a string, and the asset the contract will govern to the DataContract.creator() method.
If you programmatically modified the specification as an object, you can convert it back to its YAML string form simply by calling .toString() on the object. You are always asked to provide the YAML string form here to make sure that if you want to keep any comments, you have the option to do so (since the object form removes any comments).
- Finally, you can call the
save()method to create the new data contract in Atlan. Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
from pyatlan.model.assets import Table
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import DataContract
from pyatlan.model.contract import DataContractSpec
client = AtlanClient()
asset = Table.updater(
qualified_name="default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN",
name="SALE_TXN"
)
spec = client.contracts.generate_initial_spec(asset) # (1)
contract_spec = DataContractSpec.from_yaml(spec) # (2)
contract_spec.description = "Changed description."
contract_spec.extra_properties = {"something" : "extra"}
contract = DataContract.creator( # (3)
asset_qualified_name=asset.qualified_name,
contract_spec=contract_spec,
)
response = client.asset.save(contract) # (4)
-
Start by initializing a data contract. You can use the
.contracts.generate_initial_spec()on any Atlan client to generate the initial YAML data contract specification for a given asset. -
(Optional) You can translate the YAML string representation into a specification object that you can then programmatically extend, without needing to do direct string manipulations.
Loses all comments
Be aware that doing this conversion will remove any comments in the YAML.
:::
3. You need to provide the contract specification (YAML), as a string,
and the asset the contract will govern to the DataContract.creator() method.
4. Finally, you can call the save() method to create the new data contract in Atlan.
val asset = Table.updater("default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN", "SALE_TXN")
.build()
val spec = client
.contracts.generateInitialSpec(asset) // (1)
val dcs = DataContractSpec.fromString(spec) // (2)
.toBuilder()
.description("Changed description.")
.extraProperty("something", "extra")
.build()
val contract = DataContract.creator(spec, asset) // (3)
.build()
val response = contract.save(client) // (4)
-
Start by initializing a data contract. You can use the
.contracts.generateInitialSpec()on any Atlan client to generate the initial YAML data contract specification for a given asset. -
(Optional) You can translate the YAML string representation into a specification object that you can then programmatically extend, without needing to do direct string manipulations.
Loses all comments
Be aware that doing this conversion will remove any comments in the YAML.
:::
3. You need to provide the contract specification (YAML), as a string, and the asset the contract will govern to the DataContract.creator() method.
If you programmatically modified the specification as an object, you can convert it back to its YAML string form simply by calling .toString() on the object. You are always asked to provide the YAML string form here to make sure that if you want to keep any comments, you have the option to do so (since the object form removes any comments).
- Finally, you can call the
save()method to create the new data contract in Atlan. Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
{
"entities": [
{
"typeName": "DataContract", // (1)
"attributes": { // (2)
"dataContractJson": "{\"type\": \"Table\", \"status\": \"DRAFT\", \"kind\": \"DataContract\", \"dataset\": \"SALE_TXN\", \"data_source\": \"snowflake\", \"description\": \"Created by Python SDK.\", \"columns\": [{\"name\": \"order_id\", \"data_type\": \"BIGNUMERIC\", \"description\": \"\"}]}",
"name": "Data contract for SALE_TXN", // (3)
"qualifiedName": "default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/contract" // (4)
}
}
]
}
-
The
typeNamemust be exactlyDataContract. -
Provide the data contract JSON. In this example, we're creating it with only the minimal required properties as specified by the API. Please check the reference section for the complete data contract specification.
- type of the asset in Atlan (
Table,View, orMaterializedView). - state of the contract (
DRAFTorVERIFIED). - must always be
DataContract. - name of the asset as it exists inside Atlan.
- name of the asset connection as it exists inside Atlan.
- (Optional) description of this dataset, for documentation purposes.
- (Optional)
columns:- name of the column as it's defined in the source system (often technical).
- physical data type of values in this column.
- description of this column, for documentation purposes.
- type of the asset in Atlan (
-
You must provide a human-readable name for your contract.
-
The
qualifiedNameshould follow the pattern:<assetQualifiedName>/contract(whereassetQualifiedNameis, in this example, thequalifiedNameof a Snowflake table).
Retrieve contract
By asset:
To retrieve the latest contract and certified contract of a given asset using its qualified name:
- Java
- Python
- Kotlin
- Raw REST API
Table table = Table.get(client, "default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN", true); // (1)
DataContract latest = table.getDataContractLatest(); // (2)
DataContract certified = table.getDataContractLatestCertified(); // (3)
- First, retrieve the asset by its
qualifiedName. Because this operation will retrieve the asset from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - Retrieve the latest data contract by using
.getDataContractLatest(). - Retrieve the certified data contract by using the
.getDataContractLatestCertified().
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import DataContract
client = AtlanClient()
table = client.asset.get_by_qualified_name( # (1)
asset_type=Table,
qualified_name="default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN"
)
latest_contract = table.data_contract_latest # (2)
certified_contract = table.data_contract_latest_certified # (3)
- First, retrieve the asset by its
qualified_name. - Retrieve the latest data contract by using the
table.data_contract_latestattribute. - Retrieve the certified data contract by using the
table.data_contract_latest_certifiedattribute.
val table = Table.get(client, "default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN", true) // (1)
val latest = table.dataContractLatest // (2)
val certified = table.dataContractLatestCertified // (3)
- First, retrieve the asset by its
qualifiedName. Because this operation will retrieve the asset from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - Retrieve the latest data contract by using
.dataContractLatest. - Retrieve the certified data contract by using the
.dataContractLatestCertified.
// (1)
-
All details are in the URL itself.
URL-encoded filter
Note that the filter is URL-encoded. decoded it would be: /api/meta/entity/uniqueAttribute/type/Table?attr:qualifiedName=default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN&minExtInfo=False&ignoreRelationships=False
:::
By qualified name:
To retrieve a contract by its version (V1, V2, etc) using its qualified name:
- Java
- Python
- Kotlin
- Raw REST API
DataContract contract = DataContract.get( // (1)!
client, "default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/Table/contract/V1"
);
- The
qualifiedNameof the data contract must be in the format:<assetQualifiedName>/<assetType>/contract/V<versionNumber>. For this example:assetQualifiedName:qualifiedNameof a Snowflake table.assetType: type of this asset in Atlan, i.e:Table.versionNumber: specific version of the data contract to retrieve, e.g:1,2, and so on.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import DataContract
client = AtlanClient()
contract = client.asset.get_by_qualified_name(
asset_type=DataContract, # (1)
qualified_name="default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/Table/contract/V1"
)
- The
qualifiedNameof the data contract must be in the format:<assetQualifiedName>/<assetType>/contract/V<versionNumber>. For this example:assetQualifiedName:qualifiedNameof a Snowflake table.assetType: type of this asset in Atlan, i.e:Table.versionNumber: specific version of the data contract to retrieve, e.g:1,2, and so on.
val contract = DataContract.get( // (1)!
client, "default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/Table/contract/V1"
)
- The
qualifiedNameof the data contract must be in the format:<assetQualifiedName>/<assetType>/contract/V<versionNumber>. For this example:assetQualifiedName:qualifiedNameof a Snowflake table.assetType: type of this asset in Atlan, i.e:Table.versionNumber: specific version of the data contract to retrieve, e.g:1,2, and so on.
// (1)
-
All details are in the URL itself.
URL-encoded filter
Note that the filter is URL-encoded. decoded it would be: attr:qualifiedName=default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/Table/contract/V1&minExtInfo=False&ignoreRelationships=False
where the qualifiedName of the data contract must be in the format:
<assetQualifiedName>/<assetType>/contract/V<versionNumber>.
For this example:
assetQualifiedName:qualifiedNameof a Snowflake table.assetType: type of this asset in Atlan, i.e:Table.versionNumber: specific version of the data contract to retrieve, e.g:1,2, and so on. :::
Update contract
In the following example, we're updating the contact
certificateStatus field to VERIFIED (shown as PUBLISHED in the UI):
- Java
- Python
- Kotlin
- Raw REST API
DataContractSpec updatedContractDetails = DataContractSpec.fromString(spec) // (1)
.toBuilder()
.status(DataContractStatus.VERIFIED) // (2)
.build();
DataContract contract = DataContract.updater( // (3)
"default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/contract",
"Data contract for SALE_TXN"
)
.dataContractSpec(updatedContractDetails.toString()) // (4)
.build();
AssetMutationResponse response = contract.save(client); // (5)
-
Begin by constructing the updated data contract specification. This example assumes you already have the string YAML form in a variable named
spec, which you have retrieved from the data contract using one of the retrieval methods above. -
After converting the specification into a builder (using
.toBuilder()) you can chain any updates you want against it, such as changing its status. -
Use the
updater()method to update a data contract.qualifiedNameof the data contract, ie:<assetQualifiedName>/contract(whereassetQualifiedNameis, in this example, thequalifiedNameof a Snowflake table).nameof the data contract. (NOTE:SDKs and CLI always generate it in the format: "Data contract fordataset(asset.name)").
-
You can then add any other updates or attributes. In this example, we're updating the contract spec itself (must be
string). -
To update the data contract in Atlan, call the
save()method with the object you've built. Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import DataContract
from pyatlan.model.contract import DataContractSpec
from pyatlan.model.enums import DataContractStatus
client = AtlanClient()
spec = current_contract.data_contract_spec
updated_contract_spec = DataContractSpec.from_yaml(spec) # (1)
updated_contract_spec.status = DataContractStatus.VERIFIED # (2)
contract = DataContract.updater( # (3)
qualified_name="default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/contract",
name="Data contract for SALE_TXN",
)
contract.data_contract_spec = updated_contract_spec.to_yaml() # (4)
response = client.asset.save(contract) # (5)
-
Begin by constructing the updated data contract specification. This example assumes you already have the string YAML form in a variable named
spec, which you have retrieved from the data contract using one of the retrieval methods above. -
After converting the specification into
DataContractSpecinstance, you can then chain any updates you want against it, such as changing itsstatus. -
Use the
updater()method to update a data contract.qualifiedNameof the data contract,ie:<assetQualifiedName>/contract(whereassetQualifiedNameis, in this example, thequalifiedNameof a Snowflake table).nameof the data contract. (NOTE:SDKs and CLI always generate it in the format: "Data contract fordataset(asset.name)").
-
You can then add any other updates or attributes. In this example, we're updating the contract spec itself (make sure to use
.to_yaml()to convert spec instance to YAML string) -
To update the data contract in Atlan, call the
save()method with the object you've built.
val updatedContractDetails = DataContractSpec.fromString(spec) // (1)
.toBuilder()
.status(DataContractStatus.VERIFIED) // (2)
.build()
val contract = DataContract.updater( // (3)
"default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/contract",
"Data contract for SALE_TXN"
)
.dataContractSpec(updatedContractDetails.toString()) // (4)
.build()
val response = contract.save(client) // (5)
-
Begin by constructing the updated data contract specification. This example assumes you already have the string YAML form in a variable named
spec, which you have retrieved from the data contract using one of the retrieval methods above.Won't retain any comments
Keep in mind that when programmatically building the specification as an object, no comments will be retained. If you want to have comments in your YAML specification, you must directly manipulate the YAML string yourself.
:::
2. After converting the specification into a builder (using .toBuilder()) you can chain any updates you want against it, such as changing its status.
3. Use the updater() method to update a data contract.
qualifiedNameof the data contract, ie:<assetQualifiedName>/contract(whereassetQualifiedNameis, in this example, thequalifiedNameof a Snowflake table).nameof the data contract. (NOTE:SDKs and CLI always generate it in the format: "Data contract fordataset(asset.name)").
- You can then add any other updates or attributes. In this example, we're updating the contract spec itself (must be
string). - To update the data contract in Atlan, call the
save()method with the object you've built. Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
{
"entities": [
{
"typeName": "DataContract", // (1)
"attributes": { // (2)
"dataContractJson": "{\"type\": \"Table\", \"status\": \"VERIFIED\", \"kind\": \"DataContract\", \"dataset\": \"SALE_TXN\", \"data_source\": \"snowflake\", \"description\": \"Created by Python SDK.\", \"columns\": [{\"name\": \"order_id\", \"data_type\": \"BIGNUMERIC\", \"description\": \"\"}]}",
"name": "Data contract for SALE_TXN", // (3)
"qualifiedName": "default/snowflake/1717514525/RAW/WIDEWORLD/SALE_TXN/contract" // (4)
}
}
]
}
-
The
typeNamemust be exactlyDataContract. -
Provide the data contract JSON. In this example, we're updating it with only the minimal required properties as specified by the API. Please check the reference section for the complete data contract specification.
- type of the asset in Atlan (
Table,View, orMaterializedView). - state of the contract (
DRAFTorVERIFIED). - must always be
DataContract. - name of the asset as it exists inside Atlan.
- name of the asset connection as it exists inside Atlan.
- (Optional) description of this dataset, for documentation purposes.
- (Optional)
columns:- name of the column as it's defined in the source system (often technical).
- physical data type of values in this column.
- description of this column, for documentation purposes.
- type of the asset in Atlan (
-
Human-readable name for your contract.
-
The
qualifiedNameof your contract, ie:<assetQualifiedName>/contract(whereassetQualifiedNameis, in this example, thequalifiedNameof a Snowflake table).
Delete contract
Soft-delete (archive)
To soft-delete, or archive, a contract:
- Java
- Python
- Kotlin
- Raw REST API
Hard-delete (purge)
To permanently delete (purge) a contract:
- Java
- Python
- Kotlin
- Raw REST API