@pydantic/monty
v0.0.9
Published
Sandboxed Python interpreter for JavaScript/TypeScript
Keywords
Readme
@pydantic/monty
JavaScript/TypeScript bindings for the Monty sandboxed Python interpreter.
Installation
npm install @pydantic/montyBasic Usage
import { Monty } from '@pydantic/monty'
// Create interpreter and run code
const m = new Monty('1 + 2')
const result = m.run() // returns 3Input Variables
const m = new Monty('x + y', { inputs: ['x', 'y'] })
const result = m.run({ inputs: { x: 10, y: 20 } }) // returns 30External Functions
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 5For 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()
},
},
})Iterative Execution
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) // 20Error Handling
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())
}
}Type Checking
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 })Resource Limits
const m = new Monty('1 + 1')
const result = m.run({
limits: {
maxAllocations: 10000,
maxDurationSecs: 5,
maxMemory: 1024 * 1024, // 1MB
maxRecursionDepth: 100,
},
})Serialization
// 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 })
}API Reference
Monty Class
constructor(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 names
MontyOptions
scriptName?: 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 checking
RunOptions
inputs?: object- Input variable valueslimits?: ResourceLimits- Resource limitsexternalFunctions?: object- External function callbacks
ResourceLimits
maxAllocations?: 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 Class
Returned 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)- Serialization
MontyComplete Class
Returned by start() or resume() when execution completes.
output- The final result value
Error Classes
MontyError- Base class for all Monty errorsMontySyntaxError- Syntax/parsing errorsMontyRuntimeError- Runtime exceptions (withtraceback())MontyTypingError- Type checking errors (withdisplayDiagnostics())
