crates/monty-js/README.md
JavaScript/TypeScript bindings for the Monty sandboxed Python interpreter.
npm install @pydantic/monty
import { Monty } from '@pydantic/monty'
// Create interpreter and run code
const m = new Monty('1 + 2')
const result = m.run() // returns 3
const m = new Monty('x + y', { inputs: ['x', 'y'] })
const result = m.run({ inputs: { x: 10, y: 20 } }) // returns 30
For synchronous external functions, pass them directly to run():
const m = new Monty('add(2, 3)')
const result = m.run({
externalFunctions: {
add: (a: number, b: number) => a + b,
},
}) // returns 5
For async external functions, use runMontyAsync():
import { Monty, runMontyAsync } from '@pydantic/monty'
const m = new Monty('fetch_data(url)', {
inputs: ['url'],
})
const result = await runMontyAsync(m, {
inputs: { url: 'https://example.com' },
externalFunctions: {
fetch_data: async (url: string) => {
const response = await fetch(url)
return response.text()
},
},
})
For fine-grained control over external function calls, use start() and resume():
const m = new Monty('a() + b()')
let progress = m.start()
while (progress instanceof MontySnapshot) {
console.log(`Calling: ${progress.functionName}`)
console.log(`Args: ${progress.args}`)
// Provide the return value and resume
progress = progress.resume({ returnValue: 10 })
}
// progress is now MontyComplete
console.log(progress.output) // 20
import { Monty, MontySyntaxError, MontyRuntimeError, MontyTypingError } from '@pydantic/monty'
try {
const m = new Monty('1 / 0')
m.run()
} catch (error) {
if (error instanceof MontySyntaxError) {
console.log('Syntax error:', error.message)
} else if (error instanceof MontyRuntimeError) {
console.log('Runtime error:', error.message)
console.log('Traceback:', error.traceback())
} else if (error instanceof MontyTypingError) {
console.log('Type error:', error.displayDiagnostics())
}
}
const m = new Monty('"hello" + 1')
try {
m.typeCheck()
} catch (error) {
if (error instanceof MontyTypingError) {
console.log(error.displayDiagnostics('concise'))
}
}
// Or enable during construction
const m2 = new Monty('1 + 1', { typeCheck: true })
const m = new Monty('1 + 1')
const result = m.run({
limits: {
maxAllocations: 10000,
maxDurationSecs: 5,
maxMemory: 1024 * 1024, // 1MB
maxRecursionDepth: 100,
},
})
// Save parsed code to avoid re-parsing
const m = new Monty('complex_code()')
const data = m.dump()
// Later, restore without re-parsing
const m2 = Monty.load(data)
const result = m2.run()
// Snapshots can also be serialized
const snapshot = m.start()
if (snapshot instanceof MontySnapshot) {
const snapshotData = snapshot.dump()
// Later, restore and resume
const restored = MontySnapshot.load(snapshotData)
const result = restored.resume({ returnValue: 42 })
}
Monty Classconstructor(code: string, options?: MontyOptions) - Parse Python coderun(options?: RunOptions) - Execute and return the resultstart(options?: StartOptions) - Start iterative executiontypeCheck(prefixCode?: string) - Perform static type checkingdump() - Serialize to binary formatMonty.load(data) - Deserialize from binary formatscriptName - The script name (default: 'main.py')inputs - Declared input variable namesMontyOptionsscriptName?: string - Name used in tracebacks (default: 'main.py')inputs?: string[] - Input variable namestypeCheck?: boolean - Enable type checking on constructiontypeCheckPrefixCode?: string - Code to prepend for type checkingRunOptionsinputs?: object - Input variable valueslimits?: ResourceLimits - Resource limitsexternalFunctions?: object - External function callbacksResourceLimitsmaxAllocations?: number - Maximum heap allocationsmaxDurationSecs?: number - Maximum execution time in secondsmaxMemory?: number - Maximum heap memory in bytesgcInterval?: number - Run GC every N allocationsmaxRecursionDepth?: number - Maximum call stack depth (default: 1000)MontySnapshot ClassReturned by start() when execution pauses at an external function call.
scriptName - The script being executedfunctionName - The external function being calledargs - Positional argumentskwargs - Keyword argumentsresume(options: ResumeOptions) - Resume with return value or exceptiondump() / MontySnapshot.load(data) - SerializationMontyComplete ClassReturned by start() or resume() when execution completes.
output - The final result valueMontyError - Base class for all Monty errorsMontySyntaxError - Syntax/parsing errorsMontyRuntimeError - Runtime exceptions (with traceback())MontyTypingError - Type checking errors (with displayDiagnostics())