Of course! Here is a comprehensive guide to using OpenStack with Python 3, covering the official libraries, common tasks, and best practices.

Executive Summary
Yes, OpenStack has full and official support for Python 3. The primary way to interact with OpenStack programmatically is through the OpenStack SDK, which is a set of client libraries built on top of the lower-level python-openstacksdk. For specific services like Nova (compute) or Neutron (networking), dedicated clients like python-novaclient are also available and well-maintained.
The Main Libraries: openstacksdk vs. python-*client
You will primarily encounter two types of Python libraries for OpenStack. Understanding the difference is key.
A. The OpenStack SDK (Recommended for most use cases)
This is the modern, unified, and recommended way to interact with OpenStack. It's a high-level library that provides a common interface to almost all OpenStack services.
- What it is: A single library (
openstacksdk) that abstracts the underlying REST API calls for various services (Compute, Identity, Image, Network, etc.). - Key Features:
- Unified Interface: You use similar patterns to interact with different services.
- Session Management: Handles authentication and token management automatically.
- Pagination: Simplifies handling large lists of resources.
- Comprehensive: Covers most, if not all, OpenStack services.
- When to use it:
- Writing scripts or applications that need to interact with multiple OpenStack services.
- When you want a simpler, more abstracted API and don't need to interact with the raw API.
- For most general-purpose automation.
B. The Service-Specific Clients (e.g., python-novaclient)
These are the traditional, command-line-focused clients for individual OpenStack services. They expose the API very closely and are often used by the openstack command-line tool.

