or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asgi-middleware.mdasync-client.mdasync-server.mdclient.mdexceptions.mdindex.mdserver.mdwsgi-middleware.md

async-client.mddocs/

0

# Asynchronous Client

1

2

Asyncio-based Engine.IO client for connecting to servers from async Python applications. Provides the same functionality as the synchronous client but with full async/await support for modern async applications.

3

4

## Capabilities

5

6

### Client Initialization

7

8

Create and configure an asynchronous Engine.IO client with the same configuration options as the synchronous client.

9

10

```python { .api }

11

class AsyncClient:

12

def __init__(

13

self,

14

logger=False,

15

json=None,

16

request_timeout=5,

17

http_session=None,

18

ssl_verify=True,

19

handle_sigint=True,

20

websocket_extra_options=None,

21

timestamp_requests=True

22

):

23

"""

24

Initialize asynchronous Engine.IO client.

25

26

Args:

27

logger (bool|Logger): Logging configuration, default False

28

json (module): Alternative JSON module

29

request_timeout (int): Request timeout in seconds, default 5

30

http_session (aiohttp.ClientSession): HTTP session object for requests

31

ssl_verify (bool): Verify SSL certificates, default True

32

handle_sigint (bool): Handle SIGINT automatically, default True

33

websocket_extra_options (dict): Extra WebSocket client options

34

timestamp_requests (bool): Add timestamps to requests, default True

35

"""

36

```

37

38

### Async Connection Management

39

40

Establish connections to Engine.IO servers asynchronously with coroutine-based methods.

41

42

```python { .api }

43

async def connect(self, url, headers=None, transports=None, engineio_path='engine.io'):

44

"""

45

Connect to an Engine.IO server (coroutine).

46

47

Args:

48

url (str): Server URL (e.g., 'http://localhost:5000')

49

headers (dict, optional): Additional HTTP headers for connection

50

transports (list, optional): Allowed transports ['polling', 'websocket']

51

engineio_path (str): Engine.IO endpoint path, default 'engine.io'

52

53

Raises:

54

ConnectionError: If connection fails

55

ValueError: If URL is invalid or transports unsupported

56

"""

57

58

async def wait(self):

59

"""

60

Wait until the connection ends (coroutine).

61

62

This method suspends the current coroutine until the client disconnects

63

or the connection is lost.

64

"""

65

66

async def disconnect(self, abort=False, reason=None):

67

"""

68

Disconnect from the server (coroutine).

69

70

Args:

71

abort (bool): Abort connection immediately without graceful shutdown

72

reason (str, optional): Reason for disconnection

73

"""

74

```

75

76

### Async Message Communication

77

78

Send messages to the server asynchronously and receive responses through the event system.

79

80

```python { .api }

81

async def send(self, data):

82

"""

83

Send a message to the server (coroutine).

84

85

Args:

86

data (any): Message data to send (will be JSON-serialized)

87

88

Raises:

89

SocketIsClosedError: If not connected to server

90

"""

91

```

92

93

### Event Handling

94

95

Register event handlers that can be either synchronous or asynchronous functions.

96

97

```python { .api }

98

def on(self, event, handler=None):

99

"""

100

Register an event handler (synchronous method).

101

102

Args:

103

event (str): Event name ('connect', 'message', 'disconnect')

104

handler (callable, optional): Event handler function (sync or async)

105

106

Returns:

107

callable: Decorator function if handler not provided

108

"""

109

```

110

111

Usage examples:

112

113

```python

114

# Async event handlers

115

@client.on('connect')

116

async def on_connect():

117

print('Connected to server')

118

await client.send('Hello Server!')

119

120

@client.on('message')

121

async def on_message(data):

122

print(f'Received from server: {data}')

123

# Can perform async operations in handlers

124

await asyncio.sleep(0.1)

125

await client.send(f'Echo: {data}')

126

127

@client.on('disconnect')

128

async def on_disconnect():

129

print('Disconnected from server')

130

131

# Synchronous handlers also work

132

@client.on('connect')

133

def on_connect_sync():

134

print('Connected (sync handler)')

135

```

