API Reference¶
DiffSync front-end classes and logic.
- class diffsync.DiffSync(name=None)¶
Bases:
objectClass for storing a group of DiffSyncModel instances and diffing/synchronizing to another DiffSync instance.
- __init__(name=None)¶
Generic initialization function.
Subclasses should be careful to call super().__init__() if they override this method.
- add(obj: diffsync.DiffSyncModel)¶
Add a DiffSyncModel object to the store.
- Parameters
obj (DiffSyncModel) – Object to store
- Raises
ObjectAlreadyExists – if an object with the same uid is already present
- dict(exclude_defaults: bool = True, **kwargs) → Mapping¶
Represent the DiffSync contents as a dict, as if it were a Pydantic model.
- diff_from(source: diffsync.DiffSync, diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>, flags: diffsync.enum.DiffSyncFlags = <DiffSyncFlags.NONE: 0>, callback: Optional[Callable[[str, int, int], None]] = None) → diffsync.diff.Diff¶
Generate a Diff describing the difference from the other DiffSync to this one.
- Parameters
source (DiffSync) – Object to diff against.
diff_class (class) – Diff or subclass thereof to use for diff calculation and storage.
flags (DiffSyncFlags) – Flags influencing the behavior of this diff operation.
callback (function) – Function with parameters (stage, current, total), to be called at intervals as the calculation of the diff proceeds.
- diff_to(target: diffsync.DiffSync, diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>, flags: diffsync.enum.DiffSyncFlags = <DiffSyncFlags.NONE: 0>, callback: Optional[Callable[[str, int, int], None]] = None) → diffsync.diff.Diff¶
Generate a Diff describing the difference from this DiffSync to another one.
- Parameters
target (DiffSync) – Object to diff against.
diff_class (class) – Diff or subclass thereof to use for diff calculation and storage.
flags (DiffSyncFlags) – Flags influencing the behavior of this diff operation.
callback (function) – Function with parameters (stage, current, total), to be called at intervals as the calculation of the diff proceeds.
- get(obj: Union[str, diffsync.DiffSyncModel, Type[diffsync.DiffSyncModel]], identifier: Union[str, Mapping]) → diffsync.DiffSyncModel¶
Get one object from the data store based on its unique id.
- Parameters
obj – DiffSyncModel class or instance, or modelname string, that defines the type of the object to retrieve
identifier – Unique ID of the object to retrieve, or dict of unique identifier keys/values
- Raises
ValueError – if obj is a str and identifier is a dict (can’t convert dict into a uid str without a model class)
ObjectNotFound – if the requested object is not present
- get_all(obj: Union[str, diffsync.DiffSyncModel, Type[diffsync.DiffSyncModel]]) → List[diffsync.DiffSyncModel]¶
Get all objects of a given type.
- Parameters
obj – DiffSyncModel class or instance, or modelname string, that defines the type of the objects to retrieve
- Returns
List of Object
- Return type
List[DiffSyncModel]
- get_by_uids(uids: List[str], obj: Union[str, diffsync.DiffSyncModel, Type[diffsync.DiffSyncModel]]) → List[diffsync.DiffSyncModel]¶
Get multiple objects from the store by their unique IDs/Keys and type.
- Parameters
uids – List of unique id / key identifying object in the database.
obj – DiffSyncModel class or instance, or modelname string, that defines the type of the objects to retrieve
- Raises
ObjectNotFound – if any of the requested UIDs are not found in the store
- load()¶
Load all desired data from whatever backend data source into this instance.
- remove(obj: diffsync.DiffSyncModel, remove_children: bool = False)¶
Remove a DiffSyncModel object from the store.
- Parameters
obj (DiffSyncModel) – object to remove
remove_children (bool) – If True, also recursively remove any children of this object
- Raises
ObjectNotFound – if the object is not present
- sync_complete(source: diffsync.DiffSync, diff: diffsync.diff.Diff, flags: diffsync.enum.DiffSyncFlags = <DiffSyncFlags.NONE: 0>, logger: Optional[structlog._generic.BoundLogger] = None)¶
Callback triggered after a sync_from operation has completed and updated the model data of this instance.
Note that this callback is only triggered if the sync actually resulted in data changes. If there are no detected changes, this callback will not be called.
The default implementation does nothing, but a subclass could use this, for example, to perform bulk updates to a backend (such as a file) that doesn’t readily support incremental updates to individual records.
- Parameters
source – The DiffSync whose data was used to update this instance.
diff – The Diff calculated prior to the sync operation.
flags – Any flags that influenced the sync.
logger – Logging context for the sync.
- sync_from(source: diffsync.DiffSync, diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>, flags: diffsync.enum.DiffSyncFlags = <DiffSyncFlags.NONE: 0>, callback: Optional[Callable[[str, int, int], None]] = None)¶
Synchronize data from the given source DiffSync object into the current DiffSync object.
- Parameters
source (DiffSync) – object to sync data from into this one
diff_class (class) – Diff or subclass thereof to use to calculate the diffs to use for synchronization
flags (DiffSyncFlags) – Flags influencing the behavior of this sync.
callback (function) – Function with parameters (stage, current, total), to be called at intervals as the calculation of the diff and subsequent sync proceed.
- sync_to(target: diffsync.DiffSync, diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>, flags: diffsync.enum.DiffSyncFlags = <DiffSyncFlags.NONE: 0>, callback: Optional[Callable[[str, int, int], None]] = None)¶
Synchronize data from the current DiffSync object into the given target DiffSync object.
- Parameters
target (DiffSync) – object to sync data into from this one.
diff_class (class) – Diff or subclass thereof to use to calculate the diffs to use for synchronization
flags (DiffSyncFlags) – Flags influencing the behavior of this sync.
callback (function) – Function with parameters (stage, current, total), to be called at intervals as the calculation of the diff and subsequent sync proceed.
- class diffsync.DiffSyncModel(*, model_flags: diffsync.enum.DiffSyncModelFlags = <DiffSyncModelFlags.NONE: 0>, diffsync: DiffSync = None)¶
Bases:
pydantic.main.BaseModelBase class for all DiffSync object models.
Note that read-only APIs of this class are implemented as get_*() functions rather than as properties; this is intentional as specific model classes may want to use these names (type, keys, attrs, etc.) as model attributes and we want to avoid any ambiguity or collisions.
This class has several underscore-prefixed class variables that subclasses should set as desired; see below.
- NOTE: The groupings _identifiers, _attributes, and _children are mutually exclusive; any given field name can
be included in at most one of these three tuples.
- add_child(child: diffsync.DiffSyncModel)¶
Add a child reference to an object.
The child object isn’t stored, only its unique id. The name of the target attribute is defined in _children per object type
- Raises
ObjectStoreWrongType – if the type is not part of _children
ObjectAlreadyExists – if the unique id is already stored
- classmethod create(diffsync: diffsync.DiffSync, ids: Mapping, attrs: Mapping) → Optional[diffsync.DiffSyncModel]¶
Instantiate this class, along with any platform-specific data creation.
Subclasses must call super().create(); they may wish to then override the default status information by calling set_status() to provide more context (such as details of any interactions with underlying systems).
- Parameters
diffsync – The master data store for other DiffSyncModel instances that we might need to reference
ids – Dictionary of unique-identifiers needed to create the new object
attrs – Dictionary of additional attributes to set on the new object
- Returns
instance of this class, if all data was successfully created. None: if data creation failed in such a way that child objects of this model should not be created.
- Return type
- Raises
ObjectNotCreated – if an error occurred.
- classmethod create_unique_id(**identifiers) → str¶
Construct a unique identifier for this model class.
- Parameters
**identifiers – Dict of identifiers and their values, as in get_identifiers().
- delete() → Optional[diffsync.DiffSyncModel]¶
Delete any platform-specific data corresponding to this instance.
Subclasses must call super().delete(); they may wish to then override the default status information by calling set_status() to provide more context (such as details of any interactions with underlying systems).
- Returns
this instance, if all data was successfully deleted. None: if data deletion failed in such a way that child objects of this model should not be deleted.
- Return type
- Raises
ObjectNotDeleted – if an error occurred.
- dict(**kwargs) → dict¶
Convert this DiffSyncModel to a dict, excluding the diffsync field by default as it is not serializable.
- diffsync: Optional[diffsync.DiffSync]¶
the DiffSync instance that owns this model instance.
- Type
Optional
- get_attrs() → Mapping¶
Get all the non-primary-key attributes or parameters for this object.
Similar to Pydantic’s BaseModel.dict() method, with the following key differences: 1. Does not include the fields in _identifiers 2. Only includes fields explicitly listed in _attributes 3. Does not include any additional fields not listed in _attributes
- Returns
Dictionary of attributes for this object
- Return type
dict
- classmethod get_children_mapping() → Mapping[str, str]¶
Get the mapping of types to fieldnames for child models of this model.
- get_identifiers() → Mapping¶
Get a dict of all identifiers (primary keys) and their values for this object.
- Returns
dictionary containing all primary keys for this device, as defined in _identifiers
- Return type
dict
- get_shortname() → str¶
Get the (not guaranteed-unique) shortname of an object, if any.
By default the shortname is built based on all the keys defined in _shortname. If _shortname is not specified, then this function is equivalent to get_unique_id().
- Returns
Shortname of this object
- Return type
str
- get_status() → Tuple[diffsync.enum.DiffSyncStatus, str]¶
Get the status of the last create/update/delete operation on this object, and any associated message.
- classmethod get_type() → str¶
Return the type AKA modelname of the object or the class
- Returns
modelname of the class, used in to store all objects
- Return type
str
- get_unique_id() → str¶
Get the unique ID of an object.
By default the unique ID is built based on all the primary keys defined in _identifiers.
- Returns
Unique ID for this object
- Return type
str
- json(**kwargs) → str¶
Convert this DiffSyncModel to a JSON string, excluding the diffsync field by default as it is not serializable.
- model_flags: diffsync.enum.DiffSyncModelFlags¶
any non-default behavioral flags for this DiffSyncModel.
Can be set as a class attribute or an instance attribute as needed.
- Type
Optional
- remove_child(child: diffsync.DiffSyncModel)¶
Remove a child reference from an object.
The name of the storage attribute is defined in _children per object type.
- Raises
ObjectStoreWrongType – if the child model type is not part of _children
ObjectNotFound – if the child wasn’t previously present.
- set_status(status: diffsync.enum.DiffSyncStatus, message: str = '')¶
Update the status (and optionally status message) of this model in response to a create/update/delete call.
- str(include_children: bool = True, indent: int = 0) → str¶
Build a detailed string representation of this DiffSyncModel and optionally its children.
- update(attrs: Mapping) → Optional[diffsync.DiffSyncModel]¶
Update the attributes of this instance, along with any platform-specific data updates.
Subclasses must call super().update(); they may wish to then override the default status information by calling set_status() to provide more context (such as details of any interactions with underlying systems).
- Parameters
attrs – Dictionary of attributes to update on the object
- Returns
this instance, if all data was successfully updated. None: if data updates failed in such a way that child objects of this model should not be modified.
- Return type
- Raises
ObjectNotUpdated – if an error occurred.
diffsync.diff¶
Diff and DiffElement classes for DiffSync.
- class diffsync.diff.Diff¶
Bases:
objectDiff Object, designed to store multiple DiffElement object and organize them in a group.
- __init__()¶
Initialize a new, empty Diff object.
- add(element: diffsync.diff.DiffElement)¶
Add a new DiffElement to the changeset of this Diff.
- Raises
ObjectAlreadyExists – if an element of the same type and same name is already stored.
- children¶
DefaultDict for storing DiffElement objects.
self.children[group][unique_id] == DiffElement(…)
- complete()¶
Method to call when this Diff has been fully populated with data and is “complete”.
The default implementation does nothing, but a subclass could use this, for example, to save the completed Diff to a file or database record.
- get_children() → Iterator[diffsync.diff.DiffElement]¶
Iterate over all child elements in all groups in self.children.
For each group of children, check if an order method is defined, Otherwise use the default method.
- groups()¶
Get the list of all group keys in self.children.
- has_diffs() → bool¶
Indicate if at least one of the child elements contains some diff.
- Returns
True if at least one child element contains some diff
- Return type
bool
- classmethod order_children_default(children: Mapping) → Iterator[diffsync.diff.DiffElement]¶
Default method to an Iterator for children.
Since children is already an OrderedDefaultDict, this method is not doing anything special.
- str(indent: int = 0)¶
Build a detailed string representation of this Diff and its child DiffElements.
- class diffsync.diff.DiffElement(obj_type: str, name: str, keys: Mapping, source_name: str = 'source', dest_name: str = 'dest', diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>)¶
Bases:
objectDiffElement object, designed to represent a single item/object that may or may not have any diffs.
- __init__(obj_type: str, name: str, keys: Mapping, source_name: str = 'source', dest_name: str = 'dest', diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>)¶
Instantiate a DiffElement.
- Parameters
obj_type – Name of the object type being described, as in DiffSyncModel.get_type().
name – Human-readable name of the object being described, as in DiffSyncModel.get_shortname(). This name must be unique within the context of the Diff that is the direct parent of this DiffElement.
keys – Primary keys and values uniquely describing this object, as in DiffSyncModel.get_identifiers().
source_name – Name of the source DiffSync object
dest_name – Name of the destination DiffSync object
diff_class – Diff or subclass thereof to use to calculate the diffs to use for synchronization
- property action: Optional[str]¶
Action, if any, that should be taken to remediate the diffs described by this element.
- Returns
“create”, “update”, “delete”, or None
- Return type
str
- add_attrs(source: Optional[Mapping] = None, dest: Optional[Mapping] = None)¶
Set additional attributes of a source and/or destination item that may result in diffs.
- add_child(element: diffsync.diff.DiffElement)¶
Attach a child object of type DiffElement.
Childs are saved in a Diff object and are organized by type and name.
- Parameters
element – DiffElement
- dict() → Mapping[str, Mapping[str, Any]]¶
Build a dictionary representation of this DiffElement and its children.
- get_attrs_diffs() → Mapping[str, Mapping[str, Any]]¶
Get the dict of actual attribute diffs between source_attrs and dest_attrs.
- Returns
of the form {“-“: {key1: <value>, key2: …}, “+”: {key1: <value>, key2: …}}, where the “-“ or “+” dicts may be absent.
- Return type
dict
- get_attrs_keys() → Iterable[str]¶
Get the list of shared attrs between source and dest, or the attrs of source or dest if only one is present.
If source_attrs is not set, return the keys of dest_attrs
If dest_attrs is not set, return the keys of source_attrs
If both are defined, return the intersection of both keys
- get_children() → Iterator[diffsync.diff.DiffElement]¶
Iterate over all child DiffElements of this one.
- has_diffs(include_children: bool = True) → bool¶
Check whether this element (or optionally any of its children) has some diffs.
- Parameters
include_children – If True, recursively check children for diffs as well.
- str(indent: int = 0)¶
Build a detailed string representation of this DiffElement and its children.
diffsync.enum¶
DiffSync enums and flags.
- class diffsync.enum.DiffSyncFlags(value)¶
Bases:
enum.FlagFlags that can be passed to a sync_* or diff_* call to affect its behavior.
- CONTINUE_ON_FAILURE = 1¶
Continue synchronizing even if failures are encountered when syncing individual models.
- LOG_UNCHANGED_RECORDS = 8¶
If this flag is set, a log message will be generated during synchronization for each model, even unchanged ones.
By default, when this flag is unset, only models that have actual changes to synchronize will be logged. This flag is off by default to reduce the default verbosity of DiffSync, but can be enabled when debugging.
- NONE = 0¶
- SKIP_UNMATCHED_BOTH = 6¶
- SKIP_UNMATCHED_DST = 4¶
Ignore objects that only exist in the target/”to” DiffSync when determining diffs and syncing.
If this flag is set, no objects will be deleted from the target/”to” DiffSync.
- SKIP_UNMATCHED_SRC = 2¶
Ignore objects that only exist in the source/”from” DiffSync when determining diffs and syncing.
If this flag is set, no new objects will be created in the target/”to” DiffSync.
- class diffsync.enum.DiffSyncModelFlags(value)¶
Bases:
enum.FlagFlags that can be set on a DiffSyncModel class or instance to affect its usage.
- IGNORE = 1¶
Do not render diffs containing this model; do not make any changes to this model when synchronizing.
Can be used to indicate a model instance that exists but should not be changed by DiffSync.
- NONE = 0¶
- SKIP_CHILDREN_ON_DELETE = 2¶
When deleting this model, do not recursively delete its children.
Can be used for the case where deletion of a model results in the automatic deletion of all its children.
diffsync.exceptions¶
Exception classes used in DiffSync.
- exception diffsync.exceptions.ObjectAlreadyExists¶
Bases:
diffsync.exceptions.ObjectStoreExceptionException raised when trying to store a DiffSyncModel or DiffElement that is already being stored.
- exception diffsync.exceptions.ObjectCrudException¶
Bases:
ExceptionBase class for various failures during CRUD operations.
- exception diffsync.exceptions.ObjectNotCreated¶
Bases:
diffsync.exceptions.ObjectCrudExceptionException raised if an object Create operation failed.
- exception diffsync.exceptions.ObjectNotDeleted¶
Bases:
diffsync.exceptions.ObjectCrudExceptionException raised if an object Delete operation failed.
- exception diffsync.exceptions.ObjectNotFound¶
Bases:
diffsync.exceptions.ObjectStoreExceptionException raised when trying to access a DiffSyncModel that isn’t in storage.
- exception diffsync.exceptions.ObjectNotUpdated¶
Bases:
diffsync.exceptions.ObjectCrudExceptionException raised if an object Update operation failed.
- exception diffsync.exceptions.ObjectStoreException¶
Bases:
ExceptionBase class for various failures during object storage in local caches.
- exception diffsync.exceptions.ObjectStoreWrongType¶
Bases:
diffsync.exceptions.ObjectStoreExceptionException raised when trying to store a DiffSyncModel of the wrong type.
diffsync.helpers¶
DiffSync helper classes for calculating and performing diff and sync operations.
- class diffsync.helpers.DiffSyncDiffer(src_diffsync: DiffSync, dst_diffsync: DiffSync, flags: diffsync.enum.DiffSyncFlags, diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>, callback: Optional[Callable[[str, int, int], None]] = None)¶
Bases:
objectHelper class implementing diff calculation logic for DiffSync.
Independent from Diff and DiffElement as those classes are purely data objects, while this stores some state.
- __init__(src_diffsync: DiffSync, dst_diffsync: DiffSync, flags: diffsync.enum.DiffSyncFlags, diff_class: Type[diffsync.diff.Diff] = <class 'diffsync.diff.Diff'>, callback: Optional[Callable[[str, int, int], None]] = None)¶
Create a DiffSyncDiffer for calculating diffs between the provided DiffSync instances.
- calculate_diffs() → diffsync.diff.Diff¶
Calculate diffs between the src and dst DiffSync objects and return the resulting Diff.
- diff_child_objects(diff_element: diffsync.diff.DiffElement, src_obj: Optional[DiffSyncModel], dst_obj: Optional[DiffSyncModel])¶
For all children of the given DiffSyncModel pair, diff recursively, adding diffs to the given diff_element.
Helper method to calculate_diffs, usually doesn’t need to be called directly.
These helper methods work in a recursive cycle: diff_object_list -> diff_object_pair -> diff_child_objects -> diff_object_list -> etc.
- diff_object_list(src: List[DiffSyncModel], dst: List[DiffSyncModel]) → List[diffsync.diff.DiffElement]¶
Calculate diffs between two lists of like objects.
Helper method to calculate_diffs, usually doesn’t need to be called directly.
These helper methods work in a recursive cycle: diff_object_list -> diff_object_pair -> diff_child_objects -> diff_object_list -> etc.
- diff_object_pair(src_obj: Optional[DiffSyncModel], dst_obj: Optional[DiffSyncModel]) → Optional[diffsync.diff.DiffElement]¶
Diff the two provided DiffSyncModel objects and return a DiffElement or None.
Helper method to calculate_diffs, usually doesn’t need to be called directly.
These helper methods work in a recursive cycle: diff_object_list -> diff_object_pair -> diff_child_objects -> diff_object_list -> etc.
- incr_models_processed(delta: int = 1)¶
Increment self.models_processed, then call self.callback if present.
- static validate_objects_for_diff(object_pairs: Iterable[Tuple[Optional[DiffSyncModel], Optional[DiffSyncModel]]])¶
Check whether all DiffSyncModels in the given dictionary are valid for comparison to one another.
Helper method for diff_object_list.
- Raises
TypeError – If any pair of objects in the dict have differing get_type() values.
ValueError – If any pair of objects in the dict have differing get_shortname() or get_identifiers() values.
- class diffsync.helpers.DiffSyncSyncer(diff: diffsync.diff.Diff, src_diffsync: DiffSync, dst_diffsync: DiffSync, flags: diffsync.enum.DiffSyncFlags, callback: Optional[Callable[[str, int, int], None]] = None)¶
Bases:
objectHelper class implementing data synchronization logic for DiffSync.
Independent from DiffSync and DiffSyncModel as those classes are purely data objects, while this stores some state.
- __init__(diff: diffsync.diff.Diff, src_diffsync: DiffSync, dst_diffsync: DiffSync, flags: diffsync.enum.DiffSyncFlags, callback: Optional[Callable[[str, int, int], None]] = None)¶
Create a DiffSyncSyncer instance, ready to call perform_sync() against.
- incr_elements_processed(delta: int = 1)¶
Increment self.elements_processed, then call self.callback if present.
- log_sync_status(action: Optional[str], status: diffsync.enum.DiffSyncStatus, message: str)¶
Log the current sync status at the appropriate verbosity with appropriate context.
Helper method to sync_diff_element/sync_model.
- perform_sync() → bool¶
Perform data synchronization based on the provided diff.
- Returns
True if any changes were actually performed, else False.
- Return type
bool
- sync_diff_element(element: diffsync.diff.DiffElement, parent_model: DiffSyncModel = None) → bool¶
Recursively synchronize the given DiffElement and its children, if any, into the dst_diffsync.
Helper method to perform_sync.
- Returns
True if this element or any of its children resulted in actual changes, else False.
- Return type
bool
- sync_model(model: Optional[DiffSyncModel], ids: Mapping, attrs: Mapping) → Tuple[bool, Optional[DiffSyncModel]]¶
Create/update/delete the current DiffSyncModel with current ids/attrs, and update self.status and self.message.
Helper method to sync_diff_element.
- Returns
(changed, model) where model may be None if an error occurred
- Return type
tuple
diffsync.logging¶
Helpful APIs for setting up DiffSync logging.
- diffsync.logging.enable_console_logging(verbosity=0)¶
Enable formatted logging to console with the specified verbosity.
See https://www.structlog.org/en/stable/development.html as a reference
- Parameters
verbosity (int) – 0 for WARNING logs, 1 for INFO logs, 2 for DEBUG logs
diffsync.utils¶
Utility functions for DiffSync library.
- class diffsync.utils.OrderedDefaultDict(dict_type)¶
Bases:
collections.OrderedDictA combination of collections.OrderedDict and collections.DefaultDict behavior.
- __init__(dict_type)¶
Create a new OrderedDefaultDict.
- diffsync.utils.intersection(lst1, lst2) → List¶
Calculate the intersection of two lists, with ordering based on the first list.
- diffsync.utils.symmetric_difference(lst1, lst2) → List¶
Calculate the symmetric difference of two lists.