---
title: "designer-plugin Reference"
description: "designer-plugin reference."
url: https://developer.disguise.one/plugins/designer-plugin/reference/
---

# designer-plugin Reference

## Table of Contents

-   [Publish](#publish)
    -   [DesignerPlugin](#designerplugin)
-   [Session](#session)
    -   [D3Session](#d3session)
    -   [D3AsyncSession](#d3asyncsession)
-   [Client](#client)
    -   [D3PluginClient](#d3pluginclient)
-   [Decorators](#decorators)
    -   [@d3function](#d3function)
    -   [@d3pythonscript](#d3pythonscript)
-   [Models](#models)
    -   [PluginPayload](#pluginpayload)
    -   [PluginResponse](#pluginresponse)
    -   [PluginError](#pluginerror)
    -   [PluginRegisterResponse](#pluginregisterresponse)
    -   [PluginStatus](#pluginstatus)
    -   [PluginStatusDetail](#pluginstatusdetail)
    -   [RegisterPayload](#registerpayload)
    -   [PluginException](#pluginexception)

* * *

# Publish

## DesignerPlugin

Publish a plugin via DNS-SD so the Disguise Designer application can discover it.

Use as a context manager (sync or async) to register and unregister the service  
automatically.

### Constructor

#### ****init****

```py
__init__(name: str, port: int, hostname: str | None = None, url: str | None = None, requires_session: bool = False, is_disguise: bool = False)
```

### Static Methods

#### **default\_init**

```py
default_init(port: int, hostname: str | None = None) → 'DesignerPlugin'
```

Initialize the plugin options with the values in d3plugin.json.

Reads `name`, `url`, `requiresSession`, and `isDisguise` from `./d3plugin.json`  
in the current working directory.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `port` | `int` | The port number to publish the plugin on. |
| `hostname` | `str \| None` | Optional hostname override. Defaults to the machine hostname. |

Returns: A DesignerPlugin instance configured from d3plugin.json.

Example:

```python
# Reads name/url from ./d3plugin.json, uses provided port
with DesignerPlugin.default_init(port=9999) as plugin:
    input("Press Enter to stop...")
```

#### **from\_json\_file**

```py
from_json_file(file_path: str, port: int, hostname: str | None = None) → 'DesignerPlugin'
```

Load plugin options from a JSON file (d3plugin.json format).

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `file_path` | `str` | Path to the JSON configuration file. |
| `port` | `int` | The port number to publish the plugin on. |
| `hostname` | `str \| None` | Optional hostname override. Defaults to the machine hostname. |

Returns: A DesignerPlugin instance configured from the JSON file.

Example:

```python
with DesignerPlugin.from_json_file("config/my_plugin.json", port=9999) as plugin:
    input("Press Enter to stop...")
```

### Properties

#### **service\_info**

```py
service_info() → ServiceInfo
```

Get the ServiceInfo object suitable for DNS-SD service registration.

### Context Manager

Supports use as a context manager (`with` / `async with`):

#### ****enter****

```py
__enter__() → 'DesignerPlugin'
```

#### ****exit****

```py
__exit__(exc_type, exc_value, traceback)
```

#### ****aenter****

```py
async __aenter__() → 'DesignerPlugin'
```

#### ****aexit****

```py
async __aexit__(exc_type, exc_value, traceback)
```

* * *

# Session

Sync and async session classes for communicating with Designer.

## D3Session

Synchronous session for executing plugins on Designer.

Manages connection to a Designer instance and provides synchronous API for  
plugin execution, module registration, and generic HTTP requests.

### Constructor

#### ****init****

```py
__init__(hostname: str, port: int = D3_PLUGIN_DEFAULT_PORT, context_modules: set[str] | None = None) → None
```

Initialize synchronous Designer session.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `hostname` | `str` | The hostname of the Designer instance. |
| `port` | `int` | The port number of the Designer instance. |
| `context_modules` | `set[str] \| None` | Optional set of module names to register when entering session context. |

### Methods

#### **rpc**

```py
rpc(payload: PluginPayload[RetType], timeout_sec: float | None = None) → RetType
```

Execute a remote procedure call and return only the return value.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `payload` | `PluginPayload[RetType]` | Plugin payload containing script and optional module name. |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for the request. |

Returns: The return value from the plugin execution.

Raises:

-   `PluginException`: If the plugin execution fails.

Example:

```python
with D3Session('localhost', 80) as session:
    time: str = session.rpc(get_time.payload())
```

#### **execute**

```py
execute(payload: PluginPayload[RetType], timeout_sec: float | None = None) → PluginResponse[RetType]
```

Execute a plugin script on Designer.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `payload` | `PluginPayload[RetType]` | Plugin payload containing script and optional module name. |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for the request. |

Returns: PluginResponse containing status, logs, and return value.

Raises:

-   `PluginException`: If the plugin execution fails.

Example:

```python
with D3Session('localhost', 80) as session:
    response = session.execute(get_time.payload())
    print(f"Status: {response.status.code}")
    print(f"Python log: {response.pythonLog}")
    print(f"Value: {response.returnValue}")
```

#### **request**

```py
request(method: Method, url_endpoint: str, **kwargs: Any) → Any
```

Make a generic HTTP request to Designer API.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `method` | `Method` | HTTP method to use. |
| `url_endpoint` | `str` | The API endpoint path. \*\*kwargs: Additional arguments to pass to requests.request. |

Returns: JSON response from the API.

#### **register\_module**

```py
register_module(module_name: str, timeout_sec: float | None = None) → bool
```

Register a module with Designer.

Note that session already auto-registers modules in lazy manner on execute.  
Call this method directly only when you need to register eagerly.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `module_name` | `str` | Name of the module to register. |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for the request. |

Returns: True if module was registered successfully, False if module not found.

Raises:

-   `PluginException`: If module registration fails on Designer side.

Example:

```python
with D3Session('localhost', 80) as session:
    success = session.register_module("mymodule")
    print(f"success: {success}")
```

#### **register\_all\_modules**

```py
register_all_modules(timeout_sec: float | None = None) → dict[str, bool]
```

Register all modules decorated with @d3function.

Note that session already auto-registers modules in lazy manner on execute.  
Call this method directly only when you need to register all modules eagerly.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for each registration request. |

Returns: Dictionary mapping module names to registration success status.

Raises:

-   `PluginException`: If any module registration fails on Designer side.

Example:

```python
with D3Session('localhost', 80) as session:
    results = session.register_all_modules()
    # {"mymodule": True, "utilities": True}
```

### Context Manager

Supports use as a context manager (`with` / `async with`):

#### ****enter****

```py
__enter__() → 'D3Session'
```

Enter context manager and register all context modules.

Returns: The session instance.

Raises:

-   `RuntimeError`: If any context module is not registered with @d3function.

#### ****exit****

```py
__exit__(_type: Any, _value: Any, _traceback: Any) → None
```

Exit context manager.

## D3AsyncSession

Asynchronous session for executing plugins on Designer.

Manages connection to a Designer instance and provides asynchronous API for  
plugin execution, module registration, and generic HTTP requests.

### Constructor

#### ****init****

```py
__init__(hostname: str, port: int = D3_PLUGIN_DEFAULT_PORT, context_modules: set[str] | None = None) → None
```

Initialize asynchronous Designer session.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `hostname` | `str` | The hostname of the Designer instance. |
| `port` | `int` | The port number of the Designer instance. |
| `context_modules` | `set[str] \| None` | Optional set of module names to register when entering session context. |

### Methods

#### **request**

```py
async request(method: Method, url_endpoint: str, **kwargs: Unpack[aiohttp.client._RequestOptions]) → Any
```

Make a generic HTTP request to Designer API asynchronously.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `method` | `Method` | HTTP method to use. |
| `url_endpoint` | `str` | The API endpoint path. \*\*kwargs: Additional arguments to pass to aiohttp session.request. |

Returns: JSON response from the API.

#### **rpc**

```py
async rpc(payload: PluginPayload[RetType], timeout_sec: float | None = None) → RetType
```

Execute a remote procedure call asynchronously and return only the return value.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `payload` | `PluginPayload[RetType]` | Plugin payload containing script and optional module name. |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for the request. |

Returns: The return value from the plugin execution.

Raises:

-   `PluginException`: If the plugin execution fails.

Example:

```python
async with D3AsyncSession('localhost', 80) as session:
    time: str = await session.rpc(get_time.payload())
```

#### **execute**

```py
async execute(payload: PluginPayload[RetType], timeout_sec: float | None = None) → PluginResponse[RetType]
```

Execute a plugin script on Designer asynchronously.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `payload` | `PluginPayload[RetType]` | Plugin payload containing script and optional module name. |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for the request. |

Returns: PluginResponse containing status, logs, and return value.

Raises:

-   `PluginException`: If the plugin execution fails.

Example:

```python
async with D3AsyncSession('localhost', 80) as session:
    response = await session.execute(get_time.payload())
    print(f"Status: {response.status.code}")
    print(f"Value: {response.returnValue}")
```

#### **register\_module**

```py
async register_module(module_name: str, timeout_sec: float | None = None) → bool
```

Register a module with Designer asynchronously.

Note that session already auto-registers modules in lazy manner on execute.  
Call this method directly only when you need to register eagerly.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `module_name` | `str` | Name of the module to register. |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for the request. |

Returns: True if module was registered successfully, False if module not found.

Raises:

-   `PluginException`: If module registration fails on Designer side.

Example:

```python
async with D3AsyncSession('localhost', 80) as session:
    success = await session.register_module("mymodule")
    print(f"success: {success}")
```

#### **register\_all\_modules**

```py
async register_all_modules(timeout_sec: float | None = None) → dict[str, bool]
```

Register all modules decorated with @d3function asynchronously.

Note that session already auto-registers modules in lazy manner on execute.  
Call this method directly only when you need to register all modules eagerly.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `timeout_sec` | `float \| None` | Optional timeout in seconds for each registration request. |

Returns: Dictionary mapping module names to registration success status.

Raises:

-   `PluginException`: If any module registration fails on Designer side.

Example:

```python
async with D3AsyncSession('localhost', 80) as session:
    results = await session.register_all_modules()
    # {"mymodule": True, "utilities": True}
```

### Context Manager

Supports use as a context manager (`with` / `async with`):

#### ****aenter****

```py
async __aenter__() → 'D3AsyncSession'
```

Enter async context manager and register all context modules.

Returns: The session instance.

Raises:

-   `RuntimeError`: If any context module is not registered with @d3function.

#### ****aexit****

```py
async __aexit__(_exc_type: Any, _exc: Any, _tb: Any) → None
```

Exit async context manager.

* * *

# Client

## D3PluginClient

Base class for creating Designer plugin clients.

This class provides the foundation for building plugins that execute remotely  
on Designer. When you subclass D3PluginClient, the metaclass automatically:

-   Extracts and processes your class source code
-   Converts it to Python 2.7 compatible code
-   Wraps all your methods to execute remotely
-   Manages module registration with Designer

### Attributes

#### **instance\_code**

The code used to instantiate the plugin remotely (set on init)

### Constructor

#### ****init****

```py
__init__() → None
```

### Methods

#### **in\_session**

```py
in_session() → bool
```

Check if the client is currently in an active session.

Returns: True if both hostname and port are set, False otherwise.

#### **async\_session**

```py
async async_session(hostname: str, port: int = D3_PLUGIN_DEFAULT_PORT, register_module: bool = True, module_name: str | None = None)
```

Async context manager for plugin session with Designer.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `hostname` | `str` | The hostname of the Designer instance. |
| `port` | `int` | The port number of the Designer instance. |
| `register_module` | `bool` | Whether to register the module. Set to False when the module has already been registered with Designer. |
| `module_name` | `str \| None` | Optional module name to override the default. |

Returns: The plugin client instance with active session.

Example:

```python
import asyncio
from designer_plugin.d3sdk import D3PluginClient
from designer_plugin.pystub import *
class MyPlugin(D3PluginClient):
    async def get_surface_uid(self, surface_name: str) -> str:
        surface: Screen2 = resourceManager.load(
            Path(f'objects/screen2/{surface_name}.apx'), Screen2)
        return str(surface.uid)
async def main():
    plugin = MyPlugin()
    async with plugin.async_session('localhost', 80):
        uid = await plugin.get_surface_uid("surface 1")
asyncio.run(main())
```

#### **session**

```py
session(hostname: str, port: int = D3_PLUGIN_DEFAULT_PORT, register_module: bool = True, module_name: str | None = None)
```

Sync context manager for plugin session with Designer.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `hostname` | `str` | The hostname of the Designer instance. |
| `port` | `int` | The port number of the Designer instance. |
| `register_module` | `bool` | Whether to register the module. Set to False when the module has already been registered with Designer. |
| `module_name` | `str \| None` | Optional module name to override the default. |

Returns: The plugin client instance with active session.

Example:

```python
from designer_plugin.d3sdk import D3PluginClient
from designer_plugin.pystub import *
class MyPlugin(D3PluginClient):
    def get_surface_uid(self, surface_name: str) -> str:
        surface: Screen2 = resourceManager.load(
            Path(f'objects/screen2/{surface_name}.apx'), Screen2)
        return str(surface.uid)
plugin = MyPlugin()
with plugin.session('localhost', 80):
    uid = plugin.get_surface_uid("surface 1")
```

* * *

# Decorators

Decorators for registering Designer plugin functions.

## @d3function

d3function(module\_name: str = ”) → Callable\[\[Callable\[P, T\]\], D3Function\[P, T\]\]

Decorator to wrap a Python function for Designer module registration and execution.

This decorator transforms a regular Python function into a D3Function that can be registered  
as a reusable module in Designer and executed remotely. The decorated function is added to  
the module’s function registry and can be called by name after module registration.

Unlike @d3pythonscript which inlines the function body, @d3function registers the complete  
function definition as part of a module, allowing efficient reuse across multiple executions.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `module_name` | `str` | The module name to register this function under. This should be a unique identifier for the module that will contain this function. Multiple functions can share the same module\_name to be registered together as a single module. |

Returns: A decorator function that wraps the target function in a D3Function instance.

Example:

```python
from designer_plugin.d3sdk import d3function, D3Session
from designer_plugin.pystub import *
@d3function("my_d3module")
def get_camera_uid(cam_name: str) -> str:
    camera = resourceManager.load(
        Path(f'objects/camera/{cam_name}.apx'),
        Camera
    )
    return str(camera.uid)
# Generate payload for execution (calls the function by name)
payload = get_camera_uid.payload("camera1")
# payload.script == "return get_camera_uid('camera1')"
# "my_d3module" is auto-registered when entering the session
with D3Session('localhost', 80, {"my_d3module"}) as session:
    uid = session.rpc(get_camera_uid.payload("camera1"))
```

## @d3pythonscript

d3pythonscript(func: Callable\[P, T\]) → D3PythonScript\[P, T\]

Decorator to wrap a Python function for standalone Designer script execution.

This decorator transforms a regular Python function into a D3PythonScript that generates  
execution payloads for direct script execution in Designer. Unlike @d3function, this  
decorator does not register the function as a module and is intended for one-off script  
execution where the function body is inlined with the arguments.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `func` | `Callable[P, T]` | The Python function to wrap. |

Returns: D3PythonScript instance that wraps the function and provides payload generation.

Example:

```python
from designer_plugin.d3sdk import d3pythonscript, D3Session
@d3pythonscript
def my_add(a: int, b: int) -> int:
    return a + b
# Generate payload for execution
payload = my_add.payload(5, 3)
# The payload.script will contain:
# a=5
# b=3
# return a + b
with D3Session('localhost', 80) as session:
    result = session.rpc(my_add.payload(5, 3))
    print(result)  # 8
```

* * *

# Models

Pydantic models and types used in the Designer Plugin API.

## PluginPayload

Type-safe execution payload for plugin calls.

### Attributes

#### **moduleName**

Module name to run script on Designer.

#### **script**

Script to run on Designer.

### Methods

#### **is\_module\_payload**

```py
is_module_payload() → bool
```

Return True if this payload targets a named module.

Returns: True if moduleName is set, False otherwise.

#### **debug\_string**

```py
debug_string() → str
```

Return a human-readable debug representation of this payload.

Returns: A formatted string showing the JSON serialisation and raw script content.

## PluginResponse

Response from a plugin API call.

### Attributes

#### **status**

Status of plugin API call.

#### **d3Log**

The d3Log field captures the Designer console log for the time the Python script is executing, recording any output generated by running a Python command, including the time taken to execute the Python command. As this captures the Designer console output, it is possible other threads may write to this output during this period causing additional irrelevant output.

#### **pythonLog**

This output field is the pure Python output, recording any print statements or warnings that occur during the execution of the script. This output will also appear in the d3Log field. However, in the d3Log field it will be mixed with other Designer log output.

#### **returnValue**

Return value of python plugin execution

### Static Methods

#### **parse\_returnValue**

```py
parse_returnValue(cls, v: Any) → Any
```

### Methods

#### **returnCastValue**

```py
returnCastValue(castType: type[RetCastType]) → RetCastType
```

Validate and cast the return value to the specified type.

Parameters:

| Name | Type | Description |
| --- | --- | --- |
| `castType` | `type[RetCastType]` | The type to validate and cast the return value to. |

Returns: The validated return value as the specified type.

Raises:

-   `ValidationError`: If the return value cannot be validated as the specified type.

Example:

```python
response = session.execute(get_surface_info.payload("surface 1"))
info = response.returnCastValue(dict[str, str])
print(info["uid"])
```

#### **debug\_string**

```py
debug_string() → str
```

## PluginError

Error response when plugin execution fails.

### Attributes

#### **returnValue**

Always None for error responses.

## PluginRegisterResponse

Response from a plugin module registration API call.

### Attributes

#### **status**

Status of plugin module registration API call.

## PluginStatus

Status information from plugin API calls.

### Attributes

#### **code**

Return code of plugin API call. 0 if good.

#### **message**

Message from plugin API call.

#### **details**

List of detailed error information.

## PluginStatusDetail

Detail information for plugin status errors.

### Attributes

#### **type\_url**

Type URL identifying the error detail.

#### **value**

Error detail value.

## RegisterPayload

Payload for registering a Python module with Designer.

### Attributes

#### **moduleName**

Module name to register contents.

#### **contents**

Python code to register with the module name.

### Methods

#### **debug\_string**

```py
debug_string() → str
```

## PluginException

Exception raised when plugin execution fails.

### Attributes

#### **status**

The status information from the failed plugin call

#### **d3Log**

Designer console log output

#### **pythonLog**

Python-specific log output
