Classes

ColorCorrection

The ColorCorrection class is the backbone of cdl_convert, as it represents the basic level of the color decision list concept- the color decision list itself. All the parse functions exist to extract the CDL metadata and populate this class, and all the write functions exist to write files out from this class.

Parser → ColorCorrection → Writer

ColorCorrection can be instantiated and used without a parse function, see Script Usage for a walkthrough.

Warning

When an instance of ColorCorrection is first created, the id provided is checked against a class level dictionary variable named members to ensure that no two ColorCorrection share the same id, as this is required by the specification.

If the id does match an already created id and HALT_ON_ERROR is not set, the id assignment will go forward, appending the duplicate number to the back of the id. So the 2nd instance of ‘sh100cc’ will become ‘sh100cc001’.

Reset the members dictionary by either calling the reset_members method on ColorCorrection or by reseting all cdl_convert member lists and dictionaries with the reset_all() function.

class cdl_convert.correction.ColorCorrection(id: str, input_file: str | Path | None = None)[source]

Bases: AscDescBase, AscColorSpaceBase, AscXMLBase

Container for ASC CDL color correction values and metadata.

This class contains attributes for all 10 color correction numbers needed for an ASC CDL, as well as other metadata like shot names that typically accompanies a CDL.

These names are standardized by the ASC and where possible the attribute names will follow the ASC schema. Descriptions for some of these attributes are paraphrasing the ASC CDL documentation. For more information on the ASC CDL standard and the operations described below, you can obtain the ASC CDL implementor-oriented documentation by sending an email to: asc-cdl at theasc dot com Order of operations is Slope, Offset, Power, then Saturation.

Example

>>> cc = ColorCorrection("shot_001")
>>> cc.slope = [1.2, 1.1, 1.0]
>>> cc.sat = 0.9
>>> print(cc.id)  # "shot_001"
property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

property element: Element | None

etree style Element representing the node.

property file_in: Path | None

Return absolute path to the input file.

Returns:

Absolute path to input file, or None if no

file was specified.

Return type:

Optional[Path]

property file_out: Path | None

Return output file path for writing this ColorCorrection.

Returns:

Path where this ColorCorrection will be written,

or None if no output path has been set.

Return type:

Optional[Path]

property has_sat: bool

Return True if saturation node has been created.

Returns:

True if a SatNode instance exists, False otherwise.

Return type:

bool

property has_sop: bool

Return True if SOP (slope/offset/power) node has been created.

Returns:

True if a SopNode instance exists, False otherwise.

Return type:

bool

property id: str

Return unique identifier for this color correction.

Returns:

Unique ID string, often a shot or sequence name.

Return type:

str

members: dict[str, ColorCorrection] = {}

Class-level dictionary tracking all ColorCorrection instances by their ID. Used to enforce unique IDs and enable lookup of corrections by name. Automatically populated when ColorCorrection instances are created.

property offset: tuple[Decimal, Decimal, Decimal]

Return RGB offset values from the SOP node.

Offset values raise or lower input brightness while holding slope constant.

Returns:

RGB offset values as (R, G, B)

tuple.

Return type:

Tuple[Decimal, Decimal, Decimal]

property power: tuple[Decimal, Decimal, Decimal]

Return RGB power values from the SOP node.

Power values change the response curve of the function. Note that this has the opposite response to adjustments than a traditional gamma operator.

Returns:

RGB power values as (R, G, B)

tuple.

Return type:

Tuple[Decimal, Decimal, Decimal]

property sat: Decimal

Return saturation value from the saturation node.

Returns:

Decimal

property sat_node: SatNode

Return SatNode instance, creating one if it doesn’t exist.

Returns:

The saturation node containing saturation value and

descriptions.

Return type:

SatNode

property slope: tuple[Decimal, Decimal, Decimal]

Return RGB slope values from the SOP node.

Slope values change the slope of the input without shifting the black level established by the offset.

Returns:

RGB slope values as (R, G, B)

tuple.

Return type:

Tuple[Decimal, Decimal, Decimal]

property sop_node: SopNode

Return SopNode instance, creating one if it doesn’t exist.

Returns:

The SOP node containing slope, offset, and power values.

Return type:

SopNode

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

classmethod reset_members() None[source]

Clear the class-level members dictionary.

