How the SDK is organized¶
The following diagram shows how the project is laid out.
openstack/
connection.py
resource.py
compute/
compute_service.py
v2/
server.py
_proxy.py
tests/
compute/
v2/
test_server.py
Resource¶
The openstack.resource.Resource base class is the building block
of any service implementation. Resource objects correspond to the
resources each service’s REST API works with, so the
openstack.compute.v2.server.Server subclass maps to the compute
service’s https://openstack:1234/v2/servers resource.
The base Resource contains methods to support the typical
CRUD
operations supported by REST APIs, and handles the construction of URLs
and calling the appropriate HTTP verb on the given Adapter.
Values sent to or returned from the service are implemented as attributes
on the Resource subclass using component objects such as resource.Body,
resource.Header and resource.URI, depending on where in the request or
response the value lives. Each component is created with the exact name of what
the API expects, and can optionally include a type to be validated against
on requests. You should choose an attribute name that follows PEP-8, regardless
of what the server-side expects, as the component becomes a mapping between the
two.:
is_public = resource.Body('os-flavor-access:is_public', type=bool)
There are six additional attributes which the Resource class checks
before making requests to the REST API. allow_create, allow_fetch,
allow_commit, allow_delete, allow_head, and allow_list are set
to True or False, and are checked before making the corresponding
method call.
The base_path attribute should be set to the URL which corresponds to
this resource. Many base_paths are simple, such as "/servers".
For base_paths which are composed of non-static information, Python’s
string replacement is used, e.g., base_path = "/servers/%(server_id)s/ips".
resource_key and resources_key are attributes to set when a
Resource returns more than one item in a response, or otherwise
requires a key to obtain the response value. For example, the Server
class sets resource_key = "server" as an individual Server is
stored in a dictionary keyed with the singular noun,
and resources_key = "servers" as multiple Servers are stored in
a dictionary keyed with the plural noun in the response.
Proxy¶
Each service implements a Proxy class based on
Proxy, within the
openstack/<program_name>/vX/_proxy.py module. For example, the v2 compute
service’s Proxy exists in openstack/compute/v2/_proxy.py.
The Proxy class is based on
Adapter.
- class openstack.proxy.Proxy(session, *, service_type=None, service_name=None, interface=None, region_name=None, endpoint_override=None, version=None, auth=None, user_agent=None, connect_retries=None, logger=None, allow=None, additional_headers=None, client_name=None, client_version=None, allow_version_hack=None, global_request_id=None, min_version=None, max_version=None, default_microversion=None, status_code_retries=None, retriable_status_codes=None, raise_exc=None, rate_limit=None, concurrency=None, connect_retry_delay=None, status_code_retry_delay=None, statsd_client=None, statsd_prefix=None, prometheus_counter=None, prometheus_histogram=None, influxdb_config=None, influxdb_client=None)¶
Bases:
AdapterRepresents a service.
- api_version¶
The API version.
This is used as a descriminating attribute for type checking.
- retriable_status_codes = None¶
HTTP status codes that should be retried by default.
The number of retries is defined by the configuration in parameters called
<service-type>_status_code_retries.
Each service’s Proxy provides a higher-level interface for users to work
with via a Connection instance.
Rather than requiring users to maintain their own Adapter and work with
lower-level Resource objects, the Proxy
interface offers a place to make things easier for the caller.
Each Proxy class implements methods which act on the underlying
Resource classes which represent the service. For example:
def list_flavors(self, **params):
return flavor.Flavor.list(self.session, **params)
This method is operating on the openstack.compute.v2.flavor.Flavor.list
method. For the time being, it simply passes on the Adapter maintained
by the Proxy, and returns what the underlying Resource.list method
does.
Cloud¶
The openstack.cloud package provides the high-level cloud abstraction
layer, historically known as shade. Where the Proxy interface maps
closely onto a single service’s REST API, the cloud layer offers
business-logic-oriented methods that often span multiple requests, or even
multiple services, and that normalize the differences between clouds.
The layer is implemented as a collection of mixin classes, one per service
area, under openstack/cloud/ (for example, _compute.py provides
ComputeCloudMixin and _network.py provides NetworkCloudMixin).
These mixins are combined into the Connection
class, so their methods are available directly on a Connection instance
alongside the service Proxy objects. For example,
Connection.create_server may create a server, wait for it to become active,
attach a floating IP and return a normalized result, orchestrating several
lower-level Proxy and Resource calls on the caller’s behalf.
Application authors are generally encouraged to use these high-level methods where they exist, falling back to the Proxy interface for operations the cloud layer does not cover.
Connection¶
The openstack.connection.Connection class builds atop a
openstack.config.cloud_region.CloudRegion object, and provides a
higher level interface constructed of Proxy objects from each of the
services.
The Connection class’ primary purpose is to act as a high-level interface
to this SDK, managing the lower level connection bits and exposing the
Resource objects through their corresponding Proxy object.
If you’ve built proper Resource objects and implemented methods on the
corresponding Proxy object, the high-level interface to your service
should now be exposed.