Skip to main content

nucosObs

PyPI version Tests License: MIT

nucosObs is an observer-observable framework based on asyncio.

Status

The project supports Python 3.11 through 3.13. Continuous integration runs the full pytest suite and builds a wheel for each supported version.

Install

pip install nucosObs

Documentation

A comprehensive user guide covering beginner to expert workflows is available:

➡️ User Guide — docs/USER_GUIDE.md

The guide includes tutorials for basic observer patterns, scheduling, threaded handlers, websocket interfaces, authentication, multi-tenant runtimes, error handling, and production deployments.

The project also ships a small but handy toolbox to build applications using the observer/observable pattern with asyncio. It contains helper classes for observers, observables and a couple of interfaces (stdin, websockets and aiohttp based websockets) to communicate with running tasks.

Example

import asyncio as aio

from nucosObs import main_loop
from nucosObs.observable import Observable
from nucosObs.observer import Observer


class HelloObserver(Observer):
    async def say(self):
        print("Hello")


A = Observable()
O = HelloObserver("O", A)
aio.ensure_future(A.put({"name": "say"}))
main_loop([])

See the examples directory for more advanced usage.

Event Model

An observable delivers each event to every registered observer queue. Events can be dictionaries or command strings. Dictionary events use this shape:

{"name": "method_name", "args": ["first argument", "second argument"]}

Observers process regular async handlers sequentially. A {"action": "stop_observer"} event stops an observer after its active handler has completed.

Threaded Handlers

Use @inThread() for synchronous work that must not block the event loop. The handler runs in the runtime's thread pool. With callback=True, register an async callback for the bound handler in observer.callbacks; it runs after the threaded method finishes.

from nucosObs.observer import Observer, inThread


class Worker(Observer):
    @inThread()
    def calculate(self, value):
        return value * 2

Isolated Runtimes

The module-level main_loop() API remains available for existing programs. For multiple applications in one process, create a Runtime and pass it to each observable and observer. Each runtime owns its event loop, registries, debug state, and thread pool.

from nucosObs import Runtime
from nucosObs.observable import Observable
from nucosObs.observer import Observer


runtime = Runtime()
events = Observable(runtime=runtime)
worker = Worker("worker", events, runtime=runtime)
runtime.loop.create_task(events.put({"name": "calculate", "args": [21]}))
runtime.loop.create_task(events.put({"action": "stop_observer"}))
runtime.main_loop([])
runtime.close()

Websocket Authentication

Both websocket interfaces send an authentication challenge when doAuth=True. The configured authenticator must provide an async startAuth(message, websocket, nonce) method and return (connection_id, user). Returning a matching connection ID accepts the client; returning None rejects and closes it. Clients may send regular broker messages only after successful authentication.

Interfaces

An Interface is a bridge between the external world and the observable / observer system. It reads data from an external source (stdin, a network socket, another observable) and puts structured events into an Observable, which then dispatches them to all registered Observer instances.

Supported Interface Types

Interface Module Purpose
StdinInterface nucosObs.stdinInterface Reads commands from standard input (terminal)
TwoWayInterface nucosObs.twoWayInterface Routes events between named observables within the same process
WebsocketInterface nucosObs.websocketInterface WebSocket server/client using the websockets library
AiohttpWebsocketInterface nucosObs.aiohttpWebsocketInterface WebSocket server/client using the aiohttp framework

Websocket Backend Comparison

Feature WebsocketInterface AiohttpWebsocketInterface
Library websockets (lightweight) aiohttp (full web framework)
Use case Dedicated WebSocket server/client WebSocket alongside an HTTP server
TLS / SSL Yes (sslServer, sslClient) Yes (sslServer, sslClient)
Authentication Yes (doAuth) Yes (doAuth)
Heartbeat / ping No Yes (heartbeat)
Receive timeout No Yes (receive_timeout)
User-aware send Manual via connection dict send(msg, user) by username
Duplicate user handling Manual Built-in via connectedUser + closeSanely