Removes all ColorCorrection instances from the members dictionary. Useful for testing or when starting with a clean state.

__init__(id: str, input_file: str | Path | None = None) None[source]

Initialize ColorCorrection with unique ID and optional input file.

The ID must be unique among all ColorCorrection instances. If a duplicate ID is provided, behavior depends on the halt_on_error configuration setting.

Parameters:
  • id (str) – Unique identifier for this color correction. Often a shot or sequence name. Will be sanitized to remove invalid characters.

  • input_file (Optional[Union[str, Path]]) – Optional path to the input file used to create this ColorCorrection. Can be string or Path.

Raises:

ValidationError – If ID is empty or duplicate (when halt_on_error is enabled).

build_element() Element[source]

Build XML ElementTree Element representing this ColorCorrection.

Creates a ColorCorrection XML element with ID attribute and includes any input/viewing descriptions, general descriptions, and SOP/SAT nodes.

Returns:

XML element representing this ColorCorrection.

Return type:

ElementTree.Element

determine_dest(output: str, directory: str | Path) None[source]

Set output file path based on ID and output format.

Constructs the output filename using the ColorCorrection ID and the specified output format extension.

Parameters:
  • output (str) – File extension for output format (e.g., ‘cc’, ‘ccc’).

  • directory (Union[str, Path]) – Directory path where output file will be written.

get_color_values() ColorValues[source]

Get all color correction values as a ColorValues dataclass.

Provides a convenient way to access all color correction values in a structured format with validation and utility methods.

Returns:

Dataclass instance containing current slope, offset,

power, and saturation values.

Return type:

ColorValues

is_unity() bool[source]

Check if this color correction represents unity/identity values.

Unity values represent no color correction applied. This is useful for determining if a ColorCorrection actually modifies the image.

Returns:

True if all values are at unity (slope=1.0, offset=0.0,

power=1.0, saturation=1.0), False otherwise.

Return type:

bool

parse_xml_descs(xml_element: Element) None

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']
parse_xml_input_desc(xml_element: Element) bool

Parse an ElementTree element to find and add an input description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for an InputDescription element. If found, sets the input_desc attribute.

Returns:

True if InputDescription element was found (even if blank),

Return type:

bool

parse_xml_viewing_desc(xml_element: Element) bool

Parse an ElementTree element to find and add a viewing description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for a ViewingDescription element. If found, sets the viewing_desc attribute.

Returns:

True if ViewingDescription element was found (even if blank),

False otherwise.

Return type:

bool

set_color_values(values: ColorValues) None[source]

Set all color correction values from a ColorValues dataclass.

Provides a convenient way to set all color correction values at once from a validated ColorValues instance.

Parameters:

values (ColorValues) – ColorValues dataclass instance containing the slope, offset, power, and saturation values to set.

Raises:

ValidationError – If any values in the ColorValues instance fail validation (e.g., negative slope values).

Example

>>> from decimal import Decimal
>>> cc = ColorCorrection("test_id")
>>> values = ColorValues(
...     slope=(Decimal("1.2"), Decimal("1.1"), Decimal("1.0")),
...     saturation=Decimal("0.9"),
... )
>>> cc.set_color_values(values)
>>> print(cc.slope)

ColorCollection

This class functions as both a ColorDecisionList and a ColorCorrectionCollection. Its children can be either ColorDecisions, ColorCorrections, or a combination of the two. Despite being able to have either type of child, the ColorCollection still needs to know which type of collection you want it to represent.

Setting the type of the ColorCollection to either ccc or cdl causes children of the opposite type to be converted into the appropriate type when exporting the class.

class cdl_convert.collection.ColorCollection(input_file: str | Path | None = None)[source]

Bases: AscDescBase, AscColorSpaceBase, AscXMLBase

Container class for ColorDecisionLists and ColorCorrectionCollections.

ColorCollection stores child ColorCorrection and ColorDecision objects and can export them as either ColorCorrectionCollection (.ccc) or ColorDecisionList (.cdl) XML formats. It inherits description, colorspace, and XML functionality from base classes.

Example

>>> collection = ColorCollection()
>>> cc = ColorCorrection("shot_001")
>>> collection.append_child(cc)
>>> collection.set_to_ccc()
>>> print(collection.type)  # 'ccc'
property all_children: list[ColorCorrection | ColorDecision]

Return combined list of ColorCorrection and ColorDecision.

