Skip to main content

declarative-opcua-server

declarative-opcua-server creates an opinionated synchronous OPC UA server from three flat dictionaries of annotated Python functions. It is intended for small adapters that need a predictable Status, Parameters, and Methods address space without building nodes manually.

Installation

python -m pip install --upgrade pip
python -m pip install declarative-opcua-server

Python 3.8.3 and later are supported. The distribution selects a compatible asyncua release for the active Python version and caps the final cryptography line that supports Python 3.8. Upgrade the old pip bundled with Python 3.8.3 before installing.

Example

import time
import typing

import declarative_opcua_server

state = {"height": 10.0}


def read_height() -> float:
    return state["height"]


def write_height(height: float) -> None:
    state["height"] = height


def load_program(program: str) -> str:
    return "Loaded " + program


def list_programs() -> typing.List[str]:
    return ["Main.urp", "Production/PickPart.urp"]


server = declarative_opcua_server.create_server(
    status_interface={"ActualHeight": read_height},
    parameter_interface={"TargetHeight": write_height},
    method_interface={"LoadProgram": load_program, "ListPrograms": list_programs},
    endpoint="opc.tcp://127.0.0.1:4840/",
    namespace="urn:example:robot",
    root_object="Robot",
)

with server:
    while True:
        time.sleep(1.0)

create_server() returns a plain, unstarted asyncua.sync.Server. Callers retain the normal start(), stop(), and context-manager lifecycle.

Refreshing methods

update_method_interface() applies a complete replacement for the Methods folder without restarting the server. It validates every new callable before changing the address space, preserves nodes whose callable object and signature are unchanged, removes obsolete nodes, and adds or replaces changed nodes.

The refresh operation can itself be exposed as a method:

import typing

server_holder: typing.Dict[str, typing.Any] = {}


def run_main() -> None:
    print("run Main.urp")


def refresh_methods() -> typing.List[str]:
    method_interface = {"RefreshMethods": refresh_methods, "StartProgram_Main": run_main}
    declarative_opcua_server.update_method_interface(server_holder["server"], method_interface)
    return sorted(method_interface)


server = declarative_opcua_server.create_server(
    status_interface={},
    parameter_interface={},
    method_interface={"RefreshMethods": refresh_methods},
)
server_holder["server"] = server

Method callbacks run on a worker thread, so RefreshMethods() completes only after the replacement is visible to subsequent OPC UA browsing. The mapping is the complete desired interface, not a patch; keep the refresh callable and any fixed methods in every replacement.

Address space

The example creates:

Objects/
    Robot/
        Status/
            ActualHeight
        Parameters/
            TargetHeight
        Methods/
            LoadProgram(program) -> String
            ListPrograms() -> String[]

The selected dictionary defines each callable's role:

  • A status getter accepts no arguments and declares a return type. It becomes a polled read-only variable.
  • A parameter setter accepts one annotated argument and returns no value. It becomes a writable variable whose accepted writes invoke the setter.
  • A method exposes required annotated arguments as OPC UA inputs and an annotated return as an optional output.

Defaulted method arguments are treated as bound application configuration rather than OPC UA inputs. This makes configured functools.partial callables useful without adding wrapper functions.

Supported annotations

Python annotation OPC UA variant type
bool Boolean
int Int64
float Double
str String
bytes ByteString
typing.List[T] One-dimensional T

T must be one of the supported scalar annotations. Unsupported or unresolved signatures fail during server creation.

Scope and security

The package intentionally does not provide arbitrary folders, custom node classes, stable NodeId configuration, events, application schemas, or protocol adapters. Applications requiring a general OPC UA framework should use asyncua directly.

The current server defaults to anonymous access and NoSecurity. It is suitable for controlled development and isolated industrial networks; certificate and authentication configuration should be added before use on an untrusted network.

Development

From this package directory:

python -m pip install -e ".[dev]"
python -m pytest tests
python -m mypy
python -m build
python -m twine check dist/*

Tests use a real asyncua client to verify browsing, status polling, parameter writes, typed method calls, and lifecycle behavior.

Release history is recorded in the changelog. The gateway integration is validated independently in ur_dashboard_to_opcua_gateway.

License

This project is licensed under the MIT License. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

declarative_opcua_server-0.3.0.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

declarative_opcua_server-0.3.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file declarative_opcua_server-0.3.0.tar.gz.

File metadata

  • Download URL: declarative_opcua_server-0.3.0.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for declarative_opcua_server-0.3.0.tar.gz
Algorithm Hash digest
SHA256 3bc7befb92dcff9711f04ed12e4fcca86f513f6205f7e362755299b957257bfa
MD5 ede2b247d11e0a53811107da0944d766
BLAKE2b-256 dc59aba9f1f3a62b32cdec3e35b73338090335122c05b546b67be802e1cf2b01

See more details on using hashes here.

Provenance

The following attestation bundles were made for declarative_opcua_server-0.3.0.tar.gz:

Publisher: release.yml on CraigBuilds/declarative-opcua-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file declarative_opcua_server-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for declarative_opcua_server-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 301f8e657eee7f3b41d561ee9b92937e247cccf34c9ed069fab67d5aa0d7ccf3
MD5 b71e539ff48cf91f656f364bf46756f1
BLAKE2b-256 216372b4ca2ea348f913eeea4d7502d3a8503248305994d5b2492a5b7ec99d49

See more details on using hashes here.

Provenance

The following attestation bundles were made for declarative_opcua_server-0.3.0-py3-none-any.whl:

Publisher: release.yml on CraigBuilds/declarative-opcua-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.0

2 files

This release

0.3.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page