Package: azimuth-sdk
azimuth-sdkAn SDK for interacting withAzimuthresources usingPython.Both synchronous use and asynchronous use, using theasync/awaitsyntax fromasyncio, are supported.InstallationThe Azimuth SDK can be installed from PyPI:pipinstallazimuth-sdkUsageTo begin using the Azimuth SDK, you must first create a configuration object that defines how
to authenticate with Azimuth.Currently, authentication with Azimuth usesOpenStackcredentials.
Azimuth supports two user-facing authentication methods:Username + PasswordKeystone federationThe Keystone federation flow requires a browser, so is not supported by the Azimuth SDK.Azimuth also supports authenticating with anapplication credential.
This authentication method is usually hidden from browser-based users, but is available for use
by the SDK.This is the recommended authentication method.The SDKConfigurationobject can be initialised either using known credentials or from aclouds.yaml file.
The Azimuth SDK respects the sameOS_CLOUDandOS_CLIENT_CONFIG_FILEenvironment variables that
theOpenStack CLIrespects.fromazimuth_sdkimportConfigurationAZIMUTH_URL="https://portal.azimuth.example.org"# Initialise from variablesconfig=Configuration.create(AZIMUTH_URL,authenticator="appcred",auth_data={"application_credential_id":"<application credential id>","application_credential_secret":"<application credential secret>",},# Optionally set a default tenancydefault_tenancy_id="<tenancy id>")# Initialise from a specific clouds.yaml fileconfig=Configuration.from_openstack_clouds_file(AZIMUTH_URL,"/path/to/openstack/clouds.yaml")# Initialise from environment variablesconfig=Configuration.from_environment(AZIMUTH_URL)Once you have aConfigurationobject, it can be used to create either synchronous or
asynchronous clients with which you can interact with Azimuth, e.g. by listing the
available tenancies:# Synchronous clientwithconfig.sync_client()asclient:fortenancyinclient.tenancies().list():print(tenancy.name)# Asynchronous clientasyncwithconfig.async_client()asclient:asyncfortenancyinclient.tenancies().list():print(tenancy.name)WARNINGIt is important that the client is used inside awithorasync withblock, for
synchronous or asynchronous clients respectively, as this ensures that resources
are set up and released as required.See Python'scontextlibfor more information.You can then interact with resources for a tenancy. The following resources are available:# Interact with the images for a tenancyclient.images(tenancy_id=None)# Interact with the sizes for a tenancyclient.sizes(tenancy_id=None)# Interact with the volumes for a tenancyclient.volumes(tenancy_id=None)# Interact with the external IPs for a tenancyclient.external_ips(tenancy_id=None)# Interact with the machines for a tenancyclient.machines(tenancy_id=None)# Interact with the CaaS cluster types for a tenancyclient.cluster_types(tenancy_id=None)# Interact with the CaaS clusters for a tenancyclient.clusters(tenancy_id=None)# Interact with the Kubernetes templates for a tenancyclient.kubernetes_cluster_templates(tenancy_id=None)# Interact with the Kubernetes clusters for a tenancyclient.kubernetes_clusters(tenancy_id=None)# Interact with the Kubernetes app templates for a tenancyclient.kubernetes_app_templates(tenancy_id=None)# Interact with the Kubernetes apps for a tenancyclient.kubernetes_apps(tenancy_id=None)For each of these methods, thetenancy_idis optional. If it is not given, a default
tenancy ID will be used, which is determined as follows:Explicitly set when theConfigurationis createdFromclouds.{cloud}.auth.project_idin theclouds.yaml, if presentAs the first available tenancy in the tenancy list (may not be deterministic)The default tenancy for a client can also be changed using theswitch_tenancymethod:client.switch_tenancy(new_tenancy_id)Each of these returns aResourceobject, which can be interacted with as follows.NOTEThe sync methods are available on resources produced by synchronous clients
(i.e. created usingconfig.sync_client), and the
async methods on resources produced by asynchronous clients
(i.e. created usingconfig.async_client).# List instances#   syncforinstanceinresource.list():print(instance)#   asyncasyncforinstanceinresource.list():print(instance)# Get the first instance from a list response#   syncinstance=resource.first()#   asyncinstance=awaitresource.first()# Fetch an instance by ID#   syncinstance=resource.fetch("<id>")#   asyncinstance=awaitresource.fetch("<id>")# Create a new instance#   syncinstance=resource.create({"name":"my-instance","<prop>":"<value>"})#   asyncinstance=awaitresource.create({"name":"my-instance","<prop>":"<value>"})# Replace an instance by ID (PUT request)#   syncinstance=resource.replace("<id>",{"name":"my-instance","<prop>":"<value>"})#   asyncinstance=awaitresource.replace("<id>",{"name":"my-instance","<prop>":"<value>"})# Patch an instance by ID (PATCH request)#   syncinstance=resource.patch("<id>",{"<prop>":"<value>"})#   asyncinstance=awaitresource.patch("<id>",{"<prop>":"<value>"})# Replace an instance by ID, or create it (using the same data) if it doesn't exist#   syncinstance=resource.create_or_replace("<id>",{"name":"my-instance","<prop>":"<value>"})#   asyncinstance=awaitresource.create_or_replace("<id>",{"name":"my-instance","<prop>":"<value>"})# Patch an instance by ID, or create it (using the same data) if it doesn't exist#   syncinstance=resource.create_or_patch("<id>",{"<prop>":"<value>"})#   asyncinstance=awaitresource.create_or_patch("<id>",{"<prop>":"<value>"})# Delete an instance by ID#   syncinstance=resource.delete("<id>")#   asyncinstance=awaitresource.delete("<id>")