0
# Compute Resources
1
2
Functions and classes that execute serverless workloads in Modal's cloud infrastructure, including interactive sandboxes for development and debugging.
3
4
## Capabilities
5
6
### Function Class
7
8
Represents a deployed serverless function that can be called remotely, locally, or in parallel across multiple inputs.
9
10
```python { .api }
11
class Function:
12
def remote(self, *args, **kwargs):
13
"""
14
Call the function remotely in Modal's cloud.
15
16
Parameters:
17
- *args: Positional arguments to pass to the function
18
- **kwargs: Keyword arguments to pass to the function
19
20
Returns:
21
Result of the function execution
22
"""
23
24
def local(self, *args, **kwargs):
25
"""
26
Call the function locally (useful for testing).
27
28
Parameters:
29
- *args: Positional arguments to pass to the function
30
- **kwargs: Keyword arguments to pass to the function
31
32
Returns:
33
Result of the function execution
34
"""
35
36
def map(
37
self,
38
inputs,
39
order_outputs: bool = True,
40
return_exceptions: bool = False
41
):
42
"""
43
Map the function over a list of inputs in parallel.
44
45
Parameters:
46
- inputs: Iterable of inputs to map over
47
- order_outputs: Whether to return outputs in input order
48
- return_exceptions: Include exceptions in results instead of raising
49
50
Returns:
51
List of results
52
"""
53
54
def spawn(self, *args, **kwargs):
55
"""
56
Spawn the function asynchronously without waiting for result.
57
58
Parameters:
59
- *args: Positional arguments to pass to the function
60
- **kwargs: Keyword arguments to pass to the function
61
62
Returns:
63
FunctionCall object for retrieving result later
64
"""
65
66
@classmethod
67
def from_name(
68
cls,
69
app_name: str,
70
tag: str = None,
71
namespace: str = None,
72
environment_name: str = None
73
):
74
"""
75
Look up a deployed function by name.
76
77
Parameters:
78
- app_name: Name of the app containing the function
79
- tag: Optional deployment tag
80
- namespace: Namespace to search in
81
- environment_name: Environment name
82
83
Returns:
84
Function object
85
"""
86
```
87
88
### FunctionCall Class
89
90
Represents an executing or executed function call, providing methods to retrieve results and manage execution.
91
92
```python { .api }
93
class FunctionCall:
94
def get(self, timeout: float = None):
95
"""
96
Get the result of the function call, blocking until completion.
97
98
Parameters:
99
- timeout: Maximum time to wait for result in seconds
100
101
Returns:
102
Result of the function call
103
104
Raises:
105
TimeoutError: If timeout is exceeded
106
"""
107
108
def cancel(self):
109
"""
110
Cancel the running function call.
111
112
Returns:
113
True if cancellation was successful
114
"""
115
116
def is_finished(self) -> bool:
117
"""
118
Check if the function call has completed.
119
120
Returns:
121
True if finished, False otherwise
122
"""
123
124
@property
125
def object_id(self) -> str:
126
"""
127
Get the unique ID of this function call.
128
129
Returns:
130
Function call ID string
131
"""
132
```
133
134
### Cls Class
135
136
Serverless class for stateful compute with lifecycle methods, enabling persistent state across method calls.
137
138
```python { .api }
139
class Cls:
140
@classmethod
141
def from_name(
142
cls,
143
app_name: str,
144
tag: str = None,
145
namespace: str = None,
146
environment_name: str = None
147
):
148
"""
149
Look up a deployed class by name.
150
151
Parameters:
152
- app_name: Name of the app containing the class
153
- tag: Optional deployment tag
154
- namespace: Namespace to search in
155
- environment_name: Environment name
156
157
Returns:
158
Cls object
159
"""
160
161
def lookup(self, method_name: str):
162
"""
163
Look up a specific method of the class.
164
165
Parameters:
166
- method_name: Name of the method to look up
167
168
Returns:
169
Method object that can be called remotely
170
"""
171
```
172
173
### Sandbox Class
174
175
Interactive compute environment for development, debugging, and ad-hoc computation.
176
177
```python { .api }
178
class Sandbox:
179
@classmethod
180
def create(
181
cls,
182
image: Image = None,
183
secrets: list[Secret] = None,
184
volumes: dict[str, Volume] = None,
185
mounts: list[Mount] = None,
186
memory: int = None,
187
cpu: float = None,
188
gpu: GPU_T = None,
189
timeout: int = None,
190
workdir: str = "/root",
191
**kwargs
192
):
193
"""
194
Create a new interactive sandbox.
195
196
Parameters:
197
- image: Container image for the sandbox
198
- secrets: List of secrets to inject
199
- volumes: Dictionary mapping paths to volumes
200
- mounts: List of mount objects
201
- memory: Memory limit in MB
202
- cpu: CPU allocation
203
- gpu: GPU configuration
204
- timeout: Sandbox timeout in seconds
205
- workdir: Working directory
206
207
Returns:
208
Sandbox instance
209
"""
210
211
def exec(
212
self,
213
command: str,
214
workdir: str = None,
215
secrets: list[Secret] = None,
216
**kwargs
217
):
218
"""
219
Execute a command in the sandbox.
220
221
Parameters:
222
- command: Shell command to execute
223
- workdir: Working directory for command
224
- secrets: Additional secrets for this command
225
226
Returns:
227
Command execution result
228
"""
229
230
def terminate(self):
231
"""
232
Terminate the sandbox, cleaning up all resources.
233
"""
234
235
def tunnel(self, port: int):
236
"""
237
Create a tunnel to a port in the sandbox.
238
239
Parameters:
240
- port: Port number to tunnel to
241
242
Returns:
243
Tunnel URL for accessing the port
244
"""
245
246
@property
247
def object_id(self) -> str:
248
"""
249
Get the unique ID of this sandbox.
250
251
Returns:
252
Sandbox ID string
253
"""
254
```
255
256
### SandboxSnapshot Class
257
258
Snapshot of a sandbox environment that can be reused to create new sandboxes or deploy as container images.
259
260
```python { .api }
261
class SandboxSnapshot:
262
@classmethod
263
def create(
264
cls,
265
sandbox: Sandbox,
266
label: str = None
267
):
268
"""
269
Create a snapshot from an existing sandbox.
270
271
Parameters:
272
- sandbox: Source sandbox to snapshot
273
- label: Optional label for the snapshot
274
275
Returns:
276
SandboxSnapshot instance
277
"""
278
279
def deploy(self, name: str):
280
"""
281
Deploy the snapshot as a container image.
282
283
Parameters:
284
- name: Name for the deployed image
285
286
Returns:
287
Deployed image reference
288
"""
289
290
@classmethod
291
def from_name(
292
cls,
293
label: str,
294
namespace: str = None
295
):
296
"""
297
Look up a snapshot by label.
298
299
Parameters:
300
- label: Snapshot label
301
- namespace: Optional namespace
302
303
Returns:
304
SandboxSnapshot instance
305
"""
306
```
307
308
## Usage Examples
309
310
### Basic Function Usage
311
312
```python
313
import modal
314
315
app = modal.App("compute-example")
316
317
@app.function()
318
def fibonacci(n: int) -> int:
319
if n <= 1:
320
return n
321
return fibonacci(n-1) + fibonacci(n-2)
322
323
@app.local_entrypoint()
324
def main():
325
# Call function remotely
326
result = fibonacci.remote(10)
327
print(f"Fibonacci(10) = {result}")
328
329
# Map over multiple inputs
330
results = fibonacci.map([1, 2, 3, 4, 5])
331
print(f"Results: {results}")
332
333
# Spawn async call
334
call = fibonacci.spawn(15)
335
# Do other work...
336
result = call.get()
337
print(f"Async result: {result}")
338
```
339
340
### Stateful Class Example
341
342
```python
343
import modal
344
from modal import enter, exit, method
345
346
app = modal.App("stateful-service")
347
348
@app.cls()
349
class DatabaseService:
350
@enter()
351
def setup(self):
352
# Initialize database connection
353
self.connection = create_db_connection()
354
self.cache = {}
355
356
@exit()
357
def cleanup(self):
358
# Clean up resources
359
self.connection.close()
360
361
@method()
362
def query(self, sql: str):
363
if sql in self.cache:
364
return self.cache[sql]
365
366
result = self.connection.execute(sql)
367
self.cache[sql] = result
368
return result
369
370
@method()
371
def insert(self, table: str, data: dict):
372
return self.connection.insert(table, data)
373
374
@app.local_entrypoint()
375
def main():
376
db = DatabaseService()
377
378
# Insert data
379
db.insert.remote("users", {"name": "Alice", "email": "alice@example.com"})
380
381
# Query data (uses caching)
382
users = db.query.remote("SELECT * FROM users")
383
print(users)
384
```
385
386
### Interactive Sandbox
387
388
```python
389
import modal
390
391
# Create a sandbox with custom environment
392
sandbox = modal.Sandbox.create(
393
image=modal.Image.debian_slim().pip_install("pandas", "matplotlib"),
394
timeout=3600 # 1 hour
395
)
396
397
# Execute commands
398
result = sandbox.exec("python -c 'import pandas; print(pandas.__version__)'")
399
print(f"Pandas version: {result.stdout}")
400
401
# Run a data analysis script
402
analysis_code = """
403
import pandas as pd
404
import matplotlib.pyplot as plt
405
406
# Create sample data
407
data = {'x': range(10), 'y': [i**2 for i in range(10)]}
408
df = pd.DataFrame(data)
409
410
# Create plot
411
plt.figure(figsize=(8, 6))
412
plt.plot(df['x'], df['y'])
413
plt.savefig('/tmp/plot.png')
414
plt.close()
415
416
print("Analysis complete")
417
"""
418
419
result = sandbox.exec(f"python -c \"{analysis_code}\"")
420
print(result.stdout)
421
422
# Terminate when done
423
sandbox.terminate()
424
```
425
426
### Sandbox Snapshots
427
428
```python
429
import modal
430
431
# Create and configure a sandbox
432
sandbox = modal.Sandbox.create(
433
image=modal.Image.debian_slim()
434
)
435
436
# Install custom software
437
sandbox.exec("apt-get update && apt-get install -y git curl")
438
sandbox.exec("pip install numpy scipy scikit-learn")
439
440
# Create a snapshot
441
snapshot = modal.SandboxSnapshot.create(sandbox, label="ml-environment")
442
443
# Use the snapshot to create new sandboxes
444
new_sandbox = modal.Sandbox.create(image=snapshot)
445
446
# Or deploy as an image for functions
447
app = modal.App("ml-app")
448
449
@app.function(image=snapshot)
450
def ml_computation(data):
451
import numpy as np
452
from sklearn.linear_model import LinearRegression
453
454
# ML computation using pre-installed libraries
455
model = LinearRegression()
456
return model.fit(data['X'], data['y']).predict(data['X_test'])
457
```
458
459
### Parallel Processing
460
461
```python
462
import modal
463
464
app = modal.App("parallel-processing")
465
466
@app.function()
467
def process_batch(batch_data: list) -> dict:
468
# Process a batch of data
469
results = {}
470
for item in batch_data:
471
results[item['id']] = expensive_computation(item['data'])
472
return results
473
474
@app.local_entrypoint()
475
def main():
476
# Prepare data batches
477
all_data = [{'id': i, 'data': f"data_{i}"} for i in range(1000)]
478
batches = [all_data[i:i+100] for i in range(0, len(all_data), 100)]
479
480
# Process batches in parallel
481
batch_results = process_batch.map(batches)
482
483
# Combine results
484
final_results = {}
485
for batch_result in batch_results:
486
final_results.update(batch_result)
487
488
print(f"Processed {len(final_results)} items")
489
```