Python Guide
Overview
This page shows how to install Python dependencies, run the interactive Python examples, and use the runtime context and secure communication wrappers in application code.
The Python SDK provides a modern, clean, pythonic interface (IoTAuthContext, SecureClient, and SecureServer) for requesting session keys from Auth, completing entity-to-entity secure handshakes, and exchanging encrypted messages over TCP connections.
Install Python dependencies
Before running examples or applications using the Python SDK, create a virtual environment inside entity/python/ and install the package in editable mode:
cd entity/python
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
This installs the iotauth package and its required dependencies (cryptography) into your virtual environment.
Configuration formats
The Python API accepts two entity config formats:
- C-style dotted properties (
key=value). - Node-style JSON.
The parser detects JSON when the first non-whitespace character is {, so either format can use the .config extension.
Python does not require one format over the other. Whichever format you choose, verify the entity name, Auth and target addresses, cryptography settings, and credential paths.
Relative credential and key paths use different anchors:
| Format | Relative path anchor |
|---|---|
| C-style properties | The directory containing the config file. |
| Node-style JSON | The current working directory from which the Python process is started. |
Absolute paths work in both formats. When copying a config, update its credential and key paths for the applicable anchor.
Run the repository Python example
The following setup applies to the Python client and server examples included in the iotauth repository.
It is not required when using the Python API with your own configuration and credentials.
Prepare the example credentials and configs
Run the repository generation script to create the credentials used by the examples and the Node-style JSON configs:
cd examples
./generateAll.sh
generateAll.sh does not generate dedicated Python config files.
The repository includes checked-in Python properties fixtures at:
entity/python/examples/configs/py_client.config
entity/python/examples/configs/py_server.config
For the repository example, you can use those fixtures, copy and adapt a checked-in C-style properties config, or use a generated Node-style JSON config from entity/node/example_entities/configs/.
Verify the credential paths using the format-specific path rules above.
Start Auth and the Python entities
Start the Auth 101 server in one terminal:
cd auth/auth-server
mvn clean install
java -jar target/auth-server-jar-with-dependencies.jar -p ../properties/exampleAuth101.properties
Start the Python server example in a second terminal (with the virtual environment activated):
cd entity/python/examples
python3 py_server.py configs/py_server.config
Start the Python client example in a third terminal:
cd entity/python/examples
python3 py_client.py configs/py_client.config
The client automatically connects to Auth (port 21900), requests a session key for the target server (net1.server), connects to the peer server (port 21100), completes the secure handshake, sends encrypted messages, and receives numbered response replies.
Lifecycle inside application code
1. Load the runtime context
Both clients and servers begin by initializing IoTAuthContext from a .config file:
from iotauth import IoTAuthContext
ctx = IoTAuthContext.from_config("path/to/entity.config")
IoTAuthContext.from_config() auto-detects and parses both C-style properties files and Node-style JSON files, commonly using the .config extension, loads the entity's private key and Auth certificate, and initializes an in-memory session key cache.
2. Client side: connect and communicate securely
Use SecureClient to automatically fetch session keys and establish a secure session:
from iotauth import IoTAuthContext, SecureClient
ctx = IoTAuthContext.from_config("path/to/client.config")
with SecureClient(ctx) as client:
channel = client.connect()
# Send encrypted data
channel.send(b"Hello, Secure World!")
# Receive decrypted response
reply = channel.recv()
print("Received reply:", reply.decode('utf-8'))
If the session key cache does not contain a valid session key for the destination, client.connect() automatically communicates with Auth over TCP, stores the obtained SessionKey in ctx.session_keys, and performs the IoTSP secure handshake.
3. Server side: accept secure connections
Use SecureServer to listen for peer connections, verify handshakes, and establish encrypted sessions:
from iotauth import IoTAuthContext, SecureServer
ctx = IoTAuthContext.from_config("path/to/server.config")
with SecureServer(ctx) as server:
# serve_once() blocks waiting for a TCP connection and completes the handshake
channel = server.serve_once()
# Read encrypted data sent by client
data = channel.recv()
# Echo back securely
channel.send(b"Server ACK: " + data)
When a client initiates a connection, SecureServer reads the session key ID from the incoming handshake frame, looks up the session key in its cache (ctx.session_keys), fetches it from Auth if missing, verifies the challenge/response nonce, and returns a connected SecureChannel.
Connection waiting and handshake processing use separate timeout settings. By
default, accept_timeout=None lets the server wait indefinitely for a client,
while handshake_timeout=5.0 limits an accepted client's secure handshake to
five seconds. Configure either value independently when constructing
SecureServer:
with SecureServer(ctx, accept_timeout=30.0, handshake_timeout=10.0) as server:
channel = server.serve_once()