property color_corrections: list[ColorCorrection]

Return list of ColorCorrection children.

property color_decisions: list[ColorDecision]

Return list of ColorDecision children.

property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

property element: Element | None

etree style Element representing the node.

property file_in: Path | None

Return absolute path to the input file.

property file_out: Path | None

Return output file path for writing this collection.

property id_list: list[str]

Return sorted list of IDs from all ColorCorrection children.

property is_ccc: bool

Return True if collection type is set to ‘ccc’.

property is_cdl: bool

Return True if collection type is set to ‘cdl’.

members: list[ColorCollection] = []

All ColorCollection instances are tracked in this list. Used for generating default filenames when no input file is set.

property type: str

Return collection type that determines export format.

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

property xmlns: str

Return XML namespace URI for ASC CDL schema version.

classmethod reset_members() None[source]

Clear the class-level members list.

__init__(input_file: str | Path | None = None) None[source]
append_child(child: ColorCorrection | ColorDecision) bool[source]

Add a ColorCorrection or ColorDecision to the appropriate list.

Parameters:

child – ColorCorrection or ColorDecision instance to add.

Returns:

True if child was added successfully, False if duplicate ID

prevented addition.

Return type:

bool

Raises:

ValidationError – If child is not a ColorCorrection or ColorDecision, or if duplicate ID is found and halt_on_error is enabled.

append_children(children: Sequence[ColorCorrection | ColorDecision]) None[source]

Add multiple ColorCorrection and ColorDecision objects to lists.

Parameters:

children – Sequence of ColorCorrection and/or ColorDecision instances to add.

build_element() Element | None[source]

Build XML ElementTree Element based on current collection type.

Returns:

CCC or CDL format XML element depending on

type.

Return type:

ElementTree.Element

build_element_ccc() Element[source]

Build ColorCorrectionCollection XML element.

Returns:

CCC format XML element containing all

ColorCorrections.

Return type:

ElementTree.Element

build_element_cdl() Element[source]

Build ColorDecisionList XML element.

Returns:

CDL format XML element containing all

ColorDecisions.

Return type:

ElementTree.Element

copy_collection() ColorCollection[source]

Create a copy of this collection with the same attributes.

Returns:

New collection instance with copied attributes

and child references.

Return type:

ColorCollection

Note

Child objects are referenced, not deep copied.

determine_dest(directory: str | Path) None[source]

Set output file path based on input filename or collection index.

Parameters:

directory – Directory path where output file will be written.

merge_collections(collections: list[ColorCollection]) ColorCollection[source]

Merge collection with others to create a new combined collection.

Parameters:

collections – List of ColorCollection instances to merge with.

Returns:

New collection containing children from all input

collections, with duplicates removed and attributes from this collection preserved.

Return type:

ColorCollection

parse_xml_color_corrections(xml_element: Element) bool[source]

Parse XML element to find and add ColorCorrection elements.

Parameters:

xml_element – XML element to search for ColorCorrection child elements.

Returns:

True if ColorCorrection elements were found and added.

Return type:

bool

parse_xml_color_decisions(xml_element: Element) bool[source]

Parse XML element to find and add ColorDecision elements.

Parameters:

xml_element – XML element to search for ColorDecision child elements.

Returns:

True if ColorDecision elements were found and added.

Return type:

bool

parse_xml_descs(xml_element: Element) None

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']
parse_xml_input_desc(xml_element: Element) bool

Parse an ElementTree element to find and add an input description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for an InputDescription element. If found, sets the input_desc attribute.

Returns:

True if InputDescription element was found (even if blank),

Return type:

bool

parse_xml_viewing_desc(xml_element: Element) bool

Parse an ElementTree element to find and add a viewing description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for a ViewingDescription element. If found, sets the viewing_desc attribute.

Returns:

True if ViewingDescription element was found (even if blank),

False otherwise.

Return type:

bool

set_parentage() None[source]

Set the parent attribute of all child objects to this collection.

set_to_ccc() None[source]

Set collection type to ‘ccc’ for ColorCorrectionCollection.

set_to_cdl() None[source]

Set collection type to ‘cdl’ for ColorDecisionList format.

ColorDecision

ColorDecision’s are normally found only within ColorCollection but this limitation of the ASC CDL schema is not enforced by cdl_convert.

