
## Operate on multiple assets

URL: https://docs.atlan.com/product/capabilities/build-apps/sdks/python/how-tos/bulk-updates/update-multiple-assets

> Update multiple assets at once in Atlan using Batch and the Python SDK (pyatlan). Efficiently apply bulk attribute changes via POST /api/meta/entity/bulk.

# Batch: update multiple assets at once

Use `Batch` in the Atlan Python SDK to programmatically update many assets in a single batch operation.

You may also want to make changes to many assets at the same time.

:::tip[Optimize changes to many assets]
If you need to create or update many assets it will be more efficient to do this with fewer API calls than one API call per asset. The approach outlined below allows you to bundle together these multiple actions into a single API call.
:::
For example:

### Java

```java showLineNumbers title="Add certificate to multiple existing assets"
List assets = new ArrayList<>();
assets.add(GlossaryTerm // (1)
 .updater("gsNccqJraDZqM6WyGP3ea@FzCMyPR2LxkPFgr8eNGrq", // (2)
 "Example Term",
 "b4113341-251b-4adc-81fb-2420501c30e6")
 .certificateStatus(CertificateStatus.DEPRECATED) // (3)
 .certificateStatusMessage("This asset should no longer be used.")
 .build()); // (4)
assets.add(GlossaryTerm
 .updater("sduw38sCas83Ca8sdf982@FzCMyPR2LxkPFgr8eNGrq", // (5)
 "Another Term",
 "b267858d-8316-4c41-a56a-6e9b840cef4a")
 .certificateStatus(CertificateStatus.DEPRECATED)
 .certificateStatusMessage("This asset should no longer be used.")
 .build()); // (6)
AssetMutationResponse response = client // (7)
 .assets.save(assets, false); // (8)
assert response.getUpdatedAssets().size() == 2 // (9)
```

