or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-types.mdindex.mdmessage-handling.mdservers.mdtcp-networking.mdudp-networking.md

message-handling.mddocs/

0

# Message Handling

1

2

Core OSC message and bundle construction, parsing, and manipulation capabilities. This module provides the fundamental building blocks for creating and processing OSC messages and bundles with full support for all standard OSC data types.

3

4

## Capabilities

5

6

### Message Creation

7

8

Build OSC messages with typed arguments using the builder pattern or convenience functions.

9

10

```python { .api }

11

class OscMessageBuilder:

12

"""Builds arbitrary OSC messages with typed arguments."""

13

14

def __init__(self, address: Optional[str] = None):

15

"""Initialize builder with optional OSC address pattern."""

16

17

@property

18

def address(self) -> Optional[str]:

19

"""Get or set the OSC address pattern."""

20

21

@address.setter

22

def address(self, value: str):

23

"""Set the OSC address pattern."""

24

25

@property

26

def args(self) -> List[Tuple[str, Any]]:

27

"""Returns list of (type, value) argument tuples."""

28

29

def add_arg(self, arg_value: ArgValue, arg_type: Optional[str] = None):

30

"""Add typed argument to message.

31

32

Parameters:

33

- arg_value: The argument value (auto-typed if arg_type is None)

34

- arg_type: Explicit OSC type character ('i', 'f', 's', 'b', etc.)

35

"""

36

37

def build(self) -> OscMessage:

38

"""Build OscMessage from current state.

39

40

Returns:

41

OscMessage instance ready for transmission

42

43

Raises:

44

BuildError: If message cannot be built (missing address, etc.)

45

"""

46

47

def build_msg(address: str, value: ArgValue = "") -> OscMessage:

48

"""Convenience function to quickly build OSC message.

49

50

Parameters:

51

- address: OSC address pattern string

52

- value: Single argument value or list of values

53

54

Returns:

55

OscMessage ready for transmission

56

"""

57

```

58

59

### Message Parsing

60

61

Parse OSC messages from incoming datagram bytes with automatic type detection.

62

63

```python { .api }

64

class OscMessage:

65

"""Representation of a parsed OSC message."""

66

67

def __init__(self, dgram: bytes):

68

"""Initialize from datagram bytes.

69

70

Parameters:

71

- dgram: Raw OSC message datagram

72

73

Raises:

74

ParseError: If datagram cannot be parsed as OSC message

75

"""

76

77

@property

78

def address(self) -> str:

79

"""Returns OSC address pattern string."""

80

81

@property

82

def params(self) -> List[Any]:

83

"""Returns list of message parameters."""

84

85

@property

86

def size(self) -> int:

87

"""Returns datagram length in bytes."""

88

89

@property

90

def dgram(self) -> bytes:

91

"""Returns original datagram bytes."""

92

93

@staticmethod

94

def dgram_is_message(dgram: bytes) -> bool:

95

"""Check if datagram is an OSC message.

96

97

Parameters:

98

- dgram: Datagram bytes to check

99

100

Returns:

101

True if dgram contains OSC message

102

"""

103

104

def __iter__(self):

105

"""Iterator over message parameters."""

106

107

def __str__(self) -> str:

108

"""String representation of message."""

109

```

110

111

### Bundle Creation

112

113

Create OSC bundles that group messages and sub-bundles with shared timestamps for synchronized execution.

114

115

```python { .api }

116

class OscBundleBuilder:

117

"""Builds OSC bundles with timed message groups."""

118

119

def __init__(self, timestamp: Union[int, float]):

120

"""Initialize bundle with timestamp.

121

122

Parameters:

123

- timestamp: Execution time (seconds since epoch) or IMMEDIATELY constant

124

"""

125

126

def add_content(self, content: Union[OscMessage, OscBundle]):

127

"""Add message or sub-bundle to bundle.

128

129

Parameters:

130

- content: OscMessage or OscBundle to include

131

"""

132

133

def build(self) -> OscBundle:

134

"""Build OscBundle from current state.

135

136

Returns:

137

OscBundle ready for transmission

138

139

Raises:

140

BuildError: If bundle cannot be built

141

"""

142

143

# Bundle timing constant

144

IMMEDIATELY: int # Special timestamp value for immediate execution

145

```

146

147

### Bundle Parsing

148

149

Parse OSC bundles from datagram bytes and access contained messages and sub-bundles.

150

151

```python { .api }

152

class OscBundle:

153

"""Representation of a parsed OSC bundle."""

154

155

def __init__(self, dgram: bytes):

156

"""Initialize from datagram bytes.

157

158

Parameters:

159

- dgram: Raw OSC bundle datagram

160

161

Raises:

162

ParseError: If datagram cannot be parsed as OSC bundle

163

"""

164

165

@property

166

def timestamp(self) -> float:

167

"""Returns bundle timestamp as seconds since epoch."""

168

169

@property

170

def num_contents(self) -> int:

171

"""Returns number of contained elements."""

172

173

@property

174

def size(self) -> int:

175

"""Returns datagram length in bytes."""

176

177

@property

178

def dgram(self) -> bytes:

179

"""Returns original datagram bytes."""

180

181

def content(self, index: int) -> Union[OscMessage, OscBundle]:

182

"""Returns bundle content at given index.

183

184

Parameters:

185

- index: Zero-based index of content element

186

187

Returns:

188

OscMessage or OscBundle at the specified index

189

"""

190

191

@staticmethod

192

def dgram_is_bundle(dgram: bytes) -> bool:

193

"""Check if datagram is an OSC bundle.

194

195

Parameters:

196

- dgram: Datagram bytes to check

197

198

Returns:

199

True if dgram contains OSC bundle

200

"""

201

202

def __iter__(self):

203

"""Iterator over bundle contents."""

204

```

