or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-processing.mdbackends.mdcoroutines.mdhigh-level-parsing.mdindex.md

backends.mddocs/

0

# Backend Management

1

2

Backend selection and configuration utilities for optimizing performance based on available libraries and specific requirements. ijson's multi-backend architecture allows it to automatically select the fastest available JSON parsing implementation while maintaining a consistent API.

3

4

## Capabilities

5

6

### Backend Selection

7

8

Get a specific backend by name, useful for forcing a particular implementation or testing different backends.

9

10

```python { .api }

11

def get_backend(backend):

12

"""

13

Import and return specified backend module.

14

15

Parameters:

16

- backend (str): Backend name ('yajl2_c', 'yajl2_cffi', 'yajl2', 'yajl', 'python')

17

18

Returns:

19

Backend module with parsing functions

20

21

Raises:

22

- ImportError: If backend is not available

23

"""

24

```

25

26

**Usage Examples:**

27

28

```python

29

import ijson

30

31

# Force use of pure Python backend

32

try:

33

python_backend = ijson.get_backend('python')

34

items = python_backend.items(json_data, 'data.item')

35

for item in items:

36

process(item)

37

except ImportError:

38

print("Python backend not available")

39

40

# Try fastest backend first

41

for backend_name in ['yajl2_c', 'yajl2_cffi', 'python']:

42

try:

43

backend = ijson.get_backend(backend_name)

44

print(f"Using backend: {backend_name}")

45

break

46

except ImportError:

47

continue

48

```

49

50

### Backend Information

51

52

Access information about the currently selected backend and available backends.

53

54

```python { .api }

55

ALL_BACKENDS: tuple

56

"""

57

All supported backends in descending order of speed.

58

Value: ('yajl2_c', 'yajl2_cffi', 'yajl2', 'yajl', 'python')

59

"""

60

61

backend: object

62

"""

63

Currently selected backend instance.

64

Contains all parsing functions (parse, items, kvitems, etc.)

65

"""

66

67

backend_name: str

68

"""

69

Name of the currently loaded backend.

70

One of: 'yajl2_c', 'yajl2_cffi', 'yajl2', 'yajl', 'python'

71

"""

72

```

73

74

**Usage Examples:**

75

76

```python

77

import ijson

78

79

# Check current backend

80

print(f"Current backend: {ijson.backend_name}")

81

print(f"Available backends: {ijson.ALL_BACKENDS}")

82

83

# Get backend capabilities

84

current_backend = ijson.backend

85

if hasattr(current_backend, 'capabilities'):

86

caps = current_backend.capabilities

87

print(f"C-style comments: {caps.c_comments}")

88

print(f"Multiple values: {caps.multiple_values}")

89

```

90

91

## Backend Types

92

93

### yajl2_c (Fastest)

94

95

C extension using YAJL 2.x library. Provides the best performance but requires compilation during installation.

96

97

```python

98

# Automatically selected if available

99

import ijson

100

print(ijson.backend_name) # 'yajl2_c'

101

102

# Or force selection

103

backend = ijson.get_backend('yajl2_c')

104

```

105

106

**Characteristics:**

107

- Fastest performance (10-20x faster than Python)

108

- Requires C compiler during installation

109

- Binary wheels available for common platforms

110

- Full feature support including C-style comments

111

112

### yajl2_cffi

113

114

CFFI-based binding to YAJL 2.x library. Good performance without requiring C compiler.

115

116

```python

117

# Force CFFI backend

118

backend = ijson.get_backend('yajl2_cffi')

119

```

120

121

**Characteristics:**

122

- Fast performance (5-15x faster than Python)

123

- No C compiler required (uses CFFI)

124

- Good compatibility across platforms

125

- Full feature support

126

127

### yajl2

128

129

ctypes-based binding to YAJL 2.x library. Moderate performance with maximum compatibility.

130

131

```python

132

# Force ctypes backend

133

backend = ijson.get_backend('yajl2')

134

```

135

136

**Characteristics:**

137

- Moderate performance (3-8x faster than Python)

138

- No compilation required

139

- Works with system-installed YAJL

140

- Full feature support

141

142

### yajl (Legacy)

143

144

ctypes-based binding to YAJL 1.x library. Provided for compatibility with older YAJL installations.

145

146

```python

147

# Force legacy YAJL backend

148

backend = ijson.get_backend('yajl')

149

```

150

151

**Characteristics:**

152

- Moderate performance

153

- Compatible with YAJL 1.x

154

- Limited feature set compared to 2.x versions

155

156

### python (Pure Python)

157

158

Pure Python implementation. Always available but slowest performance.

159

160

```python

161

# Force pure Python backend

162

backend = ijson.get_backend('python')

163

```

164

165

**Characteristics:**

166

- Always available (no dependencies)

167

- Slowest performance but still memory-efficient

168

- Full feature support

169

- Best for debugging and understanding behavior

170

171

## Environment Configuration

172

173

### IJSON_BACKEND Environment Variable

174

175

Force a specific backend using environment variable:

176

177

```bash

178

# Force pure Python backend

179

export IJSON_BACKEND=python

180

python your_script.py

181

182

# Force fastest C backend

183

export IJSON_BACKEND=yajl2_c

184

python your_script.py

185

```

186

187

```python

188

import os

189

import ijson

190

191

# Check if environment override is set

192

if 'IJSON_BACKEND' in os.environ:

193

print(f"Backend forced to: {os.environ['IJSON_BACKEND']}")

194

195

print(f"Using backend: {ijson.backend_name}")

196

```

197

198

### YAJL_DLL Environment Variable

199

200

Specify custom YAJL library location:

201

202

