dart_monty 0.17.1 copy "dart_monty: ^0.17.1" to clipboard
dart_monty: ^0.17.1 copied to clipboard

Script your Dart/Flutter app with sandboxed Python — runtime extensions, Flutter glue, and FFI/WASM asset loading on top of dart_monty_core.

dart_monty #

dart_monty

CI Pages codecov

Live Demo | Documentation | GitHub

Sandboxed Python interpreter for Dart and Flutter. Run Python from native, web, and mobile — one package, every platform.

Quick Start #

Install #

dart pub add dart_monty

The low-level bindings (dart_monty_core) are pulled in transitively.

On Flutter, add the asset stanza so the bundler includes dart_monty_core's WASM/JS bridge files (plain-Dart consumers can skip this):

flutter:
  assets:
    - package: dart_monty_core

For local development against a worktree, override with path: deps:

dependencies:
  dart_monty:
    path: /path/to/dart_monty
  dart_monty_core:
    path: /path/to/dart_monty_core

Then import the package:

import 'package:dart_monty/dart_monty.dart';

On Flutter Web, initialise the bridge before first use:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await DartMonty.ensureInitialized(); // loads bridge on web; no-op native
  runApp(const MyApp());
}

No <script> tag in web/index.html is required — DartMonty.ensureInitialized() injects the bridge dynamically.

Now you can use dart_monty in three ways:

1. One-shot execution

For simple, stateless execution, use the static Monty.exec() method:

Future<void> main() async {
  final result = await Monty.exec('2 + 2');
  print(result.value); // 4
}

2. Stateful REPL

For interactive, stateful sessions, use a MontyRepl:

Future<void> main() async {
  final repl = MontyRepl();
  await repl.feedRun('x = 42');
  await repl.feedRun('def double(n): return n * 2');
  final result = await repl.feedRun('double(x)');
  print(result.value); // MontyInt(84)
  await repl.dispose();
}

3. Runtime with host functions and extensions

MontyRuntime manages host functions, extensions, and long-lived sessions. Register HostFunctions to expose Dart callbacks to Python:

Future<void> main() async {
  final runtime = MontyRuntime()
    ..register(HostFunction(
      schema: const HostFunctionSchema(
        name: 'fetch',
        params: [HostParam(name: 'url', type: HostParamType.string)],
      ),
      // DispatchMode.future lets Python `await fetch(url)` directly.
      // asyncio.gather over multiple calls runs them concurrently.
      dispatch: DispatchMode.future,
      handler: (args, _) async => httpClient.get(args['url']! as String),
    ));

  final result = await runtime.execute(
    'await fetch(base_url)',
    inputs: {'base_url': 'https://example.com/api'},
  ).result;
  print(result.value);
  await runtime.dispose();
}

For plugin-style wiring, pass extensions:

final runtime = MontyRuntime(
  extensions: [JinjaTemplateExtension(), MessageBusExtension()],
);

Examples #

Runnable end-to-end demos, all platform-agnostic (FFI on the VM, WASM in Chrome — Monty dispatches to the same Rust ABI on every backend):

File What it shows
example/example.dart Minimal Monty.exec one-shots, including error handling.
example/type_check_demo.dart Monty.typeCheck for static type analysis — clean code, type errors, prefixCode for declaring external function shapes.
example/dataclass_demo.dart Stateful dataclass round-trip across MontyRuntime.execute calls — produce, attribute-access, return, and re-bind a @dataclass, hydrating into a typed Dart User on the way back.

Run any of them with dart run example/<file>.dart from the repo root. For the native and web runners (with built Rust library and a COOP/COEP server), see example/native/run.sh and example/web/run.sh.

Documentation #

Stability and versioning #

This package does not follow semantic versioning. Breaking changes can land in any release. The CHANGELOG is kept up-to-date with every breaking change, so pin to a specific version and read the changelog before upgrading.

We expect to stabilise the API and adopt semver when the package goes into production — roughly 1–3 months from now. If you are planning to depend on this package, please open an issue so we can factor your use-case into the stabilisation work.

License #

MIT License. See LICENSE.

3
likes
150
points
338
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Script your Dart/Flutter app with sandboxed Python — runtime extensions, Flutter glue, and FFI/WASM asset loading on top of dart_monty_core.

Repository (GitHub)
View/report issues
Contributing

Topics

#python #sandbox #interpreter #dart

License

MIT (license)

Dependencies

collection, dart_monty_core, dinja, file, meta, path, signals_core, struct_log, test, web

More

Packages that depend on dart_monty