DocumentationDocumentation
API reference/Python API

Window and page declarations

Find size, position, target-region, and page declarations. A declaration does not open a window.

Declaration and opening are separate steps

web creates page, size, and position declarations without opening a window. The bound client's plugin.open_window requests display. Check declarations first, then open results. For the full introduction, see Window position, size, and visibility.

Declare a local tool window
python
from .nexus_web import web

spec = web.window(
    web.local_app("web/index.html"),
    size=web.window_size((640, 420), minimum=(360, 260)),
    title="我的工具",
    placement=web.window_placement("top_right", margin=(24, 24)),
    transparent=True,
)

Displayed types describe exact argument/result structures, not a recommendation to import internal modules. Prefer web declaration functions rather than copying implementations from internal type paths.

Page sources: local, development server, and remote

local_app
Public definitions
def local_app(path: 'str', *, root: 'Path | str | None' = None, auto_reload: 'bool' = False) -> 'WebLocalApp'

path is an entry path relative to the resource root, such as web/index.html. root defaults to None, using the client default or add-on package directory on opening. Returns WebLocalApp; trusted local pages can use the bridge. Resources must respect local boundaries. See Local resources and page restrictions.

auto_reload=False Disabled by default. True watches the resource root during development and reloads the whole page after writes settle. This is not module hot replacement and has no fixed latency guarantee. It resets page memory, input, and scroll state. Point built frontends at runnable output.

dev_server
Public definitions
def dev_server(url: 'str') -> 'WebDevServerApp'

Accepts loopback HTTP/HTTPS URLs and returns WebDevServerApp without starting a server. These pages receive neither Python communication nor acquireNexusWebUI. Use for visual development, not action/state acceptance.

remote_page
Public definitions
def remote_page(url: 'str') -> 'WebRemotePageApp'

Accepts only HTTPS and returns WebRemotePageApp without a bridge. Remote pages and public browser navigation are frozen. This documents existing boundaries, not remote bridging or Blender control integration.

View all return-type fields
WebLocalApp
Public definitions
class WebLocalApp (dataclass frozen slots):
  __init__(path: 'str', root: 'Path | str | None' = None, auto_reload: 'bool' = False) -> None
  path: str
  root: Path | str | None = None
  auto_reload: bool = False
WebDevServerApp
Public definitions
class WebDevServerApp (dataclass frozen slots):
  __init__(url: 'str') -> None
  url: str
WebRemotePageApp
Public definitions
class WebRemotePageApp (dataclass frozen slots):
  __init__(url: 'str') -> None
  url: str
WebWindowApp
Public definitions
WebWindowApp = nexus_web.contracts.source.WebLocalApp | nexus_web.contracts.source.WebDevServerApp | nexus_web.contracts.source.WebRemotePageApp

window_size: dimensions and constraints

window_size
Public definitions
def window_size(initial: 'tuple[int, int]', *, minimum: 'tuple[int, int] | None' = None, maximum: 'tuple[int, int] | None' = None, resizable: 'bool' = False, auto_fit: 'bool' = False) -> 'WebWindowSize'

initial is required as positive integer (width, height), each at most 4096. minimum and maximum share that cap, default to None, and must be consistent with the initial size and each other. resizable defaults to False; only explicit True enables gestures on all edges and corners. Returns WebWindowSize.

Resize handles cover the entire rectangle, including transparent margins. Bounds constrain the viewport; equal bounds lock an axis. The framework changes available space in the same page without reloading or scaling the whole page. The page owns text and button sizes and responsive layout. Reopening uses initial dimensions. Old embedded copies remain non-resizable; authors must upgrade and opt in.

View all return-type fields
WebWindowSize
Public definitions
class WebWindowSize (dataclass frozen slots):
  __init__(initial: 'tuple[int, int]', minimum: 'tuple[int, int] | None' = None, maximum: 'tuple[int, int] | None' = None, resizable: 'bool' = False, auto_fit: 'bool' = False) -> None
  initial: tuple[int, int]
  minimum: tuple[int, int] | None = None
  maximum: tuple[int, int] | None = None
  resizable: bool = False
  auto_fit: bool = False

