disguise developers

Designer Plugins

Plugins for Disguise Designer software.

Python Environment

This page describes the Python execution environment within Designer, including available utility functions, restrictions, execution context, and best practices.

Contents


Overview

Designer uses an embedded Python interpreter that provides access to the Designer API. Python scripts executed through the /api/session/python/execute endpoint run in a controlled environment that has been configured for stability and integration with Designer’s core systems.

Python Version

Designer uses Python 2.7 for its embedded interpreter. While Python 2.7 reached end-of-life in 2020, it remains the version used within Designer for compatibility and stability reasons.

Important Considerations:


Execution Context

When you execute Python code through the API, your script is automatically wrapped in a function called userScript. This has some implications for error reporting and execution:

Script Wrapping

Your code is indented and embedded within a function structure:

def userScript():
    # Your code here (indented)
    pass

Error Line Numbers

Because of this wrapping, error line numbers are offset by 10. When you see an error referencing line 10, it actually refers to the first line of your script. If an error references line 15, it’s line 5 of your actual code.

Example:

Error at line 12: NameError: name 'foo' is not defined

This error is actually on line 2 of your script.

Debugging Tips


Execution Utility Functions

When using the /api/session/python/execute endpoint without a module name, some additional global variables and functions are available to help access the Designer environment. These are aimed at simplifying Python implementation.

Note: For real-time feedback about timing elements, use the Live Update API instead.

Time Helpers

Track Time

trackTime() -> float

Returns the current track time for the current transport in seconds.

Equivalent to: LocalState.localState().currentTransport.player.tCurrent

Example:

# Add a layer at the current playhead position
current_time = trackTime()
layer = guisystem.track.addNewLayer(VideoModule, current_time, 60, 'My Layer')

Running Time

runningTime() -> float

Returns the length of time the application has been running in seconds.

Equivalent to: LocalState.localState().currentTransport.player.tRunning

Example:

# Check how long Designer has been running
uptime = runningTime()
print("Designer has been running for {} seconds".format(uptime))

Global Objects and Current State

The execution environment provides direct access to key Designer objects:

ObjectDescription
guisystemMain GUI system - access to track, layers, and UI state
stateCurrent Designer state - access to stage, devices, and project
d3Global Designer application object
resourceManagerResource manager for loading, creating, and managing resources
ResourceBase resource class for creating typed resources

Example:

# Access the current track
track = guisystem.track

# Get all video layers
video_layers = [l for l in track.layers if l.moduleType() == VariableVideoModule]

# Access the stage
stage = state.stage

# Access devices
devices = state.devices

# Load a resource
clip = resourceManager.loadOrCreate('objects/videoclip/myclip.mov.apx', VideoClip)

Python Restrictions

To ensure stability and prevent conflicts with Designer’s internal systems, some functionality has been removed or restricted in the Designer Python environment.

Removed Python Modules

The following standard Python modules have been removed and are not available:

Why these restrictions?

Removed Designer Functionality

The following Designer-specific functionality cannot be accessed through the Python environment:

Alternative Approaches

If you need functionality that’s restricted:

  1. For threading: If you need to run a threaded execution, run it as a remote plugin and use APIs to interact with Designer when needed
  2. For system access: Use the REST APIs from an external script
  3. For UI interaction: Build custom plugin interfaces using HTML/JavaScript

Best Practices

1. Keep Scripts Short and Focused

Python scripts execute on Designer’s main application thread, which means Designer will pause while your script runs. To prevent scripts from hanging the application, a timeout interrupt is enforced.

Timeout Behavior:

Best practice: Break complex operations into smaller steps or chain multiple execute calls through the API.

Good:

# Quick operation
layer = guisystem.track.addNewLayer(VideoModule, trackTime(), 60, 'Video')
layer.findSequence('video').sequence.setResource(0, my_clip)

Avoid:

# Long loop that could block Designer and hit the timeout
for i in range(10000):
    # Heavy processing
    pass

2. Use Resource Management Patterns

Always use the resource manager and follow proper save/dirty patterns. See the Resources Guide for details.

# Mark resource as dirty before changes
markDirty(my_resource)

# Make changes
my_resource.property = new_value

# Save changes
my_resource.saveOnDelete()

3. Handle Errors Gracefully

Always include error handling to prevent script failures from affecting Designer:

try:
    layer = next(l for l in track.layers if l.name == "My Layer")
    # Do something with layer
except StopIteration:
    print("Layer not found")
except Exception as e:
    print("Error: {}".format(str(e)))

4. Use Descriptive Names

When creating resources, use descriptive names to make your project easier to navigate:

# Good
video_clip = resourceManager.loadOrCreate('objects/videoclip/hero_shot.mp4.apx', VideoClip)

# Less clear
clip = resourceManager.loadOrCreate('objects/videoclip/v1.mp4.apx', VideoClip)

5. Leverage the Guides

For detailed information on specific workflows, consult the Python API Guides:


Further Information

For questions or to report issues with the Python environment, contact integrations@disguise.one.