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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bc7befb92dcff9711f04ed12e4fcca86f513f6205f7e362755299b957257bfa
|
|
| MD5 |
ede2b247d11e0a53811107da0944d766
|
|
| BLAKE2b-256 |
dc59aba9f1f3a62b32cdec3e35b73338090335122c05b546b67be802e1cf2b01
|
Provenance
The following attestation bundles were made for declarative_opcua_server-0.3.0.tar.gz:
Publisher:
release.yml on CraigBuilds/declarative-opcua-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
declarative_opcua_server-0.3.0.tar.gz -
Subject digest:
3bc7befb92dcff9711f04ed12e4fcca86f513f6205f7e362755299b957257bfa - Sigstore transparency entry: 2219600423
- Sigstore integration time:
-
Permalink:
CraigBuilds/declarative-opcua-server@13c95da4341a21c00243131a5f5cb13adf9e9e2f -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/CraigBuilds
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@13c95da4341a21c00243131a5f5cb13adf9e9e2f -
Trigger Event:
push
-
Statement type:
File details
Details for the file declarative_opcua_server-0.3.0-py3-none-any.whl.
File metadata
- Download URL: declarative_opcua_server-0.3.0-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
301f8e657eee7f3b41d561ee9b92937e247cccf34c9ed069fab67d5aa0d7ccf3
|
|
| MD5 |
b71e539ff48cf91f656f364bf46756f1
|
|
| BLAKE2b-256 |
216372b4ca2ea348f913eeea4d7502d3a8503248305994d5b2492a5b7ec99d49
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
declarative_opcua_server-0.3.0-py3-none-any.whl -
Subject digest:
301f8e657eee7f3b41d561ee9b92937e247cccf34c9ed069fab67d5aa0d7ccf3 - Sigstore transparency entry: 2219600485
- Sigstore integration time:
-
Permalink:
CraigBuilds/declarative-opcua-server@13c95da4341a21c00243131a5f5cb13adf9e9e2f -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/CraigBuilds
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@13c95da4341a21c00243131a5f5cb13adf9e9e2f -
Trigger Event:
push
-
Statement type: