Quick Start (Python)
Looking for Rust? See Quick Start (Rust)
This tutorial demonstrates building a temperature monitoring system with HORUS using Python. Estimated time: 10 minutes.
What We're Building
A system with two components:
- Sensor - Generates temperature readings
- Monitor - Displays the readings
They'll communicate using HORUS's ultra-fast shared memory.
Step 1: Create a New Project
# Create a new Python HORUS project
horus new temperature-monitor -p
cd temperature-monitor
This creates:
main.py- Your code (we'll customize this)horus.toml- Project config (name, version, description).horus/- Build cache (packages, virtualenv)
Step 2: Write the Code
Replace main.py with this complete example:
import horus
#===========================================
# SENSOR NODE - Generates temperature data
#===========================================
def make_sensor():
temp = [20.0] # mutable state via list
def tick(node):
temp[0] += 0.1
node.send("temperature", temp[0])
return horus.Node(name="TemperatureSensor", tick=tick, rate=1, order=0,
pubs=["temperature"])
#============================================
# MONITOR NODE - Displays temperature data
#============================================
def monitor_tick(node):
temp = node.recv("temperature")
if temp is not None:
print(f"Temperature: {temp:.1f}\u00b0C")
monitor = horus.Node(name="TemperatureMonitor", tick=monitor_tick, rate=1, order=1,
subs=["temperature"])
#============================================
# MAIN - Run both nodes
#============================================
print("Starting temperature monitoring system...\n")
# Run forever (press Ctrl+C to stop)
horus.run(make_sensor(), monitor)
Step 3: Run It!
horus run
HORUS will automatically:
- Detect Python from
main.py - Set up the virtual environment if needed
- Execute your program
You'll see:
Starting temperature monitoring system...
Temperature: 20.1\u00b0C
Temperature: 20.2\u00b0C
Temperature: 20.3\u00b0C
Temperature: 20.4\u00b0C
...
Press Ctrl+C to stop.
Understanding the Code
Topics - Communication Channels
# Sending data (in the tick function)
node.send("temperature", value)
# Receiving data (in the tick function)
temp = node.recv("temperature")
Both use the same topic name ("temperature"). HORUS manages all shared memory operations automatically. Same API as Rust, but Pythonic.
The Node - Component Definition
Each component is a horus.Node with a tick function:
def make_sensor():
temp = [20.0]
def tick(node):
temp[0] += 0.1
node.send("temperature", temp[0])
return horus.Node(name="TemperatureSensor", tick=tick, rate=1,
pubs=["temperature"])
The tick function is your main logic, called every cycle. State lives in the closure (or as a plain class instance passed via tick=obj.tick).
Running Everything
# Create nodes with rate and order
sensor = make_sensor()
monitor = horus.Node(name="TemperatureMonitor", tick=monitor_tick,
rate=1, order=1, subs=["temperature"])
# Run all nodes (press Ctrl+C to stop)
horus.run(sensor, monitor)
Key configuration on horus.Node(...):
order=n- Set execution priority (lower = runs first)rate=n- Set tick frequency in Hzpubs/subs- Declare topic names
Running Nodes in Separate Processes
The example above runs both nodes in a single process. HORUS uses a flat namespace, so multi-process communication works automatically.
# Terminal 1: Run sensor
horus run sensor.py
# Terminal 2: Run monitor (automatically connects!)
horus run monitor.py
Both use the same topic name ("temperature") and communication just works.
Next Steps
Add More Features
1. Add a temperature alert:
def alert_tick(node):
temp = node.recv("temperature")
if temp is not None:
print(f"Temperature: {temp:.1f}\u00b0C")
if temp > 25.0:
print("WARNING: Temperature too high!")
2. Integrate with NumPy:
import numpy as np
import horus
def array_tick(node):
# Generate 100 sensor readings
readings = np.random.normal(22.0, 0.5, 100)
node.send("readings", readings.tolist())
sensor_array = horus.Node(name="SensorArray", tick=array_tick, rate=10,
pubs=["readings"])
Learn More
Core Concepts:
- Nodes - Deep dive into the Node pattern
- Topic - How ultra-fast communication works
- Scheduler - Priority-based execution
Python-Specific:
- Python Bindings - Full Python API reference
- Async Nodes - Using async/await with HORUS
- ML Utilities - TensorFlow/PyTorch integration
See More Examples:
- Python Examples - Real Python applications
- Choosing a Language - Rust vs Python comparison
Common Questions
Can I use pip packages?
Yes! Add them to horus.toml:
horus add numpy --source pypi
horus add torch --source pypi
Can I use async/await?
Yes! HORUS supports async nodes in Python:
async def async_tick(node):
data = await read_sensor_async()
node.send("sensor_data", data)
sensor = horus.Node(name="AsyncSensor", tick=async_tick, pubs=["sensor_data"])
See Async Nodes for details.
How do I stop the application?
Press Ctrl+C. The scheduler handles graceful shutdown automatically.
Where does the data go?
Data is stored in shared memory, managed automatically by HORUS. You never need to configure paths — horus_sys handles platform differences internally.
Troubleshooting
"ModuleNotFoundError: No module named 'horus'"
Install the HORUS Python bindings:
pip install horus-robotics
Or if using a virtual environment:
horus run # automatically installs dependencies
"Failed to create Topic"
Another program might be using the same topic name. Pick a unique name:
node.send("temperature_sensor_1", value)
Nothing prints
Make sure both nodes are passed to horus.run():
horus.run(make_sensor(), monitor)
What You've Learned
- How to create a Python HORUS project with
horus new -p - The functional
horus.Node(tick=fn)pattern - Using
node.send()andnode.recv()for communication - Running multiple nodes with
horus.run() - Sending and receiving messages in Python
Ready for More?
- Python API Reference for the full API
- Run the examples to see real applications
- Open the monitor to monitor your system visually
For issues, see the Troubleshooting Guide.
See Also
- Quick Start (Rust) - Build the same app in Rust
- Python API Reference - Full Python API documentation
- Python Examples - Real Python applications
- Choosing a Language - Rust vs Python comparison