%define scl rh-python36 %{?scl:%scl_package %{name}} %{!?scl:%global pkg_name %{name}} %define name ovirt-engine-sdk-python %define version 4.3.0 %define unmangled_version 4.3.0 %define unmangled_version 4.3.0 %define release 1 Summary: Python SDK for oVirt Engine API %{?scl:Requires: %{scl}-runtime} %{?scl:BuildRequires: %{scl}-runtime} Name: %{?scl_prefix}ovirt-engine-sdk-python Version: %{version} Release: %{release} Source0: ovirt-engine-sdk-python-%{unmangled_version}.tar.gz License: ASL2 Group: Development/Libraries BuildRoot: %{_tmppath}/ovirt-engine-sdk-python-%{version}-%{release}-buildroot Prefix: %{_prefix} Vendor: Michael Pasternak, Juan Hernandez, Ondra Machacek Packager: Martin Juhl %description = oVirt Engine API Python SDK == Introduction This project contains the Python SDK for the oVirt Engine API. == Important Note that most of the code of this SDK is automatically generated. If you just installed the package then you will have everything already, but if you downloaded the source then you will need to generate it, follow the instructions in the `README.adoc` file of the parent directory. == Installation The SDK can be installed in Fedora 24 and CentOS 7 using the RPM packages provided by the oVirt project. To do so install the oVirt release package: # dnf install http://resources.ovirt.org/pub/yum-repo/ovirt-release41.rpm Then install the SDK packages. For Python 2: # dnf install python-ovirt-engine-sdk4 For Python 3: # dnf install python3-ovirt-engine-sdk4 For other operating systems (and also for Fedora and CentOS) you can install the SDK using the `pip` command, which will download the source from https://pypi.python.org/pypi[PyPI], build and install it. The SDK uses http://www.xmlsoft.org[libxml2] for parsing and rendering XML. The part of the SDK that interacts with that library is written in C. This means that before building you must make sure you have the C compiler and the required header and libraries files installed in your system. For example, if you are using distributions like Fedora, or CentOS: # dnf -y install \ gcc \ libxml2-devel \ python-devel For Python 3: # dnf -y install \ gcc \ libxml2-devel \ python3-devel If you are using distributions like Debian, or Ubuntu: # apt-get --assume-yes install \ gcc \ libxml2-dev \ python-dev For Python 3: # apt-get --assume-yes install \ gcc \ libxml2-dev \ python3-dev NOTE: The examples above use the `dnf` command, which is the default in Fedora 24. In CentOS 7 you may need to use the `yum` command, as `dnf` is optional. == Usage === Packages The following are the Python modules that are most frequently needed in order to use the SDK: ovirtsdk4:: This is the top level module. It most important element is the `Connection` class, as is the mechanism to connect to the server and to get the reference to the root of the services tree. + The `Error` class, is the base exception class that the SDK will raise when it needs to report any error. For certain kinds of errors there are specific error classes, extending the base error class: * `AuthError` - Raised when authentication or authorization fail. * `ConnectionError` - Raised when the name of the server can't be resolved, and when the server is down or unreachable. * `NotFoundError` - Raised when the requested object doesn't exist. * `TimeoutError` - Raised when an operation times out. ovirtsdk4.types:: This module contains the classes that implement the _types_ used in the API. For example, the `ovirtsdk4.types.Vm` Python class is the implementation of the virtual machine type. These classes are just containers of data, they don't contain any logic. + Instances of these classes are used as parameters and return values of _service methods_. The conversion to/from the underlying representation is handled transparently by the SDK. ovirtsdk4.services:: This module contains the classes that implement the _services_ supported by the API. For example, the `ovirtsdk4.services.VmsService` Python class is the implementation of the service that manages the collection of virtual machines of the system. + Instances of these classes are automatically created by the SDK when a service is located. For example, a new instance of the `VmsService` class will be automatically created by the SDK when doing the following: + [source,python] ---- vms_service = connection.system_service().vms_service() ---- + Avoid creating instances of these classes manually, as the parameters of the constructors, and in general all the methods except the _service locators_ and _service methods_ (described later) may change in the future. There are other modules, like `ovirtsdk4.http`, `ovirtsdk4.readers` and `ovirtsdk4.writers`. These are used to implement the HTTP communication, and to for XML parsing and rendering. Refrain from using them, as they are internal implementation details that may change in the future: backwards compatibility isn't guaranteed. === Connecting to the server To connect to the server import the `ovirtsdk4` module. That will give to the `Connection` class. This is the entry point of the SDK, and gives you access to the root of the tree of services of the API: [source,python] ---- import ovirtsdk4 as sdk # Create a connection to the server: connection = sdk.Connection( url='https://engine.example.com/ovirt-engine/api', username='admin@internal', password='...', ca_file='ca.pem', ) ---- The connection holds expensive resources, including a pool of HTTP connections to the server and an authentication token. It is very important to free these resources when they are no longer in use: [source,python] ---- # Close the connection to the server: connection.close() ---- Once a connection is closed it can't be reused. The `ca.pem` file is required when connecting to a server protected with TLS. In an usual oVirt installation it will be in `/etc/pki/ovirt-engine/ca.pem`. If you don't specify `ca_file`, then system wide CA certificate store will be used. If something fails when trying to create the connection (authentication failure, communication failure, etc) the SDK will raise a `ovirtsdk4.Error` exception containing the details. === Using _types_ The classes in the `ovirtsdk4.types` module are pure data containers, they don't have any logic or operations. Instances can be created and modified at will. Creating or modifying one of this instances does *not* have any effect in the server side, unless one they are explicitly passed to a call to one of the service methods described below. Changes in the server side are *not* automatically reflected in the instances that already exist in memory. The constructors of these classes have multiple optional arguments, one for each attribute of the type. This is intended to simplify creation of objects using nested calls to multiple constructors. For example, to create an instance of a virtual machine, with an specification of the cluster and template that it should use, and the memory it should have: [source,python] ---- from ovirtsdk4 import types vm = types.Vm( name='myvm', cluster=types.Cluster( name='mycluster' ), template=types.Template( name='mytemplate' ), memory=1073741824 ) ---- Using the constructors in this way is recommended, but not mandatory. You can also create the instance with no arguments in the call to the constructor, and then populate the object step by step, using the setters, or using a mix of both approaches: [source,python] ---- vm = types.Vm() vm.name = 'myvm' vm.cluster = types.Cluster(name='mycluster') vm.template = types.Template(name='mytemplate') vm.memory=1073741824 ---- Attributes that are defined as lists of objects in the specification of the API are implemented as Python lists. For example, the `custom_properties` attributes of the http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm[Vm] type is defined as a list of objects of type `CustomProperty`, so when using it in the SDK it will be a Python list: [source,python] ---- vm = types.Vm( name='myvm', custom_properties=[ types.CustomProperty(...), types.CustomProperty(...), ... ] ) ---- Attributes that are defined as enumerated values in the specification of the API are implemented as `enum` in Python, using the native support for enums in Python 3, and using the https://pypi.python.org/pypi/enum34[enum34] package in Python 2.7. For example, the `status` attribute of the `Vm` type is defined using the http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm_status[VmStatus] enum: [source,python] ---- if vm.status == types.VmStatus.DOWN: ... elif vm.status == types.VmStatus.IMAGE_LOCKED: .... ---- NOTE: In the specification of the API the values of enum types appear in lower case, because that is what is used in the XML or JSON documents. But in Python it is common practice to use upper case for this kind of constants, so that is how they are defined in the Python SDK: all upper case. Reading the attributes of instances of types is done using the corresponding properties: [source,python] ---- print("vm.name: %s" % vm.name) print("vm.memory: %s" % vm.memory) for custom_property in vm.custom_properties: ... ---- === Using _links_ Some of the attributes of types are defined as _links_ in the specification of the API. This is done to indicate that their value won't usually be populated when retrieving the representation of that object, only a link will be returned instead. For example, when retrieving a virtual machine, the XML returned by the server will look like this: [source,python] ---- myvm