⚠️ This notebook assumes you followed installation instructions in Getting Started or the home page. If you are running this in an online environment such as Colab, install the package first:
!pip install aiondemand
Sharing Metadata on AI-on-Demand¶
🧑💻 You can try this notebook interactively on Google Colab or Binder.
To share metadata on AI-on-Demand, you need to have an AI-on-Demand account. To obtain one, head over to the AI-on-Demand website and click 'login'. You will be prompted to sign in with an authentication service (e.g., Google or an institutional login), which will initiate the account creation process. You can later use these same credentials to log in to your account - no need for AI-on-Demand specific login credentials! 🎉
After creating an account, we can use it to grant us programmatic access from Python.
The programmatic access is granted through an 'access token', which you can obtain by running the code below.
It will initiate an authorization request, and print instructions to confirm your authorization in the browser.
Follow these instructions, the method will wait for you to complete this process.
We call the function with argument write_to_file=True
, which will automatically save the obtained token in a file (~/.aiod/token.toml
) so it can be loaded from disk next time you use the package.
You can choose not to store your token, but you will need to obtain a new token each time you start a new Python process (i.e., run your script).
import aiod
aiod.create_token(write_to_file=True)
Please authenticate using one of two methods: 1. Navigate to http://localhost/aiod-auth/realms/aiod/device?user_code=VSIF-SFQQ 2. Navigate to http://localhost/aiod-auth/realms/aiod/device and enter code VSIF-SFQQ This workflow will automatically abort after 300 seconds.
<aiod.authentication.authentication.Token at 0x1133d5e10>
You can test whether authentication has been successful by obtaining information about the logged in user:
aiod.get_current_user()
User(name='user', roles=('offline_access', 'default-roles-aiod', 'uma_authorization'))
Registering New Metadata¶
You can register new metadata of any resource type. For the full schema specification, reference the REST API documentation.
💡To find the schema specification in the REST API documentation, go to the asset type of interested, expand the POST /ASSET_TYPE
section (e.g., POST /persons
) and under request body click schema. We are working on making these schema's more easily available.
⚠️ Metadata submitted to the metadata catalogue will be available for all to see. In the example below, consider updating it to reflect your own identity, the organisation you work for, or an interesting AI asset that isn't yet registered on AI-on-Demand. Fake data may be removed without warning, and repeated offenses may result in a ban. Making mistakes is allowed, but please use the replace
method to correct information or the delete
method to remove accidental uploads (more about those methods
# Or alternatively, use a local server for testing, see https://github.com/aiondemand/aiod-rest-api
# import aiod
# aiod.config.auth_server = 'http://localhost/aiod-auth/'
# aiod.config.api_server = 'http://localhost/'
# aiod.create_token() # The old token is not valid for the new authentication server
identifier = aiod.persons.register(metadata=dict(name="Arthur Dent"))
If our asset was registered successfully, we should now be able to obtain it from the server:
person = aiod.persons.get_asset(identifier=identifier, data_format="json")
person
{'platform': 'aiod', 'platform_resource_identifier': 'prsn_zKwBU5BHJldmqfUXcu5hBWsp', 'name': 'Arthur Dent', 'wants_to_be_contacted': False, 'agent_identifier': 'prsn_zKwBU5BHJldmqfUXcu5hBWsp', 'ai_resource_identifier': 'prsn_zKwBU5BHJldmqfUXcu5hBWsp', 'aiod_entry': {'editor': [], 'status': 'published', 'date_modified': '2025-09-16T08:35:09', 'date_created': '2025-09-16T08:35:09'}, 'alternate_name': [], 'application_area': [], 'contact': [], 'contacts': [], 'creator': [], 'expertise': [], 'has_part': [], 'industrial_sector': [], 'is_part_of': [], 'keyword': [], 'languages': [], 'media': [], 'member_of': [], 'note': [], 'relevant_link': [], 'relevant_resource': [], 'relevant_to': [], 'research_area': [], 'scientific_domain': [], 'identifier': 'prsn_zKwBU5BHJldmqfUXcu5hBWsp'}
If we find we need to update something, we can use the update
method to provide new metadata for the asset.
aiod.persons.update(identifier=identifier, metadata=dict(keyword=["example", "fictional"]))
<Response [200]>
Changes from the call above are reflected on the server:
person = aiod.persons.get_asset(identifier=identifier, data_format="json")
person["keyword"]
['fictional', 'example']
We can also use the replace
method, which replaces all values back to default except for those specified. For example, using replace
without specifying keyword
will set it back to its default value:
aiod.persons.replace(identifier=identifier, metadata=dict(name="King Arthur", wants_to_be_contacted=True))
<Response [200]>
person = aiod.persons.get_asset(identifier=identifier, data_format="json")
print("Wants to be contacted:", person["wants_to_be_contacted"])
print("Keywords:", person["keyword"])
print("Name:", person["name"])
Wants to be contacted: True Keywords: [] Name: King Arthur
Note: while we generally think people prefer to use the update
method over the replace
method, the update
method is simply a best-effort wrapper around replace
as the PATCH
functionality to natively support update
is not yet supported by the server's REST API. For the time being, if you experience issues using update
please consider using replace
instead. Here is a simple recipe for fetching the data before a replace
request:
person = aiod.persons.get_asset(identifier=identifier, data_format="json")
del person["aiod_entry"] # This field may not be present in the update request
person["keyword"] = ["example", "fictional"] # Now you manually set any fields
aiod.persons.replace(identifier=person['identifier'], metadata=person)
<Response [200]>
Finally, we can also remove assets that we registered using the delete
method.
⚠️ Deleting an asset is final. It cannot be undone.
aiod.persons.delete(identifier=identifier)
<Response [200]>
aiod.persons.get_asset(identifier=identifier)
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[12], line 1 ----> 1 aiod.persons.get_asset(identifier=identifier) File ~/repositories/aiod-py-sdk/src/aiod/calls/calls.py:282, in get_asset(identifier, asset_type, version, data_format) 278 res = requests.get(url, headers=_get_auth_headers(required=False)) 279 if res.status_code == HTTPStatus.NOT_FOUND and "not found" in res.json().get( 280 "detail" 281 ): --> 282 raise KeyError(f"No {asset_type} with identifier {identifier!r} found.") 283 resources = format_response(res.json(), data_format) 284 return resources KeyError: "No persons with identifier 'prsn_zKwBU5BHJldmqfUXcu5hBWsp' found."