|
8 | 8 | [](https://runyaga.github.io/dart_monty/) |
9 | 9 | [](https://codecov.io/gh/runyaga/dart_monty) |
10 | 10 |
|
11 | | -[Live Demo](https://runyaga.github.io/dart_monty/) | [Documentation](https://github.com/runyaga/dart_monty/tree/main/docs) | [GitHub](https://github.com/runyaga/dart_monty) |
| 11 | +`dart_monty` runs restricted Python from Dart and Flutter on native and web |
| 12 | +platforms. It adds stateful runtimes, Dart host functions, extensions, event |
| 13 | +streams, and OS-call policy to the pool and session primitives supplied by |
| 14 | +`dart_monty_core`. |
12 | 15 |
|
13 | | -Sandboxed Python interpreter for Dart and Flutter. Run Python from native, web, and mobile — one package, every platform. |
| 16 | +## Installation |
14 | 17 |
|
15 | | -## Quick Start |
16 | | - |
17 | | -### Install |
18 | | - |
19 | | -```sh |
20 | | -dart pub add dart_monty |
21 | | -``` |
22 | | - |
23 | | -The low-level bindings (`dart_monty_core`) are pulled in transitively. |
24 | | - |
25 | | -Flutter Web uses the worker assets declared by core's `flutter.assets` |
26 | | -stanza and core's asset-path probe. Both packages remain pure Dart; no |
27 | | -Flutter SDK dependency or initialization call is added to core. |
28 | | -See [installation](docs/user/install.md#flutter-web) for bundling details. |
29 | | - |
30 | | -For local development against a worktree, override with `path:` |
31 | | -deps: |
| 18 | +The package and its core dependency are released from matching Git tags. Add |
| 19 | +the package and override core in the application `pubspec.yaml`: |
32 | 20 |
|
33 | 21 | ```yaml |
34 | 22 | dependencies: |
35 | 23 | dart_monty: |
36 | | - path: /path/to/dart_monty |
37 | | - dart_monty_core: |
38 | | - path: /path/to/dart_monty_core |
39 | | -``` |
| 24 | + git: |
| 25 | + url: https://github.com/runyaga/dart_monty.git |
| 26 | + ref: v0.110.0-dev.4 |
40 | 27 |
|
41 | | -Then import the package: |
42 | | -
|
43 | | -```dart |
44 | | -import 'package:dart_monty/dart_monty.dart'; |
| 28 | +dependency_overrides: |
| 29 | + dart_monty_core: |
| 30 | + git: |
| 31 | + url: https://github.com/runyaga/dart_monty_core.git |
| 32 | + ref: v0.110.0-dev.4 |
45 | 33 | ``` |
46 | 34 |
|
47 | | -Now you can use `dart_monty` in three ways: |
| 35 | +See [Installation](docs/user/install.md) for direct core imports and local |
| 36 | +worktree dependencies. |
48 | 37 |
|
49 | | -**1. One-shot execution** |
50 | | - |
51 | | -Use a pool and a session for execution: |
| 38 | +## Quick start |
52 | 39 |
|
53 | 40 | ```dart |
54 | | -final value = await Monty.withPool( |
55 | | - (pool) => pool.withSession((session) => session.feedRun('2 + 2')), |
56 | | -); |
57 | | -print(value.dartValue); // 4 |
58 | | -``` |
59 | | - |
60 | | -**2. Stateful session** |
| 41 | +import 'package:dart_monty/dart_monty.dart'; |
61 | 42 |
|
62 | | -```dart |
63 | | -await Monty.withPool((pool) async { |
64 | | - final session = await pool.checkout(typeCheck: true); |
| 43 | +Future<void> main() async { |
| 44 | + final runtime = await MontyRuntime.start(); |
65 | 45 | try { |
66 | | - await session.feedRun('x: int = 42'); |
67 | | - final result = await session.feedRun('x * 2'); |
68 | | - print(result.dartValue); // 84 |
| 46 | + await runtime.execute('x = 41').result; |
| 47 | + final value = await runtime.execute('x + 1').result; |
| 48 | + print(value.dartValue); // 42 |
69 | 49 | } finally { |
70 | | - await session.close(); |
| 50 | + await runtime.dispose(); |
71 | 51 | } |
72 | | -}); |
73 | | -``` |
74 | | - |
75 | | -Type checking happens before each feed runs. A rejected feed throws |
76 | | -`MontyTypingError`, available from core's public library. See the |
77 | | -[type-checking example](example/type_check_demo.dart) for `typeCheckStubs`. |
78 | | - |
79 | | -**3. Runtime with host functions and extensions** |
80 | | - |
81 | | -`MontyRuntime` manages host functions, extensions, and long-lived sessions. |
82 | | -Register `HostFunction`s to expose Dart callbacks to Python: |
83 | | - |
84 | | -```dart |
85 | | -Future<void> main() async { |
86 | | - final runtime = (await MontyRuntime.start()) |
87 | | - ..register(HostFunction( |
88 | | - schema: const HostFunctionSchema( |
89 | | - name: 'fetch', |
90 | | - description: 'Fetch a URL', |
91 | | - params: [HostParam(name: 'url', type: HostParamType.string)], |
92 | | - ), |
93 | | - // DispatchMode.future lets Python `await fetch(url)` directly. |
94 | | - // asyncio.gather over multiple calls runs them concurrently. |
95 | | - dispatch: DispatchMode.future, |
96 | | - handler: (args, _) async => httpClient.get(args['url']! as String), |
97 | | - )); |
98 | | -
|
99 | | - final result = await runtime.execute( |
100 | | - 'await fetch(base_url)', |
101 | | - inputs: {'base_url': 'https://example.com/api'}, |
102 | | - ).result; |
103 | | - print(result.dartValue); |
104 | | - await runtime.dispose(); |
105 | 52 | } |
106 | 53 | ``` |
107 | 54 |
|
108 | | -For plugin-style wiring, pass `extensions`: |
109 | | - |
110 | | -```dart |
111 | | -final runtime = await MontyRuntime.start( |
112 | | - extensions: [EventLoopExtension()], |
113 | | -); |
114 | | -``` |
115 | | - |
116 | | -## Examples |
117 | | - |
118 | | -Runnable end-to-end demos, all platform-agnostic (FFI on the VM, WASM |
119 | | -in Chrome — `Monty` dispatches to the same Rust ABI on every backend): |
| 55 | +See [Choosing an API](docs/user/api-reference.md) for the runtime and direct |
| 56 | +session tradeoffs. |
120 | 57 |
|
121 | | -| File | What it shows | |
122 | | -|---|---| |
123 | | -| [`example/example.dart`](example/example.dart) | Minimal pool/session one-shots, including error handling. | |
124 | | -| [`example/type_check_demo.dart`](example/type_check_demo.dart) | Session type checking with `checkout(typeCheck: true)` and `typeCheckStubs`. | |
125 | | -| [`example/dataclass_demo.dart`](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. | |
| 58 | +## Platform support |
126 | 59 |
|
127 | | -Run any of them with `dart run example/<file>.dart` from the repo root. |
128 | | -For the native and web runners (with built Rust library and a COOP/COEP |
129 | | -server), see `example/native/run.sh` and `example/web/run.sh`. |
| 60 | +The Dart VM and Flutter native targets use core's native worker. Browser |
| 61 | +targets use its Web Worker and WASM assets. Web deployments require the |
| 62 | +worker assets and cross-origin isolation headers. Native applications that use |
| 63 | +`MountDir` or self-contained executables must opt in to core's worker build. |
| 64 | +See [Deployment and Bundling](docs/user/deployment.md) for those constraints. |
130 | 65 |
|
131 | 66 | ## Documentation |
132 | 67 |
|
133 | | -- [**Installation**](docs/user/install.md) — Add to your project |
134 | | -- [**Overview**](docs/help.md) — API summary and quick start |
135 | | -- [**Architecture**](docs/architecture/overview.md) — Module structure and internals |
136 | | -- [**REPL Guide**](docs/user/repl.md) — Stateful interactive execution |
137 | | -- [**Extensions**](docs/user/extensions.md) — EventLoop, Sandbox |
138 | | -- [**Contributing**](CONTRIBUTING.md) — Build, run tests, gate scripts, release process |
139 | | -- [**Contributor Setup**](docs/contributor/setup.md) — Toolchain install (Rust, Dart, Python) |
140 | | - |
141 | | -## Stability and versioning |
142 | | - |
143 | | -This package does **not** follow semantic versioning. Breaking changes can |
144 | | -land in any release. The [CHANGELOG](CHANGELOG.md) is kept up-to-date with |
145 | | -every breaking change, so pin to a specific version and read the changelog |
146 | | -before upgrading. |
| 68 | +- [Stateful and concurrent execution](docs/deep-dives/bridge-concurrency.md) |
| 69 | +- [Host functions](docs/tutorials/host-functions-intro.md) |
| 70 | +- [Extensions](docs/deep-dives/extension-system.md) |
| 71 | +- [Sandbox lifecycle and isolation](docs/deep-dives/sandbox-architecture.md) |
| 72 | +- [Filesystem and workspace policy](docs/deep-dives/oscall-vfs.md) |
| 73 | +- [Failure propagation](docs/deep-dives/error-hierarchy.md) |
| 74 | +- [Testing](docs/contributor/testing.md) |
147 | 75 |
|
148 | | -We expect to stabilise the API and adopt semver when the package goes into |
149 | | -production — roughly 1–3 months from now. If you are planning to depend on |
150 | | -this package, please open an issue so we can factor your use-case into the |
151 | | -stabilisation work. |
| 76 | +The public declarations are listed in |
| 77 | +[`lib/dart_monty.dart`](lib/dart_monty.dart). |
152 | 78 |
|
153 | 79 | ## License |
154 | 80 |
|
155 | | -MIT License. See [LICENSE](LICENSE). |
| 81 | +The package uses the [MIT License](LICENSE). |
0 commit comments