Initial position: anchors and exact coordinates

window_placement
Public definitions
def window_placement(placement: 'str', *, margin: 'int | float | tuple[int | float, int | float]' = 0, offset: 'tuple[int | float, int | float]' = (0, 0), padding: 'int | float' = 8, overflow: 'WebWindowOverflowMode' = 'shift', stick: 'bool' = False) -> 'WebWindowPlacement'
Parameter Defaults and meaning
placement Required: top_left, top, top_right, left, center, right, bottom_left, bottom, or bottom_right, corresponding to nine anchors.
margin 0; nonnegative space from the relevant edges. A scalar applies to both axes; (x,y) is also accepted.
offset (0,0); finite per-axis offsets from the anchored position.
padding 8; nonnegative safety padding in host UI units for shift overflow correction.
overflow shift moves out-of-bounds positions back into the region; none preserves them.
stick False; must be boolean. Currently stored without a promise of continuous edge sticking or automatic reflow.
window_position
Public definitions
def window_position(x: 'int | float', y: 'int | float', *, padding: 'int | float' = 8, overflow: 'WebWindowOverflowMode' = 'shift', stick: 'bool' = False) -> 'WebWindowPlacement'

x/y are local coordinates in the host editor content region, not global screen or CSS coordinates. padding, overflow, and stick have the same meaning above. Both functions return WebWindowPlacement.

Placement applies only on opening; dragging preserves manual position. Region changes may vertically adjust the header for reachability without recentering or scaling content. overflow='none' preserves out-of-bounds behavior. Without an explicit target or usable region rectangle, placement is not resolved; arbitrary background contexts are not normal opening environments.

View all return-type fields
WebWindowPlacement
Public definitions
class WebWindowPlacement (dataclass frozen slots):
  __init__(mode: 'WebWindowPlacementMode', placement: 'WebWindowPlacementName | None' = None, position: 'tuple[float, float] | None' = None, container: 'WebWindowPlacementContainer' = 'area', margin: 'tuple[float, float]' = (0.0, 0.0), offset: 'tuple[float, float]' = (0.0, 0.0), padding: 'float' = 8.0, overflow: 'WebWindowOverflowMode' = 'shift', stick: 'bool' = False) -> None
  mode: WebWindowPlacementMode
  placement: WebWindowPlacementName | None = None
  position: tuple[float, float] | None = None
  container: WebWindowPlacementContainer = 'area'
  margin: tuple[float, float] = (0.0, 0.0)
  offset: tuple[float, float] = (0.0, 0.0)
  padding: float = 8.0
  overflow: WebWindowOverflowMode = 'shift'
  stick: bool = False

window: combine declarations

window
Public definitions
def window(app: 'WebWindowApp', *, size: 'WebWindowSize', title: 'str | None' = None, placement: 'WebWindowPlacement | None' = None, browser_state: 'WebBrowserStateSpec | None' = None, transparent: 'bool | None' = None, external_files: 'WebExternalFilesSpec | None' = None, resource_io: 'WebResourceIOSpec | None' = None, debug_label: 'str | None' = None) -> 'WebWindowSpec'
Parameter Purpose
app, size Required values from page-source and window_size functions, not a URL string with an arbitrary dictionary.
title Optional title, default None.
placement Optional placement, default None. Supply it for an explicit initial position.
browser_state Optional browser storage scope, defaulting to plugin scope; see below.
transparent Defaults to None, allowing the local page hint to decide. Explicit True/False takes precedence. Visual transparency and click-through are separate; also configure Page interaction markers.
external_files, resource_io Default None, mutually exclusive, and only for local-page user file interaction. These are declarations, not file paths. See File import and File export; for tools, see Page file-tool reference.
debug_label Optional diagnostic label, default None. Does not determine window keys or add-on identity.

Returns WebWindowSpec. Invalid pages, dimensions, placement, or conflicting file policies fail. Fix declarations before opening; ignoring exceptions does not yield a partially valid window.

