
## Find and apply suggestions

URL: https://docs.atlan.com/product/capabilities/build-apps/sdks/python/how-tos/asset-crud/apply-suggestions

> Find and apply metadata suggestions to assets programmatically using the Atlan Python SDK (pyatlan) and Suggestions API.

# Suggestions: find and apply asset suggestions

Use `Suggestions` in the Atlan Python SDK to programmatically retrieve and apply metadata suggestions to assets.

As a data team ourselves, we understand that metadata curation can be time-consuming.
To streamline this process, each time you fill in a metadata gap, Atlan looks
for opportunities to reuse that information.

This is where [trident suggestions 🔱](https://ask.atlan.com/hc/en-us/articles/7781078875921-Suggestions-from-similar-assets) come into play.
It provides metadata suggestions for similar assets.

:::note[For example: CUSTOMER (table)]

You add the description **"Information about customers"** to a table called `CUSTOMER`.

- Atlan searches for other tables named `CUSTOMER` that lack a description.

- Atlan then suggests **"Information about customers"** as the description for these other `CUSTOMER` tables.
:::
In Atlan's SDK, you can use the `Suggestions` object to
find and apply these recommendations to your assets.

## Find suggestions

Find suggestions for a given asset:

### Java

```java showLineNumbers title="Find suggestions for a given asset"

Table table = Table.get(
 "default/snowflake/1720661835/db/schema/table"
); // (1)

SuggestionResponse response = Suggestions.finder(table) // (2)
 .include(Suggestions.TYPE.GroupOwners)
 .include(Suggestions.TYPE.UserDescription)
 .maxSuggestions(5)
 .withOtherType(View.TYPE_NAME)
 .includeArchived(false)
 .get(); // (3)

assertNotNull(response); // (4)
assertNotNull(response.getOwnerGroups());
assertNotNull(response.getUserDescriptions());
```

1. First, you need to retrieve the asset for which you want to find suggestions.
2. Start by building a `Suggestions` request by chaining the following methods:

 - `finder`: specify the asset for which you want to find suggestions.
 - `include`: add criteria to specify the types of suggestions
 to include in the search results. For this example, we're retrieving
 suggestions for `GroupOwners` and `UserDescription`.

 :::tip[Want to find suggestions for ALL types?]

To include all suggestion types
(`description`, `owner`, `tags`, and `terms`):

```
Suggestions.includes(Arrays.asList(Suggestions.TYPE.values()))
```
 :::
 - `maxSuggestions`: **(Optional)** specify the maximum
 number of suggestions to return. Defaults to `5`.
 - `includeArchived`: **(Optional)** specify whether to include
 archived assets in the suggestions (`true`) or not (`false`). Defaults to `false`.
 - `withOtherType`: **(Optional)** add a criterion
 to include another asset type in the suggestions.

 :::info[`withOtherType`]

By default, we will only look for suggestions on
assets of the same type. You may want to expand this,
for example, by including `View`(s) when looking
for suggested metadata for `Table`(s).
 :::
 - `where`: **(Optional)** add a criterion that must be present
 in every search result. (**NOTE:** These are translated to filters.)
 - `whereNot`: **(Optional)** add a criterion
 that must not be present in any search result.
3. Finally, to retrieve the suggestions, call the `.get()` method.
4. The suggestion response contains a list of
suggestions for the requested types. You can access
specific suggestions by directly referencing the response attributes,
such as `response.getOwnerGroups()` and `response.getUserDescriptions()`.

### Python

```python showLineNumbers title="Find suggestions for a given asset"
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.suggestions import Suggestions

client = AtlanClient()

asset = client.asset.get_by_qualified_name(
 qualified_name="default/snowflake/1720661835/db/schema/table",
 asset_type=Table
) # (1)

response = (
 Suggestions() # (2)
 .finder(asset)
 .include(Suggestions.TYPE.GROUP_OWNERS)
 .include(Suggestions.TYPE.USER_DESCRIPTION)
 .max_suggestion(5)
 .with_other_type("View")
 .include_archive(False)
 .get(client=client) # (3)
)

assert response # (4)
assert response.owner_groups and response.owner_groups[0]
assert response.user_descriptions and response.user_descriptions[0]
```

1. First, you need to retrieve the asset for which you want to find suggestions.
2. Start by instantiating the `Suggestions()` object.
You can then build a suggestion request by chaining the following methods:

 - `finder`: specify the asset for which you want to find suggestions.
 - `include`: add criteria to specify the types of suggestions
 to include in the search results. For this example, we're retrieving
 suggestions for `GROUP_OWNERS` and `USER_DESCRIPTION`.

 :::tip[Want to find suggestions for ALL types?]

To include all suggestion types
(`description`, `owner`, `tags`, and `terms`),
you can directly pass `Suggestions.TYPE.all()` to the `Suggestions`:

```
Suggestions(includes=Suggestions.TYPE.all())
```
 :::
 - `max_suggestion`: **(Optional)** specify the maximum
 number of suggestions to return. Defaults to `5`.
 - `include_archive`: **(Optional)** specify whether to include
 archived assets in the suggestions (`True`) or not (`False`). Defaults to `False`.
 - `with_other_type`: **(Optional)** add a criterion
 to include another asset type in the suggestions.

 :::info[`with_other_type`]

By default, we will only look for suggestions on
assets of the same type. You may want to expand this,
for example, by including `View`(s) when looking
for suggested metadata for `Table`(s).
 :::
 - `where`: **(Optional)** add a criterion that must be present
 in every search result. (**NOTE:** These are translated to filters.)
 - `where_not`: **(Optional)** add a criterion
 that must not be present in any search result.
3. Finally, to retrieve the suggestions, call the `.get()` method.
4. The suggestion response contains a list of
suggestions for the requested types. You can access
specific suggestions by directly referencing the response attributes,
such as `response.owner_groups` and `response.user_descriptions`.

### Kotlin

```kotlin showLineNumbers title="Find suggestions for a given asset"

var table = Table.get(
 "default/snowflake/1720661835/db/schema/table"
); // (1)

var response = Suggestions.finder(table) // (2)
 .include(Suggestions.TYPE.GroupOwners)
 .include(Suggestions.TYPE.UserDescription)
 .maxSuggestions(5)
 .withOtherType(View.TYPE_NAME)
 .includeArchived(false)
 .get(); // (3)

assertNotNull(response); // (4)
assertNotNull(response.getOwnerGroups());
assertNotNull(response.getUserDescriptions());
```

1. First, you need to retrieve the asset for which you want to find suggestions.
2. Start by building a `Suggestions` request by chaining the following methods:

 - `finder`: specify the asset for which you want to find suggestions.
 - `include`: add criteria to specify the types of suggestions
 to include in the search results. For this example, we're retrieving
 suggestions for `GroupOwners` and `UserDescription`.

 :::tip[Want to find suggestions for ALL types?]

To include all suggestion types
(`description`, `owner`, `tags`, and `terms`):

```
Suggestions.includes(Suggestions.TYPE.values().toList())
```
 :::
 - `maxSuggestions`: **(Optional)** specify the maximum
 number of suggestions to return. Defaults to `5`.
 - `includeArchived`: **(Optional)** specify whether to include
 archived assets in the suggestions (`true`) or not (`false`). Defaults to `false`.
 - `withOtherType`: **(Optional)** add a criterion
 to include another asset type in the suggestions.

 :::info[`withOtherType`]

By default, we will only look for suggestions on
assets of the same type. You may want to expand this,
for example, by including `View`(s) when looking
for suggested metadata for `Table`(s).
 :::
 - `where`: **(Optional)** add a criterion that must be present
 in every search result. (**NOTE:** These are translated to filters.)
 - `whereNot`: **(Optional)** add a criterion
 that must not be present in any search result.
3. Finally, to retrieve the suggestions, call the `.get()` method.
4. The suggestion response contains a list of
suggestions for the requested types. You can access
specific suggestions by directly referencing the response attributes,
such as `response.getOwnerGroups()` and `response.getUserDescriptions()`.

## Apply suggestions

Apply suggestions to a given asset:

### Java

```java showLineNumbers title="Apply suggestions to a given asset"

Table table = Table.get(
 "default/snowflake/1720661835/db/schema/table"
); // (1)

SuggestionResponse response = Suggestions.finder(table) // (2)
 .include(Suggestions.TYPE.GroupOwners)
 .include(Suggestions.TYPE.UserDescription)
 .maxSuggestions(5)
 .withOtherType(View.TYPE_NAME)
 .includeArchived(false)
 .apply(true); // (3)

assertNotNull(response); // (4)
assertNotNull(response.getUpdatedAssets())
```

1. First, retrieve the asset for which you want to apply suggestions.
2. Start by building `Suggestions` request in the same
way as described in [Find suggestions section](#find-suggestions),
since here we first find the suggestions and then apply them.
3. To apply the suggestions, call the `.apply()` method.
Optionally, you can set `allowMultiple` to `true` to allow
multiple suggestions to be applied to the asset (up to the
`maxSuggestions` requested), such as for **owners**, **terms**, and **tags**.
4. The `AssetMutationResponse` will contain the updated asset entities.

### Python

```python showLineNumbers title="Apply suggestions to a given asset"

from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.suggestions import Suggestions

client = AtlanClient()

asset = client.asset.get_by_qualified_name(
 qualified_name="default/snowflake/1720661835/db/schema/table",
 asset_type=Table
) # (1)

response = (
 Suggestions() # (2)
 .finder(asset)
 .include(Suggestions.TYPE.GROUP_OWNERS)
 .include(Suggestions.TYPE.USER_DESCRIPTION)
 .max_suggestion(5)
 .with_other_type("View")
 .include_archive(False)
 .apply(client=client, allow_multiple=True) # (3)
)

assert response and response.mutated_entities # (4)
assert response.mutated_entities.UPDATE
assert response.mutated_entities.UPDATE[0]
```

1. First, retrieve the asset for which you want to apply suggestions.
2. Start by instantiating the `Suggestions()` object.
You can then build a suggestion request in the same
way as described in [Find suggestions section](#find-suggestions),
since here we first find the suggestions and then apply them.
3. To apply the suggestions, call the `.apply()` method.
Optionally, you can set `allow_multiple` to `True` to allow
multiple suggestions to be applied to the asset (up to the
`max_suggestions` requested), such as for **owners**, **terms**, and **tags**.
4. The `AssetMutationResponse` will contain the mutated asset entities.

### Kotlin

```kotlin showLineNumbers title="Apply suggestions to a given asset"

var table = Table.get(
 "default/snowflake/1720661835/db/schema/table"
); // (1)

var response = Suggestions.finder(table) // (2)
 .include(Suggestions.TYPE.GroupOwners)
 .include(Suggestions.TYPE.UserDescription)
 .maxSuggestions(5)
 .withOtherType(View.TYPE_NAME)
 .includeArchived(false)
 .apply(true); // (3)

assertNotNull(response); // (4)
assertNotNull(response.getUpdatedAssets())
```

1. First, retrieve the asset for which you want to apply suggestions.
2. Start by building `Suggestions` request in the same
way as described in [Find suggestions section](#find-suggestions),
since here we first find the suggestions and then apply them.
3. To apply the suggestions, call the `.apply()` method.
Optionally, you can set `allowMultiple` to `true` to allow
multiple suggestions to be applied to the asset (up to the
`maxSuggestions` requested), such as for **owners**, **terms**, and **tags**.
4. The `AssetMutationResponse` will contain the updated asset entities.

---