136

137

### Async Background Tasks

138

139

Manage background tasks using asyncio.

140

141

```python { .api }

142

def start_background_task(self, target, *args, **kwargs):

143

"""

144

Start a background task using asyncio.

145

146

Args:

147

target (callable): Async task function to run

148

*args: Arguments for the task function

149

**kwargs: Keyword arguments for the task function

150

151

Returns:

152

asyncio.Task: Asyncio task object

153

"""

154

155

async def sleep(self, seconds=0):

156

"""

157

Sleep using asyncio (coroutine).

158

159

Args:

160

seconds (float): Sleep duration in seconds

161

"""

162

```

163

164

### Synchronous Utility Methods

165

166

Inherited synchronous methods from the base client class.

167

168

```python { .api }

169

def transport(self):

170

"""

171

Return the current transport name.

172

173

Returns:

174

str: Transport name ('polling' or 'websocket')

175

176

Raises:

177

ValueError: If not connected

178

"""

179

180

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

181

"""

182

Create an asyncio queue object.

183

184

Returns:

185

asyncio.Queue: Asyncio queue object

186

"""

187

188

def get_queue_empty_exception(self):

189

"""

190

Return the asyncio queue empty exception.

191

192

Returns:

193

asyncio.QueueEmpty: Asyncio queue empty exception

194

"""

195

196

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

197

"""

198

Create an asyncio event object.

199

200

Returns:

201

asyncio.Event: Asyncio event object

202

"""

203

```

204

205

### AsyncClient-specific Methods

206

207

Methods specific to the async client implementation.

208

209

```python { .api }

210

def is_asyncio_based(self):

211

"""

212

Return True to identify as asyncio-based client.

213

214

Returns:

215

bool: Always True for AsyncClient

216

"""

217

```

218

219

## Client Lifecycle Events

220

221

The async client supports the same events as the synchronous client, but handlers can be async:

222

223

- **connect**: Fired when connection to server is established

224

- Handler signature: `async () -> None` or `() -> None`

225

226

- **message**: Fired when a message is received from the server

227

- Handler signature: `async (data: any) -> None` or `(data: any) -> None`

228

229

- **disconnect**: Fired when disconnected from the server

230

- Handler signature: `async () -> None` or `() -> None`

231

232

## Connection Examples

233

234

### Basic Async Connection

235

236

```python

237

import asyncio

238

import engineio

239

240

async def main():

241

client = engineio.AsyncClient()

242

243

@client.on('connect')

244

async def on_connect():

245

print('Connected!')

246

await client.send('Hello from async client')

247

248

@client.on('message')

249

async def on_message(data):

250

print(f'Server says: {data}')

251

252

@client.on('disconnect')

253

async def on_disconnect():

254

print('Disconnected')

255

256

await client.connect('http://localhost:5000')

257

await client.wait()

258

259

# Run the async main function

260

asyncio.run(main())

261

```

262

263

### Connection with Custom aiohttp Session

264

265

```python

266

import asyncio

267

import aiohttp

268

import engineio

269

270

async def main():

271

# Create custom aiohttp session

272

async with aiohttp.ClientSession() as session:

273

client = engineio.AsyncClient(

274

http_session=session,

275

request_timeout=10

276

)

277

278

await client.connect('http://localhost:5000')

279

await client.wait()

280

281

asyncio.run(main())

282

```

283

284

### Async Background Tasks

285

286

```python

287

import asyncio

288

import engineio

289

290

async def heartbeat_task(client):

291

"""Send periodic heartbeat messages"""

292

while True:

293

try:

294

await client.send({'type': 'heartbeat', 'timestamp': time.time()})

295

await asyncio.sleep(30)

296

except Exception as e:

297

print(f'Heartbeat failed: {e}')

298

break

299

300

async def main():

301

client = engineio.AsyncClient()

302

303

@client.on('connect')

304

async def on_connect():

305

print('Connected, starting heartbeat')

306

# Start background heartbeat task

307

client.start_background_task(heartbeat_task, client)

308

309

await client.connect('http://localhost:5000')

310

await client.wait()

311

312

asyncio.run(main())

313

```

