designer-plugin Reference
Table of Contents
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
__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
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:
# 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
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:
with DesignerPlugin.from_json_file("config/my_plugin.json", port=9999) as plugin:
input("Press Enter to stop...")
Properties
service_info
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
__enter__() → 'DesignerPlugin'
exit
__exit__(exc_type, exc_value, traceback)
aenter
async __aenter__() → 'DesignerPlugin'
aexit
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
__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
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:
with D3Session('localhost', 80) as session:
time: str = session.rpc(get_time.payload())
execute
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:
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
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
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:
with D3Session('localhost', 80) as session:
success = session.register_module("mymodule")
print(f"success: {success}")
register_all_modules
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:
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
__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
__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
__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
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
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:
async with D3AsyncSession('localhost', 80) as session:
time: str = await session.rpc(get_time.payload())
execute
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:
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
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:
async with D3AsyncSession('localhost', 80) as session:
success = await session.register_module("mymodule")
print(f"success: {success}")
register_all_modules
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:
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
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
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
__init__() → None
Methods
in_session
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
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:
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
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:
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:
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:
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
is_module_payload() → bool
Return True if this payload targets a named module.
Returns: True if moduleName is set, False otherwise.
debug_string
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
parse_returnValue(cls, v: Any) → Any
Methods
returnCastValue
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:
response = session.execute(get_surface_info.payload("surface 1"))
info = response.returnCastValue(dict[str, str])
print(info["uid"])
debug_string
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
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