205

206

### Packet Processing

207

208

Handle complete OSC transmissions that may contain messages or bundles with timing information.

209

210

```python { .api }

211

class OscPacket:

212

"""Represents complete OSC transmission unit."""

213

214

def __init__(self, dgram: bytes):

215

"""Initialize from UDP datagram bytes.

216

217

Parameters:

218

- dgram: Complete OSC packet datagram

219

220

Raises:

221

ParseError: If packet cannot be parsed

222

"""

223

224

@property

225

def messages(self) -> List[TimedMessage]:

226

"""Returns time-sorted list of messages for execution.

227

228

Returns:

229

List of TimedMessage objects with execution timestamps

230

"""

231

232

class TimedMessage:

233

"""Message with execution timestamp."""

234

235

time: float # Execution timestamp (seconds since epoch)

236

message: OscMessage # The actual OSC message

237

```

238

239

### Message Builder Constants

240

241

Type constants for explicit argument typing in message builders.

242

243

```python { .api }

244

# Numeric types

245

ARG_TYPE_INT: str = "i" # 32-bit integer

246

ARG_TYPE_INT64: str = "h" # 64-bit integer

247

ARG_TYPE_FLOAT: str = "f" # 32-bit float

248

ARG_TYPE_DOUBLE: str = "d" # 64-bit double

249

250

# Data types

251

ARG_TYPE_STRING: str = "s" # UTF-8 string

252

ARG_TYPE_BLOB: str = "b" # Binary data

253

254

# Special types

255

ARG_TYPE_RGBA: str = "r" # RGBA color (32-bit)

256

ARG_TYPE_MIDI: str = "m" # MIDI packet (4 bytes)

257

258

# Boolean/null types

259

ARG_TYPE_TRUE: str = "T" # Boolean true

260

ARG_TYPE_FALSE: str = "F" # Boolean false

261

ARG_TYPE_NIL: str = "N" # Null/nil value

262

263

# Array delimiters

264

ARG_TYPE_ARRAY_START: str = "[" # Array start marker

265

ARG_TYPE_ARRAY_STOP: str = "]" # Array end marker

266

```

267

268

## Usage Examples

269

270

### Building Complex Messages

271

272

```python

273

from pythonosc.osc_message_builder import OscMessageBuilder, ARG_TYPE_FLOAT, ARG_TYPE_STRING

274

275

# Build message with explicit types

276

builder = OscMessageBuilder("/synth/params")

277

builder.add_arg(440.0, ARG_TYPE_FLOAT)

278

builder.add_arg("sine", ARG_TYPE_STRING)

279

builder.add_arg([1, 2, 3]) # Auto-typed as array

280

message = builder.build()

281

282

# Quick message building

283

from pythonosc.osc_message_builder import build_msg

284

msg = build_msg("/filter", 0.75)

285

```

286

287

### Creating Synchronized Bundles

288

289

```python

290

from pythonosc.osc_bundle_builder import OscBundleBuilder, IMMEDIATELY

291

import time

292

293

# Create bundle for immediate execution

294

bundle_builder = OscBundleBuilder(IMMEDIATELY)

295

bundle_builder.add_content(build_msg("/note/on", [60, 127]))

296

bundle_builder.add_content(build_msg("/note/on", [64, 127]))

297

bundle_builder.add_content(build_msg("/note/on", [67, 127]))

298

chord_bundle = bundle_builder.build()

299

300

# Create bundle for future execution

301

future_time = time.time() + 2.0 # 2 seconds from now

302

delayed_builder = OscBundleBuilder(future_time)

303

delayed_builder.add_content(build_msg("/note/off", [60, 64, 67]))

304

delayed_bundle = delayed_builder.build()

305

```

306

307

### Parsing Incoming Data

308

309

```python

310

from pythonosc.osc_message import OscMessage

311

from pythonosc.osc_bundle import OscBundle

312

from pythonosc.osc_packet import OscPacket

313

314

# Parse raw datagram

315

def handle_datagram(dgram_bytes):

316

if OscMessage.dgram_is_message(dgram_bytes):

317

message = OscMessage(dgram_bytes)

318

print(f"Message: {message.address} {message.params}")

319

elif OscBundle.dgram_is_bundle(dgram_bytes):

320

bundle = OscBundle(dgram_bytes)

321

print(f"Bundle with {bundle.num_contents} items at {bundle.timestamp}")

322

for i in range(bundle.num_contents):

323

content = bundle.content(i)

324

if isinstance(content, OscMessage):

325

print(f" Message: {content.address} {content.params}")

326

327

# Or use packet for unified handling

328

packet = OscPacket(dgram_bytes)

329

for timed_msg in packet.messages:

330

print(f"Execute at {timed_msg.time}: {timed_msg.message}")

331

```

332

333

## Types and Exceptions

334

335

```python { .api }

336

from typing import Union, List, Tuple, Any, Optional

337

338

ArgValue = Union[str, bytes, bool, int, float, MidiPacket, list]

339

MidiPacket = Tuple[int, int, int, int] # (port_id, status_byte, data1, data2)

340

341

class ParseError(Exception):

342

"""Raised when datagram parsing fails."""

343

344

class BuildError(Exception):

345

"""Raised when message/bundle building fails."""

346

```