From cf630c342f145c81fb752530ee63ee02797aeec4 Mon Sep 17 00:00:00 2001 From: David Feltell Date: Fri, 23 Feb 2024 16:14:32 +0000 Subject: [PATCH] squash: Modernise after rebase Nearly working, still need BAL to better differentiate between read/write/managerDriven access patterns. Signed-off-by: David Feltell --- examples/querying_entity_traits.ipynb | 409 +++++++++++------- .../querying_entity_traits/bal_database.json | 45 ++ .../openassetio_config.toml | 5 + 3 files changed, 292 insertions(+), 167 deletions(-) create mode 100644 examples/resources/querying_entity_traits/bal_database.json create mode 100644 examples/resources/querying_entity_traits/openassetio_config.toml diff --git a/examples/querying_entity_traits.ipynb b/examples/querying_entity_traits.ipynb index 4079a84..fb469ca 100644 --- a/examples/querying_entity_traits.ipynb +++ b/examples/querying_entity_traits.ipynb @@ -26,118 +26,28 @@ "tags": [] }, "source": [ - "## Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "80285f6a-8134-4055-9430-a48a5f79e7d3", - "metadata": { - "editable": true, - "scrolled": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "try:\n", - " from pprint import pprint\n", - " from resources import helpers\n", - " import openassetio\n", - " import openassetio_mediacreation\n", - "except ImportError:\n", - " print(\n", - " \"This notebook requires the packages listed in `resources/requirements.txt` to be installed\")\n", - " raise" - ] - }, - { - "cell_type": "markdown", - "id": "16ff8ea1-5bc4-41e2-b7ca-1ffd48618b3a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "#### Bootstrap OpenAssetIO" - ] - }, - { - "cell_type": "markdown", - "id": "99caa904-09f1-4736-85a8-3c7cd384ca62", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "The code initializing the OpenAssetIO API is known as a \"Host\".\n", + "## Setup\n", "\n", - "This section shows how the API is set up for use with a asset management systems. In this notebook, we make use of the highly-puppetable [BasicAssetLibrary](https://github.com/OpenAssetIO/OpenAssetIO-Manager-BAL), which is configured to read from a simple database included in the resources folder." + "See \"Hello OpenAssetIO\" notebook for details on how to bootstrap OpenAssetIO. " ] }, { "cell_type": "code", - "execution_count": null, - "id": "6ef73b42-a7ad-4bfb-9420-7d4def269459", - "metadata": {}, "outputs": [], "source": [ - "from openassetio.hostApi import HostInterface, ManagerFactory\n", - "from openassetio.log import ConsoleLogger, SeverityFilter\n", - "from openassetio.pluginSystem import PythonPluginSystemManagerImplementationFactory\n", - "\n", - "\n", - "# OpenAssetIO requires the host of the API to identify itself.\n", - "class NotebookHostInterface(HostInterface):\n", - " def identifier(self):\n", - " return \"org.jupyter.notebook\"\n", - "\n", - " def displayName(self):\n", - " return \"Jupyter Notebook\"\n", - "\n", - "\n", - "host_interface = NotebookHostInterface()\n", + "from resources import helpers\n", "\n", - "# We also need to direct log messages that emerge from the\n", - "# API and Manager plugins to somewhere visible. This setup\n", - "# filters based on severity, and prints to stdout/err.\n", - "logger = SeverityFilter(ConsoleLogger())\n", - "\n", - "# Specify that plugins should be loaded via the python plugin\n", - "# system.\n", - "impl_factory = PythonPluginSystemManagerImplementationFactory(logger)\n", - "\n", - "# We can now use the ManagerFactory to instantiate a suitable\n", - "# manager - in this case, the notebook uses a predefined\n", - "# BAL library\n", - "manager = ManagerFactory.defaultManagerForInterface(\n", - " \"resources/querying_entity_versions/openassetio_config.toml\",\n", - " host_interface,\n", - " impl_factory,\n", - " logger)\n", - "\n", - "# API calls that are part of the same logical \"process\"\n", - "# should share a Context. Making one here simplifies the\n", - "# code in the rest of the notebook.\n", - "context = manager.createContext()" - ] - }, - { - "cell_type": "markdown", - "id": "1f59d1de-d6de-4141-822b-e08e0c3fc78a", - "metadata": {}, - "source": [ - "We now have working `Manager` instance, that we can use to query asset information, and a `Context`. The context is used to correlate all of the API calls we make in this notebook, so the manager knows they are part of the same user session." - ] + "manager, context = helpers.bootstrap(\"resources/querying_entity_traits/openassetio_config.toml\")" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.628878901Z", + "start_time": "2024-02-23T16:12:44.565848853Z" + } + }, + "id": "df703c44ad53b21c", + "execution_count": 55 }, { "cell_type": "markdown", @@ -166,17 +76,28 @@ "source": [ "In the following examples we're going to ask the manager about the traits associated with an asset.\n", "\n", - "We've been given a URI by a colleague, which we need to turn into an `EntityReference` before we can use it to query the asset management system. This process ensures that only URIs known to the manager are passed to the various API calls.\n", - "\n", - "This call will throw if the input is not known to the manager. There are other forms of this method with different failure behaviours if exceptions aren't your thing." + "We've been given a URI by a colleague, which we need to turn into an `EntityReference` before we can use it to query the asset management system." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 56, "id": "82c3962a-27b5-4375-b4fa-dbd14dcfc93b", - "metadata": {}, - "outputs": [], + "metadata": { + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.661641284Z", + "start_time": "2024-02-23T16:12:44.632112008Z" + } + }, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> ``" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "logo_ref = manager.createEntityReference(\"bal:///project_artwork/logos/openassetio\")\n", "\n", @@ -246,14 +167,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 57, "id": "0fcf0214-2561-488a-8eee-0330ca27710d", "metadata": { - "scrolled": true - }, - "outputs": [], + "scrolled": true, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.707098268Z", + "start_time": "2024-02-23T16:12:44.661791793Z" + } + }, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `{'openassetio-mediacreation:identity.DisplayName', 'openassetio-mediacreation:content.LocatableContent', 'openassetio-mediacreation:timeDomain.FrameRanged', 'openassetio-mediacreation:lifecycle.Version', 'openassetio-mediacreation:usage.Entity'}`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "entity_trait_set = manager.entityTraits(logo_ref, EntityTraitAccess.kRead, context)\n", + "from openassetio.access import EntityTraitsAccess\n", + "\n", + "entity_trait_set = manager.entityTraits(logo_ref, EntityTraitsAccess.kRead, context)\n", "\n", "helpers.display_result(entity_trait_set)" ] @@ -276,15 +211,29 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 58, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `TraitsData({\"openassetio-mediacreation:identity.DisplayName\", \"openassetio-mediacreation:content.LocatableContent\", \"openassetio-mediacreation:lifecycle.Version\"})`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ + "from openassetio.access import ResolveAccess\n", + "\n", "entity_data = manager.resolve(logo_ref, entity_trait_set, ResolveAccess.kRead, context)\n", "\n", "helpers.display_result(entity_data)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.707897430Z", + "start_time": "2024-02-23T16:12:44.689633876Z" + } }, "id": "fbae28c950c33589" }, @@ -302,22 +251,36 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 59, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `TraitsData({\"openassetio-mediacreation:managementPolicy.Managed\", \"openassetio-mediacreation:lifecycle.Version\", \"openassetio-mediacreation:content.LocatableContent\", \"openassetio-mediacreation:identity.DisplayName\"})`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "policy_data = manager.managementPolicy(entity_trait_set, PolicyAccess.kRead, context)\n", + "from openassetio.access import PolicyAccess\n", + "\n", + "[policy_data] = manager.managementPolicy([entity_trait_set], PolicyAccess.kRead, context)\n", "\n", "helpers.display_result(policy_data)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.711487793Z", + "start_time": "2024-02-23T16:12:44.707200885Z" + } }, "id": "b5c27257bb1af339" }, { "cell_type": "markdown", "source": [ - "Note how the trait set returned from `managementPolicy` (minus any `policy` traits) matches the trait set we successfully `resolve`d. This is missing the `FrameRangedTrait`, despite it being included in the result of `entityTraits`, meaning that the `FrameRangedTrait` is a quality of the entity, but properties of it cannot be resolved (perhaps due to some technical limitation of the manager).\n", + "Note how the trait set returned from `managementPolicy` (minus any `managementPolicy` traits) matches the trait set we successfully `resolve`d. This is missing the `FrameRangedTrait`, despite it being included in the result of `entityTraits`, meaning that the `FrameRangedTrait` is a quality of the entity, but properties of it cannot be resolved (perhaps due to some technical limitation of the manager).\n", "\n", "In this way `managementPolicy` can be used to filter the trait set of an entity to only those traits that have `resolve`able properties. However, note that `mangementPolicy` does not take an entity reference argument, only trait set(s). The result of `managementPolicy` is therefore constant for any given manager, regardless of entity.\n", "\n", @@ -360,17 +323,29 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 60, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `set()`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "new_entity_ref = manager.createEntityReference(\"bal:///some/new/ref\")\n", "\n", - "entity_trait_set = manager.entityTraits(new_entity_ref, EntityTraitAccess.kWrite, context)\n", + "entity_trait_set = manager.entityTraits(new_entity_ref, EntityTraitsAccess.kWrite, context)\n", "\n", "helpers.display_result(entity_trait_set)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.786859139Z", + "start_time": "2024-02-23T16:12:44.711089944Z" + } }, "id": "c771cf01dc76f671" }, @@ -402,10 +377,28 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 61, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `{'openassetio-mediacreation:identity.DisplayName', 'openassetio-mediacreation:content.LocatableContent', 'openassetio-mediacreation:usage.Entity', 'openassetio-mediacreation:timeDomain.FrameRanged'}`" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/markdown": "> **Result:**\n> `Does our widget support this entity? False`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "entity_trait_set = manager.entityTraits(logo_ref, EntityTraitAccess.kWrite, context)\n", + "from openassetio_mediacreation.traits.content import LocatableContentTrait\n", + "from openassetio_mediacreation.traits.threeDimensional import GeometryTrait\n", + "\n", + "entity_trait_set = manager.entityTraits(logo_ref, EntityTraitsAccess.kWrite, context)\n", "\n", "helpers.display_result(entity_trait_set)\n", "\n", @@ -415,7 +408,11 @@ "helpers.display_result(f\"Does our widget support this entity? {is_entity_supported}\")" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.787865610Z", + "start_time": "2024-02-23T16:12:44.752964843Z" + } }, "id": "c5cf5d230e7bc4d6" }, @@ -455,20 +452,36 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 62, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `bal:///project_artwork/logos/openassetio`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ + "from openassetio.trait import TraitsData\n", + "from openassetio.access import PublishingAccess\n", + "from openassetio_mediacreation.traits.auth import BearerTokenTrait\n", + "\n", "data = TraitsData()\n", - "LocateableContentTrait(data).setLocation(\"file:///some/path\")\n", + "LocatableContentTrait(data).setLocation(\"file:///some/path\")\n", "BearerTokenTrait(data).setToken(\"==ZxErn43G\")\n", "\n", "entity_ref_or_error = manager.preflight(\n", - " logo_ref, data, PublishAccess.kWrite, context, BatchElementErrorPolicyTag.kVariant)\n", + " logo_ref, data, PublishingAccess.kWrite, context, manager.BatchElementErrorPolicyTag.kVariant)\n", "\n", "helpers.display_result(entity_ref_or_error)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.855666486Z", + "start_time": "2024-02-23T16:12:44.760666894Z" + } }, "id": "77a3047239a3c76a" }, @@ -500,18 +513,30 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 63, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `{'openassetio-mediacreation:identity.DisplayName', 'openassetio-mediacreation:content.LocatableContent', 'openassetio-mediacreation:timeDomain.FrameRanged', 'openassetio-mediacreation:lifecycle.Version', 'openassetio-mediacreation:usage.Entity'}`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "future_ref = manager.createEntityReference(\"bal:///project_artwork/logos?new\")\n", + "future_ref = manager.createEntityReference(\"bal:///project_artwork/logos/new\")\n", "\n", "trait_set_or_error = manager.entityTraits(\n", - " logo_ref, EntityTraitAccess.kRead, context, BatchElementErrorPolicyTag.kVariant)\n", + " logo_ref, EntityTraitsAccess.kRead, context, manager.BatchElementErrorPolicyTag.kVariant)\n", "\n", "helpers.display_result(trait_set_or_error)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.858297379Z", + "start_time": "2024-02-23T16:12:44.832814495Z" + } }, "id": "32f76d73bd99a340" }, @@ -529,16 +554,28 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 64, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `set()`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "trait_set_or_error = manager.entityTraits(\n", - " future_ref, EntityTraitAccess.kWrite, context, BatchElementErrorPolicyTag.kVariant)\n", + " future_ref, EntityTraitsAccess.kWrite, context, manager.BatchElementErrorPolicyTag.kVariant)\n", "\n", "helpers.display_result(trait_set_or_error)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.918770778Z", + "start_time": "2024-02-23T16:12:44.859236096Z" + } }, "id": "1debd3dfd60cb52d" }, @@ -568,18 +605,30 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 65, + "outputs": [ + { + "data": { + "text/markdown": "> **Result:**\n> `{'openassetio-mediacreation:identity.DisplayName', 'openassetio-mediacreation:content.LocatableContent', 'openassetio-mediacreation:usage.Entity', 'openassetio-mediacreation:timeDomain.FrameRanged'}`" + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "v1_ref = manager.createEntityReference(\"bal:///project_artwork/logos/openassetio?v=1\")\n", "\n", "trait_set_or_error = manager.entityTraits(\n", - " logo_ref, EntityTraitAccess.kWrite, context, BatchElementErrorPolicyTag.kVariant)\n", + " logo_ref, EntityTraitsAccess.kWrite, context, manager.BatchElementErrorPolicyTag.kVariant)\n", "\n", "helpers.display_result(trait_set_or_error)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.933169844Z", + "start_time": "2024-02-23T16:12:44.918924732Z" + } }, "id": "ee61dbb2bd4b828f" }, @@ -623,15 +672,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 66, "outputs": [], "source": [ + "from openassetio_mediacreation.traits.identity import DisplayNameTrait\n", + "\n", "# Get the complete trait set of the entity.\n", - "entity_trait_set = manager.entityTraits(logo_ref, EntityTraitAccess.kRead, context)\n", + "entity_trait_set = manager.entityTraits(logo_ref, EntityTraitsAccess.kRead, context)\n", "\n", "# Ensure the manager will accept a publish of this entity with an updated display name.\n", - "policy_data = manager.managementPolicy(\n", - " entity_trait_set | {DisplayNameTrait.kId}, PolicyAccess.kWrite, context)\n", + "[policy_data] = manager.managementPolicy(\n", + " [entity_trait_set | {DisplayNameTrait.kId}], PolicyAccess.kWrite, context)\n", "\n", "if not DisplayNameTrait.kId in policy_data.traitSet():\n", " raise Exception(\"Cannot update display name of this entity\")\n", @@ -647,10 +698,14 @@ "DisplayNameTrait(data_to_publish).setName(\"My New Name\")\n", "\n", "# Publish it. Any properties we `resolve`d that cannot be re-published will be silently ignored.\n", - "updated_ref = manager.register(logo_ref, data_to_publish, PublishAccess.kWrite, context)" + "updated_ref = manager.register(logo_ref, data_to_publish, PublishingAccess.kWrite, context)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:44.987321720Z", + "start_time": "2024-02-23T16:12:44.932469897Z" + } }, "id": "499f2040f821e2cd" }, @@ -670,18 +725,34 @@ }, { "cell_type": "code", - "execution_count": null, - "outputs": [], + "execution_count": 67, + "outputs": [ + { + "ename": "BatchElementException", + "evalue": "entityAccessError: Unsupported access mode for resolve [index=0] [access=managerDriven] [entity=bal:///project_artwork/logos/openassetio]", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mBatchElementException\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[67], line 19\u001B[0m\n\u001B[1;32m 16\u001B[0m trait_set_to_keep \u001B[38;5;241m=\u001B[39m trait_set_to_publish \u001B[38;5;241m-\u001B[39m {BearerTokenTrait\u001B[38;5;241m.\u001B[39mkId, LocatableContentTrait\u001B[38;5;241m.\u001B[39mkId}\n\u001B[1;32m 18\u001B[0m \u001B[38;5;66;03m# Get the properties that we wish to keep from the current version.\u001B[39;00m\n\u001B[0;32m---> 19\u001B[0m data_to_publish \u001B[38;5;241m=\u001B[39m \u001B[43mmanager\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mresolve\u001B[49m\u001B[43m(\u001B[49m\u001B[43mlogo_ref\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtrait_set_to_keep\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mResolveAccess\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mkManagerDriven\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 21\u001B[0m \u001B[38;5;66;03m# Any traits without properties, or where the manager cannot provide them, will be missing from the data.\u001B[39;00m\n\u001B[1;32m 22\u001B[0m \u001B[38;5;66;03m# We still need to imbue those traits, so that manager knows what kind of entity we are publishing.\u001B[39;00m\n\u001B[1;32m 23\u001B[0m data_to_publish\u001B[38;5;241m.\u001B[39maddTraits(minimum_trait_set)\n", + "File \u001B[0;32m~/workspace/cloud/assetapi/OpenAssetIO-Manager-BAL/plugin/openassetio_manager_bal/BasicAssetLibraryInterface.py:79\u001B[0m, in \u001B[0;36msimulated_delay..wrapper_simulated_delay\u001B[0;34m(self, *args, **kwargs)\u001B[0m\n\u001B[1;32m 77\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m delay_ms \u001B[38;5;241m>\u001B[39m \u001B[38;5;241m0\u001B[39m:\n\u001B[1;32m 78\u001B[0m time\u001B[38;5;241m.\u001B[39msleep(delay_ms \u001B[38;5;241m/\u001B[39m \u001B[38;5;241m1000.0\u001B[39m) \u001B[38;5;66;03m# sleep takes seconds\u001B[39;00m\n\u001B[0;32m---> 79\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mfunc\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", + "File \u001B[0;32m~/workspace/cloud/assetapi/OpenAssetIO-Manager-BAL/plugin/openassetio_manager_bal/BasicAssetLibraryInterface.py:291\u001B[0m, in \u001B[0;36mBasicAssetLibraryInterface.resolve\u001B[0;34m(self, entityReferences, traitSet, access, context, hostSession, successCallback, errorCallback)\u001B[0m\n\u001B[1;32m 289\u001B[0m successCallback(idx, result)\n\u001B[1;32m 290\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m exc: \u001B[38;5;66;03m# pylint: disable=broad-except\u001B[39;00m\n\u001B[0;32m--> 291\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m__handle_exception\u001B[49m\u001B[43m(\u001B[49m\u001B[43mexc\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43midx\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43merrorCallback\u001B[49m\u001B[43m)\u001B[49m\n", + "File \u001B[0;32m~/workspace/cloud/assetapi/OpenAssetIO-Manager-BAL/plugin/openassetio_manager_bal/BasicAssetLibraryInterface.py:620\u001B[0m, in \u001B[0;36mBasicAssetLibraryInterface.__handle_exception\u001B[0;34m(exc, idx, error_callback)\u001B[0m\n\u001B[1;32m 618\u001B[0m code \u001B[38;5;241m=\u001B[39m BatchElementError\u001B[38;5;241m.\u001B[39mErrorCode\u001B[38;5;241m.\u001B[39mkMalformedEntityReference\n\u001B[1;32m 619\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m--> 620\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exc\n\u001B[1;32m 622\u001B[0m error_callback(idx, BatchElementError(code, msg))\n", + "File \u001B[0;32m~/workspace/cloud/assetapi/OpenAssetIO-Manager-BAL/plugin/openassetio_manager_bal/BasicAssetLibraryInterface.py:269\u001B[0m, in \u001B[0;36mBasicAssetLibraryInterface.resolve\u001B[0;34m(self, entityReferences, traitSet, access, context, hostSession, successCallback, errorCallback)\u001B[0m\n\u001B[1;32m 266\u001B[0m \u001B[38;5;66;03m# Ensure this entity supports the type of access\u001B[39;00m\n\u001B[1;32m 267\u001B[0m \u001B[38;5;66;03m# requested.\u001B[39;00m\n\u001B[1;32m 268\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m kAccessNames[\u001B[38;5;28mint\u001B[39m(access)] \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m entity\u001B[38;5;241m.\u001B[39msupported_access_modes:\n\u001B[0;32m--> 269\u001B[0m \u001B[43merrorCallback\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 270\u001B[0m \u001B[43m \u001B[49m\u001B[43midx\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 271\u001B[0m \u001B[43m \u001B[49m\u001B[43mBatchElementError\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 272\u001B[0m \u001B[43m \u001B[49m\u001B[43mBatchElementError\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mErrorCode\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mkEntityAccessError\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 273\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mUnsupported access mode for resolve\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[1;32m 274\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 275\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 276\u001B[0m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[1;32m 278\u001B[0m result \u001B[38;5;241m=\u001B[39m TraitsData()\n", + "\u001B[0;31mBatchElementException\u001B[0m: entityAccessError: Unsupported access mode for resolve [index=0] [access=managerDriven] [entity=bal:///project_artwork/logos/openassetio]" + ] + } + ], "source": [ "# The minimum set of traits required to publish to this entity reference.\n", - "minimum_trait_set = manager.entityTraits(logo_ref, EntityTraitAccess.kWrite, context)\n", + "minimum_trait_set = manager.entityTraits(logo_ref, EntityTraitsAccess.kWrite, context)\n", "\n", "# Whatever the minimum trait set is, we know we want to publish a location and auth token.\n", "desired_trait_set = minimum_trait_set | {BearerTokenTrait.kId, LocatableContentTrait.kId}\n", "\n", "# Get the set of traits that have properties the manager can persist.\n", - "policy_for_desired_traits = manager.managementPolicy(\n", - " desired_trait_set, PolicyAccess.kWrite, context)\n", + "[policy_for_desired_traits] = manager.managementPolicy(\n", + " [desired_trait_set], PolicyAccess.kWrite, context)\n", "\n", "# Filter down the desired traits to only those that are supported.\n", "trait_set_to_publish = desired_trait_set & policy_for_desired_traits.traitSet()\n", @@ -691,15 +762,15 @@ "trait_set_to_keep = trait_set_to_publish - {BearerTokenTrait.kId, LocatableContentTrait.kId}\n", "\n", "# Get the properties that we wish to keep from the current version.\n", - "data_to_publish = manager.resolve(logo_ref, trait_set_to_keep, ResolveAccess.kRead, context)\n", + "data_to_publish = manager.resolve(logo_ref, trait_set_to_keep, ResolveAccess.kManagerDriven, context)\n", "\n", "# Any traits without properties, or where the manager cannot provide them, will be missing from the data.\n", "# We still need to imbue those traits, so that manager knows what kind of entity we are publishing.\n", "data_to_publish.addTraits(minimum_trait_set)\n", "\n", "# Get the manager's policy for dictating trait properties, i.e. which traits the manager can `kDerive` for us.\n", - "policy_for_derived_traits = manager.managementPolicy(\n", - " trait_set_to_publish, PolicyAccess.kDerive, context)\n", + "[policy_for_derived_traits] = manager.managementPolicy(\n", + " [trait_set_to_publish], PolicyAccess.kManagerDriven, context)\n", "\n", "# Check if the manager can derive a location for us.\n", "if LocatableContentTrait.kId in policy_for_derived_traits.traitSet():\n", @@ -716,12 +787,12 @@ " BearerTokenTrait(data_to_publish).setToken(\"==ZxErn43G\")\n", "\n", "# We can now successfully begin the publishing process.\n", - "working_ref = manager.preflight(logo_ref, data_to_publish, PublishAccess.kWrite, context)\n", + "working_ref = manager.preflight(logo_ref, data_to_publish, PublishingAccess.kWrite, context)\n", "\n", "# Check if the manager can provide a location to us.\n", "if LocatableContentTrait.kId in policy_for_derived_traits.traitSet():\n", " derived_data = manager.resolve(\n", - " working_ref, {LocatableContentTrait.kId}, ResolveAccess.kDerive, context)\n", + " working_ref, {LocatableContentTrait.kId}, ResolveAccess.kManagerDriven, context)\n", "\n", " # TODO(DF): `upsert` function for `TraitsData`.\n", " LocatableContentTrait(data_to_publish).setLocation(\n", @@ -730,10 +801,14 @@ "# [Do some work to write the new file...]\n", "\n", "# We can now finally publish\n", - "updated_ref = manager.register(logo_ref, data_to_publish, PublishAccess.kWrite, context)" + "updated_ref = manager.register(logo_ref, data_to_publish, PublishingAccess.kWrite, context)" ], "metadata": { - "collapsed": false + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-02-23T16:12:45.038185988Z", + "start_time": "2024-02-23T16:12:44.972924415Z" + } }, "id": "beab2b9a9c071302" } diff --git a/examples/resources/querying_entity_traits/bal_database.json b/examples/resources/querying_entity_traits/bal_database.json new file mode 100644 index 0000000..49aab3a --- /dev/null +++ b/examples/resources/querying_entity_traits/bal_database.json @@ -0,0 +1,45 @@ +{ + "managementPolicy": { + "read": { + "default": { + "openassetio-mediacreation:managementPolicy.Managed": {}, + "openassetio-mediacreation:content.LocatableContent": {}, + "openassetio-mediacreation:identity.DisplayName": {}, + "openassetio-mediacreation:lifecycle.Version": {} + } + }, + "write": { + "default": { + "openassetio-mediacreation:managementPolicy.Managed": {}, + "openassetio-mediacreation:content.LocatableContent": {}, + "openassetio-mediacreation:identity.DisplayName": {} + } + }, + "managerDriven": { + "default": { + "openassetio-mediacreation:managementPolicy.Managed": {}, + "openassetio-mediacreation:content.LocatableContent": {}, + "openassetio-mediacreation:identity.DisplayName": {} + } + } + }, + "entities": { + "project_artwork/logos/openassetio": { + "versions": [ + { + "traits": { + "openassetio-mediacreation:usage.Entity": {}, + "openassetio-mediacreation:identity.DisplayName": { + "name": "OpenAssetIO logo" + }, + "openassetio-mediacreation:content.LocatableContent": { + "location": "file:///mnt/shows/artwork/logos/openassetio.png" + }, + "openassetio-mediacreation:timeDomain.FrameRanged": {} + }, + "supported_access_modes": ["read", "managerDriven"] + } + ] + } + } +} diff --git a/examples/resources/querying_entity_traits/openassetio_config.toml b/examples/resources/querying_entity_traits/openassetio_config.toml new file mode 100644 index 0000000..083d491 --- /dev/null +++ b/examples/resources/querying_entity_traits/openassetio_config.toml @@ -0,0 +1,5 @@ +[manager] +identifier = "org.openassetio.examples.manager.bal" + +[manager.settings] +library_path = "${config_dir}/bal_database.json"