```bash

203

# Use custom YAJL library

204

export YAJL_DLL=/usr/local/lib/libyajl.so.2

205

python your_script.py

206

```

207

208

## Backend Capabilities

209

210

Each backend supports different feature sets through the capabilities system:

211

212

```python { .api }

213

class BackendCapabilities:

214

"""

215

Capabilities supported by a backend.

216

"""

217

c_comments: bool # C-style comments (non-standard JSON)

218

multiple_values: bool # Multiple top-level values

219

invalid_leading_zeros_detection: bool # Leading zeros detection

220

incomplete_json_tokens_detection: bool # Incomplete token detection

221

int64: bool # 64-bit integer support with use_float=True

222

```

223

224

**Usage Examples:**

225

226

```python

227

import ijson

228

229

# Check backend capabilities

230

caps = ijson.backend.capabilities

231

print(f"Supports C comments: {caps.c_comments}")

232

print(f"Supports multiple values: {caps.multiple_values}")

233

print(f"Detects invalid leading zeros: {caps.invalid_leading_zeros_detection}")

234

235

# Use capabilities to enable features

236

if caps.multiple_values:

237

# Parse multiple JSON values in stream

238

items = ijson.parse(stream, multiple_values=True)

239

240

if caps.c_comments:

241

# Parse JSON with C-style comments

242

data = '{"key": "value" /* comment */}'

243

result = list(ijson.items(data, ''))

244

```

245

246

## Performance Comparison

247

248

Typical performance characteristics (relative to pure Python):

249

250

| Backend | Speed Multiplier | Compilation Required | Dependencies |

251

|-------------|------------------|---------------------|--------------|

252

| yajl2_c | 10-20x | Yes (C compiler) | None (wheels available) |

253

| yajl2_cffi | 5-15x | No | CFFI, YAJL |

254

| yajl2 | 3-8x | No | YAJL 2.x |

255

| yajl | 3-8x | No | YAJL 1.x |

256

| python | 1x (baseline) | No | None |

257

258

### Performance Testing

259

260

```python

261

import time

262

import ijson

263

264

def benchmark_backend(backend_name, data, iterations=1000):

265

try:

266

backend = ijson.get_backend(backend_name)

267

start_time = time.time()

268

269

for _ in range(iterations):

270

list(backend.items(data, 'items.item'))

271

272

elapsed = time.time() - start_time

273

return elapsed

274

except ImportError:

275

return None

276

277

# Benchmark all available backends

278

test_data = '{"items": [' + ','.join([f'{{"id": {i}}}' for i in range(100)]) + ']}'

279

280

results = {}

281

for backend_name in ijson.ALL_BACKENDS:

282

elapsed = benchmark_backend(backend_name, test_data)

283

if elapsed is not None:

284

results[backend_name] = elapsed

285

print(f"{backend_name}: {elapsed:.4f}s")

286

287

# Find fastest backend

288

if results:

289

fastest = min(results.keys(), key=lambda k: results[k])

290

print(f"Fastest available backend: {fastest}")

291

```

292

293

## Error Handling

294

295

### Backend Loading Errors

296

297

```python

298

import ijson

299

from ijson.backends import YAJLImportError

300

301

try:

302

backend = ijson.get_backend('yajl2_c')

303

except ImportError as e:

304

print(f"C backend not available: {e}")

305

# Fall back to pure Python

306

backend = ijson.get_backend('python')

307

308

try:

309

backend = ijson.get_backend('yajl2')

310

except YAJLImportError as e:

311

print(f"YAJL version issue: {e}")

312

```

313

314

### Version Compatibility

315

316

```python

317

import ijson

318

319

# Check for specific backend features

320

backend = ijson.backend

321

if hasattr(backend, 'capabilities'):

322

if backend.capabilities.int64:

323

# Safe to use large integers with use_float=True

324

data = ijson.parse(source, use_float=True)

325

else:

326

# Use Decimal for precision

327

data = ijson.parse(source)

328

```

329

330

## Custom Backend Configuration

331

332

### Backend Selection Strategy

333

334

```python

335

import ijson

336

import os

337

338

def get_optimal_backend():

339

"""Select best backend based on environment and requirements"""

340

341

# Check environment override

342

if 'IJSON_BACKEND' in os.environ:

343

return ijson.get_backend(os.environ['IJSON_BACKEND'])

344

345

# Prefer compiled backends for production

346

if os.environ.get('ENVIRONMENT') == 'production':

347

for backend_name in ['yajl2_c', 'yajl2_cffi']:

348

try:

349

return ijson.get_backend(backend_name)

350

except ImportError:

351

continue

352

353

# Use pure Python for development/debugging

354

if os.environ.get('ENVIRONMENT') == 'development':

355

return ijson.get_backend('python')

356

357

# Default: use whatever ijson selected

358

return ijson.backend

359

360

# Use optimal backend

361

optimal_backend = get_optimal_backend()

362

print(f"Selected backend: {optimal_backend.backend_name}")

363

```

364

365

### Feature-Based Selection

366

367

```python

368

import ijson

369

370

def select_backend_for_features(need_comments=False, need_multiple_values=False):

371

"""Select backend based on required features"""

372

373

for backend_name in ijson.ALL_BACKENDS:

374

try:

375

backend = ijson.get_backend(backend_name)

376

caps = backend.capabilities

377

378

if need_comments and not caps.c_comments:

379

continue

380

if need_multiple_values and not caps.multiple_values:

381

continue

382

383

return backend

384

except ImportError:

385

continue

386

387

raise RuntimeError("No backend supports required features")

388

389

# Select backend that supports C-style comments

390

backend = select_backend_for_features(need_comments=True)

391

print(f"Using backend with comment support: {backend.backend_name}")

392

```