Python OOCSI Client

The OOCSI Python client (oocsi-python) allows Python scripts to easily send and receive messages, subscribe to channels, synchronize variables, and participate in synchronous call-response services over the OOCSI network. It is ideal for data analysis, AI/machine learning prototyping, hardware interfacing (e.g., Raspberry Pi), and desktop automation.


Installation

Install the library using pip:

pip install oocsi

The source code and distribution details are available on GitHub: iddi/oocsi-python.


Connecting to OOCSI

To connect to an OOCSI server, import the OOCSI class and provide a client name and server address:

from oocsi import OOCSI

# Tip: Use '####' in the client name; the server will replace it with random numbers to guarantee a unique handle
oocsi = OOCSI('data_collector_####', 'localhost')

If connecting to a remote server on a custom port:

oocsi = OOCSI('data_collector_####', 'oocsi.example.com', 4444)

Sending Messages

You can send key-value data to a channel (for broadcasting) or directly to another client:

# Send data to a channel
oocsi.send('livingroom_lights', {
    'power': True,
    'brightness': 85,
    'color': '#FFAA00'
})

# Send data directly to an individual client
oocsi.send('display_device_1', {
    'notification': 'Doorbell rang!'
})

Receiving Messages

You can register event handlers using the @oocsi.event decorator:

# Handle messages from a channel
@oocsi.event('livingroom_lights')
def handle_lights(sender, recipient, data):
    print(f"Message from {sender}: {data}")
    if 'brightness' in data:
        print("Updated brightness to:", data['brightness'])

# Handle direct messages sent specifically to this client
@oocsi.event()
def handle_direct(sender, recipient, data):
    print(f"Direct message from {sender}: {data}")

Using Subscription Functions

Alternatively, you can subscribe with a callback function:

def process_message(sender, recipient, data):
    print(f"Received from {sender}: {data}")

oocsi.subscribe('livingroom_lights', process_message)

OOCSI Variables (State Synchronization)

OOCSI variables allow you to synchronize state automatically across multiple clients on a channel without manually drafting message payloads:

# Link a variable to the 'room_temperature' variable on channel 'home'
temp = oocsi.variable('home', 'room_temperature')

# Read current synchronized value
print("Current temperature:", temp.get())

# Update the value (automatically broadcasts the new state to all connected clients)
temp.set(22.5)

Synchronous Call-Response (RPC)

When you need an immediate answer from another client rather than fire-and-forget messaging, you can use the call-response pattern.

Providing a Service (Responder)

@oocsi.responder('weather_service', 'get_forecast')
def provide_forecast(data):
    city = data.get('city', 'Eindhoven')
    return {'city': city, 'forecast': 'Sunny', 'temp': 23}

Calling a Service

# Call service on channel 'weather_service' with operation 'get_forecast' (timeout in seconds)
response = oocsi.call('weather_service', 'get_forecast', {'city': 'Amsterdam'}, timeout=2.0)

if response:
    print("Forecast response:", response)
else:
    print("Service request timed out.")

Complete Example

import time
from oocsi import OOCSI

# Connect with a randomized handle
oocsi = OOCSI('weather_station_####', 'localhost')

# Subscribe to incoming sensor data
@oocsi.event('environment')
def on_environment(sender, recipient, data):
    print(f"[{sender}] Temperature: {data.get('temp')} C, Humidity: {data.get('humidity')}%")

# Publish simulated readings
try:
    while True:
        oocsi.send('environment', {
            'temp': 21.4,
            'humidity': 55.0
        })
        time.sleep(5)
except KeyboardInterrupt:
    print("Stopping OOCSI client...")
    oocsi.stop()

Copyright © 2013-2026 Mathias Funk.

This site uses Just the Docs, a documentation theme for Jekyll.