|
18 | 18 | # below two imports instead.
|
19 | 19 | # from openassetio.traits import TraitsData
|
20 | 20 | # from openassetio.errors import BatchElementError
|
21 |
| -from openassetio.access import PolicyAccess, ResolveAccess |
| 21 | +from openassetio.access import PolicyAccess, ResolveAccess, EntityTraitsAccess |
22 | 22 | from openassetio.managerApi import ManagerInterface
|
23 | 23 | from openassetio_mediacreation.traits.content import LocatableContentTrait
|
24 | 24 | from openassetio_mediacreation.traits.managementPolicy import ManagedTrait
|
| 25 | +from openassetio_mediacreation.traits.application import ConfigTrait |
| 26 | +from openassetio_mediacreation.traits.usage import EntityTrait |
25 | 27 |
|
26 | 28 | # OpenAssetIO is building out the implementation vertically, there are
|
27 | 29 | # known fails for missing abstract methods.
|
@@ -67,6 +69,7 @@ def hasCapability(self, capability):
|
67 | 69 | ManagerInterface.Capability.kEntityReferenceIdentification,
|
68 | 70 | ManagerInterface.Capability.kManagementPolicyQueries,
|
69 | 71 | ManagerInterface.Capability.kResolution,
|
| 72 | + ManagerInterface.Capability.kEntityTraitIntrospection, |
70 | 73 | ):
|
71 | 74 | return True
|
72 | 75 |
|
@@ -121,6 +124,90 @@ def isEntityReferenceString(self, someString, hostSession):
|
121 | 124 | # info()
|
122 | 125 | return someString.startswith(self.__reference_prefix)
|
123 | 126 |
|
| 127 | + def entityTraits( |
| 128 | + self, |
| 129 | + entityReferences, |
| 130 | + entityTraitsAccess, |
| 131 | + context, |
| 132 | + _hostSession, |
| 133 | + successCallback, |
| 134 | + errorCallback, |
| 135 | + ): |
| 136 | + # This function is used by the host to retrieve the trait sets |
| 137 | + # for specific entities. The behaviour of this function differs |
| 138 | + # per access mode. `kRead` is a request for an exhaustive trait |
| 139 | + # set for an entity according to this manager, whilst `kWrite` |
| 140 | + # is a request for the minimal trait set required to publish to |
| 141 | + # that entity. As this manager example is read-only, we will |
| 142 | + # simply reject any `kWrite` requests. |
| 143 | + |
| 144 | + # For the purposes of this template, we use this fake map of |
| 145 | + # traits to serve as our "database", arbitrarily assuming that |
| 146 | + # asset 2 is a config entity of some sort. |
| 147 | + # Replace this with querying your backend systems. |
| 148 | + managed_assets_map = { |
| 149 | + "my_asset_manager:///anAsset": {EntityTrait.kId, LocatableContentTrait.kId}, |
| 150 | + "my_asset_manager:///anAsset2": { |
| 151 | + EntityTrait.kId, |
| 152 | + LocatableContentTrait.kId, |
| 153 | + ConfigTrait.kId, |
| 154 | + }, |
| 155 | + "my_asset_manager:///anAsset3": {EntityTrait.kId, LocatableContentTrait.kId}, |
| 156 | + } |
| 157 | + |
| 158 | + # If your manager doesn't support write, like this one, reject |
| 159 | + # a write access mode via calling the error callback. |
| 160 | + if entityTraitsAccess != EntityTraitsAccess.kRead: |
| 161 | + result = BatchElementError( |
| 162 | + BatchElementError.ErrorCode.kEntityAccessError, "Entities are read-only" |
| 163 | + ) |
| 164 | + for idx in range(len(entityReferences)): |
| 165 | + errorCallback(idx, result) |
| 166 | + return |
| 167 | + |
| 168 | + # Iterate over all the entity references, calling the correct |
| 169 | + # error/success callbacks into the host. |
| 170 | + # You should handle success/failure on an entity-by-entity |
| 171 | + # basis, do not abort your entire operation because any single |
| 172 | + # entity is malformed/can't be processed for any reason, use |
| 173 | + # the error callback and continue. |
| 174 | + for idx, ref in enumerate(entityReferences): |
| 175 | + # It may be that one of the references you are provided is |
| 176 | + # recognized for this manager, but has some syntax error or |
| 177 | + # is otherwise incorrect for your specific resolve context. |
| 178 | + # For example, an asset reference that specifies a version |
| 179 | + # for an un-versioned entity could be considered malformed. |
| 180 | + # |
| 181 | + # N.B. It's not required to perform an explicit check here |
| 182 | + # if this is naturally serviced during your backend lookup, |
| 183 | + # the key is not to error the whole batch, but use the error |
| 184 | + # callback for relevant references. |
| 185 | + identifier_is_malformed = is_malformed_ref(ref) |
| 186 | + if identifier_is_malformed: |
| 187 | + error_result = BatchElementError( |
| 188 | + BatchElementError.ErrorCode.kMalformedEntityReference, |
| 189 | + "Entity identifier is malformed", |
| 190 | + ) |
| 191 | + errorCallback(idx, error_result) |
| 192 | + else: |
| 193 | + # If our manager has the asset in question, we can |
| 194 | + # let the host know which traits make up this specific |
| 195 | + # entity. |
| 196 | + if ref.toString() in managed_assets_map: |
| 197 | + # Return the traits imbued the the entity in |
| 198 | + # question |
| 199 | + success_result = managed_assets_map[ref.toString()] |
| 200 | + successCallback(idx, success_result) |
| 201 | + else: |
| 202 | + # Otherwise, we don't know about the entity, so call |
| 203 | + # the error callback with an entity resolution error |
| 204 | + # for this specific entity. |
| 205 | + error_result = BatchElementError( |
| 206 | + BatchElementError.ErrorCode.kEntityResolutionError, |
| 207 | + f"Entity '{ref.toString()}' not found", |
| 208 | + ) |
| 209 | + errorCallback(idx, error_result) |
| 210 | + |
124 | 211 | def resolve(
|
125 | 212 | self,
|
126 | 213 | entityReferences,
|
@@ -208,11 +295,11 @@ def resolve(
|
208 | 295 | errorCallback(idx, error_result)
|
209 | 296 |
|
210 | 297 |
|
211 |
| -# Internal function used in Resolve, replace with logic based on what a |
212 |
| -# malformed ref means in your backend. For the demonstrative purposes of |
213 |
| -# this template, we pretend to support query parameters, then invent a |
214 |
| -# completely arbitrary query parameter that we don't support. (We then |
215 |
| -# test our implementation using the api compliance suite, see |
216 |
| -# fixtures.py) |
| 298 | +# Internal function used in Resolve and EntityTraits, replace with logic |
| 299 | +# based on what a malformed ref means in your backend. For the |
| 300 | +# demonstrative purposes of this template, we pretend to support query |
| 301 | +# parameters, then invent a completely arbitrary query parameter that we |
| 302 | +# don't support. (We then test our implementation using the api |
| 303 | +# compliance suite, see fixtures.py) |
217 | 304 | def is_malformed_ref(entityReference):
|
218 | 305 | return "?unsupportedQueryParam" in entityReference.toString()
|
0 commit comments