Getting Started =============== =================================== Install ``o2a.registry.python.lib`` =================================== ``o2a.registry.python.lib`` requires Python 3.12+. Install the latest development version of ``o2a.registry.python.lib`` via your command-line with .. code-block:: bash pip install o2a.registry.python.lib to get the latest version from the git repository. ======================== Run your first query ======================== First you need to define, which registry server you want use. You can either import one of two predefined registry services .. code-block:: python from o2a_registry.api import ProductionAPI # registry.o2a-data.de from o2a_registry.api import SandboxAPI # registry.sandbox.o2a-data.de or define a service yourself .. code-block:: python from o2a_registry.api import RegistryApi MyAPI = RegistryApi("example.com") You then can query the registry API using these API objects. For example lets retrieve the data for the Polarstern I .. code-block:: python POLARSTERN_ITEM_ID = 90 polarstern = await SandboxAPI.get_item(POLARSTERN_ITEM_ID) print("Polarstern description:", polarstern.description) When you finished all your request to the registry, you should close your API object again, to properly close the connection to registry service .. code-block:: python await SandboxAPI.close() .. warning:: Note that all API methods are ``async``. If you never heard about ``async`` you can read this `guide `_. TL:DR If you use python in an IPython environment (the interactive python terminal or jupyter notebooks), you only need to put the ``await`` keyword in front of your method calls, like above. If you write "normal" python scripts/programs you need to wrap the code which calls the API in an ``async`` context. This can be done like this: .. code-block:: python import asyncio from o2a_registry.api import SandboxAPI async def main(): POLARSTERN_ITEM_ID = 90 polarstern = await SandboxAPI.get_item(POLARSTERN_ITEM_ID) print("Polarstern description:", polarstern.description) if __name__ == '__main__': asyncio.run(main()) ================ Query everything ================ The registry API allows to retrieve all items/contacts/vocables/etc. from the registry .. code-block:: python all_items = await SandboxAPI.get_items() but only in chunks of 100 entries at a time. All items can items/contacts/vocables/etc. can still be retrieved by iterating over all available chunks (also called pages) .. code-block:: python offset = 0 while True: items = await SandboxAPI.get_items(hits=100, offset=offset) # Do something with the items if len(items) < 100: break offset += len(items) This uses the optional argument `offset`, which defines the number of entries to skip before returning data. If your application takes a long time to process a single result of the pagination, it might be helpful to reduce the number of hits further by using the `hits` option. The order of results can be influenced with the ``sorts`` option. This takes a list of fields from the object you are querying.. The result is then sorted by these fields in ascending order. .. code-block:: python offset = 0 while True: items = await SandboxAPI.get_items(hits=100, offset=offset, sorts=["created"]) # Do something with the items if len(items) < 100: break offset += len(items) ``o2a.registry.python.lib`` also provides convenience functions ``paginated_get_all`` and ``paginated_iter`` to get all items without you having to worry about the pagination. While ``paginated_get_all`` gets all items from the registry service when called .. code-block:: python from o2a_registry.utils.pagination import paginated_get_all all_items = await paginated_get_all(SandboxAPI.get_items, sorts=["created"]) ``paginated_iter`` provides an generator, which only loads the next chunk from the registry service, when the previous chunk was processed .. code-block:: python from o2a_registry.utils.pagination import paginated_iter async for item in paginated_iter(SandboxAPI.get_items, sorts=["created"]): # Do something with the item ====================== Search the haystack ====================== You will be often searching for specific entries with certain field values. The ``where`` field allows you to do this, by specifying a RSQL query. For example, to search all items, which have the Polarstern as a parent device use .. code-block:: python ps_children = await SandboxAPI.get_items(where="parent.id==90") This also allows you to search for fields of sub-objects, for example to search for items with type vessel .. code-block:: python vessels = await SandboxAPI.get_items(where="type.systemName==vessel") ========= Vocables ========= Sub-objects like types are organized as ``vocables``, which in turn are organized as ``vocablesGroups``. These can be browsed with: .. code-block:: python vocable_groups = await SandboxAPI.get_vocable_groups() To get all ``vocables`` for a ``vocablesGroup`` use the search pattern shown before: .. code-block:: python DEVICE_TYPE_ID = 7 device_types = await SandboxAPI.get_vocables(where="vocableGroup.id==7") ============ Change data ============ To create, edit or delete entries in the registry log in with your AWI username and password, or your email and API token. In the latter case you first need to visit https://o2a-data.de/auth/settings to create an API token. See https://o2a-data.de/documentation/index.md.html#account-authentication-and-login for further instruction. .. note:: Currently, token creation via the GUI is only possible for https://registry.o2a-data.de (``ProductionAPI``). If you need a token for https://registry.sandbox.o2a-data.de (``SandboxAPI``) please contact the O2A support at https://registry.sandbox.o2a-data.de/contact. .. code-block:: python await SandboxAPI.login(username="user", password="pwd") To create an item, first create a ``CreateItem`` object with all mandatory / non-optional fields. Then send the object to the corresponding endpoint: .. code-block:: python from o2a_registry.models import CreateItem voyager_create = CreateItem( short_name="NCC-74656", long_name="USS Voyager", status_id=2, type_id=236, description="https://memory-alpha.fandom.com/wiki/USS_Voyager", parent_id=0, model="Intrepid-class" ) await SandboxAPI.create_item(voyager_create) Editing an item works similar, while only requires you to fill out the fields, you want to change. .. code-block:: python from o2a_registry.models import EditItem voyager_edit = EditItem( status_id=1 ) await SandboxAPI.edit_item(voyager_create.id, voyager_edit) Deleting an item only requires the ``ID`` of the item. .. code-block:: python await SandboxAPI.delete_item(voyager_create.id) .. note:: "Deleting" an item via the API only sets its status to "Decommissioned".