- What they are: Separate libraries for each service (e.g.,
python-novaclientfor compute,python-neutronclientfor networking). - Key Features:
- API Fidelity: The Python methods map almost directly to the API actions.
- Mature and Stable: These have been around for a long time and are very stable.
- CLI Foundation: The
openstackCLI is built on top of these.
- When to use it:
- When you need to use a specific API feature that might not be exposed by the
openstacksdk. - When you are porting an existing script that already uses these libraries.
- For very simple, single-service tasks.
- When you need to use a specific API feature that might not be exposed by the
Setting Up Your Python 3 Environment
First, ensure you have Python 3 installed. It's highly recommended to use a virtual environment to manage project dependencies.
# Create a virtual environment python3 -m venv openstack-project # Activate the virtual environment source openstack-project/bin/activate # Your prompt should change to indicate the active environment
Next, install the necessary libraries.
Option 1: Install the OpenStack SDK (Recommended)
This single package gives you access to almost everything.
pip install openstacksdk
Option 2: Install Specific Service Clients
If you only need to work with one or two services, you can install them individually.
# For Compute (Nova) pip install python-novaclient # For Networking (Neutron) pip install python-neutronclient # For Identity (Keystone) pip install python-keystoneclient # For Image (Glance) pip install python-glanceclient
Authentication: The First Step
Before you can do anything, you need to authenticate with OpenStack and get a token. The openstacksdk makes this incredibly simple using a "cloud" configuration file.
A. Using a clouds.yaml file (Best Practice)
This file stores your connection details, keeping them out of your code. The SDK automatically looks for it in standard locations (, ~/.config/openstack/, etc.).
Create a file named clouds.yaml:
# clouds.yaml
clouds:
my_openstack_cloud:
auth:
auth_url: http://your-keystone-url:5000/v3
username: 'your_username'
password: 'your_password'
project_name: 'your_project_name'
user_domain_name: 'Default' # Or your user domain
project_domain_name: 'Default' # Or your project domain
region_name: 'RegionOne'
interface: 'public'
identity_api_version: 3
B. Using Environment Variables (Alternative)
You can also set the required information as environment variables.
export OS_AUTH_URL=http://your-keystone-url:5000/v3 export OS_PROJECT_ID=your_project_id export OS_PROJECT_NAME="your_project_name" export OS_USER_DOMAIN_NAME="Default" export OS_USERNAME="your_username" export OS_PASSWORD="your_password" export OS_REGION_NAME="RegionOne" export OS_INTERFACE="public" export OS_IDENTITY_API_VERSION=3
Code Examples
Here are practical examples using both the openstacksdk and a specific client.
Example 1: Using the OpenStack SDK (Modern & Recommended)
This example connects, lists servers (VMs), and creates a new one.
# list_and_create_server_sdk.py
import openstack
import time
# The connection object will automatically use clouds.yaml or env vars
conn = openstack.connect(cloud='my_openstack_cloud') # Or use cloud='openstack'
print("Connected to OpenStack cloud:", conn)
# --- List all servers ---
print("\n--- Listing Servers ---")
for server in conn.compute.servers():
print(f"Server: {server.name} (Status: {server.status})")
# --- Create a new server ---
print("\n--- Creating a New Server ---")
# You need an image and a flavor ID. You can find them using the SDK.
image = conn.compute.find_image("ubuntu-22.04") # Or an image ID
flavor = conn.compute.find_flavor("m1.small") # Or a flavor ID
network = conn.network.find_network("provider_net") # Or a network ID
instance_name = "my-python3-test-vm"
server = conn.compute.create_server(
name=instance_name,
image=image,
flavor=flavor,
networks=[{"uuid": network.id}],
)
# The create_server call is async. We need to wait for it to be active.
server = conn.compute.wait_for_server(server)
print(f"Server {server.name} is now active with IP: {server.access_ipv4}")
# --- Clean up ---
print("\n--- Deleting the Server ---")
conn.compute.delete_server(server, wait=True)
print(f"Server {server.name} has been deleted.")
Example 2: Using python-novaclient (Specific Client)
This example does the same thing as above but using the Nova client directly.
# list_and_create_server_nova.py
from novaclient import client
from novaclient import exceptions
import time
# Authenticate using environment variables
# OS_AUTH_URL, OS_PROJECT_NAME, OS_USERNAME, OS_PASSWORD, etc. must be set
nova = client.Client(2, 'my_username', 'my_password', 'my_project_name',
auth_url='http://your-keystone-url:5000/v3',
project_domain_name='Default',
user_domain_name='Default')
# --- List all servers ---
print("\n--- Listing Servers ---")
for server in nova.servers.list():
print(f"Server: {server.name} (Status: {server.status})")
# --- Create a new server ---
print("\n--- Creating a New Server ---")
# You need image and flavor IDs
image_id = 'a1b2c3d4-e5f6-7890-1234-567890abcdef' # Your image ID
flavor_id = '1' # Your flavor ID (e.g., m1.small is often 1)
server = nova.servers.create(name="my-novaclient-test-vm", image=image_id, flavor=flavor_id)
# Wait for the server to become active
print(f"Waiting for server {server.name} to become active...")
server = nova.servers.get(server.id)
server = nova.servers.wait_for(server, status='ACTIVE', intervals=2, timeout=300)
print(f"Server {server.name} is now active with IP: {server.access_ipv4}")
# --- Clean up ---
print("\n--- Deleting the Server ---")
nova.servers.delete(server.id)
print(f"Server {server.name} has been deleted.")
Best Practices
- Use
clouds.yaml: Never hardcode credentials in your scripts. Use aclouds.yamlfile and manage its permissions securely (chmod 600). - Use the OpenStack SDK: For new projects, default to
openstacksdk. It's easier to use and more maintainable. - Handle Exceptions: OpenStack API calls can fail for many reasons (e.g., invalid permissions, resource not found). Always wrap your code in
try...exceptblocks.openstacksdkraises specific exceptions likeopenstack.exceptions.SDKException.python-novaclientraisesexceptions.ClientExceptionand its subclasses.
- *Use `waitfor
Methods:** When creating, deleting, or changing the state of a resource (like a server), use the SDK'swait_for_server` or similar methods. This prevents your script from proceeding before the action is complete. - Resource Cleanup: In scripts, always ensure you clean up the resources you create to avoid leaving "zombie" VMs or networks in your cloud. Use
try...finallyblocks if necessary to guarantee cleanup.
