Creating asset
All objects in the SDK that you can create within Atlan implement the builder pattern. This allows you to progressively build-up the object you want to create. In addition, each object provides a method that takes the minimal set of required fields to create that asset.
Every asset in Atlan can have slightly different parent objects in which they exist. For example, a GlossaryTerm can't exist outside a Glossary. A Column can't exist outside a Table, View or MaterializedView; these can't exist outside a Schema; which can't exist outside a Database; which can't exist outside a Connection.
The minimal required fields for each asset type will therefore be slightly different.
As a result of this containment, creation order is important. Parent objects must be created (exist) before child objects can be created.
:::
Build minimal object needed
For example, to create a glossary term you need to provide the name of the term and either the GUID or qualifiedName of the glossary in which to create the term:
- Java
- Python
- Kotlin
- Raw REST API
GlossaryTermBuilder<?,?> termCreator = GlossaryTerm
.creator("Example Term", // (1)
"b4113341-251b-4adc-81fb-2420501c30e6"); // (2)
- A name for the new term.
- The GUID or
qualifiedNameof the glossary in which to create the term.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import AtlasGlossaryTerm
client = AtlanClient()
term = AtlasGlossaryTerm.creator(
name="Example Term", # (1)
glossary_guid="b4113341-251b-4adc-81fb-2420501c30e6" # (2)
)
- A name for the new term.
- The GUID of the glossary in which to create the term.
val termCreator = GlossaryTerm
.creator(
"Example Term", // (1)
"b4113341-251b-4adc-81fb-2420501c30e6", // (2)
)
- A name for the new term.
- The GUID or
qualifiedNameof the glossary in which to create the term.
There is nothing specific to do for this step when using the raw APIs—constructing the object is simply what you place in the payload of the API calls in the steps below.
Create asset from object
This term object will have the minimal required information for Atlan to create it. You must then actually persist the object in Atlan1:
- Java
- Python
- Kotlin
- Raw REST API
GlossaryTerm term = termCreator.build(); // (1)
AssetMutationResponse response = term.save(client); // (2)
Asset created = response.getCreatedAssets().get(0); // (3)
if (created instanceof GlossaryTerm)
Asset updated = response.getUpdatedAssets().get(0); // (5)
Glossary glossary;
if (updated instanceof Glossary)
-
Before you can take actions on the builder object you've been interacting with, you need to
build()it into a full object. -
Then you can do operations, like
save(), which will either:- create a new asset, if Atlan doesn't have a term with the same name in the same glossary
- update an existing asset, if Atlan already has a term with the same name in the same glossary
Because this operation will persist the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
You can distinguish what was created or updated:
getCreatedAssets()lists assets that were createdgetUpdatedAssets()lists assets that were updated
Note that the
save()method always returns objects of typeAsset, though. -
The
Assetclass is a superclass of all assets. So you need to cast to more specific types (likeGlossaryTerm) after verifying the object that was actually returned. -
In this example, creating the
GlossaryTermactually also updates the parentGlossary. This is why theresponsecontains genericAssetobjects rather than specific types—any operation could side-effect a number of different assets. -
Like with the
GlossaryTerm, you can check and cast the genericAssetreturned by the response into its more specific type (Glossary).
response = client.asset.save(term) # (1)
created = response.assets_created(asset_type=AtlasGlossaryTerm) # (2)
if created: # (3)
term = created[0] # (4)
updated = response.assets_updated(asset_type=AtlasGlossaryTerm) # (5)
if updated: # (6)
term = updated[0] # (7)
-
Call the
savemethod which will create or update the asset in atlan. -
You can distinguish what was created or updated:
assets_created(asset_type=AtlasGlossaryTerm)returns a lists assets of the specified type that were created.assets_updated(asset_type=AtlasGlossaryTerm)returns a lists assets of the specified type that were updated.
-
Check if the list is empty to determine if an
AtlasGlossaryTermwas created. -
Get the new
AtlasGlossaryTermthat was created. -
In this example, creating the
AtlasGlossaryTermactually also updates the parentAtlasGlossary. This is why theresponsecontains anAtlasGlossary. -
Check if the list is empty to determine if an
AtlasGlossarywas updated. -
Get the
AtlasGlossarythat was updated.
var term = termCreator.build() // (1)
val response = term.save(client) // (2)
val created = response.createdAssets[0] // (3)
if (created is GlossaryTerm)
val updated = response.updatedAssets[0] // (5)
val glossary = if (updated is Glossary) updated else null // (6)
-
Before you can take actions on the builder object you've been interacting with, you need to
build()it into a full object. -
Then you can do operations, like
save(), which will either:- create a new asset, if Atlan doesn't have a term with the same name in the same glossary
- update an existing asset, if Atlan already has a term with the same name in the same glossary
Because this operation will persist the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
You can distinguish what was created or updated:
getCreatedAssets()lists assets that were createdgetUpdatedAssets()lists assets that were updated
Note that the
save()method always returns objects of typeAsset, though. -
The
Assetclass is a superclass of all assets. So you need to cast to more specific types (likeGlossaryTerm) after verifying the object that was actually returned. -
In this example, creating the
GlossaryTermactually also updates the parentGlossary. This is why theresponsecontains genericAssetobjects rather than specific types—any operation could side-effect a number of different assets. -
Like with the
GlossaryTerm, you can check and cast the genericAssetreturned by the response into its more specific type (Glossary).
{
"entities": [ // (1)
}
}
]
}
- All assets must be wrapped in an
entitiesarray. - You must provide the exact type name for the asset (case-sensitive). For a term, this is
AtlasGlossaryTerm. - You must provide the exact name of the asset (case-sensitive).
- You must provide a
qualifiedNameof the asset (case-sensitive). In the case of glossary objects (like terms), this will actually be replaced in the back-end with a generatedqualifiedName, but you must provide some value when creating the object. - You must also specify the parent object in which this object is contained (if any). In the case of a term, it can only exist within a glossary. So here we specify the details of the parent glossary through the
anchorrelationship (specific to glossary assets).
(Optional) Enrich before creating
If you want to further enrich the asset before creating it, you can do this using the builder pattern:
- Java
- Python
- Kotlin
- Raw REST API
GlossaryTerm term = termCreator // (1)
.certificateStatus(CertificateStatus.VERIFIED) // (2)
.announcementType(AtlanAnnouncementType.INFORMATION)
.announcementTitle("Imported")
.announcementMessage("This term was imported from ...")
.build(); // (3)
AssetMutationResponse response = term.save(client); // (4)
- We'll create an object you can take actions on from this creator.
- In this example, you're adding a certificate and announcement to the object.
- To persist the enrichment back to the object, you must
build()the builder. - You can call the
save()operation against this enriched object, the same as shown earlier. Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
Remember to assign the result of the build() operation back to a variable! (In the example above this happens on line 5 with GlossaryTerm term =.)
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import AtlasGlossary, AtlasGlossaryTerm
from pyatlan.model.enums import AnnouncementType, CertificateStatus
client = AtlanClient()
term = AtlasGlossaryTerm.creator(
name="Example Term",
glossary_guid="b4113341-251b-4adc-81fb-2420501c30e6"
)
term.certificate_status = CertificateStatus.VERIFIED
announcement = Announcement(
announcement_type=AnnouncementType.INFORMATION,
announcement_title="Imported",
announcement_message="This term was imported from ..",
)
term.set_announcement(announcement)
response = client.asset.save(term) # (1)
- You can call the
save()operation against this enriched object, the same as shown earlier.
val term = termCreator // (1)
.certificateStatus(CertificateStatus.VERIFIED) // (2)
.announcementType(AtlanAnnouncementType.INFORMATION)
.announcementTitle("Imported")
.announcementMessage("This term was imported from ...")
.build() // (3)
val response = term.save(client) // (4)
- We'll create an object you can take actions on from this creator.
- In this example, you're adding a certificate and announcement to the object.
- To persist the enrichment back to the object, you must
build()the builder. - You can call the
save()operation against this enriched object, the same as shown earlier. Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
Remember to assign the result of the build() operation back to a variable! (In the example above this happens on line 6 with val term =.)
{
"entities": [ // (1),
"certificateStatus": "VERIFIED", // (2)
"announcementType": "information",
"announcementTitle": "Imported",
"announcementMessage": "This term was imported from..."
}
}
]
}
- You would still create the asset by wrapping it within the
entitiesarray. - But you can also extend the information you store on the asset. In this example, you're adding a certificate and announcement to the object when it's created.