OpenStack SDK for Python
openstacksdk is the official Python SDK for building applications to work with OpenStack clouds. It provides a consistent and comprehensive set of interactions with OpenStack's numerous services, offering both a high-level abstraction layer and direct access to underlying APIs. The library is actively maintained, with version 4.10.0 being the current stable release, and it follows a continuous release model aligned with OpenStack's development cycles.
Warnings
- breaking Major breaking changes were introduced in `openstacksdk` versions `0.99.0` and `1.0.0`. The `Connection` interface now consistently utilizes `Resource` interfaces under the hood, and many API responses, which previously returned `Munch` objects, now return standard Python dictionaries. Additionally, many keys in the returned data were renamed.
- gotcha OpenStack services often use 'microversions' for their APIs. If not explicitly specified, `openstacksdk` will default to the lowest API version supported by the service. This can lead to missing features or unexpected behavior if you expect a newer API version's functionality.
- gotcha Some resource attributes in `openstacksdk` are lazy-loaded, meaning they are not populated immediately when a resource object is created or returned from a list operation. For example, `block_device_mapping` or `networks` for a `Server` object might only be present after a `server.fetch()` call.
- gotcha Authentication and configuration can be a common source of errors. Incorrect `clouds.yaml` file formats, missing environment variables, or mixing OpenStack Identity API versions (v2 vs. v3) in configuration can lead to authentication failures.
- deprecated `openstacksdk` utilizes a warnings infrastructure (e.g., `openstack.warnings.OpenStackDeprecationWarning`, `RemovedInSDK50Warning`, `RemovedInSDK60Warning`) to signal deprecated features, resources, or behavior. By default, `DeprecationWarning` messages are silenced in Python.
Install
-
pip install openstacksdk
Imports
- openstack
import openstack
- Connection
from openstack import connection
- Server
conn.compute.servers()
Quickstart
import os
import openstack
import time
# Configure connection via environment variables for a quickstart
# In a real application, consider using a clouds.yaml file for more robust configuration.
# Example: export OS_CLOUD='devstack' or set individual OS_ prefixed variables.
# You can also pass auth parameters directly to openstack.connect()
# Initialize and turn on debug logging (optional, but useful for troubleshooting)
openstack.enable_logging(debug=True)
try:
# Establish a connection to your OpenStack cloud
# 'envvars' tells openstacksdk to look for OS_CLOUD or individual OS_ prefixed environment variables
conn = openstack.connect(cloud='envvars')
print("Successfully connected to OpenStack!")
# List available images
print("\nAvailable images:")
for image in conn.image.images():
print(f" ID: {image.id}, Name: {image.name}")
# List available flavors (instance types)
print("\nAvailable flavors:")
for flavor in conn.compute.flavors():
print(f" ID: {flavor.id}, Name: {flavor.name}, RAM: {flavor.ram}MB, VCPUs: {flavor.vcpus}")
# --- Example: Create a new server (instance) ---
# Requires an existing image, flavor, network, and keypair in your OpenStack cloud.
# Replace with actual values from your environment or obtained from the above listings.
IMAGE_NAME = os.environ.get('OS_TEST_IMAGE', 'cirros')
FLAVOR_NAME = os.environ.get('OS_TEST_FLAVOR', 'm1.tiny')
NETWORK_NAME = os.environ.get('OS_TEST_NETWORK', 'private') # Or 'public' if applicable
KEYPAIR_NAME = os.environ.get('OS_TEST_KEYPAIR', 'my_keypair')
SERVER_NAME = f"test-sdk-server-{int(time.time())}"
# Find the image, flavor, and network by name
image = conn.image.find_image(IMAGE_NAME)
flavor = conn.compute.find_flavor(FLAVOR_NAME)
network = conn.network.find_network(NETWORK_NAME)
keypair = conn.compute.find_keypair(KEYPAIR_NAME)
if not all([image, flavor, network, keypair]):
print("\nError: One or more required resources (image, flavor, network, keypair) not found. Skipping server creation.")
else:
print(f"\nCreating server '{SERVER_NAME}'...")
server = conn.compute.create_server(
name=SERVER_NAME,
image_id=image.id,
flavor_id=flavor.id,
networks=[{"uuid": network.id}],
key_name=keypair.name
)
print(f"Server '{SERVER_NAME}' created (ID: {server.id}). Waiting for active status...")
conn.compute.wait_for_server(server)
print(f"Server '{SERVER_NAME}' is now {server.status}.")
print(f"Access IPv4: {getattr(server, 'access_ipv4', 'N/A')}")
# Cleanup: Delete the created server
print(f"\nDeleting server '{SERVER_NAME}' (ID: {server.id})...")
conn.compute.delete_server(server.id)
conn.compute.wait_for_delete(server)
print(f"Server '{SERVER_NAME}' deleted.")
except openstack.exceptions.SDKException as e:
print(f"An OpenStack SDK error occurred: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")