opcua-asyncio: OPC UA Client and Server for Python
OPC UA library for python >= 3.10
At a glance
- What is it?
- opcua-asyncio is a pure Python OPC UA library for Python 3.10 and later, with asynchronous client and server APIs plus a synchronous wrapper. It suits applications that need node access, subscriptions, events, history, methods, or encryption without moving to a native OPC UA stack.
- Who is it for?
- Adopt opcua-asyncio when an application needs an asyncio-native OPC UA client or server, Python 3.10 or later, and access to common services such as subscriptions, events, history, methods, and encryption. Do not adopt it when WebSocket transport, the XML protocol, session restore, alarms, localized text, or automatic reconnection is a firm requirement.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 13 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why opcua-asyncio Serves Industrial Python Applications
opcua-asyncio addresses applications that need to communicate with OPC UA servers or expose OPC UA server behavior from Python. Its intended users are developers already familiar with Python, `asyncio`, `async` and `await`, and asyncio Tasks. The package supports Python 3.10 and later, as declared by `requires-python = ">=3.10"` in `pyproject.toml`.
The project is intended for more than a simple read operation. Its client capabilities include sessions, browsing, node lookup, data reads and writes, subscriptions, data-change and event subscriptions, method calls, history reads, user and password authentication, certificate login, encryption, and node removal. The server side can create sessions and address-space nodes, expose attributes, publish data-change and event notifications, execute methods, handle certificates, and retain history.
This is particularly relevant to services that need several nonblocking connections without manually coordinating locks around synchronous client calls. The README says asynchronous programming can reduce locking requirements and may provide performance improvements, but it does not promise a fixed latency or throughput improvement for every deployment.
The package supports both a high-level API and access to OPC UA-defined structures at a lower level. That matters when an application starts with `Client`, `Node`, `Subscription`, and `Server`, then needs a protocol operation not exposed conveniently by those abstractions. According to the README, low-level UA calls and high-level objects can be mixed in the same application.
The Async Client, Node, and Subscription Data Flow
The central client abstraction is `Client`. According to the README, it manages connections, sessions, and basic address-space services. A connection can be scoped with the asynchronous context manager, which invokes connection and disconnection around the `async with` block. Inside that block, the client resolves a node by NodeId and awaits `read_value()`.
That flow has three visible layers. `Client` handles the endpoint and session. `Node` represents an address-space element and exposes data-access operations. The asynchronous operation is awaited by the calling program, allowing it to continue processing other asyncio Tasks while an OPC UA service is pending.
`Subscription` manages monitored items. The documented client feature set includes data-change subscriptions and event subscriptions. This separates recurring server notifications from ordinary node reads: a program can request a current value with `read_value()` or ask the server to send changes through a monitored item. The README does not provide a complete subscription initialization example in its installation section, so its `examples/client-subscription.py` and `examples/client-events.py` files are the documented references for those flows.
The protocol implementation is also accessible below these objects. The README says most low-level code is autogenerated from the XML specification, and the repository places protocol code under the `opcua` directory. Based on `pyproject.toml`, dependencies include `cryptography`, `aiosqlite`, `anyio`, `python-dateutil`, `pytz`, `sortedcontainers`, and `typing-extensions`. The project identifies itself as a pure Python implementation, which can simplify deployment, although its optional or unused code paths still depend on the operating environment.
Installing asyncua and Performing a First Client Read
The README gives `uv` as its installation route. The PyPI package name is `asyncua`, while the repository and import namespace are `opcua-asyncio` and `asyncua`. Installing the distribution makes the `asyncua` package and command-line entry points available.
Install it in an environment managed by `uv`:
uv pip install asyncuaThe next documented example assumes an OPC UA server at `opc.tcp://localhost:4840/freeopcua/server/`. It connects through `Client`, obtains node `i=85`, and awaits its value:
from asyncua import Client
async with Client(url='opc.tcp://localhost:4840/freeopcua/server/') as client:
node = client.get_node('i=85')
value = await node.read_value()The README example places these operations inside an endless loop to represent an ongoing client application. A finite first check would stop after `value` has been obtained, but the endpoint and NodeId still have to exist on the server being contacted. If no server is available at that URL, connection or session establishment is the expected point to fail.
The README also documents `connect` and `disconnect` for code that should manage the lifecycle explicitly. The context manager is preferable when the entire client scope should be bounded cleanly, while explicit methods fit applications that control lifecycle transitions across different functions.
Server Construction, Address-Space Caching, and Operations
The `Server` class creates OPC UA server instances. The README lists address-space generation from a specification, node addition and removal, attribute reads and writes, browsing, methods, events, data-change notifications, certificate handling, encryption, and history for data changes and events. This gives the package a role on both sides of an integration, which is useful for prototypes, gateways, simulators, and applications that need to test client behavior against a locally created endpoint.
The repository includes minimal client and server examples under `examples/`, and the README identifies `examples/client-minimal.py` and `examples/server-minimal.py` as starting points. It also lists command-line tools for discovery, browsing, history, reading, writing, method calls, subscriptions, an interactive client, and a demo server. The installed script names come from `[project.scripts]` in `pyproject.toml`, including `uabrowse`, `uacall`, `uaclient`, `uadiscover`, `uahistoryread`, `uals`, `uaread`, `uaserver`, `uasubscribe`, and `uawrite`.
Startup cost matters on constrained devices. The README states that constructing the standard address space from XML is the slowest part of server startup. Passing a cache-file path to the server constructor creates a shelve on the first startup and reuses it on later starts. Its Raspberry Pi Model B example reports about 3.5 seconds with the cache versus 125 seconds without it. That is a documented project example, not a guarantee for other hardware or address spaces.
The shipped server user model is intentionally basic. The README describes one existing `admin` user, which can be disabled, while other users are read-only. It also states that a stronger user and password security model is not implemented.
Transport Gaps That Can Rule Out opcua-asyncio
The largest adoption constraint is the list of unsupported protocol and server features. The README explicitly lists WebSocket, the XML protocol, and localized text as not implemented on both client and server sides. Server support also excludes session restore, alarms, and views. Automatic reconnection is listed as possibly missing on the client side, so an application requiring unattended recovery after connection loss should not infer that behavior from the existence of a separate `examples/client-reconnect.py` file.
This is a genuine feature boundary, not merely a documentation omission. The repository includes `examples/client-reconnect.py`, but the client feature list still describes automatic reconnection with “maybe.” The example may demonstrate application-level handling, yet the README does not specify its guarantees, timing, or recovery semantics.
The repository also contains deployment files that require careful review. `pyproject.toml` and the README require Python 3.10 or later, while the repository's `Dockerfile` starts from `python:3.8` and installs `asyncua`. That base image does not match the package metadata. Anyone considering the Dockerfile should resolve this mismatch before treating the image as a supported deployment path.
The project also warns that bugs and API changes will happen. It specifically notes API changes before any 1.0 release and describes earlier renames such as `get_xx` to `read_xx` and `set_xx` to `write_xxx`. The current version is `2.1.0`, but applications should still pin and review releases rather than assuming permanent API compatibility.
Synchronous Use and the Alternative to python-opcua
opcua-asyncio is based on `python-opcua`, and it retains a mostly unchanged API while making most methods asynchronous. It also provides a synchronous wrapper in `asyncua/sync.py`. That wrapper allows existing synchronous Python code to use the async implementation without converting the entire program to `async` and `await`.
The direct alternative is to use `python-opcua` itself. The practical difference is the execution model. `opcua-asyncio` centers its client and server APIs on Python's asyncio framework, while its synchronous wrapper creates a bridge for code that cannot yet adopt async control flow. The README says method renames were made to align more closely with OPC UA naming conventions, so code migrating from the synchronous project must account for API differences rather than changing only the import.
Another choice is to remain at the low-level UA structures exposed by this library. That is not a separate implementation, but it is a different use of the same package. High-level classes make common reads, writes, subscriptions, and server construction concise. Direct UA calls are the documented fallback when an application needs protocol structures that are awkward through the high-level interface.
The README says the binary protocol implementation has been exercised with several OPC UA stacks and names client and server implementations from FreeOpcUa, Prosys, Kepware, Beckhoff, WinCC, B&R, UAExpert, and Quick OPC. It also reports coverage above 95%, with much of the uncovered code described as autogenerated and not currently in use. These are repository statements rather than an independent compatibility certification. Target-server behavior still needs verification against the exact release.
Release Cadence, Dependencies, and LGPLv3+ Obligations
Maintenance status is supported by recent repository activity. The last push was on 2026-10-10, and release `v2.1.0` was published on 2026-10-06 after `v2.0.1` and `v2.0`. That recency indicates ongoing code movement, but it does not remove the project's warning about API changes.
The upgrade cost is shaped by the package's dependencies and protocol surface. `pyproject.toml` declares `cryptography>=45.0.0` plus `aiosqlite`, `anyio`, `python-dateutil`, `pytz`, `sortedcontainers`, and `typing-extensions`. Python below 3.12 also receives `wait_for2`. Development dependencies include `pytest`, `pytest-asyncio`, `coverage`, `mypy`, and `ruff`, but they are not listed as normal installation requirements.
The declared license is `GNU Lesser General Public License v3 or later`, with the SPDX-style license text `LGPL-3.0`. Applications that modify or redistribute the library must assess how the LGPL obligations apply to their distribution, linking, notices, and source availability. This is a compliance consideration, not legal advice. Review `COPYING` and the terms for the exact version selected.
For upgrades, pin the package version, run the project's test suite in the target Python version, and retest against the real OPC UA server. The README does not document a formal compatibility matrix for every recent release, so release notes, project tests, and server-specific examples are the available checks.
Editorial conclusion
Adopt opcua-asyncio when an application needs an asyncio-native OPC UA client or server, Python 3.10 or later, and access to common services such as subscriptions, events, history, methods, and encryption. Do not adopt it when WebSocket transport, the XML protocol, session restore, alarms, localized text, or automatic reconnection is a firm requirement. Verify those feature boundaries against the target OPC UA server, the Python version in the deployment image, and the project version being installed before committing an application.
Frequently asked questions
How do I install opcua-asyncio for Python?
Install the PyPI distribution with `uv pip install asyncua`. The package requires Python 3.10 or later, although the repository's Dockerfile uses `python:3.8` and should not be treated as aligned with that requirement.
Does opcua-asyncio support a synchronous API?
Yes. The repository provides a synchronous wrapper in `asyncua/sync.py` for use from synchronous code, although most of the underlying API is asynchronous.
Does opcua-asyncio support WebSocket and automatic reconnection?
The README lists WebSocket as not implemented. It describes automatic reconnection as possibly missing, so an application that requires it should verify the exact release and recovery behavior before adoption.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/freeopcua-opcua-asyncio)Was this useful?