---
title: "Python Environment"
description: "Understanding the Designer Python execution environment, utility functions, and restrictions"
url: https://developer.disguise.one/python-api/environment/
---

# Python Environment

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

## Contents

-   [Overview](#overview)
-   [Execution Context](#execution-context)
-   [Execution Utility Functions](#execution-utility-functions)
-   [Python Restrictions](#python-restrictions)
-   [Best Practices](#best-practices)
-   [Further Information](#further-information)

* * *

## Overview

Designer uses an embedded Python interpreter that provides access to the Designer API. Python scripts executed through the [`/api/session/python/execute`](/python-api/execution-api#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:**

-   Use Python 2.7 syntax and standard library features
-   Be aware of differences from Python 3 (e.g., `print` is a statement, not a function)
-   String handling, division behavior, and dictionary methods differ from Python 3

* * *

## 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:

### Automatic d3 Import

Scripts sent to the `execute` endpoint run in a namespace into which the whole `d3` package has already been imported (the equivalent of `from d3 import *`), so Designer types and globals are available without an import statement.

This does **not** apply to modules registered through the `registermodule` endpoint. Those are compiled as ordinary Python modules and must import `d3` themselves — see [Importing d3 in registered modules](/python-api/execution-api#importing-d3-in-registered-modules).

### Script Wrapping

Your code is indented and embedded within a function structure:

```python
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:**

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

This error is actually on line 2 of your script.

### Debugging Tips

-   Add `print` statements to trace execution
-   Remember the line offset when interpreting errors
-   Use try/except blocks to catch and handle errors gracefully
-   Check the execution response for detailed error messages

* * *

## Execution Utility Functions

When using the [`/api/session/python/execute`](/python-api/execution-api#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](/api/session/liveupdate) instead.

### Time Helpers

#### Track Time

```python
trackTime() -> float
```

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

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

**Example:**

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

#### Running Time

```python
runningTime() -> float
```

Returns the current track time for the current GUI transport, in seconds. It also includes the number of seconds the playhead has been holding at the end of a section.

This is used for “normal mode” playback modes.

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

**Example:**

```python
uptime = runningTime()
print("Playhead running time: {} seconds".format(uptime))
```

### Global Objects and Current State

The execution environment provides direct access to key Designer objects:

| Object | Description |
| :-- | :-- |
| `guisystem` | Current user interface state of the running Designer application (not including active Widgets, etc) |
| `state` | Current Designer project state - access to stage, devices, and project |
| `d3` | Global Designer application object |
| `resourceManager` | Used for loading, creating, removing, and finding resources |
| `Resource` | Base resource class for most aspects of the Designer project |

**Example:**

```python
# Access the current UI selected 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:

-   **[`threading`](https://docs.python.org/2/library/threading.html)**
-   **[`sys`](https://docs.python.org/2.7/library/sys.html)**

**Why these restrictions?**

-   Threading could interfere with Designer’s render loop and cause instability
-   `sys` module access could allow modification of the Python environment in unsafe ways

### Removed Designer Functionality

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

-   **Designer Widgets** - Internal UI widgets are not exposed to prevent UI corruption and encourage adoption of HTML interfaces
-   **Designer Actions** - Action subscriptions are forbidden as plugin python execution is not intended to be persistent
-   **Designer Screenshots** - Screenshot functionality is not available through Python

### 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:**

-   The default timeout is controlled by the `pythonApiExecutionTimeout` experimental option in d3Manager
-   When a script exceeds the timeout, a `KeyboardInterrupt` is executed
-   The execution stops and returns a `TimeoutError` in the response
-   See the [Python Execution API](/python-api/execution-api#run-time-and-timeouts) for more details

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

**Good:**

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

**Avoid:**

```python
# 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](/python-api/guides/resources) for details.

```python
# 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:

```python
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:

```python
# 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](/python-api/introduction#python-api-guides):

-   [Track & Sequencing](/python-api/guides/track-and-sequencing) - Working with timeline
-   [Resources](/python-api/guides/resources) - Resource management patterns
-   [Stage](/python-api/guides/stage) - Stage object manipulation
-   [And more…](/python-api/introduction#python-api-guides)

* * *

## Further Information

-   **[Python Execution API](/python-api/execution-api)** - Details on the execute endpoint
-   **[Useful Python Snippets](/python-api/useful-strings)** - Code examples for common tasks
-   **[Python API Guides](/python-api/introduction#python-api-guides)** - Comprehensive workflow guides
-   **[API Documentation](/python-api/docs)** - Complete API reference

For questions or to report issues with the Python environment, contact [integrations@disguise.one](mailto:integrations@disguise.one).
