denosaurs 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. denosaurs-0.1.0/.github/workflows/benchmarks.yml +32 -0
  2. denosaurs-0.1.0/.github/workflows/docs.yml +53 -0
  3. denosaurs-0.1.0/.github/workflows/workflow.yaml +90 -0
  4. denosaurs-0.1.0/.gitignore +72 -0
  5. denosaurs-0.1.0/BENCHMARKS.md +68 -0
  6. denosaurs-0.1.0/CLAUDE.md +472 -0
  7. denosaurs-0.1.0/Cargo.lock +2727 -0
  8. denosaurs-0.1.0/Cargo.toml +50 -0
  9. denosaurs-0.1.0/LICENSE +22 -0
  10. denosaurs-0.1.0/Makefile +100 -0
  11. denosaurs-0.1.0/PATCH.md +114 -0
  12. denosaurs-0.1.0/PKG-INFO +228 -0
  13. denosaurs-0.1.0/README.md +198 -0
  14. denosaurs-0.1.0/benches/runtime_benches.rs +90 -0
  15. denosaurs-0.1.0/benches_py/test_bench_runtime.py +87 -0
  16. denosaurs-0.1.0/benchmarks/README.md +70 -0
  17. denosaurs-0.1.0/benchmarks/bench_memory.py +105 -0
  18. denosaurs-0.1.0/benchmarks/bench_regex.py +86 -0
  19. denosaurs-0.1.0/benchmarks/bench_startup.py +56 -0
  20. denosaurs-0.1.0/benchmarks/bench_threading.py +71 -0
  21. denosaurs-0.1.0/benchmarks/suite.py +102 -0
  22. denosaurs-0.1.0/docs/api/config.md +3 -0
  23. denosaurs-0.1.0/docs/api/denosaurs.md +14 -0
  24. denosaurs-0.1.0/docs/api/runtime.md +3 -0
  25. denosaurs-0.1.0/docs/api/types.md +17 -0
  26. denosaurs-0.1.0/docs/assets/banner.png +0 -0
  27. denosaurs-0.1.0/docs/assets/logo.png +0 -0
  28. denosaurs-0.1.0/docs/assets/logo.svg +4 -0
  29. denosaurs-0.1.0/docs/concepts/evaluation.md +282 -0
  30. denosaurs-0.1.0/docs/concepts/runtime.md +291 -0
  31. denosaurs-0.1.0/docs/concepts/types.md +275 -0
  32. denosaurs-0.1.0/docs/contributing/architecture.md +367 -0
  33. denosaurs-0.1.0/docs/contributing/development.md +66 -0
  34. denosaurs-0.1.0/docs/guides/advanced/inspector.md +63 -0
  35. denosaurs-0.1.0/docs/guides/advanced/snapshots.md +206 -0
  36. denosaurs-0.1.0/docs/guides/advanced/webassembly.md +80 -0
  37. denosaurs-0.1.0/docs/guides/bindings.md +283 -0
  38. denosaurs-0.1.0/docs/guides/modules.md +270 -0
  39. denosaurs-0.1.0/docs/index.md +47 -0
  40. denosaurs-0.1.0/docs/quickstart.md +116 -0
  41. denosaurs-0.1.0/docs/stubs/denosaurs/__init__.py +68 -0
  42. denosaurs-0.1.0/docs/stubs/denosaurs/_denosaurs.py +1002 -0
  43. denosaurs-0.1.0/docs/stylesheets/extra.css +6 -0
  44. denosaurs-0.1.0/docs/use-cases/ai-agent.md +211 -0
  45. denosaurs-0.1.0/docs/use-cases/playground.md +100 -0
  46. denosaurs-0.1.0/docs/use-cases/plugin-system.md +177 -0
  47. denosaurs-0.1.0/docs/use-cases/serverless-runtime.md +259 -0
  48. denosaurs-0.1.0/docs/use-cases/workflow.md +226 -0
  49. denosaurs-0.1.0/examples/README.md +69 -0
  50. denosaurs-0.1.0/examples/add.wasm +0 -0
  51. denosaurs-0.1.0/examples/basic_eval.py +57 -0
  52. denosaurs-0.1.0/examples/bindings_async.py +121 -0
  53. denosaurs-0.1.0/examples/bindings_basic.py +232 -0
  54. denosaurs-0.1.0/examples/context_local_api.py +166 -0
  55. denosaurs-0.1.0/examples/fastapi_multitenant.py +172 -0
  56. denosaurs-0.1.0/examples/inspector.py +48 -0
  57. denosaurs-0.1.0/examples/markdown_parser.py +86 -0
  58. denosaurs-0.1.0/examples/modules_basic.py +43 -0
  59. denosaurs-0.1.0/examples/modules_wasm.py +41 -0
  60. denosaurs-0.1.0/examples/resource_limits.py +292 -0
  61. denosaurs-0.1.0/examples/snapshot_example.py +245 -0
  62. denosaurs-0.1.0/examples/threading_gil.py +81 -0
  63. denosaurs-0.1.0/examples/type_conversion.py +280 -0
  64. denosaurs-0.1.0/mkdocs.yml +108 -0
  65. denosaurs-0.1.0/pyproject.toml +60 -0
  66. denosaurs-0.1.0/python/denosaurs/__init__.py +257 -0
  67. denosaurs-0.1.0/python/denosaurs/__main__.py +63 -0
  68. denosaurs-0.1.0/python/denosaurs/_denosaurs.pyi +1002 -0
  69. denosaurs-0.1.0/python/denosaurs/py.typed +0 -0
  70. denosaurs-0.1.0/src/lib.rs +42 -0
  71. denosaurs-0.1.0/src/runtime/config.rs +574 -0
  72. denosaurs-0.1.0/src/runtime/conversion.rs +375 -0
  73. denosaurs-0.1.0/src/runtime/error.rs +271 -0
  74. denosaurs-0.1.0/src/runtime/handle.rs +822 -0
  75. denosaurs-0.1.0/src/runtime/inspector.rs +515 -0
  76. denosaurs-0.1.0/src/runtime/js_value.rs +448 -0
  77. denosaurs-0.1.0/src/runtime/loader.rs +399 -0
  78. denosaurs-0.1.0/src/runtime/mod.rs +179 -0
  79. denosaurs-0.1.0/src/runtime/ops.rs +520 -0
  80. denosaurs-0.1.0/src/runtime/python/bridge.rs +220 -0
  81. denosaurs-0.1.0/src/runtime/python/error.rs +94 -0
  82. denosaurs-0.1.0/src/runtime/python/mod.rs +73 -0
  83. denosaurs-0.1.0/src/runtime/python/runtime.rs +1048 -0
  84. denosaurs-0.1.0/src/runtime/python/snapshot.rs +49 -0
  85. denosaurs-0.1.0/src/runtime/python/stats.rs +153 -0
  86. denosaurs-0.1.0/src/runtime/python/utils.rs +58 -0
  87. denosaurs-0.1.0/src/runtime/runner.rs +3253 -0
  88. denosaurs-0.1.0/src/runtime/snapshot.rs +100 -0
  89. denosaurs-0.1.0/src/runtime/stats.rs +241 -0
  90. denosaurs-0.1.0/src/runtime/stream.rs +533 -0
  91. denosaurs-0.1.0/tests/test_denosaurs_api.py +341 -0
  92. denosaurs-0.1.0/tests/test_function.py +195 -0
  93. denosaurs-0.1.0/tests/test_modules.py +274 -0
  94. denosaurs-0.1.0/tests/test_ops.py +642 -0
  95. denosaurs-0.1.0/tests/test_runtime.py +1880 -0
  96. denosaurs-0.1.0/tests/test_termination_handle.py +132 -0
  97. denosaurs-0.1.0/uv.lock +859 -0