314

315

### Automatic Reconnection with Async/Await

316

317

```python

318

import asyncio

319

import engineio

320

321

async def connect_with_retry(client, url, max_retries=5):

322

"""Connect with automatic retry logic"""

323

for attempt in range(max_retries):

324

try:

325

await client.connect(url)

326

print('Connected successfully')

327

return

328

except Exception as e:

329

print(f'Connection attempt {attempt + 1} failed: {e}')

330

if attempt < max_retries - 1:

331

await asyncio.sleep(2 ** attempt) # Exponential backoff

332

raise ConnectionError('Max connection attempts exceeded')

333

334

async def main():

335

client = engineio.AsyncClient()

336

337

@client.on('connect')

338

async def on_connect():

339

print('Connected to server')

340

341

@client.on('disconnect')

342

async def on_disconnect():

343

print('Disconnected, attempting to reconnect...')

344

await asyncio.sleep(5)

345

try:

346

await connect_with_retry(client, 'http://localhost:5000')

347

except Exception as e:

348

print(f'Reconnection failed permanently: {e}')

349

350

await connect_with_retry(client, 'http://localhost:5000')

351

await client.wait()

352

353

asyncio.run(main())

354

```

355

356

### Integration with Web Frameworks

357

358

```python

359

# FastAPI integration example

360

from fastapi import FastAPI

361

import engineio

362

363

app = FastAPI()

364

client = engineio.AsyncClient()

365

366

@app.on_event("startup")

367

async def startup():

368

await client.connect('http://external-service:5000')

369

370

@app.on_event("shutdown")

371

async def shutdown():

372

await client.disconnect()

373

374

@app.post("/send-message")

375

async def send_message(message: str):

376

await client.send(message)

377

return {"status": "sent"}

378

```

379

380

### Multiple Concurrent Connections

381

382

```python

383

import asyncio

384

import engineio

385

386

async def handle_client(client_id, url):

387

"""Handle a single client connection"""

388

client = engineio.AsyncClient()

389

390

@client.on('connect')

391

async def on_connect():

392

print(f'Client {client_id} connected')

393

394

@client.on('message')

395

async def on_message(data):

396

print(f'Client {client_id} received: {data}')

397

398

await client.connect(url)

399

await client.wait()

400

401

async def main():

402

# Connect multiple clients concurrently

403

tasks = [

404

handle_client(i, 'http://localhost:5000')

405

for i in range(5)

406

]

407

408

await asyncio.gather(*tasks)

409

410

asyncio.run(main())

411

```

412

413

## Error Handling

414

415

The async client may raise the same exceptions as the synchronous client:

416

417

- `ConnectionError`: When connection to server fails or is lost

418

- `SocketIsClosedError`: When attempting to send while not connected

419

- `ValueError`: When invalid parameters are provided

420

- `asyncio.TimeoutError`: When requests exceed the configured timeout

421

422

## Advanced Async Patterns

423

424

### Context Manager Usage

425

426

```python

427

import asyncio

428

import engineio

429

430

class AsyncEngineIOClient:

431

def __init__(self, url, **kwargs):

432

self.url = url

433

self.client = engineio.AsyncClient(**kwargs)

434

435

async def __aenter__(self):

436

await self.client.connect(self.url)

437

return self.client

438

439

async def __aexit__(self, exc_type, exc_val, exc_tb):

440

await self.client.disconnect()

441

442

# Usage

443

async def main():

444

async with AsyncEngineIOClient('http://localhost:5000') as client:

445

@client.on('message')

446

async def on_message(data):

447

print(f'Received: {data}')

448

449

await client.send('Hello')

450

await asyncio.sleep(10)

451

452

asyncio.run(main())

453

```