Oslo Versioned Objects

3.9.0 · active · verified Thu Apr 16

Oslo Versioned Objects is an OpenStack library that provides a framework for defining data objects with built-in versioning capabilities. It allows for seamless evolution of object schemas, particularly important in RPC (Remote Procedure Call) contexts where different service versions might communicate. It's currently at version 3.9.0 and is part of the OpenStack Oslo libraries, receiving updates in sync with OpenStack releases.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a basic VersionedObject with fields and methods. It then shows how to instantiate it, modify its state, and finally serialize it to a primitive representation (dictionary) and deserialize it back, illustrating the core versioning and serialization capabilities of the library.

import uuid
from oslo_versionedobjects import base, fields

# 1. Define your VersionedObject
class MyExampleObject(base.VersionedObject):
    # The current version of this object schema.
    # Increment this when making backwards-incompatible changes.
    VERSION = '1.0'

    # Define the fields for your object
    fields = {
        'id': fields.UUIDField(),
        'name': fields.StringField(nullable=False),
        'status': fields.StringField(default='active'),
        'value': fields.IntegerField(nullable=True, default=0),
    }

    # Optional: Override __init__ to set defaults or perform custom logic
    def __init__(self, context=None, **kwargs):
        super().__init__(context, **kwargs)
        # Call obj_set_defaults() to ensure default values from fields are applied.
        self.obj_set_defaults()

    # Optional: Add methods to your object
    def activate(self):
        if self.status != 'active':
            self.status = 'active'
            self.obj_make_compatible() # Mark object as changed for serialization
            print(f"Object {self.name} activated.")
        else:
            print(f"Object {self.name} is already active.")

# 2. Instantiate and use your object
# Create an instance with some data
obj_id = str(uuid.uuid4())
my_obj = MyExampleObject(id=obj_id, name="First Item", value=100)

print(f"Initial object: {my_obj.obj_name} v{my_obj.obj_version}")
print(f"ID: {my_obj.id}")
print(f"Name: {my_obj.name}")
print(f"Status: {my_obj.status}")
print(f"Value: {my_obj.value}")
print(f"Is changed? {my_obj.obj_what_changed()}")

my_obj.activate()
print(f"Status after activation: {my_obj.status}")
print(f"Is changed? {my_obj.obj_what_changed()}")

# 3. Serialize and Deserialize (demonstrates versioning capability)
serializer = base.VersionedObjectSerializer()

# Convert the object to a primitive (dictionary) for serialization
primitive = serializer.serialize_entity(None, my_obj)
print("\nSerialized primitive:")
print(primitive)

# Simulate deserialization (e.g., after receiving over RPC)
deserialized_obj = serializer.deserialize_entity(None, MyExampleObject, primitive)
print("\nDeserialized object:")
print(f"Name: {deserialized_obj.name}")
print(f"Status: {deserialized_obj.status}")
print(f"Value: {deserialized_obj.value}")
print(f"Are objects equal? {my_obj == deserialized_obj}")
print(f"Has deserialized object changed? {deserialized_obj.obj_what_changed()}")

view raw JSON →