⚠️ 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=YFNT-SXGW 2. Navigate to http://localhost/aiod-auth/realms/aiod/device and enter code YFNT-SXGW This workflow will automatically abort after 300 seconds.
<aiod.authentication.authentication.Token at 0x116618310>
You can test whether authentication has been successful by obtaining information about the logged in user:
aiod.get_current_user()
User(name='user', roles=('default-roles-aiod', 'offline_access', '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_n0PRebGuARI8KLaGPAVFnIrh',
'name': 'Arthur Dent',
'wants_to_be_contacted': False,
'agent_identifier': 'prsn_n0PRebGuARI8KLaGPAVFnIrh',
'ai_resource_identifier': 'prsn_n0PRebGuARI8KLaGPAVFnIrh',
'aiod_entry': {'editor': [],
'status': 'draft',
'date_modified': '2025-11-05T13:45:27',
'date_created': '2025-11-05T13:45:27'},
'alternate_name': [],
'application_area': [],
'contact': [],
'contacts': [],
'creator': [],
'expertise': [],
'falls_under_paradigm': [],
'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_n0PRebGuARI8KLaGPAVFnIrh'}
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"]
['example', 'fictional']
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]>
try:
aiod.persons.get_asset(identifier=identifier)
except KeyError as e: # If the identifier doesn't match any asset
print(e)
"No persons with identifier 'prsn_n0PRebGuARI8KLaGPAVFnIrh' found."