1. Define our object directly into an element of a `List`, rather than managing a separate object.
2. Use the `updater()` method to initialize the object with all [necessary attributes for updating it](https://docs.atlan.com/llms/platform/python/update-asset/llms.txt).
3. Directly chain our enrichment methods to add the certificate and message onto the `updater()` method's result.
4. Call the `build()` method to build the enriched object.
5. Use the `updater()` method to initialize the object for another [asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt).
6. Chain the enrichment and `build()` methods like we did for the previous [asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt).
7. To optimize our update, we want to limit the number of API calls we make. If we called `save()` against each of *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) individually, we would have *n* API calls. To avoid this we use an [`AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
8. Here we use the client directly with a list of [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt)—this makes 1 API call to update all *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) at the same time.
9. The response will include all *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) that were updated.

### Python

```python showLineNumbers title="Add certificate to multiple existing assets"
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import (
 Announcement,
 AtlasGlossaryTerm,
 AtlasGlossaryCategory,
 AtlasBusiness Graph,
)
from pyatlan.model.enums import AnnouncementType, CertificateStatus

client = AtlanClient()
term_1 = AtlasGlossaryTerm.updater( # (1)
 qualified_name="z9mfCRg6tItxcEyaJRNB3@reqKq68ZTSzuf7ezoZoGS",
 name="Example Term",
 glossary_guid="37e50bf7-abcb-4509-8155-c4894c05c9b9",
)
term_1.certificate_status = CertificateStatus.DEPRECATED # (2)
term_1.certificate_status_message = "This asset should no longer be used." # (3)
term_2 = AtlasGlossaryTerm.updater( # (4)
 qualified_name="2EqDFWZ6sCjbxcDNL0jFV@3Wn0W7PFCfjyKmGBZ7FLD",
 name="Term Test",
 glossary_guid="b9548564-4a2e-457a-a6fc-d7311dd39eef",
)
term_2.certificate_status = CertificateStatus.DEPRECATED # (5)
term_2.certificate_status_message = "This asset should no longer be used." # (6)
response = client.asset.save([term_1, term_2]) # (7)
assert len(response.assets_updated(asset_type=AtlasGlossaryTerm)) == 2 # (8)
```

1. Use the `updater()` method to initialize the object with all [necessary attributes for updating it](https://docs.atlan.com/llms/platform/python/update-asset/llms.txt).
2. Set the certificate_status.
3. Set the certificate_status_message.
4. Use the `updater()` method to initialize another object with all [necessary attributes for updating it](https://docs.atlan.com/llms/platform/python/update-asset/llms.txt).
5. Set the certificate_status.
6. Set the certificate_status_message.
7. To optimize our update, we want to limit the number of API calls we make. If we called `save()` against each of *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) individually, we would have *n* API calls. Here we pass list of [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt)—this makes 1 API call to update all *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) at the same time.
8. The response will include all *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) that were updated.

### Kotlin

```kotlin showLineNumbers title="Add certificate to multiple existing assets"
val assets = mutableListOf();
assets.add(GlossaryTerm // (1)
 .updater("gsNccqJraDZqM6WyGP3ea@FzCMyPR2LxkPFgr8eNGrq", // (2)
 "Example Term",
 "b4113341-251b-4adc-81fb-2420501c30e6")
 .certificateStatus(CertificateStatus.DEPRECATED) // (3)
 .certificateStatusMessage("This asset should no longer be used.")
 .build()) // (4)
assets.add(GlossaryTerm
 .updater("sduw38sCas83Ca8sdf982@FzCMyPR2LxkPFgr8eNGrq", // (5)
 "Another Term",
 "b267858d-8316-4c41-a56a-6e9b840cef4a")
 .certificateStatus(CertificateStatus.DEPRECATED)
 .certificateStatusMessage("This asset should no longer be used.")
 .build()) // (6)
val response = client // (7)
 .assets.save(assets, false) // (8)
assert(response.updatedAssets.size == 2) // (9)
```

1. Define our object directly into an element of a `List`, rather than managing a separate object.
2. Use the `updater()` method to initialize the object with all [necessary attributes for updating it](https://docs.atlan.com/llms/platform/python/update-asset/llms.txt).
3. Directly chain our enrichment methods to add the certificate and message onto the `updater()` method's result.
4. Call the `build()` method to build the enriched object.
5. Use the `updater()` method to initialize the object for another [asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt).
6. Chain the enrichment and `build()` methods like we did for the previous [asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt).
7. To optimize our update, we want to limit the number of API calls we make. If we called `save()` against each of *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) individually, we would have *n* API calls. To avoid this we use an [`AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
8. Here we use the client directly with a list of [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt)—this makes 1 API call to update all *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) at the same time.
9. The response will include all *n* [assets](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt) that were updated.

### Raw REST API

```json showLineNumbers title="POST /api/meta/entity/bulk"
{
 "entities": [ // (1),
 "certificateStatus": "DEPRECATED", // (4)
 "certificateStatusMessage": "This asset should no longer be used."
 }
 },
 { // (5)
 "typeName": "AtlasGlossaryTerm",
 "attributes": {
 "name": "Another Term",
 "qualifiedName": "sduw38sCas83Ca8sdf982@FzCMyPR2LxkPFgr8eNGrq",
 "anchor": {
 "typeName": "AtlasBusiness Graph",
 "guid": "b267858d-8316-4c41-a56a-6e9b840cef4a"
 },
 "certificateStatus": "DEPRECATED",
 "certificateStatusMessage": "This asset should no longer be used."
 }
 }
 ]
}
```

1. All details must still be included in an outer `entities` array.
2. You need to specify the type for each asset you are updating.
3. You need to specify other required attributes for each asset, such as its name and qualifiedName. (And in the case of terms and categories, also the parent glossary they exist within.)
4. Add on any other attributes or relationships you want to set on the asset, such as in this example for a deprecation certificate.
5. Add another object to the payload to represent another asset that should be updated by the same API call. Once again specify all the required information for that kind of asset, and any of the details for attributes or relationships you want to set.

And you can naturally combine this with [multiple operations](https://docs.atlan.com/llms/platform/python/combine-operations/llms.txt) per asset—to make many changes to many assets, all in a single API call.

> *Be aware of how much you're updating per request — see full content on the documentation site.*

---