@@ -0,0 +1,32 @@
1
+ name: Benchmarks
2
+
3
+ # Informational only -- reports numbers in the log/summary, never fails the build.
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ benchmarks:
14
+ # macos-latest: the Linux cdylib build currently fails to link V8 (rust-lld
15
+ # TLS relocation vs -shared, tracked separately, pre-existing/unrelated to
16
+ # benchmarking) -- same failure as the v0.1.0 Linux wheel build.
17
+ runs-on: macos-latest
18
+ steps:
19
+ - uses: actions/checkout@v5
20
+
21
+ - uses: astral-sh/setup-uv@v7
22
+
23
+ - name: Rust benchmarks (Criterion)
24
+ run: cargo bench --features bench | tee -a "$GITHUB_STEP_SUMMARY"
25
+
26
+ - name: Build release extension
27
+ run: |
28
+ uv sync --group all
29
+ uv run maturin develop --uv --release
30
+
31
+ - name: Python benchmarks (pytest-benchmark)
32
+ run: uv run pytest benches_py/ --benchmark-only | tee -a "$GITHUB_STEP_SUMMARY"
@@ -0,0 +1,53 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ # push:
5
+ # branches:
6
+ # - main
7
+ workflow_dispatch:
8
+
9
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
10
+ permissions:
11
+ contents: read
12
+ pages: write
13
+ id-token: write
14
+
15
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
16
+ # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
17
+ concurrency:
18
+ group: "pages"
19
+ cancel-in-progress: false
20
+
21
+ jobs:
22
+ build:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v5
26
+
27
+ - uses: actions/setup-python@v6
28
+ with:
29
+ python-version: "3.x"
30
+
31
+ - uses: astral-sh/setup-uv@v7
32
+
33
+ - name: Install dependencies
34
+ run: uv sync --no-install-project --group docs
35
+
36
+ - name: Build documentation
37
+ run: source .venv/bin/activate && mkdocs build
38
+
39
+ - name: Upload artifact
40
+ uses: actions/upload-pages-artifact@v4
41
+ with:
42
+ path: ./site
43
+
44
+ deploy:
45
+ environment:
46
+ name: github-pages
47
+ url: ${{ steps.deployment.outputs.page_url }}
48
+ runs-on: ubuntu-latest
49
+ needs: build
50
+ steps:
51
+ - name: Deploy to GitHub Pages
52
+ id: deployment
53
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,90 @@
1
+ name: Publish to PyPI
2
+
3
+ # Runs only when a GitHub Release is published -- never on every push.
4
+ # Actually publishing requires PyPI Trusted Publishing to be configured for
5
+ # this exact repo + workflow on the PyPI project page first (see README).
6
+ on:
7
+ release:
8
+ types: [published]
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ linux:
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ target: [x86_64]
19
+ steps:
20
+ - uses: actions/checkout@v5
21
+ - name: Build manylinux wheels
22
+ uses: PyO3/maturin-action@v1
23
+ with:
24
+ target: ${{ matrix.target }}
25
+ args: --release --out dist --find-interpreter
26
+ # v8 >=150.1 (pulled in via deno_core >=0.409, see Cargo.toml) needs
27
+ # glibc's memfd_create (glibc >=2.27), which manylinux2014's glibc
28
+ # 2.17 lacks ("auto" resolved to manylinux2014 and the resulting
29
+ # wheel failed to import: "undefined symbol: memfd_create").
30
+ # manylinux_2_28 ships glibc 2.28.
31
+ manylinux: 2_28
32
+ - uses: actions/upload-artifact@v4
33
+ with:
34
+ name: wheels-linux-${{ matrix.target }}
35
+ path: dist
36
+
37
+ macos:
38
+ runs-on: macos-latest
39
+ steps:
40
+ - uses: actions/checkout@v5
41
+ - uses: PyO3/maturin-action@v1
42
+ with:
43
+ args: --release --out dist --find-interpreter
44
+ - uses: actions/upload-artifact@v4
45
+ with:
46
+ name: wheels-macos
47
+ path: dist
48
+
49
+ windows:
50
+ runs-on: windows-latest
51
+ steps:
52
+ - uses: actions/checkout@v5
53
+ - uses: PyO3/maturin-action@v1
54
+ with:
55
+ args: --release --out dist --find-interpreter
56
+ - uses: actions/upload-artifact@v4
57
+ with:
58
+ name: wheels-windows
59
+ path: dist
60
+
61
+ sdist:
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - uses: actions/checkout@v5
65
+ - uses: PyO3/maturin-action@v1
66
+ with:
67
+ command: sdist
68
+ args: --out dist
69
+ - uses: actions/upload-artifact@v4
70
+ with:
71
+ name: wheels-sdist
72
+ path: dist
73
+
74
+ publish:
75
+ name: Publish to PyPI (Trusted Publishing)
76
+ needs: [linux, macos, windows, sdist]
77
+ runs-on: ubuntu-latest
78
+ environment:
79
+ name: pypi
80
+ url: https://pypi.org/p/denosaurs
81
+ permissions:
82
+ id-token: write # required for PyPI Trusted Publishing (OIDC) -- no API token secret needed
83
+ steps:
84
+ - uses: actions/download-artifact@v6
85
+ with:
86
+ pattern: wheels-*
87
+ path: dist
88
+ merge-multiple: true
89
+ - name: Publish
90
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,72 @@
1
+ /target
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ .pytest_cache/
6
+ *.py[cod]
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ .venv/
14
+ env/
15
+ bin/
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ include/
26
+ man/
27
+ venv/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+
32
+ # Installer logs
33
+ pip-log.txt
34
+ pip-delete-this-directory.txt
35
+ pip-selfcheck.json
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .coverage
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+
45
+ # Translations
46
+ *.mo
47
+
48
+ # Mr Developer
49
+ .mr.developer.cfg
50
+ .project
51
+ .pydevproject
52
+
53
+ # Rope
54
+ .ropeproject
55
+
56
+ # Django stuff:
57
+ *.log
58
+ *.pot
59
+
60
+ .DS_Store
61
+
62
+ # Sphinx documentation
63
+ docs/_build/
64
+
65
+ # PyCharm
66
+ .idea/
67
+
68
+ # VSCode
69
+ .vscode/
70
+
71
+ # Pyenv
72
+ .python-version
@@ -0,0 +1,68 @@
1
+ # Benchmarks
2
+
3
+ Two suites: Rust-level (Criterion, `benches/`, bypasses the Python API) and
4
+ Python-level (pytest-benchmark, `benches_py/`, the real user-facing surface).
5
+ Both run in CI on every push/PR (`.github/workflows/benchmarks.yml`),
6
+ informational only -- they report numbers, they don't gate merges.
7
+
8
+ Numbers below are one real measured run, not simulated. They are
9
+ environment-dependent -- re-run locally before trusting them for a regression
10
+ decision on different hardware.
11
+
12
+ ## Measurement environment
13
+
14
+ - Apple M2, 8 cores, 16 GB RAM, macOS 25.5.0 (Darwin), arm64
15
+ - Rust 1.93.1, `cargo bench --features bench` (release/`bench` profile)
16
+ - Python 3.14.3, `pytest-benchmark` 5.3.0, `maturin develop --release`
17
+
18
+ ## Rust (Criterion, `cargo bench --features bench`)
19
+
20
+ | Benchmark | Time |
21
+ |---|---|
22
+ | `isolate_creation_and_close` | 2.52 ms |
23
+ | `simple_eval_throughput` (`1 + 41`) | 4.20 µs |
24
+ | `host_callback_op_dispatch` (real Python callable via `register_op`) | 13.14 µs |
25
+ | `termination_handle/is_terminated_check` | 0.92 ns |
26
+ | `termination_handle/terminate_round_trip` (idle runtime) | 87.16 µs |
27
+
28
+ `is_terminated()` is a single atomic load -- effectively free to poll. The
29
+ 206x-larger `terminate_round_trip` number is the cost of the full path:
30
+ requesting termination, calling `v8::IsolateHandle::terminate_execution()`,
31
+ and waiting for the runtime thread to acknowledge shutdown.
32
+
33
+ ## Python (`pytest-benchmark`, `pytest benches_py/ --benchmark-only`)
34
+
35
+ | Benchmark | Mean |
36
+ |---|---|
37
+ | `test_cold_start` (new `Runtime()` + one eval) | 2.82 ms |
38
+ | `test_steady_state_100_evals` (100 sequential evals, warm runtime) | 363.25 µs total (~3.63 µs/eval) |
39
+ | `test_steady_state_1000_evals` (1000 sequential evals, warm runtime) | 3.46 ms total (~3.46 µs/eval) |
40
+ | `test_host_callback_round_trip` (`bind_function` + call from JS) | 13.98 µs |
41
+ | `test_normal_completing_eval_baseline` | 3.77 µs |
42
+ | `test_watchdog_termination_overhead` | 59.62 ms |
43
+
44
+ Per-eval cost at the Python layer (~3.5-3.8 µs) matches the Rust-level
45
+ `simple_eval_throughput` number closely -- the Python binding adds negligible
46
+ overhead over the raw `RuntimeHandle`.
47
+
48
+ ### Watchdog-termination proof, timed precisely
49
+
50
+ `test_watchdog_termination_overhead` runs the exact scenario in
51
+ `tests/test_termination_handle.py`: a runaway `while(true){}` eval, killed
52
+ from a separate watchdog thread via `TerminationHandle.terminate()`, but with
53
+ the watchdog's sleep shortened to 50 ms (20 rounds) so the suite stays fast.
54
+ Measured mean: 59.62 ms. Subtracting the artificial 50 ms delay leaves
55
+ **~9.6 ms** of real overhead for the cross-thread termination path itself
56
+ (watchdog wakes up, calls into V8's isolate handle from a foreign thread,
57
+ the runtime thread unwinds and returns control to Python) -- consistent with
58
+ the Rust-level `terminate_round_trip` number once you add Python's own
59
+ call/exception overhead on top.
60
+
61
+ ## Reproducing
62
+
63
+ ```bash
64
+ cargo bench --features bench
65
+ uv sync --group all
66
+ uv run maturin develop --uv --release
67
+ uv run pytest benches_py/ --benchmark-only
68
+ ```