or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication-and-security.mdclassic-mode.mdcli-tools.mdconnection-factory.mdindex.mdregistry-and-discovery.mdservers.mdservices-protocols.mdstreams-and-channels.mdutilities.md

services-protocols.mddocs/

0

# Services and Protocols

1

2

Service classes for defining remote interfaces and protocol management for handling RPyC connections. Services define what methods and objects are exposed across connections, while the protocol layer handles the low-level communication and object proxying.

3

4

## Capabilities

5

6

### Base Service Classes

7

8

Core service classes that define the interface between local and remote objects.

9

10

```python { .api }

11

class Service:

12

"""

13

Base class for RPyC services. Override methods to create custom services.

14

"""

15

16

def on_connect(self, conn):

17

"""Called when client connects"""

18

19

def on_disconnect(self, conn):

20

"""Called when client disconnects"""

21

22

def exposed_get_service_name(self):

23

"""Returns the service name"""

24

25

def exposed_get_service_aliases(self):

26

"""Returns list of service aliases"""

27

28

class VoidService(Service):

29

"""

30

Empty service that exposes no methods. Used as default service.

31

"""

32

```

33

34

### Specialized Service Classes

35

36

Pre-built service classes for common distributed computing patterns.

37

38

```python { .api }

39

class SlaveService(Service):

40

"""

41

Service that provides access to the local namespace and modules.

42

Used in classic mode for remote Python execution.

43

"""

44

45

def exposed_execute(self, code):

46

"""Execute Python code remotely"""

47

48

def exposed_eval(self, expression):

49

"""Evaluate Python expression remotely"""

50

51

def exposed_getattr(self, obj, name):

52

"""Get attribute from remote object"""

53

54

def exposed_setattr(self, obj, name, value):

55

"""Set attribute on remote object"""

56

57

class MasterService(Service):

58

"""

59

Service that provides master-side functionality for distributed computing.

60

"""

61

62

class ClassicService(MasterService, SlaveService):

63

"""

64

Combined service providing both master and slave functionality.

65

Used for symmetric connections where both sides can execute code.

66

"""

67

```

68

69

### Connection Management

70

71

The Connection class manages the protocol-level communication and object proxying.

72

73

```python { .api }

74

class Connection:

75

"""

76

Represents an RPyC connection, handling protocol communication and object proxying.

77

"""

78

79

def __init__(self, service, channel, config=None):

80

"""

81

Initialize connection.

82

83

Parameters:

84

- service (Service): Local service instance

85

- channel: Communication channel

86

- config (dict): Configuration dictionary

87

"""

88

89

@property

90

def root(self):

91

"""Access to remote service's root namespace"""

92

93

@property

94

def closed(self) -> bool:

95

"""True if connection is closed"""

96

97

def close(self):

98

"""Close the connection"""

99

100

def ping(self, data=None, timeout=3):

101

"""

102

Ping remote side to test connectivity.

103

104

Parameters:

105

- data: Optional data to send with ping

106

- timeout (float): Ping timeout in seconds

107

108

Returns:

109

data: Echo of sent data

110

"""

111

112

def serve(self, timeout=1):

113

"""

114

Serve incoming requests for specified time.

115

116

Parameters:

117

- timeout (float): Time to serve requests

118

"""

119

120

def serve_all(self):

121

"""Serve all pending requests"""

122

123

def serve_forever(self):

124

"""Serve requests indefinitely"""

125

126

def poll_all(self, timeout=0):

127

"""

128

Poll and handle all pending requests.

129

130

Parameters:

131

- timeout (float): Polling timeout

132

133

Returns:

134

bool: True if requests were handled

135

"""

136

```

137

138

### Network References (Netrefs)

139

140

Network references provide transparent proxying of remote objects.

141

142

```python { .api }

143

class BaseNetref:

144

"""

145

Base class for network references - transparent proxies to remote objects.

146

"""

147

148

def __getattr__(self, name):

149

"""Get attribute from remote object"""

150

151

def __setattr__(self, name, value):

152

"""Set attribute on remote object"""

153

154

def __call__(self, *args, **kwargs):

155

"""Call remote object if callable"""

156

157

def __str__(self):

158

"""String representation of remote object"""

159

160

def __repr__(self):

161

"""Detailed representation of remote object"""

162

```

163

164

### Asynchronous Operations

165

166

Support for non-blocking remote operations.

167

168

```python { .api }

169

class AsyncResult:

170

"""

171

Container for asynchronous operation results.

172

"""

173

174

@property

175

def ready(self) -> bool:

176

"""True if result is ready"""

177

178

@property

179

def expired(self) -> bool:

180

"""True if result has expired"""

181

182

def wait(self, timeout=None):

183

"""

184

Wait for result to be ready.

185

186

Parameters:

187

- timeout (float): Maximum time to wait

188

189

Raises:

190

AsyncResultTimeout: If timeout exceeded

191

"""

192

193

@property

194

def value(self):

195

"""Get the result value (blocks if not ready)"""

196

197

class AsyncResultTimeout(Exception):

198

"""Raised when async operations timeout"""

199

```

