
## Certify assets

URL: https://docs.atlan.com/product/capabilities/build-apps/sdks/python/how-tos/certify-assets

> Certify assets in Atlan using CertificateStatus and the Python SDK (pyatlan). Add, update, or remove certification status programmatically.

# CertificateStatus: certify assets programmatically

Use `CertificateStatus` in the Atlan Python SDK to programmatically add or remove certification on assets.

## Add to existing asset

To add a certificate to an existing [asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt):

### dbt

```yaml showLineNumbers title="Add certificate to existing assets"
models:
 - name: TOP_BEVERAGE_USERS # (1)
 meta:
 atlan:
 attributes: # (2)
 certificateStatus: VERIFIED # (3)
 certificateStatusMessage: >- # (4)
 Verified through automation.
```

1. You must of course give the name of the object.
2. The details for the certificate must be nested within the `meta`.`atlan`.`attributes` structure.
3. You must provide a valid status for the certificate (`DRAFT`, `VERIFIED` or `DEPRECATED`).
4. (Optional) You can also provide a message to associate with the certificate.

### Java

```java showLineNumbers title="Add certificate to existing assets"
Table result = Table.updateCertificate( // (1)
 client, // (2)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (3)
 CertificateStatus.VERIFIED, // (4)
 "Verified through automation."); // (5)
```

1. Use the `updateCertificate()` helper method, which for most objects requires a minimal set of information. This helper method will construct the necessary request, call the necessary APIs, and return with the result of the update operation all-in-one.
2. Because this operation will directly change the asset in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
3. The `qualifiedName` of the object.
4. The type of certificate (the `CertificateStatus` enumeration gives the valid values).
5. (Optional) A message to include in the certificate.

### Python

```python showLineNumbers title="Add certificate to existing assets"
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.enums import CertificateStatus

client = AtlanClient()
table = client.asset.update_certificate( # (1)
 asset_type=Table,
 qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
 name="TOP_BEVERAGE_USERS",
 certificate_status=CertificateStatus.VERIFIED,
 message="Verified through automation.",
)
if table is None: # (2)
 print("Certificate status did not change")
else: # (3)
 print("Certificate status updated")
```

1. Use the `asset.update_certificate()` helper method, which for most objects requires a minimal set of information. This helper method will construct the necessary request, call the necessary APIs, and return with the result of the update operation all-in-one.
2. If no change occurs to the asset then `None` will be returned.
3. If the asset is updated then the asset will be returned.

### Kotlin

```kotlin showLineNumbers title="Add certificate to existing assets"
val result = Table.updateCertificate( // (1)
 client, // (2)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (3)
 CertificateStatus.VERIFIED, // (4)
 "Verified through automation.") // (5)
```

1. Use the `updateCertificate()` helper method, which for most objects requires a minimal set of information. This helper method will construct the necessary request, call the necessary APIs, and return with the result of the update operation all-in-one.
2. Because this operation will directly change the asset in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
3. The `qualifiedName` of the object.
4. The type of certificate (the `CertificateStatus` enumeration gives the valid values).
5. (Optional) A message to include in the certificate.

### Raw REST API

```json showLineNumbers title="POST /api/meta/entity/bulk"
{
 "entities": [ // (1)
 }
 ]
}
```

1. All assets must be wrapped in an `entities` array.
2. You must provide the exact type name for the asset (case-sensitive).
3. You must provide the exact name of the asset (case-sensitive).
4. You must provide the exact `qualifiedName` of the asset (case-sensitive).
5. You must provide a valid status for the certificate.
6. (Optional) You can also provide a status message for the certificate.

## Remove from existing asset

To remove a certificate from an existing asset:

### dbt

It's currently not possible to _remove_ a certificate from an asset via dbt.

### Java

```java showLineNumbers title="Remove certificate from existing asset"
Column column = Column.removeCertificate( // (1)
 client, // (2)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS/USER_ID", // (3)
 "USER_ID"); // (4)
```

1. Use the `removeCertificate()` helper method, which for most objects requires a minimal set of information. This helper method will construct the necessary request, call the necessary APIs, and return with the result of the removal operation all-in-one.
2. Because this operation will directly change the asset in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
3. The `qualifiedName` of the column (this is generally needed on all assets).
4. The name of the column (this varies by asset, but most assets need the name specified).

### Python

```python showLineNumbers title="Remove certificate from existing asset"
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Column

client = AtlanClient()
column = client.asset.remove_certificate( # (1)
 asset_type=Column,
 qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS/USER_ID",
 name="USER_ID",
)
if column is None: # (2)
 print("Certificate was not present")
else: # (3)
 print("Certificate was removed")
```

1. Use the `asset.remove_certificate()` helper method, which for most objects requires a minimal set of information. This helper method will construct the necessary request, call the necessary APIs, and return with the result of the removal operation all-in-one.
2. If no change occurs to the asset because the certificate isn't present then `None` will be returned.
3. If certificate is removed from the asset then the asset will be returned.

### Kotlin

```kotlin showLineNumbers title="Remove certificate from existing asset"
val column = Column.removeCertificate( // (1)
 client, // (2)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS/USER_ID", // (3)
 "USER_ID") // (4)
```