View all return-type fields
WebWindowSpec
Public definitions
class WebWindowSpec (dataclass frozen slots):
  __init__(app: 'WebWindowApp', size: 'WebWindowSize', title: 'str | None' = None, placement: 'WebWindowPlacement | None' = None, browser_state: 'WebBrowserStateSpec | None' = None, transparent: 'bool | None' = None, external_files: 'WebExternalFilesSpec | None' = None, resource_io: 'WebResourceIOSpec | None' = None, debug_label: 'str | None' = None) -> None
  app: WebWindowApp
  size: WebWindowSize
  title: str | None = None
  placement: WebWindowPlacement | None = None
  browser_state: WebBrowserStateSpec | None = None
  transparent: bool | None = None
  external_files: WebExternalFilesSpec | None = None
  resource_io: WebResourceIOSpec | None = None
  debug_label: str | None = None

browser_state: browser storage scope

browser_state
Public definitions
def browser_state(kind: 'WebBrowserStateKind' = 'plugin', name: 'str | None' = None) -> 'WebBrowserStateSpec'

Returns WebBrowserStateSpec. kind defaults to plugin and controls cookie, localStorage, and cache reuse. It does not widen resource, action, or page permissions.

  • plugin: shared within the add-on (default).
  • client: separate per client.
  • window: separate per real window instance, useful for multi-region isolation.
  • ephemeral: temporary browser state, not persistent named storage.
  • named: an explicit named scope within one add-on, requiring nonempty name. Other kinds reject name.
View all return-type fields
WebBrowserStateSpec
Public definitions
class WebBrowserStateSpec (dataclass frozen slots):
  __init__(kind: 'WebBrowserStateKind' = 'plugin', name: 'str | None' = None) -> None
  kind: WebBrowserStateKind = 'plugin'
  name: str | None = None

area_target: choose editor regions

area_target
Public definitions
def area_target(scope: 'WebAreaScope' = 'current', *, area_type: 'str | None' = None, space_type: 'str | None' = None, tree_type: 'str | None' = None, existing: 'WebExistingPolicy' = 'error') -> 'WebAreaTarget'

Returns WebAreaTarget for open_window's target, not the window declaration. scope defaults to current for the context region; same_type matches visible, bindable regions of the same type across windows in this Blender process.

area_type, space_type, and tree_type default to None. For same_type, omitted filters are inferred from the current region. Omitting tree_type in the shader editor does not match all node trees. There is no special value to explicitly disable one inferred filter.

existing defaults to error on conflicts. reuse reuses a surviving instance only for the same client, logical key, and region. With target, keep replace_existing False and use existing rather than combining strategies.

View all return-type fields
WebAreaTarget
Public definitions
class WebAreaTarget (dataclass frozen slots):
  __init__(scope: 'WebAreaScope' = 'current', area_type: 'str | None' = None, space_type: 'str | None' = None, tree_type: 'str | None' = None, existing: 'WebExistingPolicy' = 'error') -> None
  scope: WebAreaScope = 'current'
  area_type: str | None = None
  space_type: str | None = None
  tree_type: str | None = None
  existing: WebExistingPolicy = 'error'

open_window: open and inspect results

plugin.open_window(window_key, spec, *, target=None, replace_existing=False) Returns WebWindowOpenResult. window_key must be stable and nonempty. Without target, an existing key fails by default. replace_existing=True replaces only this client's window and is not a toggle.

Place inside an existing operator's execute; plugin and spec are already prepared
python
result = plugin.open_window("main", spec)
if not result.ok:
    self.report({"ERROR"}, result.message or "窗口未能打开")
    if result.hint:
        self.report({"WARNING"}, result.hint)
    return {"CANCELLED"}
return {"FINISHED"}

Success means required host entry points were activated; verify actual page scripts and application state separately. Failed multi-instance preflight opens none. Failure after successful preflight can leave already opened instances, so overall failure does not imply no windows exist.

View all return-type fields
WebWindowOpenResult
Public definitions
class WebWindowOpenResult (dataclass frozen slots):
  __init__(ok: 'bool', window_key: 'str', state: 'WebWindowState | None', error: 'WebErrorKind | None' = None, message: 'str' = '', hint: 'str | None' = None, logical_window_key: 'str | None' = None, instances: 'tuple[WebWindowInstance, ...]' = ()) -> None
  ok: bool
  window_key: str
  state: WebWindowState | None
  error: WebErrorKind | None = None
  message: str = ''
  hint: str | None = None
  logical_window_key: str | None = None
  instances: tuple[WebWindowInstance, ...] = ()
