OpenAssetIO [beta]
An abstract API for generalising interactions between a host application and an asset management system
Notes for Asset System Integrators

Architecture Summary

  • In OpenAssetIO, a manager is some centralized system that serves as a source of truth regarding the status and/or location of digital media and other organizational aspects of a project. The goal of the API is to allow these systems to be more easily integrated, and critically, more comprehensively involved in the lifetime of content as it moves between various tools and applications.
  • The implementation of any given manager may consist of several discrete services, but within any OpenAssetIO session, it is represented though a singular Manager Plugin.
  • The API is initialized and coordinated by a host. The host may instantiate one or more managers.
  • All interaction between the host and a manager occurs through the manager's implementation of the ManagerInterface.
  • A manager's implementation of the ManagerInterface supplied through its Manager Plugin is wrapped in the Manager class before being made available to the host. This is to allow for host session state management and other auditing/logging functionality. It also provides a degree of isolation against future API changes.
  • Methods of the ManagerInterface are required to be reentrant and thread-safe. The response to any method should only depend on the local state established during initialization, the underlying asset data and any other objects passed into each call. The same logical operation may be spread out over time and across processes. It is critical that any particular implementation does not rely on local in-memory state across different API requests. The only exception here being read-through caches etc. as long as they are suitably invalidated when upstream data changes.
  • The main currency in the interaction with a host is the Entity Reference. These are URIs that uniquely identify an entity within the management system. The form of an entity reference is entirely determined by the manager. They are considered to be opaque handles by the host, even if they look like well-formed strings.
  • The manager is expected to store and recall the properties of supported traits registered to any given Entity Reference, and return this data from the relevant query methods when supplied the reference returned from the registration.
  • A host may query other well-known or host-specific traits to provide additional customization of behavior or the handling of data referenced by an Entity Reference. For example, determining the correct frame range and colorspace of an image sequence.
  • The Context supplied to a method can be used to understand the intentions and/or requirements of the caller, as well as to determine which part of an application is involved in the call. This can be used to help determine the correct values for Trait properties during resolve.
  • Many API calls are passed a Trait Set. They form a strong type mechanism, and must be respected as a filter predicate for browsing/query operations, and as a type specifier for creation operations. See Entities, Traits and Specifications for more details on this mechanism.
  • The ManagerInterface implementation will be passed a HostSession to the majority of API calls. This should be used for all logging, and any generic host queries via the supplied Host object. Managers may wish to use details of the host obtained from this object to adapt their behavior if desired.
  • If a manager wants to support some kind of temporally stable resolution of Meta-versions or similar, implement createState, and return some token that can be used as an anchor. A new token will be requested each time a Context is made, and will then be available via Context.managerState in any call that receives a context. Hosts will take care of managing the lifetime of any given Context in terms that are meaningful for the user. Eg. the state token will be shared across distributed multi-host renders.
  • If the host executes code from Python, then the Global Interpreter Lock (GIL) will be released before executing any C++ implementation of the ManagerInterface and EntityReferencePagerInterface class methods.

Implementation Check List

Note
You can use the manager test harness to check your implementation, and as a basis for additional tests/CI of your own.

Required for Resolution Only

Required for Publishing

  • Update the implementation of hasCapability to return true when queried with kPublishing.
  • Update the implementation of managementPolicy to return suitable traits for a kWrite (and other publishing-related) access mode.
  • Implement the methods listed under the publishing capability to support the registration of new assets.
  • Map supported OpenAssetIO traits to internal asset types where possible.
  • Persist the full Trait Set of the specification supplied to register. This allows new asset types to be registered and filtered, even if they don't have a unique type within the manager's native data model.
  • Persist the trait data supplied to register. It should be considered opaque, unless the trait is well understood. In all other cases it should be returned verbatim by resolve when passed the reference returned from the registration (conditional on any subsequent registrations to the reference and the policy regarding entity versioning).
Note
An example of a situation where the manager is allowed to mutate trait property values is when it is semantically understood. A good example of this is the location property of the locatableContent trait, that is known to be a file path. In these cases, it may be rewritten at will providing it still points to synonymous data. This allows data to be relocated after it has been registered, as appropriate.

Supporting Relationships

Relationship support is not a pre-requisite, but allows for advanced functionality in many hosts, such as handling concepts like versioning.

Relationships aren't required for publishing itself, as the parent for an new entity is always inferred from the entity addressed by the reference used in the preflight or register call.

For example, publishing an ImageSpecification to the entity reference for a shot means that the image should be published under that shot as the manager sees fit.

This may sound counterintuitive, but the references used for publishing will generally originate either from the user, or the manager itself - in response to browsing for a writable target entity for the appropriate Trait Set. Consequently, they should be conceptually valid for the operation.

Hosts will include in their documentation notes on specific scenarios in which they register entities with one set of traits to references known to be of another, such as the editorial example above.

This approach is critical to ensure that OpenAssetIO has no inherent concept of any specific entity hierarchy, which ensures it never places any constraints on the implementation of any given asset management system.

In order to support entity relationships:

  • Implement the API methods grouped under Related Entities to return any appropriate entity references for the supplied relationship(s). Hosts may use these relationships to simplify common pipeline integration tasks. For example, loading multiple AOVs for a render, or determining data dependencies when transferring assets.
  • Update your implementation of hasCapability to report that you are now implement relationship queries.
  • Update your implementation of managementPolicy to cover the relationship trait sets you support.

Recommended Reading

See also
Entities, Traits and Specifications
ManagerInterface
PythonPluginSystemManagerPlugin
Context
Host