Use WebsocketInterface when you need a simple, standalone WebSocket endpoint. Use AiohttpWebsocketInterface when you already run an aiohttp web application, need heartbeats and timeouts, or want user-aware message delivery.

Interface Lifecycle

  1. An interface reads or receives input (stdin line, WebSocket message, internal event).
  2. It converts the input into an event (dict or string).
  3. It calls await observable.put(event) to dispatch the event.
  4. All observers registered on that observable process the event.
  5. The interface handles shutdown via stop commands or connection closure.

Diagnostics

Run python -m nucosObs to print the installed package version, dependency versions, supported Python range, and default runtime state. Add --json for machine-readable output suitable for support reports.

License

Distributed under the MIT License.

Platforms

No specific platform dependency. Python 3.11 or later is required.

Testing

Install development dependencies with pip install -r requirements-dev.txt, then run the test suite with python -m pytest.

The repository runs this command in GitHub Actions on Python 3.11 through 3.13.

For a coverage-grounded view of current readiness and compatible next steps, see docs/FINAL_READINESS.md.

Contributing and Support

See CONTRIBUTING.md for the development workflow and CODE_OF_CONDUCT.md for community expectations. Report security vulnerabilities according to SECURITY.md; for general questions or reproducible bugs, open a GitHub issue.

Download files

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

Source Distribution

nucosobs-0.4.18.tar.gz (40.9 kB view details)

Uploaded Source

Built Distribution

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

nucosobs-0.4.18-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

Details for the file nucosobs-0.4.18.tar.gz.

File metadata

  • Download URL: nucosobs-0.4.18.tar.gz
  • Upload date:
  • Size: 40.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for nucosobs-0.4.18.tar.gz
Algorithm Hash digest
SHA256 0aa6cf00851020592f6af8689670c8acc776f28cf6dc6f48ae896a44209796f8
MD5 e5151828a7a623acd32f07273787031d
BLAKE2b-256 15747325c909975d32e9380b5cbdaddd73a9cf09b0f66a1f20097f6bd88cdfc8

See more details on using hashes here.

File details

Details for the file nucosobs-0.4.18-py3-none-any.whl.

File metadata

  • Download URL: nucosobs-0.4.18-py3-none-any.whl
  • Upload date:
  • Size: 17.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for nucosobs-0.4.18-py3-none-any.whl
Algorithm Hash digest
SHA256 3d6192dfa7e2ca76c061dd038421dcde53701ad4b9a5ea25f29e2124b80b2431
MD5 f4cbf02650cdcdd466dda8eff2870c8c
BLAKE2b-256 6c463fc280b3d49d6ee30fcff0f823ce96562a36255e2c7dff19c9485b5f07b5

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.4.18 This release

2 files

0.4.17

1 file

0.4.16

1 file

0.4.15

1 file

0.4.13

1 file

0.4.12

1 file

0.4.11

1 file

0.4.10

1 file

0.4.9

1 file

0.4.8

1 file

0.4.7

1 file

0.4.6

1 file

0.4.5

1 file

0.4.4

1 file

0.4.3

1 file

0.4.2

1 file

0.4.1

1 file

0.4.0

1 file

0.3.9

1 file

0.3.8

1 file

0.3.7

1 file

0.3.6

1 file

0.3.5

1 file

0.3.4

1 file

0.3.3

1 file

0.3.2

1 file

0.3.1

1 file

0.3.0

1 file

0.2.9

1 file

0.2.8

1 file

0.2.7

1 file

0.2.5

1 file

0.2.4

1 file

0.2.3

1 file

0.2.2

1 file

0.2.1

1 file

0.2.0

1 file

0.1.7

1 file

0.1.6

1 file

0.1.4

1 file

0.1.3

1 file

0.1.2

1 file

0.1.1

1 file

0.1.0

1 file

0.0.1

1 file

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