class cdl_convert.decision.ColorDecision(color_correct: ColorCorrection | ColorCorrectionRef | None = None, media: MediaRef | None = None)[source]

Bases: AscDescBase, AscColorSpaceBase, AscXMLBase

Container linking ColorCorrections with media references.

Associates a ColorCorrection (or ColorCorrectionRef) with an optional MediaRef to link color corrections with reference media files. This is the primary mechanism for connecting color corrections to specific media in CDL workflows.

The ColorCorrection component is required, while MediaRef is optional. ColorDecision can contain either a direct ColorCorrection or a ColorCorrectionRef that points to an existing ColorCorrection.

ColorDecision is the only container that can hold ColorCorrectionRef objects, allowing the same ColorCorrection to be linked with multiple different media references across different ColorDecisions.

An example containing a ColorCorrection node:

<ColorDecision>
    <MediaRef ref="http://www.theasc.com/foasc-logo2.png"/>
    <ColorCorrection id="ascpromo">
        <SOPNode>
            <Description>get me outta here</Description>
            <Slope>0.9 1.1 1.0</Slope>
            <Offset>0.1 -0.01 0.0</Offset>
            <Power>1.0 0.99 1.0</Power>
        </SOPNode>
    </ColorCorrection>
</ColorDecision>

But it can also contain just a reference:

<ColorDecision>
    <MediaRef ref="best/project/ever/jim.0100.dpx"/>
    <ColorCorrectionRef ref="xf45.x628"/>
</ColorDecision>
property cc: ColorCorrection | ColorCorrectionRef | None

Return the contained ColorCorrection or ColorCorrectionRef.

Returns:

The color

correction instance or reference, or None if not set.

Return type:

Optional[Union[ColorCorrection, ColorCorrectionRef]]

property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

property element: Element | None

etree style Element representing the node.

property is_ref: bool

Return True if contains ColorCorrectionRef.

Returns:

True if cc is a ColorCorrectionRef, False if ColorCorrection.

Return type:

bool

property media_ref: MediaRef | None

Return the associated MediaRef instance if present.

Returns:

The media reference associated with this

decision, or None if no media reference is set.

Return type:

Optional[MediaRef]

members: dict[str, list[ColorDecision]] = {}

Dictionary mapping ColorCorrection IDs to lists of ColorDecision instances that contain them. Multiple decisions can reference the same correction.

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

classmethod reset_members() None[source]

Clear the class-level members dictionary.

Removes all ColorDecision instances from the members dictionary. Useful for testing or when starting with a clean state.

__init__(color_correct: ColorCorrection | ColorCorrectionRef | None = None, media: MediaRef | None = None) None[source]

Initialize ColorDecision with ColorCorrection and optional MediaRef.

Parameters:
  • color_correct (Optional[Union[ColorCorrection, ColorCorrectionRef]]) – ColorCorrection or ColorCorrectionRef to associate with media. Can be None initially and set later.

  • media (Optional[MediaRef]) – Optional media reference to associate with the color correction.

build_element(resolve: bool = False) Element[source]

Build XML ElementTree Element representing this ColorDecision.

Creates a ColorDecision XML element containing descriptions, MediaRef (if present), and ColorCorrection or ColorCorrectionRef.

Parameters:

resolve (bool) – If True and this contains a ColorCorrectionRef, resolve the reference and include the actual ColorCorrection element instead of the reference element.

Returns:

XML element representing this ColorDecision.

Return type:

ElementTree.Element

parse_xml_color_correction(xml_element: Element) bool[source]

Parse ColorDecision XML element to find ColorCorrection or reference.

Searches for either a ColorCorrection or ColorCorrectionRef element within the ColorDecision and creates the appropriate object.

Parameters:

xml_element (ElementTree.Element) – ColorDecision XML element to parse.

Returns:

True if ColorCorrection or ColorCorrectionRef was found and

parsed successfully, False otherwise.

Return type:

bool

parse_xml_color_decision(xml_element: Element) None[source]

Parse ColorDecision XML element and populate this instance.

Parses a ColorDecision XML element to extract descriptions, input/viewing descriptions, ColorCorrection or ColorCorrectionRef, and MediaRef.

Parameters:

xml_element (ElementTree.Element) – ColorDecision XML element to parse.

Raises:

ParseError – If ColorDecision element is missing required ColorCorrection or ColorCorrectionRef child element.

parse_xml_descs(xml_element: Element) None

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']
parse_xml_input_desc(xml_element: Element) bool

Parse an ElementTree element to find and add an input description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for an InputDescription element. If found, sets the input_desc attribute.

Returns:

True if InputDescription element was found (even if blank),

Return type:

bool

parse_xml_media_ref(xml_element: Element) None[source]

Parse ColorDecision XML element to find and create MediaRef.

Searches for a MediaRef element within the ColorDecision and creates a MediaRef instance if found.

Parameters:

xml_element (ElementTree.Element) – ColorDecision XML element to parse.

parse_xml_viewing_desc(xml_element: Element) bool

Parse an ElementTree element to find and add a viewing description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for a ViewingDescription element. If found, sets the viewing_desc attribute.

Returns:

True if ViewingDescription element was found (even if blank),

False otherwise.

Return type:

bool

set_parentage() None[source]

Set parent attribute of child objects to reference this instance.

Updates the parent attribute of the contained ColorCorrection or ColorCorrectionRef and MediaRef (if present) to point to this ColorDecision instance.

ColorCorrectionRef

class cdl_convert.decision.ColorCorrectionRef(id: str)[source]

Bases: AscXMLBase

Reference to an existing ColorCorrection by ID.

Contains a reference to a ColorCorrection instance by storing its ID. The reference can be resolved to retrieve the actual ColorCorrection object if it exists in the ColorCorrection.members dictionary.

When writing to formats that support references (like CDL), the reference writes as a ColorCorrectionRef element. When writing to formats that don’t support references (like CCC), behavior depends on halt_on_error setting.

Example

>>> cc = ColorCorrection("shot_001")
>>> ref = ColorCorrectionRef("shot_001")
>>> print(ref.cc.id)  # "shot_001"
>>> print(ref.id)  # "shot_001"
property cc: ColorCorrection | None

Return the referenced ColorCorrection instance if it exists.

Returns:

The ColorCorrection instance with

matching ID, or None if reference cannot be resolved.

Return type:

Optional[ColorCorrection]

property element: Element | None

etree style Element representing the node.

property id: str | None

Return the ID of the referenced ColorCorrection.

Returns:

ColorCorrection ID this reference points to.

Return type:

Optional[str]

members: dict[str, list[ColorCorrectionRef]] = {}

Dictionary mapping ColorCorrection IDs to lists of ColorCorrectionRef instances that reference them. Multiple references can point to the same ID.

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

classmethod reset_members() None[source]

Clear the class-level members dictionary.

Removes all ColorCorrectionRef instances from the members dictionary. Useful for testing or when starting with a clean state.

__init__(id: str) None[source]

Initialize ColorCorrectionRef with target ColorCorrection ID.

Parameters:

id (str) – ID of the ColorCorrection this reference should point to. The ColorCorrection doesn’t need to exist at creation time.

build_element() Element[source]

Build XML ElementTree Element representing this reference.

Creates a ColorCorrectionRef XML element with ref attribute containing the referenced ColorCorrection ID.

Returns:

XML element representing this reference.

Return type:

ElementTree.Element

resolve_reference() ColorCorrection | None[source]

Resolve reference to return the actual ColorCorrection instance.

Attempts to find and return the ColorCorrection instance with matching ID from the ColorCorrection.members dictionary.

Returns:

The referenced ColorCorrection if found,

None if not found (when halt_on_error is False).

Return type:

Optional[ColorCorrection]

Raises:

ValidationError – If reference cannot be resolved and halt_on_error is enabled.

MediaRef

Media Ref’s are normally found only inside of ColorDecision, which itself is found only inside of the ColorDecisionList collection. This isn’t a restriction that cdl_convert explicitly enforces, but the parse and write functions will only be creating and writing found MediaRef objects following the rules.

Where possible when writing filetypes that don’t support MediaRef, the information kept in MediaRef will be converted into description field metadata and preserved in that way.

MediaRef is meant to provide a convenient interface for managing and interpreting data stored in CDLs. You can change a broken absolute link directory to a relative link without touching the filename, or retrieve a full list of image sequences contained within a referenced directory.

class cdl_convert.decision.MediaRef(ref_uri: str, parent: ColorDecision | None = None)[source]

Bases: AscXMLBase