200

201

### Configuration

202

203

Default configuration options for RPyC connections.

204

205

```python { .api }

206

DEFAULT_CONFIG = {

207

'allow_all_attrs': False,

208

'allow_pickle': False,

209

'allow_getattr': True,

210

'allow_setattr': False,

211

'allow_delattr': False,

212

'allow_public_attrs': True,

213

'exposed_prefix': 'exposed_',

214

'allow_safe_attrs': True,

215

'safe_attrs': frozenset(['__abs__', '__add__', '__and__', '__bool__', '__cmp__',

216

'__contains__', '__div__', '__divmod__', '__doc__', '__eq__',

217

'__float__', '__floordiv__', '__ge__', '__getitem__',

218

'__gt__', '__hash__', '__hex__', '__iadd__', '__iand__',

219

'__idiv__', '__ifloordiv__', '__ilshift__', '__imod__',

220

'__imul__', '__int__', '__invert__', '__ior__', '__ipow__',

221

'__irshift__', '__isub__', '__iter__', '__itruediv__',

222

'__ixor__', '__le__', '__len__', '__long__', '__lshift__',

223

'__lt__', '__mod__', '__mul__', '__ne__', '__neg__',

224

'__next__', '__oct__', '__or__', '__pos__', '__pow__',

225

'__radd__', '__rand__', '__rdiv__', '__rdivmod__',

226

'__repr__', '__rfloordiv__', '__rlshift__', '__rmod__',

227

'__rmul__', '__ror__', '__rpow__', '__rrshift__',

228

'__rshift__', '__rsub__', '__rtruediv__', '__rxor__',

229

'__setitem__', '__str__', '__sub__', '__truediv__',

230

'__xor__', 'next']),

231

'instantiate_custom_exceptions': False,

232

'instantiate_oldstyle_exceptions': False,

233

'propagate_SystemExit_locally': False,

234

'propagate_KeyboardInterrupt_locally': False,

235

'logger': None,

236

'connid': None,

237

'credentials': None,

238

'endpoints_timeout': 3,

239

'sync_request_timeout': 30,

240

}

241

```

242

243

## Examples

244

245

### Creating Custom Services

246

247

```python

248

import rpyc

249

from rpyc import exposed

250

251

class CalculatorService(rpyc.Service):

252

"""Custom service providing calculator functionality"""

253

254

@exposed

255

def add(self, a, b):

256

return a + b

257

258

@exposed

259

def multiply(self, a, b):

260

return a * b

261

262

@exposed

263

def get_history(self):

264

# Could return calculation history

265

return []

266

267

def on_connect(self, conn):

268

print(f"Client connected: {conn}")

269

270

def on_disconnect(self, conn):

271

print(f"Client disconnected: {conn}")

272

273

# Use the service

274

from rpyc.utils.server import ThreadedServer

275

server = ThreadedServer(CalculatorService, port=12345)

276

server.start()

277

```

278

279

### Using Connections with Custom Configuration

280

281

```python

282

import rpyc

283

284

# Custom configuration

285

config = {

286

'allow_pickle': True, # Allow pickle serialization

287

'sync_request_timeout': 60, # 60 second timeout

288

}

289

290

# Connect with custom config

291

conn = rpyc.connect('localhost', 12345, config=config)

292

293

# Use connection

294

result = conn.root.some_function()

295

conn.close()

296

```

297

298

### Asynchronous Operations

299

300

```python

301

import rpyc

302

303

conn = rpyc.connect('localhost', 12345)

304

305

# Start async operation

306

async_result = rpyc.async_(conn.root.long_running_function)()

307

308

# Do other work while operation runs

309

print("Operation started, doing other work...")

310

311

# Wait for result

312

try:

313

result = async_result.wait(timeout=30)

314

print(f"Result: {async_result.value}")

315

except rpyc.AsyncResultTimeout:

316

print("Operation timed out")

317

318

conn.close()

319

```

320

321

### Connection Lifecycle Management

322

323

```python

324

import rpyc

325

326

# Connect and manage lifecycle

327

conn = rpyc.connect('localhost', 12345)

328

329

try:

330

# Test connectivity

331

conn.ping()

332

333

# Use connection

334

result = conn.root.get_data()

335

336

# Serve any pending requests

337

conn.serve_all()

338

339

finally:

340

# Always close connection

341

conn.close()

342

```

343

344

## Exceptions

345

346

```python { .api }

347

class GenericException(Exception):

348

"""Wrapper for remote exceptions"""

349

350

class PingError(Exception):

351

"""Raised when connection ping fails"""

352

```