Getting Started


As a convention throughout this documentation, whenever we write an entity such as pool, volume, system etc., it will always refer to a Python object – never to a name string or to an object identifier. When we want to indicate a name or an id we will name variables accordingly (e.g. volume_id, pool_name etc.).


Installing InfiniSDK is done by using pip:

$ pip install infinisdk


Depending on your Python installation, the above command might require root privileges

See also

For more information on pip and how to use it to install Python packages, see

Creating the InfiniBox Object

In your Python interpreter, import the infinisdk.InfiniBox class, and initialize it with your system address:

>>> from infinisdk import InfiniBox
>>> system = InfiniBox(SYSTEM_ADDRESS)


SYSTEM_ADDRESS can be a hostname for your system’s management address, or an IP address

SSL is disabled by default, but can be easily turned on by passing use_ssl=True to the system constructor:

>>> system = InfiniBox(SYSTEM_ADDRESS, use_ssl=True)


By default, constructing a system does not send any traffic or API calls to the system. Only performing actual actions or queries does.


Authentication information can also be specified via the constructor:

>>> system = InfiniBox(SYSTEM_ADDRESS, auth=("admin", "password"))

Note that you need to explicitly call login to actually log in to the system:

>>> system.login()
<Response [200]>

Another way authentication information can be provided is through an .ini file. Create a file named ~/.infinidat/infinisdk.ini, with the following structure:


Now constructing an InfiniBox object will use the credentials above by default. You can also specify authorization for specific system, by adding sections to the .ini file titled infinibox:<system name>:

[infinibox] # will be used for default

[infinibox:system01] # will be used for interacting with the InfiniBox named 'system01'


InfiniSDK uses Logbook for logging, and by default all logs are emitted to the standard error stream.

The emitted logs also include the full debug outputs of the API calls made to the system, which might be a bit too much in some cases, overflowing your console unnecessarily. If you prefer less verbosity, you can set up a different logging scheme. For instance, the following code will only emit INFO logs to the console:

>>> import logbook
>>> import sys
>>> with logbook.NestedSetup([
...        logbook.NullHandler(),
...        logbook.StreamHandler(sys.stderr, level=logbook.INFO)]):
...     pass  # your code here

Approving Dangerous Operations

By default, InfiniSDK performs operations regardless of the level of caution required for them. When a user uses a CLI or a GUI, Infinidat products often require confirmation before carrying out some dangerous operations requiring extra attention.

If you want your script to interactively ask the user for confirmation for such operations, use the set_interactive_approval() method:

>>> system.api.set_interactive_approval()

You can also turn off approvals temporarily, causing your script to fail with an exception in case dangerous operations are about to be carried out:

>>> with system.api.get_unapproved_context():
...     pass # operations here

Representing API Entities

InfiniSDK provides reflection for objects or entities defined on the system in the form of Pythonic objects. This makes creation, deletion and manipulation of objects easier. Supported objects are defined as Python classes such as infinisdk.infinibox.volume.Volume or infinisdk.infinibox.pool.Pool, and are accessed more easily through collection proxies, such as system.volumes, system.pools etc. For each supported object type X, there exists system.Xs.

The following examples illustrate how to use those proxies.

Creating Objects

Creation of objects can be done easily via the create method. InfiniSDK provides defaults for all required fields that can be autogenerated. For instance, creating a pool can be done via system.pools.create():

>>> pool = system.pools.create()


the create shortcut used above is a very thin wrapper around the create method of the Pool class. All it does is automatically assign the “right” system to the first argument.

Object Attributes

Once an object is obtained (either by creation or querying as described further down), it can be inspected for its attributes or manipulated in various ways. This is done using getter/setter methods. For most used names, there are direct setters and getters:

>>> pool.update_name('new_name')
>>> pool.get_name() == 'new_name'

All fields can be accessed via the SystemObject.get_field() / SystemObject.update_field() methods:

>>> pool.update_field('name', 'yet_another_name')
>>> pool.get_field('name') == 'yet_another_name'


Whenever an object attribute is fetched, it is cached for later use. By default, getting fields always fetches them from the cache of the requested object.

In case you need to fetch an up-to-date value for a field, there are several options:

  1. Use from_cache=False:

    >>> print(pool.get_field('name', from_cache=False))

    The above forces InfiniSDK to fetch the name from the system regardless of the cache

  2. Disable caching completely:

    >>> system.disable_caching()

Storage Capacity Handling

InfiniSDK reflects data sizes using the capacity module, allowing easy computations and manipulations of data sizes, including units:

>>> from capacity import GiB

>>> size = pool.get_virtual_capacity()
>>> print(size)
1 TB
>>> print(size * 2)
2 TB
>>> print(size // GiB)

Querying Objects

Querying objects of various types is done relatively easily through InfiniSDK. The InfiniBox system exposes collection proxies, which provide iteration and filtering. Here’s an example of querying all volumes on a system:

>>> system.volumes.count()

>>> system.volumes.to_list()

See also

Querying Objects

Deleting Objects

Deleting objects can be done by the delete method, which is available for the vast majority of the object types.

>>> host = system.hosts.create()
>>> host.delete() # <-- host gets deleted


The delete method usually doesn’t take care of indirect deletion needed to fullfill the request (like deleting volumes inside pools). This is a design decision that has been made to prevent unintended operations from being unwittingly made on the user’s behalf.

Accessing HTTP/REST API Directly

InfiniSDK supports calling the HTTP/REST API of the system directly:

>>> response = system.api.get('system/product_id')

The above accesses /api/rest/system/product_id. API.get(),, API.delete() and API.put() all return Response objects. Results can be fetched by Response.get_result():

>>> print(response.get_result())

You can always access the response belonging to requests through .response:

>>> response.response.status_code

By default, requests are checked for success. This behavior can be overriden by providing assert_success=False:

>>> response = system.api.get('nonexistent/path', assert_success=False)
>>> response.response.status_code