1. Use the `removeCertificate()` helper method, which for most objects requires a minimal set of information. This helper method will construct the necessary request, call the necessary APIs, and return with the result of the removal operation all-in-one.
2. Because this operation will directly change the asset in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
3. The `qualifiedName` of the column (this is generally needed on all assets).
4. The name of the column (this varies by asset, but most assets need the name specified).

### Raw REST API

```json showLineNumbers title="POST /api/meta/entity/bulk"
{
 "entities": [ // (1)
 }
 ]
}
```

1. All assets must be wrapped in an `entities` array.
2. You must provide the exact type name for the asset (case-sensitive).
3. You must provide the exact name of the asset (case-sensitive).
4. You must provide the exact `qualifiedName` of the asset (case-sensitive).
5. To remove the certificate, set its status and message to `null`.

## When creating asset

To add a certificate when creating an asset:

### dbt

```yaml showLineNumbers title="Add certificate when creating asset"
models:
 - name: TOP_BEVERAGE_USERS # (1)
 meta:
 atlan:
 attributes: # (2)
 certificateStatus: VERIFIED # (3)
 certificateStatusMessage: >- # (4)
 Verified at creation.
```

1. You must of course give the name of the object.
2. The details for the certificate must be nested within the `meta`.`atlan`.`attributes` structure.
3. You must provide a valid status for the certificate (`DRAFT`, `VERIFIED` or `DEPRECATED`).
4. (Optional) You can also provide a message to associate with the certificate.

### Java

```java showLineNumbers title="Add certificate when creating asset"
Table table = Table
 .creator("TOP_BEVERAGE_USERS", // (1)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV")
 .certificateStatus(CertificateStatus.VERIFIED) // (2)
 .certificateStatusMessage("Verified at creation.") // (3)
 .build(); // (4)
AssetMutationResponse response = table.save(client); // (5)
assert response.getCreatedAssets().size() == 1 // (6)
```

1. Use the `creator()` method to initialize the object with all [necessary attributes for creating it](https://docs.atlan.com/llms/platform/python/create-asset/llms.txt).
2. Set the certificate that should be added (in this example, we're using `VERIFIED`).
3. (Optional) Add a message for the certificate.
4. Call the `build()` method to build the enriched object.
5. Call the `save()` method to actually create the asset with this certificate. Because this operation will persist the asset in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
6. The response will include that single asset that was created.

### Python

```python showLineNumbers title="Add certificate when creating asset"
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.enums import CertificateStatus

client = AtlanClient()
table = Table.creator( # (1)
 name="TOP_BEVERAGE_USERS",
 schema_qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV",
)
table.certificate_status = CertificateStatus.VERIFIED # (2)
table.certificate_status_message = "Verified at creation." # (3)
response = client.asset.save(table) # (4)
assert response.assets_created(Table) # (5)
table = response.assets_created(Table)[0] # (6)
```

1. Use the `create()` method to initialize the object with all necessary attributes for creating it.
2. Set the certificate that should be added (in this example, we're using `VERIFIED`).
3. (Optional) Add a message for the certificate.
4. Invoke the `save()` method with asset. This method will return an AssetMutationResponse object that encapsulates the results.
5. Since a save can add, update, delete or partially update multiple assets the `assets_created()` method can be used to return a list of the assets of the specified type that were added. The assert statement is present to make sure a `Table` asset was created.
6. Since only one `Table` should have been created we use an index of 0 to retrieve the newly created table.

### Kotlin

```kotlin showLineNumbers title="Add certificate when creating asset"
val table: Table = Table
 .creator("TOP_BEVERAGE_USERS", // (1)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV")
 .certificateStatus(CertificateStatus.VERIFIED) // (2)
 .certificateStatusMessage("Verified at creation.") // (3)
 .build() // (4)
val response = table.save(client) // (5)
assert(response.createdAssets.size == 1) // (6)
```

1. Use the `creator()` method to initialize the object with all [necessary attributes for creating it](https://docs.atlan.com/llms/platform/python/create-asset/llms.txt).
2. Set the certificate that should be added (in this example, we're using `VERIFIED`).
3. (Optional) Add a message for the certificate.
4. Call the `build()` method to build the enriched object.
5. Call the `save()` method to actually create the asset with this certificate. Because this operation will persist the asset in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
6. The response will include that single asset that was created.

### Raw REST API

```json showLineNumbers title="POST /api/meta/entity/bulk"
{
 "entities": [ // (1)
 },
 "certificateStatus": "VERIFIED", // (6)
 "certificateStatusMessage": "Verified at creation." // (7)
 }
 }
 ]
}
```

1. All assets must be wrapped in an `entities` array.
2. You must provide the exact type name for the asset (case-sensitive).
3. You must provide a name for the asset.
4. In the case of a table, the `qualifiedName` must be the concatenation of the parent schema's qualifiedName and the name of the table.
5. When creating a table, you must specify the schema to create it within. This is defined by the `atlanSchema` attribute. You must specify both the type (must be `Schema`) and qualifiedName of the schema within the `atlanSchema` attribute—and the schema must already exist.
6. You must provide a valid status for the certificate.
7. (Optional) You can also provide a status message for the certificate.

---
