0
# Python Bindings
1
2
The Python bindings provide a high-level interface to Jsonnet with support for external variables, import callbacks, native extensions, and comprehensive error handling. The module exposes two main evaluation functions with extensive configuration options.
3
4
## Capabilities
5
6
### Core Evaluation Functions
7
8
Primary functions for evaluating Jsonnet code from files or strings with flexible configuration.
9
10
```python { .api }
11
def evaluate_file(filename, **kwargs):
12
"""
13
Evaluate Jsonnet file and return JSON string.
14
15
Args:
16
filename (str): Path to Jsonnet file to evaluate
17
jpathdir (str | list[str], optional): Import search paths
18
max_stack (int, optional): Maximum stack depth (default: 500)
19
gc_min_objects (int, optional): GC minimum objects (default: 1000)
20
gc_growth_trigger (float, optional): GC growth trigger (default: 2.0)
21
ext_vars (dict[str, str], optional): External string variables
22
ext_codes (dict[str, str], optional): External code variables
23
tla_vars (dict[str, str], optional): Top-level string arguments
24
tla_codes (dict[str, str], optional): Top-level code arguments
25
max_trace (int, optional): Maximum trace lines (default: 20)
26
import_callback (callable, optional): Custom import handler
27
native_callbacks (dict, optional): Native function callbacks
28
29
Returns:
30
str: JSON output string
31
32
Raises:
33
RuntimeError: On Jsonnet evaluation errors
34
TypeError: On invalid parameter types
35
"""
36
37
def evaluate_snippet(filename, src, **kwargs):
38
"""
39
Evaluate Jsonnet code string and return JSON string.
40
41
Args:
42
filename (str): Filename for error reporting
43
src (str): Jsonnet source code to evaluate
44
All other parameters same as evaluate_file()
45
46
Returns:
47
str: JSON output string
48
49
Raises:
50
RuntimeError: On Jsonnet evaluation errors
51
TypeError: On invalid parameter types
52
"""
53
```
54
55
### Module Constants
56
57
```python { .api }
58
# Version string constant
59
version: str # "v0.21.0"
60
```
61
62
## Parameter Details
63
64
### Import Search Paths
65
66
```python
67
# Single path
68
evaluate_file("config.jsonnet", jpathdir="/usr/local/lib/jsonnet")
69
70
# Multiple paths (searched in order)
71
evaluate_file("config.jsonnet", jpathdir=[
72
"./lib",
73
"/usr/local/lib/jsonnet",
74
"/opt/jsonnet/lib"
75
])
76
```
77
78
### External Variables
79
80
```python
81
# String variables accessible via std.extVar()
82
ext_vars = {
83
"environment": "production",
84
"version": "1.2.3",
85
"debug": "false"
86
}
87
88
# Code variables that are evaluated as Jsonnet
89
ext_codes = {
90
"config": "{ port: 8080, ssl: true }",
91
"features": "['auth', 'logging', 'metrics']"
92
}
93
94
result = evaluate_file("app.jsonnet", ext_vars=ext_vars, ext_codes=ext_codes)
95
```
96
97
### Top-Level Arguments
98
99
```python
100
# For Jsonnet files that accept function parameters
101
# function(cluster, region="us-west-1") { ... }
102
103
tla_vars = {
104
"cluster": "production",
105
"region": "us-east-1"
106
}
107
108
tla_codes = {
109
"replicas": "if std.extVar('environment') == 'prod' then 3 else 1"
110
}
111
112
result = evaluate_file("deployment.jsonnet", tla_vars=tla_vars, tla_codes=tla_codes)
113
```
114
115
### VM Configuration
116
117
```python
118
# Performance tuning
119
result = evaluate_file("large-config.jsonnet",
120
max_stack=2000, # Increase stack for deep recursion
121
gc_min_objects=5000, # More objects before GC
122
gc_growth_trigger=3.0, # Less frequent GC
123
max_trace=50 # More error context
124
)
125
```
126
127
### Custom Import Callback
128
129
```python
130
def custom_import(base_path, relative_path):
131
"""
132
Custom import handler for loading files from alternative sources.
133
134
Args:
135
base_path (str): Directory containing the importing file
136
relative_path (str): Relative import path from Jsonnet code
137
138
Returns:
139
tuple[str, bytes]: (resolved_absolute_path, file_content_bytes)
140
141
Raises:
142
Exception: On import errors (converted to Jsonnet error)
143
"""
144
import os
145
146
# Resolve path
147
if relative_path.startswith("http://"):
148
# Handle HTTP imports
149
import urllib.request
150
response = urllib.request.urlopen(relative_path)
151
content = response.read()
152
return relative_path, content
153
else:
154
# Handle file system imports
155
abs_path = os.path.join(base_path, relative_path)
156
with open(abs_path, 'rb') as f:
157
content = f.read()
158
return abs_path, content
159
160
result = evaluate_file("config.jsonnet", import_callback=custom_import)
161
```
162
163
### Native Callbacks
164
165
```python
166
def add_numbers(a, b):
167
"""Native function: add two numbers"""
168
return a + b
169
170
def get_timestamp():
171
"""Native function: get current timestamp"""
172
import time
173
return int(time.time())
174
175
def format_config(config, template):
176
"""Native function: format configuration with template"""
177
return template.format(**config)
178
179
# Register native functions
180
native_callbacks = {
181
"addNumbers": (["a", "b"], add_numbers),
182
"getTimestamp": ([], get_timestamp),
183
"formatConfig": (["config", "template"], format_config)
184
}
185
186
# Use in Jsonnet code:
187
# local timestamp = std.native("getTimestamp")();
188
# local sum = std.native("addNumbers")(10, 20);
189
result = evaluate_snippet('''
190
{
191
timestamp: std.native("getTimestamp")(),
192
sum: std.native("addNumbers")(10, 20),
193
formatted: std.native("formatConfig")(
194
{ name: "app", version: "1.0" },
195
"Application {name} version {version}"
196
)
197
}
198
''', native_callbacks=native_callbacks)
199
```
200
201
## Usage Examples
202
203
**Basic evaluation:**
204
```python
205
import _jsonnet
206
207
# Simple evaluation
208
result = _jsonnet.evaluate_snippet("example.jsonnet", '''
209
{
210
greeting: "Hello World!",
211
numbers: [1, 2, 3],
212
nested: {
213
key: "value"
214
}
215
}
216
''')
217
218
print(result) # JSON string output
219
```
220
221
**File evaluation with variables:**
222
```python
223
import _jsonnet
224
225
result = _jsonnet.evaluate_file("config.jsonnet",
226
ext_vars={
227
"environment": "production",
228
"region": "us-west-1"
229
},
230
tla_vars={
231
"service_name": "api-server"
232
}
233
)
234
235
# config.jsonnet might contain:
236
# function(service_name) {
237
# name: service_name,
238
# env: std.extVar("environment"),
239
# region: std.extVar("region")
240
# }
241
```
242
243
**Complex configuration with all options:**
244
```python
245
import _jsonnet
246
import os
247
248
def load_secret(base, rel):
249
# Custom import for loading secrets
250
secret_path = os.path.join("/etc/secrets", rel)
251
with open(secret_path, 'rb') as f:
252
return secret_path, f.read()
253
254
def encrypt_value(value):
255
# Native function for encryption
256
import base64
257
return base64.b64encode(value.encode()).decode()
258
259
result = _jsonnet.evaluate_file("app-config.jsonnet",
260
jpathdir=["/usr/local/lib/jsonnet", "./lib"],
261
max_stack=1500,
262
ext_vars={
263
"environment": "production",
264
"cluster": "us-west-1a"
265
},
266
ext_codes={
267
"database_config": '''
268
{
269
host: "db.example.com",
270
port: 5432,
271
ssl: true
272
}
273
'''
274
},
275
tla_vars={
276
"service_name": "user-service",
277
"replica_count": "3"
278
},
279
import_callback=load_secret,
280
native_callbacks={
281
"encrypt": (["value"], encrypt_value)
282
},
283
max_trace=30
284
)
285
```
286
287
**Error handling:**
288
```python
289
import _jsonnet
290
291
try:
292
result = _jsonnet.evaluate_snippet("invalid.jsonnet", '''
293
{
294
invalid: syntax error here
295
}
296
''')
297
except RuntimeError as e:
298
print(f"Jsonnet error: {e}")
299
# Error includes line numbers and context
300
```
301
302
**Working with complex imports:**
303
```python
304
import _jsonnet
305
import json
306
import urllib.request
307
308
def http_import(base, rel):
309
"""Handle HTTP/HTTPS imports"""
310
if rel.startswith(("http://", "https://")):
311
try:
312
response = urllib.request.urlopen(rel)
313
content = response.read()
314
return rel, content
315
except Exception as e:
316
raise Exception(f"Failed to fetch {rel}: {e}")
317
else:
318
# Fall back to file system
319
import os
320
full_path = os.path.join(base, rel)
321
with open(full_path, 'rb') as f:
322
return full_path, f.read()
323
324
# Jsonnet code can now import from URLs:
325
# local schema = import "https://api.example.com/schema.jsonnet";
326
result = _jsonnet.evaluate_snippet("remote.jsonnet", '''
327
local remote_config = import "https://config.example.com/base.jsonnet";
328
{
329
local_override: "value",
330
base: remote_config
331
}
332
''', import_callback=http_import)
333
```
334
335
**Integration with Python applications:**
336
```python
337
import _jsonnet
338
import json
339
import sys
340
341
class JsonnetConfig:
342
def __init__(self, config_file, **kwargs):
343
self.config_file = config_file
344
self.jsonnet_vars = kwargs
345
346
def load(self):
347
try:
348
result = _jsonnet.evaluate_file(
349
self.config_file,
350
ext_vars=self.jsonnet_vars
351
)
352
return json.loads(result)
353
except RuntimeError as e:
354
print(f"Config error: {e}", file=sys.stderr)
355
sys.exit(1)
356
357
# Usage in application
358
config = JsonnetConfig("app.jsonnet",
359
environment=os.getenv("ENV", "development"),
360
debug=str(os.getenv("DEBUG", "false")).lower()
361
).load()
362
363
print(f"Starting {config['service_name']} on port {config['port']}")
364
```