
## Manage asset owners

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

> Change, add, or remove owners for assets programmatically using the Atlan Python SDK (pyatlan).

# Change owners

:::tip[There are actually two kinds of owners per asset]
There are actually two fields in Atlan that capture the owners of an asset: `ownerUsers` and `ownerGroups`.

The examples below illustrate how to change individual (user) owners. To change group owners, replace `ownerUsers` with `ownerGroups`.
:::

## Change existing asset

:::warning[Could create a new asset]
Remember that Atlan matches the provided `qualifiedName` to determine whether to [update or create the asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt).
:::
To change owners on an existing [asset](https://docs.atlan.com/llms/platform/python/build-your-first-metadata-workflow/llms.txt):

### dbt

```yaml showLineNumbers title="Change owners on existing asset"
models:
 - name: TOP_BEVERAGE_USERS # (1)
 meta:
 atlan:
 attributes: # (2)
 ownerUsers: ["jsmith", "jdoe"] # (3)
```

1. You must of course give the name of the object.
2. The usernames must be nested within the `meta`.`atlan`.`attributes` structure.
3. You must provide valid usernames, or email addresses, as a list.

 :::warning[Users must be valid]
If the user doesn't exist in Atlan, there will be no updates to the asset. Please verify the usernames or email addresses in Atlan before assigning them to assets.
 :::

### Java

```java showLineNumbers title="Change owners on existing asset"
Table table = Table.updater( // (1)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (2)
 "TOP_BEVERAGE_USERS") // (3)
 .ownerUsers(List.of("jsmith", "jdoe")) // (4)
 .build(); // (5)
AssetMutationResponse response = table.save(client); // (6)
assert response.getUpdatedAssets().size() == 1 // (7)
```

1. Use the `updater()` helper method to create the minimal object necessary to do an update.
2. The `qualifiedName` of the object.
3. The `name` of the object.
4. Provide the new owners. Note that this is a list of the usernames of the users.
5. Build the updater into an object.
6. Send the update to Atlan. 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.
7. The response will include that single asset that was updated.

### Python

```python showLineNumbers title="Change owners on existing asset"
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table

client = AtlanClient()
table = Table.updater( # (1)
 qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
 name="TOP_BEVERAGE_USERS",
)
table.owner_users = ["jsmith", "jdoe"] # (2)
response = client.asset.save(table) # (3)
assert 1 == len(response.assets_updated(asset_type=Table)) # (4)
```

1. Use the `updater()` method to create an asset suitable for modification that is, with all the requisite attributes.
2. Provide the new owners. Note that this is a list of the usernames of the users.
3. Send the update to Atlan.
4. The response should only include that single asset that was updated.

### Kotlin

```kotlin showLineNumbers title="Change owners on existing asset"
val table = Table.updater( // (1)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (2)
 "TOP_BEVERAGE_USERS") // (3)
 .ownerUsers(listOf("jsmith", "jdoe")) // (4)
 .build() // (5)
val response = table.save(client) // (6)
assert(response.updatedAssets.size == 1) // (7)
```

1. Use the `updater()` helper method to create the minimal object necessary to do an update.
2. The `qualifiedName` of the object.
3. The `name` of the object.
4. Provide the new owners. Note that this is a list of the usernames of the users.
5. Build the updater into an object.
6. Send the update to Atlan. 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.
7. The response will include that single asset that was updated.

### 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. Provide the new owners, as a list of usernames of users.

## Remove from existing asset

To remove owners from an existing asset:

### dbt

```yaml showLineNumbers title="Remove owners from existing asset"
models:
 - name: TOP_BEVERAGE_USERS # (1)
 meta:
 atlan:
 attributes: # (2)
 ownerUsers: [ "jdoe" ] # (3)
```

1. You must of course give the name of the object.
2. The details for the owners must be nested within the `meta`.`atlan`.`attributes` structure.
3. Specify only the usernames or email addresses of the users you want to _keep_ as owners. (Compared to the other examples, this would remove `jsmith` and keep `jdoe`.)

 :::warning[Users must be valid]
If the user doesn't exist in Atlan, there will be no updates to the asset. Please verify the usernames or email addresses in Atlan before assigning them to assets.
 :::

### Java

```java showLineNumbers title="Remove owners from existing asset"
Table table = Table.removeOwners( // (1)
 client, // (2)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (3)
 "TOP_BEVERAGE_USERS"); // (4)
```

1. Use the `removeOwners()` 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 object.
4. The `name` of the object.

### Python

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

client = AtlanClient()
table = Table.updater( # (1)
 qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
 name="TOP_BEVERAGE_USERS",
)
table.owner_users = None # (2)
response = client.asset.save(table) # (3)
assert 1 == len(response.assets_updated(asset_type=Table)) # (4)
```

1. Use the `updater()` method to create an asset suitable for modification that is, with all the requisite attributes.
2. Set the owners to `None`.
3. Send the update to Atlan.
4. The response should only include that single asset that was updated (again, removing owners is an update to the asset—we'ren't deleting the asset itself).

### Kotlin

```kotlin showLineNumbers title="Remove owners from existing asset"
val table = Table.removeOwners( // (1)
 client, // (2)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (3)
 "TOP_BEVERAGE_USERS") // (4)
```

1. Use the `removeOwners()` 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 object.
4. The `name` of the object.

### 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 set the `ownerUsers` and `ownerGroups` to an empty list.

## When creating asset

To add owners when creating an asset:

### dbt

```yaml showLineNumbers title="Add owners when creating asset"
models:
 - name: TOP_BEVERAGE_USERS # (1)
 meta:
 atlan:
 attributes: # (2)
 ownerUsers: ["jsmith", "jdoe"] # (3)
```

1. You must of course give the name of the object.
2. The usernames must be nested within the `meta`.`atlan`.`attributes` structure.
3. You must provide valid usernames, or email addresses, as a list.

 :::warning[Users must be valid]
If the user doesn't exist in Atlan, there will be no updates to the asset. Please verify the usernames or email addresses in Atlan before assigning them to assets.
 :::

### Java

```java showLineNumbers title="Add owners when creating asset"
Table table = Table
 .creator("TOP_BEVERAGE_USERS", // (1)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV")
 .ownerUsers(List.of("jsmith", "jdoe")) // (2)
 .build(); // (3)
AssetMutationResponse response = table.save(client); // (4)
assert response.getCreatedAssets().size() == 1 // (5)
```

1. Use the `creator()` method to initialize the object with all necessary attributes for creating it](../advanced-examples/create.md#build-minimal-object-needed).
2. Set the owners that should be added. Note that this is a list of the usernames of the users.
3. Call the `build()` method to build the enriched object.
4. Call the `save()` method to actually create the asset with these owners. 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.
5. The response will include that single asset that was created.

### Python

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

client = AtlanClient()
table = Table.creator( # (1)
 name="TOP_BEVERAGE_USERS",
 schema_qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV",
)
table.owner_users = ["jsmith", "jdoe"] # (2)
response = client.asset.save(table) # (3)
assert 1 == len(assets_created := response.assets_created(asset_type=Table)) # (4)
table = assets_created[0] # (5)
```

1. Use the `creator()` method to initialize the object with all necessary attributes for creating it.
2. Set the owners that should be added. Note that this is a list of the usernames of the users.
3. Call the `save()` method to actually create the asset with these owners.
4. 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.
5. Since only one `Table` has been created we use an index of 0 to retrieve the newly created table.

### Kotlin

```kotlin showLineNumbers title="Add owners when creating asset"
val table = Table
 .creator("TOP_BEVERAGE_USERS", // (1)
 "default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV")
 .ownerUsers(listOf("jsmith", "jdoe")) // (2)
 .build() // (3)
val response = table.save(client) // (4)
assert(response.createdAssets.size == 1) // (5)
```

1. Use the `creator()` method to initialize the object with all necessary attributes for creating it](../advanced-examples/create.md#build-minimal-object-needed).
2. Set the owners that should be added. Note that this is a list of the usernames of the users.
3. Call the `build()` method to build the enriched object.
4. Call the `save()` method to actually create the asset with these owners. 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.
5. The response will include that single asset that was created.

### Raw REST API

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

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. Provide the owners, as a list of usernames of users.

---