WebWindowInstance
Public definitions
class WebWindowInstance (dataclass frozen slots):
  __init__(ok: 'bool', logical_window_key: 'str', window_key: 'str', state: 'WebWindowState | None', target_index: 'int', target: 'WebAreaSummary | None', action: 'WebWindowInstanceAction | None' = None, error: 'WebErrorKind | None' = None, message: 'str' = '') -> None
  ok: bool
  logical_window_key: str
  window_key: str
  state: WebWindowState | None
  target_index: int
  target: WebAreaSummary | None
  action: WebWindowInstanceAction | None = None
  error: WebErrorKind | None = None
  message: str = ''
WebAreaSummary
Public definitions
class WebAreaSummary (dataclass frozen slots):
  __init__(area_type: 'str | None', space_type: 'str | None', tree_type: 'str | None', is_current: 'bool' = False) -> None
  area_type: str | None
  space_type: str | None
  tree_type: str | None
  is_current: bool = False
  • ok: true only if all instances succeed; do not inspect only the primary state.
  • window_key / state: real key and state of the primary instance; logical_window_key is the logical group key.
  • error / message / hint: failure category, message, and optional hint. Multi-instance summaries use the first failed instance.
  • instances: per-instance ok, real key, state, target_index, and target summary. action may be opened, reused, or None. Inspect each result; state is not guaranteed on every item.
  • target The target summary includes area/space/tree types and is_current, not a Blender region object.

Use returned real keys for multi-instance records. Do not construct them or assume restart stability. For complete toggle behavior, read Choose how users open the interface.

close_window and close_windows

plugin.close_window(window_key, *, reason="window_close") closes one real window; plugin.close_windows(logical_window_key, *, reason="window_close") closes the client's logical group. reason is a string normally left at its default. Both return WebWindowCloseResult.

View all return-type fields
WebWindowCloseResult
Public definitions
class WebWindowCloseResult (dataclass frozen slots):
  __init__(ok: 'bool', window_key: 'str', closed: 'bool', error: 'WebErrorKind | None' = None, message: 'str' = '', hint: 'str | None' = None, logical_window_key: 'str | None' = None, instances: 'tuple[WebWindowCloseInstance, ...]' = ()) -> None
  ok: bool
  window_key: str
  closed: bool
  error: WebErrorKind | None = None
  message: str = ''
  hint: str | None = None
  logical_window_key: str | None = None
  instances: tuple[WebWindowCloseInstance, ...] = ()
WebWindowCloseInstance
Public definitions
class WebWindowCloseInstance (dataclass frozen slots):
  __init__(ok: 'bool', logical_window_key: 'str', window_key: 'str', closed: 'bool', error: 'WebErrorKind | None' = None, message: 'str' = '', hint: 'str | None' = None) -> None
  ok: bool
  logical_window_key: str
  window_key: str
  closed: bool
  error: WebErrorKind | None = None
  message: str = ''
  hint: str | None = None

Check ok before closed. ok=True, closed=False may mean no registered window exists to close; ok=False means closing failed. Do not treat it as not open and create another window. For groups, inspect each instance's ok, closed, error, message, and hint to catch partial failures.

Client ownership limits window keys. close_window neither interprets a group key as close-all nor closes other clients' windows. Closing does not dispose the whole client; disabling still requires Client cleanup.

Add-on image dragging

plugin.begin_drag(window_key, preview=..., mode="release") starts an image drag from a real window owned by this client. preview is a WebDragPreview; its local image is copied at the start. size and offset use CSS pixels, and opacity ranges from 0 to 1.