Reference to media files or directories for color correction context.

Container for media file or directory paths that should be referenced in relation to color corrections being performed. Supports both individual files and image sequences, with automatic sequence detection and path manipulation capabilities.

URIs can include protocols (e.g., ‘http://’) but many path manipulation methods work best with local file paths. The class provides comprehensive path parsing and sequence detection for film and TV workflows.

Example

>>> media = MediaRef("footage/shot_001.0001.exr")
>>> print(media.is_seq)  # True
>>> print(media.seq)  # "shot_001.####.exr"
>>> print(media.exists)
property directory: str

Return directory portion of the URI path.

Returns:

Directory path without protocol or filename. Empty string

if URI points to a file in the current directory.

Return type:

str

property element: Element | None

etree style Element representing the node.

property exists: bool

Check if the referenced path exists in the file system.

Returns:

True if the file or directory exists, False otherwise.

Return type:

bool

property filename: str

Return filename portion of the URI path.

Returns:

Filename with extension, or empty string if URI points

to a directory only.

Return type:

str

property is_abs: bool

Check if the path is absolute.

Returns:

True if path is absolute, False if relative.

Return type:

bool

property is_dir: bool

Check if the path points to a directory.

Returns:

True if path is a directory, False if file or non-existent.

Return type:

bool

property is_seq: bool

Check if the path represents an image sequence.

Detects sequences by analyzing filenames for frame number patterns like digits, # padding, or %d formatting. For directories, scans contained files for sequence patterns.

Returns:

True if path represents an image sequence, False otherwise.

Return type:

bool

members: dict[str, list[MediaRef]] = {}

Dictionary mapping reference URIs to lists of MediaRef instances that point to them. Multiple MediaRef instances can reference the same URI.

property path: str

Return complete file path without URI protocol.

Uses the original URI if available to preserve exact formatting. If original_uri has been cleared due to property changes, uses intelligent separator detection based on directory pattern.

Returns:

Complete file path without protocol. Returns directory

if no filename, or ‘.’ if both directory and filename are empty.

Return type:

str

property protocol: str

//’ suffix.

Returns:

Protocol portion of URI (e.g., ‘http’, ‘file’, ‘ftp’).

Empty string if no protocol is present.

Return type:

str

Type:

Return URI protocol without ‘

property ref: str

Return complete URI including protocol, directory, and filename.

Returns:

Complete URI string. Includes protocol with ‘://’ if present,

followed by directory and filename components.

Return type:

str

property seq: str | None

Return first detected image sequence with # padding notation.

Converts frame number patterns to # padding format (e.g., ‘image.0001.exr’ becomes ‘image.####.exr’).

Returns:

First sequence with # padding, or None if no

sequences detected.

Return type:

Optional[str]

property seqs: list[str]

Return all detected image sequences with # padding notation.

For directories, returns all unique sequence patterns found. For files, returns single-item list if file is part of a sequence.

Returns:

All sequences with # padding notation. Empty list

if no sequences detected.

Return type:

List[str]

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

classmethod reset_members() None[source]

Clear the class-level members dictionary.

Removes all MediaRef instances from the members dictionary. Useful for testing or when starting with a clean state.

__init__(ref_uri: str, parent: ColorDecision | None = None) None[source]
build_element() Element[source]

Build XML ElementTree Element representing this MediaRef.

Creates a MediaRef XML element with the ‘ref’ attribute containing the complete URI.

Returns:

XML element with MediaRef tag and ref

attribute.

Return type:

ElementTree.Element

SopNode

Note

This class is meant only to be created by a ColorCorrection, and thus has the required arg of parent when instantiating it.

Warning

Setting any of the sop node values with a single value as in offset = 5.4 will cause that value to be copied over all 3 colors, resulting in [5.4, 5.4, 5.4].

class cdl_convert.correction.SopNode(parent: ColorCorrection)[source]

Bases: ColorNodeBase

Container for slope, offset, and power values.

The SopNode stores the slope, offset, and power values that form the core of the CDL color correction. Values are stored internally as lists but returned as tuples to prevent direct index modification and maintain data integrity.

Example

>>> cc = ColorCorrection("test")
>>> cc.slope = [1.2, 1.1, 1.0]
>>> print(cc.sop_node.slope)
>>> cc.offset = 0.1  # Applied to all RGB channels
>>> print(cc.sop_node.offset)
property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

property element: Element | None

etree style Element representing the node.

element_names: list[str] = ['ASC_SOP', 'SOPNode', 'SopNode']

XML element names that map to this class during parsing (‘ASC_SOP’, ‘SOPNode’, ‘SopNode’).

property offset: tuple[Decimal, Decimal, Decimal]

Return RGB offset values as tuple.

Returns:

RGB offset values as (R, G, B)

tuple. Values raise or lower input brightness while holding slope constant.

Return type:

Tuple[Decimal, Decimal, Decimal]

property parent: ColorCorrection

Return parent ColorCorrection instance that created this SopNode.

Returns:

The ColorCorrection instance that owns this

SopNode.

Return type:

ColorCorrection

property power: tuple[Decimal, Decimal, Decimal]

Return RGB power values as tuple.

Returns:

RGB power values as (R, G, B)

tuple. Values change response curve with opposite behavior to traditional gamma.

Return type:

Tuple[Decimal, Decimal, Decimal]

property slope: tuple[Decimal, Decimal, Decimal]

Return RGB slope values as tuple.

Returns:

RGB slope values as (R, G, B)

tuple. Values change input slope without shifting black level.

Return type:

Tuple[Decimal, Decimal, Decimal]

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

__init__(parent: ColorCorrection) None[source]
build_element() Element[source]

Build XML ElementTree Element representing this SopNode.

Creates a SOP XML element using the configured tag name from config.sop_tag_name. The element contains any descriptions and the slope, offset, and power values formatted as space-separated strings.

Returns:

XML element representing this SopNode.

Return type:

ElementTree.Element

parse_xml_descs(xml_element: Element) None

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']

SatNode

Note

This class is meant only to be created by a ColorCorrection, and thus has the required arg of parent when instantiating it.

class cdl_convert.correction.SatNode(parent: ColorCorrection)[source]

Bases: ColorNodeBase

Container for saturation value and descriptions.

The SatNode stores the saturation value which is the last operation applied in the CDL color correction process.

Example

>>> cc = ColorCorrection("test")
>>> cc.sat = 0.8
>>> print(cc.sat_node.sat)  # Decimal('0.8')
>>> print(cc.sat_node.parent.id)
property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

property element: Element | None

etree style Element representing the node.

element_names: list[str] = ['ASC_SAT', 'SATNode', 'SatNode']

XML element names that map to this class during parsing (‘ASC_SAT’, ‘SATNode’, ‘SatNode’).

property parent: ColorCorrection

Return parent ColorCorrection instance that created this SatNode.

Returns:

The ColorCorrection instance that owns this

SatNode.

Return type:

ColorCorrection

property sat: Decimal

Return saturation value.

Returns:

Saturation value applied with Rec 709 coefficients.

Return type:

Decimal

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

__init__(parent: ColorCorrection) None[source]
build_element() Element[source]

Build XML ElementTree Element representing this SatNode.

Creates a Saturation XML element using the configured tag name from config.sat_tag_name. The element contains any descriptions and the saturation value.

Returns:

XML element representing this SatNode.

Return type:

ElementTree.Element

parse_xml_descs(xml_element: Element) None

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']

Base Classes

AscColorSpaceBase

Classes that deal with input and viewer colorspace can subclass from this class to get the input_desc and viewing_desc attributes.

class cdl_convert.base.AscColorSpaceBase[source]

Bases: object

Base class for ASC XML type nodes that deal with colorspace.

This class is meant to be inherited by any node type that uses viewing and input colorspace descriptions. It provides standardized handling of colorspace metadata according to ASC CDL specifications.

input_desc

Description of the color space, format and properties of the input images. Individual ColorCorrections can override this. Defaults to None.

Type:

Optional[str]

viewing_desc

Viewing device, settings and environment. Individual ColorCorrections can override this. Defaults to None.

Type:

Optional[str]

Example

>>> class MyColorNode(AscColorSpaceBase):
...     def __init__(self):
...         super().__init__()
...         self.input_desc = "Rec.709 Linear"
...         self.viewing_desc = "sRGB Display"
__init__() None[source]
parse_xml_input_desc(xml_element: Element) bool[source]

Parse an ElementTree element to find and add an input description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for an InputDescription element. If found, sets the input_desc attribute.

Returns:

True if InputDescription element was found (even if blank),

Return type:

bool

parse_xml_viewing_desc(xml_element: Element) bool[source]

Parse an ElementTree element to find and add a viewing description.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for a ViewingDescription element. If found, sets the viewing_desc attribute.

Returns:

True if ViewingDescription element was found (even if blank),

False otherwise.

Return type:

bool

AscDescBase

Classes that are allowed to have a description field subclass from this class to get the desc attribute. The desc attribute can be set with a single string, which will append to the list of strings already present in desc. If set to a list or tuple, desc will become a list of those values. If set to None, desc will become an empty list.

class cdl_convert.base.AscDescBase[source]

Bases: object

Base class for ASC XML type nodes that support multiple descriptions.

This class is meant to be inherited by any node type that uses description fields. It provides standardized handling of multiple description elements as specified in the ASC CDL schema.

Example

>>> node = AscDescBase()
>>> node.desc = "First description"
>>> node.desc = "Second description"
>>> print(node.desc)
['First description', 'Second description']
>>> node.desc = ["New list", "of descriptions"]
>>> print(node.desc)
['New list', 'of descriptions']
>>> node.desc = None  # Clear descriptions
>>> print(node.desc)
[]
property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

__init__() None[source]
parse_xml_descs(xml_element: Element) None[source]

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']

AscXMLBase

class cdl_convert.base.AscXMLBase[source]

Bases: object

Base class for nodes which can be converted to XML Elements.

This class provides convenience attributes and methods for converting CDL objects to XML representations.

Example

>>> class MyNode(AscXMLBase):
...     def build_element(self):
...         import xml.etree.ElementTree as ET
...
...         return ET.Element("MyNode")
>>> node = MyNode()
>>> print(node.xml)  # Pretty-formatted XML without header
>>> print(node.xml_root)  # With XML declaration

Note

Subclasses must override build_element() to return a valid ElementTree.Element for the XML-related attributes to work.

property element: Element | None

etree style Element representing the node.

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

__init__() None[source]
build_element() Element | None[source]

Build an ElementTree Element representing this node.

This is a placeholder method that must be overridden by inheriting classes to provide actual XML element construction.

Returns:

None in base implementation.

Subclasses should return a valid ElementTree.Element.

Return type:

Optional[ElementTree.Element]

ColorNodeBase

This class only exists to be subclassed by SatNode and SopNode and should not be used directly.

class cdl_convert.base.ColorNodeBase[source]

Bases: AscDescBase, AscXMLBase

Base class for SOP and SAT color correction nodes.

This class is meant only to be inherited by SopNode and SatNode classes and should not be used directly. It combines description and XML functionality while providing value validation methods for color correction parameters.

Example

>>> # This class is not used directly, but through SopNode/SatNode
>>> from cdl_convert import ColorCorrection
>>> cc = ColorCorrection("test_id")
>>> cc.slope = [1.2, 1.1, 1.0]  # Uses SopNode internally
>>> print(cc.sop_node.xml)  # XML representation
property desc: list[str]

Returns the list of descriptions.

Since ASC nodes can

contain multiple description elements, this attribute stores all descriptions found during parsing.

Setting desc directly will:

  • Append single values to the end of the list

  • Replace the list when given a list or tuple

  • Empty the list when given None, [], or ()

property element: Element | None

etree style Element representing the node.

property xml: str

A nicely formatted XML string representing the node

property xml_root: str

A nicely formatted XML string with a root element ready to write

__init__() None[source]
build_element() Element | None

Build an ElementTree Element representing this node.

This is a placeholder method that must be overridden by inheriting classes to provide actual XML element construction.

Returns:

None in base implementation.

Subclasses should return a valid ElementTree.Element.

Return type:

Optional[ElementTree.Element]

parse_xml_descs(xml_element: Element) None

Parse an ElementTree element to find and add any descriptions.

Parameters:

xml_element (ElementTree.Element) – The XML element to parse for Description elements. Any found will be appended to the desc list.

Example

>>> import xml.etree.ElementTree as ET
>>> node = AscDescBase()
>>> xml = ET.fromstring('''
... <root>
...     <Description>First description</Description>
...     <Description>Second description</Description>
... </root>
... ''')
>>> node.parse_xml_descs(xml)
>>> print(node.desc)
['First description', 'Second description']