View all return-type fields
WebDragPreview
Public definitions
class WebDragPreview (dataclass frozen slots):
  __init__(path: 'Path | str', size: 'tuple[float, float]' = (180.0, 180.0), opacity: 'float' = 0.65, offset: 'tuple[float, float]' = (18.0, -18.0)) -> None
  path: Path | str
  size: tuple[float, float] = (180.0, 180.0)
  opacity: float = 0.65
  offset: tuple[float, float] = (18.0, -18.0)
WebDragState
Public definitions
class WebDragState (dataclass frozen slots):
  __init__(drag_id: 'str', phase: "Literal['dragging', 'dropped', 'cancelled']", target: 'WebDragTarget | None' = None, reason: 'str' = '') -> None
  drag_id: str
  phase: Literal['dragging', 'dropped', 'cancelled']
  target: WebDragTarget | None = None
  reason: str = ''
WebDragTarget
Public definitions
class WebDragTarget (dataclass frozen slots):
  __init__(window_pointer: 'int', area_pointer: 'int', area_type: 'str', x: 'float', y: 'float', over_web: 'bool' = False, window_key: 'str | None' = None, web_x: 'float | None' = None, web_y: 'float | None' = None, region_pointer: 'int | None' = None) -> None
  window_pointer: int
  area_pointer: int
  area_type: str
  x: float
  y: float
  over_web: bool = False
  window_key: str | None = None
  web_x: float | None = None
  web_y: float | None = None
  region_pointer: int | None = None

release mode continues a left-button press that started in this Web window and is still held. It ends on release; starting after asynchronous preparation is rejected if the button is already released. click mode ends on the next left-button press. Esc, right-click, or window deactivation cancels it. Dragging stays within the original Blender window; cross-window and desktop dragging are not promised.

begin_drag returns WebDragState. Inspect it with plugin.drag_state(drag_id) or cancel it with plugin.cancel_drag(drag_id). phase is dragging, dropped, or cancelled; unknown or cleared identifiers return None. dropped means the gesture ended. Target acceptance, data copying, and Blender changes remain the add-on's responsibility.

target may be absent. x/y use physical pixels in the target editor content area, with a bottom-left origin. web_x/web_y use CSS pixels with a top-left origin. over_web indicates a Web hit; window_key and Web coordinates are provided only for this client's own Web windows. Window and area pointers are transient and must not be persisted.

Only one such drag can be active in the process. Each client retains its active or most recent terminal state, replaced by the next drag. Handle a terminal state once and stop polling to avoid duplicate business objects. Closing the owning window, reloading the host, switching files, or disposing the client cancels it and releases the preview. This API is separate from numeric page transforms and external file imports.

WebBrowser and window state

plugin.browser(window_key) Returns WebBrowser for a real window key. Obtaining controls does not prove the window exists; calls may still fail.

WebBrowser
Public definitions
class WebBrowser (dataclass frozen slots):
  back(self) -> 'WebWindowState'
  forward(self) -> 'WebWindowState'
  navigate(self, url: 'str') -> 'WebWindowState'
  reload(self) -> 'WebWindowState'
  state(self) -> 'WebWindowState'
  stop(self) -> 'WebWindowState'

state reads a snapshot; back/forward navigate history; reload reloads the page; stop stops loading rather than closing. navigate accepts a URL, but public navigation is frozen and is not a new remote-integration entry point.

WebWindowState
Public definitions
class WebWindowState (dataclass frozen slots):
  __init__(status: 'str', url: 'str | None', title: 'str | None', loading: 'bool', can_go_back: 'bool', can_go_forward: 'bool', error: 'WebErrorKind | None', message: 'str', hint: 'str | None' = None) -> None
  status: str
  url: str | None
  title: str | None
  loading: bool
  can_go_back: bool
  can_go_forward: bool
  error: WebErrorKind | None
  message: str
  hint: str | None = None

All methods return WebWindowState: status is a string; url/title may be None; loading indicates loading; can_go_back/can_go_forward describe history; error/message/hint describe failure. State reflects received events, not a promise that every script finished.

Browser controls may raise WebOperationError; also inspect error in returned state. For complete client signatures, see Framework entry points and lifecycle. Do not replace public state with internal session access.

Definitions are generated from the public baseline; behavior is checked against declaration, entry-point, and input documentation.

Back to API reference · All topics