flowbook-python 0.0.1__py3-none-any.whl → 0.1.2__py3-none-any.whl
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.
- flowbook/__init__.py +74 -23
- flowbook/__main__.py +44 -0
- flowbook/_version.py +4 -0
- flowbook/baseline_kernel/__init__.py +37 -0
- flowbook/baseline_kernel/__main__.py +13 -0
- flowbook/baseline_kernel/baseline_kernel.py +238 -0
- flowbook/baseline_kernel/kernelspec/kernel.json +14 -0
- flowbook/checkpoint_kernel/__init__.py +37 -0
- flowbook/checkpoint_kernel/__main__.py +11 -0
- flowbook/checkpoint_kernel/checkpoint_client.py +19 -0
- flowbook/checkpoint_kernel/checkpoint_kernel.py +123 -0
- flowbook/checkpoint_kernel/kernelspec/kernel.json +14 -0
- flowbook/cli/__init__.py +1 -0
- flowbook/cli/cli.py +307 -0
- flowbook/cli/compare_fixed_overhead.py +671 -0
- flowbook/cli/compare_overhead.py +4930 -0
- flowbook/cli/flowbook_timers.py +1660 -0
- flowbook/cli/helpers.py +738 -0
- flowbook/cli/metadata_cli.py +228 -0
- flowbook/cli/models.py +746 -0
- flowbook/cli/optimization_metadata.py +90 -0
- flowbook/cli/plot_extraction.py +1137 -0
- flowbook/cli/plot_rendering.py +1490 -0
- flowbook/cli/show_errors.py +409 -0
- flowbook/cli/slurm_logs.py +433 -0
- flowbook/cli/stats_cli.py +93 -0
- flowbook/cli/stats_display.py +140 -0
- flowbook/cli/tests/__init__.py +0 -0
- flowbook/cli/tests/test_flowbook_timers.py +444 -0
- flowbook/cli/tests/test_metadata_format.py +127 -0
- flowbook/cli/tests/test_models.py +359 -0
- flowbook/cli/tests/test_models_v5.py +179 -0
- flowbook/cli/tests/test_plot_extraction.py +434 -0
- flowbook/cli/tests/test_plot_extraction_v5.py +291 -0
- flowbook/cli/tests/test_plot_rendering.py +205 -0
- flowbook/cli/tests/test_rerun_overhead_plots.py +163 -0
- flowbook/handlers.py +24 -0
- flowbook/kernel/__init__.py +40 -0
- flowbook/kernel/__main__.py +11 -0
- flowbook/kernel/access_events.py +143 -0
- flowbook/kernel/change_detector.py +537 -0
- flowbook/kernel/changes.py +229 -0
- flowbook/kernel/flowbook_client.py +76 -0
- flowbook/kernel/flowbook_kernel.py +1959 -0
- flowbook/kernel/kernelspec/kernel.json +8 -0
- flowbook/kernel/kernelspec/logo-32x32.png +0 -0
- flowbook/kernel/kernelspec/logo-64x64.png +0 -0
- flowbook/kernel/loc_ids.py +181 -0
- flowbook/kernel/locations.py +792 -0
- flowbook/kernel/models.py +370 -0
- flowbook/kernel/notebook_state.py +640 -0
- flowbook/kernel/protocol.py +207 -0
- flowbook/kernel/reproducibility_enforcer.py +2803 -0
- flowbook/kernel/tests/LITMUS_TESTS.yaml +1586 -0
- flowbook/kernel/tests/__init__.py +0 -0
- flowbook/kernel/tests/conftest.py +170 -0
- flowbook/kernel/tests/generate_litmus_latex.py +131 -0
- flowbook/kernel/tests/litmus_helpers.py +121 -0
- flowbook/kernel/tests/litmus_output/litmus_tests.tex +906 -0
- flowbook/kernel/tests/litmus_output/litmus_tests.txt +499 -0
- flowbook/kernel/tests/test_alias_conflicts.py +509 -0
- flowbook/kernel/tests/test_change_detector_locs.py +160 -0
- flowbook/kernel/tests/test_column_staleness_bug.py +724 -0
- flowbook/kernel/tests/test_converters.py +517 -0
- flowbook/kernel/tests/test_delete_transitions.py +1435 -0
- flowbook/kernel/tests/test_flowbook_kernel.py +271 -0
- flowbook/kernel/tests/test_forward_dependency.py +1532 -0
- flowbook/kernel/tests/test_implementation_theory_diff.py +630 -0
- flowbook/kernel/tests/test_inplace_mutation_detection.py +313 -0
- flowbook/kernel/tests/test_litmus.py +773 -0
- flowbook/kernel/tests/test_loc_ids.py +474 -0
- flowbook/kernel/tests/test_locations.py +827 -0
- flowbook/kernel/tests/test_locset_integration.py +770 -0
- flowbook/kernel/tests/test_meaningful_edit.py +243 -0
- flowbook/kernel/tests/test_measure_rerun_overhead.py +239 -0
- flowbook/kernel/tests/test_notebook_state.py +1137 -0
- flowbook/kernel/tests/test_optimizations.py +482 -0
- flowbook/kernel/tests/test_order_changes.py +414 -0
- flowbook/kernel/tests/test_order_changes_complex.py +806 -0
- flowbook/kernel/tests/test_paper_examples.py +1807 -0
- flowbook/kernel/tests/test_protocol.py +223 -0
- flowbook/kernel/tests/test_provenance.py +164 -0
- flowbook/kernel/tests/test_removed_writes_scenario.py +212 -0
- flowbook/kernel/tests/test_reproducibility_enforcer.py +6405 -0
- flowbook/kernel/tests/test_reproducibility_structural.py +676 -0
- flowbook/kernel/tests/test_typed_predicates.py +607 -0
- flowbook/kernel/tests/test_uncopyable_as_write.py +256 -0
- flowbook/kernel/tests/test_var_binding_semantics.py +496 -0
- flowbook/kernel_discovery.py +134 -0
- flowbook/kernel_support/__init__.py +0 -0
- flowbook/kernel_support/ast_utils.py +56 -0
- flowbook/kernel_support/base_client.py +79 -0
- flowbook/kernel_support/base_kernel.py +284 -0
- flowbook/kernel_support/checkpoint.py +238 -0
- flowbook/kernel_support/checkpoint.py.backup +1749 -0
- flowbook/kernel_support/column_provenance.py +196 -0
- flowbook/kernel_support/column_tracking.py +1304 -0
- flowbook/kernel_support/cudf_compat.py +1683 -0
- flowbook/kernel_support/deepcopy.py +2934 -0
- flowbook/kernel_support/deepcopyable.py +445 -0
- flowbook/kernel_support/df_subset_detector.py +454 -0
- flowbook/kernel_support/diff.py +4203 -0
- flowbook/kernel_support/display_helpers.py +74 -0
- flowbook/kernel_support/experimental_client.py +207 -0
- flowbook/kernel_support/extended_types.py +354 -0
- flowbook/kernel_support/file_checkpoint.py +296 -0
- flowbook/kernel_support/fs_magics.py +103 -0
- flowbook/kernel_support/heap_size.py +1096 -0
- flowbook/kernel_support/install.py +50 -0
- flowbook/kernel_support/json_utils.py +46 -0
- flowbook/kernel_support/kernelspec/kernel.json +11 -0
- flowbook/kernel_support/kernelspec/logo-64x64.png +0 -0
- flowbook/kernel_support/locals.py +215 -0
- flowbook/kernel_support/memory_checkpoint.py +3419 -0
- flowbook/kernel_support/models.py +342 -0
- flowbook/kernel_support/opaque.py +1156 -0
- flowbook/kernel_support/process_cleanup.py +105 -0
- flowbook/kernel_support/structural_tracking.py +1025 -0
- flowbook/kernel_support/test_diff.py.backup +1289 -0
- flowbook/kernel_support/test_subset_perf.py +327 -0
- flowbook/kernel_support/tests/__init__.py +0 -0
- flowbook/kernel_support/tests/test_ast_utils.py +105 -0
- flowbook/kernel_support/tests/test_base_kernel.py +89 -0
- flowbook/kernel_support/tests/test_catboost_pool.py +207 -0
- flowbook/kernel_support/tests/test_chained_assignment_error.py +214 -0
- flowbook/kernel_support/tests/test_checkpoint.py +141 -0
- flowbook/kernel_support/tests/test_checkpoint_comprehensive.py +564 -0
- flowbook/kernel_support/tests/test_checkpoint_corner_cases.py +996 -0
- flowbook/kernel_support/tests/test_checkpoint_df_subsets.py +461 -0
- flowbook/kernel_support/tests/test_checkpoint_functions.py +688 -0
- flowbook/kernel_support/tests/test_checkpoint_memory_sharing.py +870 -0
- flowbook/kernel_support/tests/test_checkpoint_nested.py +436 -0
- flowbook/kernel_support/tests/test_checkpoint_object_conversion.py +287 -0
- flowbook/kernel_support/tests/test_checkpoint_overhead_measurement.py +319 -0
- flowbook/kernel_support/tests/test_column_provenance.py +482 -0
- flowbook/kernel_support/tests/test_column_tracking.py +670 -0
- flowbook/kernel_support/tests/test_column_tracking_methods.py +144 -0
- flowbook/kernel_support/tests/test_column_tracking_performance.py +357 -0
- flowbook/kernel_support/tests/test_column_tracking_setitem_reads.py +244 -0
- flowbook/kernel_support/tests/test_cudf_checkpoint_dedup.py +267 -0
- flowbook/kernel_support/tests/test_cudf_checkpoint_inflation.py +271 -0
- flowbook/kernel_support/tests/test_cudf_checkpoint_perf.py +353 -0
- flowbook/kernel_support/tests/test_cudf_compat.py +1671 -0
- flowbook/kernel_support/tests/test_cudf_proxy_fingerprint.py +304 -0
- flowbook/kernel_support/tests/test_cudf_proxy_tracking.py +286 -0
- flowbook/kernel_support/tests/test_deep_alias_detection.py +878 -0
- flowbook/kernel_support/tests/test_deepcopy_preserve_mode.py +216 -0
- flowbook/kernel_support/tests/test_deepcopyable.py +677 -0
- flowbook/kernel_support/tests/test_df_subset_detector.py +976 -0
- flowbook/kernel_support/tests/test_diff_byte_comparison.py +464 -0
- flowbook/kernel_support/tests/test_diff_deep.py +1066 -0
- flowbook/kernel_support/tests/test_diff_float_tolerance.py +237 -0
- flowbook/kernel_support/tests/test_diff_keras_catboost.py +578 -0
- flowbook/kernel_support/tests/test_diff_object_float.py +244 -0
- flowbook/kernel_support/tests/test_diff_structural.py +601 -0
- flowbook/kernel_support/tests/test_display_helpers.py +66 -0
- flowbook/kernel_support/tests/test_extended_types_coverage.py +403 -0
- flowbook/kernel_support/tests/test_extension_dtypes.py +292 -0
- flowbook/kernel_support/tests/test_file_checkpoint.py +195 -0
- flowbook/kernel_support/tests/test_file_checkpoint_comprehensive.py +758 -0
- flowbook/kernel_support/tests/test_fs_magics.py +175 -0
- flowbook/kernel_support/tests/test_gpu_checkpoint.py +396 -0
- flowbook/kernel_support/tests/test_gpu_checkpoint_perf.py +458 -0
- flowbook/kernel_support/tests/test_heap_size.py +1695 -0
- flowbook/kernel_support/tests/test_incremental_checkpoint.py +236 -0
- flowbook/kernel_support/tests/test_index_deepcopy.py +676 -0
- flowbook/kernel_support/tests/test_install.py +63 -0
- flowbook/kernel_support/tests/test_json_utils.py +166 -0
- flowbook/kernel_support/tests/test_keras_deepcopy.py +209 -0
- flowbook/kernel_support/tests/test_large_list_cache.py +1030 -0
- flowbook/kernel_support/tests/test_lightgbm_checkpoint.py +449 -0
- flowbook/kernel_support/tests/test_locals.py +346 -0
- flowbook/kernel_support/tests/test_memory_checkpoint.py +2127 -0
- flowbook/kernel_support/tests/test_memory_checkpoint_comprehensive.py +1222 -0
- flowbook/kernel_support/tests/test_memory_checkpoint_edge_cases.py +606 -0
- flowbook/kernel_support/tests/test_memory_snapshot.py +199 -0
- flowbook/kernel_support/tests/test_models.py +273 -0
- flowbook/kernel_support/tests/test_models_coverage.py +291 -0
- flowbook/kernel_support/tests/test_multiindex.py +362 -0
- flowbook/kernel_support/tests/test_opaque_keras.py +429 -0
- flowbook/kernel_support/tests/test_opaque_keras_gaps.py +780 -0
- flowbook/kernel_support/tests/test_opaque_ml.py +295 -0
- flowbook/kernel_support/tests/test_opaque_pytorch.py +405 -0
- flowbook/kernel_support/tests/test_opaque_pytorch_gaps.py +404 -0
- flowbook/kernel_support/tests/test_pytorch_diff.py +249 -0
- flowbook/kernel_support/tests/test_shap_checkpoint.py +364 -0
- flowbook/kernel_support/tests/test_stacking_checkpoint.py +562 -0
- flowbook/kernel_support/tests/test_structural_tracking.py +2144 -0
- flowbook/kernel_support/tests/test_targetencoder_checkpoint.py +413 -0
- flowbook/kernel_support/tests/test_timeout_handler.py +131 -0
- flowbook/kernel_support/tests/test_tracking.py +695 -0
- flowbook/kernel_support/tests/test_tracking_coverage.py +209 -0
- flowbook/kernel_support/tests/test_tracking_performance.py +265 -0
- flowbook/kernel_support/tests/test_tracking_structural.py +709 -0
- flowbook/kernel_support/tests/test_types_coverage.py +511 -0
- flowbook/kernel_support/tests/test_virtual_fs.py +2151 -0
- flowbook/kernel_support/timeout_handler.py +94 -0
- flowbook/kernel_support/tracking.py +448 -0
- flowbook/kernel_support/types.py +623 -0
- flowbook/kernel_support/virtual_fs.py +932 -0
- flowbook/mcp/__init__.py +0 -0
- flowbook/mcp/jupyter_config.py +102 -0
- flowbook/mcp/server.py +906 -0
- flowbook/mcp/session.py +1523 -0
- flowbook/mcp/tests/__init__.py +0 -0
- flowbook/mcp/tests/test_cell_validation.py +60 -0
- flowbook/mcp/tests/test_contents_api.py +417 -0
- flowbook/mcp/tests/test_jupyter_config.py +51 -0
- flowbook/mcp/tests/test_kernel_discovery.py +153 -0
- flowbook/mcp/tests/test_new_tools.py +556 -0
- flowbook/mcp/tests/test_session_integration.py +204 -0
- flowbook/nbi/MANUAL_UI_TESTS.md +255 -0
- flowbook/nbi/__init__.py +0 -0
- flowbook/nbi/claude_commands/flowbook-nb-fix.md +225 -0
- flowbook/nbi/extension.py +122 -0
- flowbook/nbi/extension_data/extension.json +1 -0
- flowbook/nbi/session.py +140 -0
- flowbook/nbi/tests/__init__.py +0 -0
- flowbook/nbi/tests/test_extension.py +105 -0
- flowbook/nbi/tests/test_session.py +194 -0
- flowbook/nbi/tests/test_tools.py +806 -0
- flowbook/nbi/tools.py +682 -0
- flowbook/scripts/__init__.py +16 -0
- flowbook/scripts/fix_repro_errors.py +963 -0
- flowbook/scripts/parse_repro_errors.py +216 -0
- flowbook/scripts/tests/__init__.py +1 -0
- flowbook/scripts/tests/test_fix_repro_errors.py +546 -0
- flowbook/server/__init__.py +53 -0
- flowbook/server/base.py +178 -0
- flowbook/server/comm_models.py +21 -0
- flowbook/server/commands/__init__.py +13 -0
- flowbook/server/commands/compare_baseline.py +3061 -0
- flowbook/server/commands/execute.py +308 -0
- flowbook/server/commands/execute_base.py +241 -0
- flowbook/server/commands/tests/__init__.py +0 -0
- flowbook/server/commands/tests/test_compare_baseline_rerun.py +166 -0
- flowbook/server/commands/tests/test_compare_baseline_v3.py +167 -0
- flowbook/server/commands/tests/test_downsample_csv.py +256 -0
- flowbook/server/commands/tests/test_flowbook_update_protocol.py +684 -0
- flowbook/server/commands/tests/test_gpu_memory_recording.py +483 -0
- flowbook/server/commands/tests/test_path_traversal.py +87 -0
- flowbook/server/handlers.py +296 -0
- flowbook/server/kernel_helper.py +233 -0
- flowbook/server/kernel_manager.py +86 -0
- flowbook/server/registry.py +73 -0
- flowbook/server/tests/__init__.py +0 -0
- flowbook/server/tests/test_handlers.py +140 -0
- flowbook/server/tests/test_kernel_manager.py +116 -0
- flowbook/slurm/slurm_cli.py +1355 -0
- flowbook/testing/README.md +423 -0
- flowbook/testing/__init__.py +23 -0
- flowbook/testing/benchmark_checkpoint.py +1240 -0
- flowbook/testing/checkpoint_overhead_test.py +728 -0
- flowbook/testing/correctness.py +221 -0
- flowbook/testing/kernel_comparison.py +469 -0
- flowbook/testing/notebook_loader.py +63 -0
- flowbook/testing/notebooks/data_pipeline.ipynb +185 -0
- flowbook/testing/notebooks/dependencies.ipynb +106 -0
- flowbook/testing/notebooks/deterministic.ipynb +91 -0
- flowbook/testing/notebooks/ml_workflow.ipynb +194 -0
- flowbook/testing/notebooks/multi_dataframe.ipynb +167 -0
- flowbook/testing/notebooks/nondeterministic.ipynb +75 -0
- flowbook/testing/notebooks/pandas_heavy.ipynb +126 -0
- flowbook/testing/performance.py +624 -0
- flowbook/testing/plot_checkpoint_percentage.py +117 -0
- flowbook/testing/plot_checkpoint_timings.py +125 -0
- flowbook/testing/results.py +178 -0
- flowbook/testing/runner.py +332 -0
- flowbook/testing/scripts/__init__.py +1 -0
- flowbook/testing/scripts/run_correctness.py +158 -0
- flowbook/testing/scripts/run_kernel_comparison.py +96 -0
- flowbook/testing/scripts/run_performance.py +171 -0
- flowbook/util/cell_ids.py +205 -0
- flowbook/util/cell_index.py +134 -0
- flowbook/util/dependencies.py +1517 -0
- flowbook/util/flowbook_metadata.py +380 -0
- flowbook/util/gpu_memory.py +98 -0
- flowbook/util/kernel_installer.py +165 -0
- flowbook/util/liveness.py +590 -0
- flowbook/util/metadata_extractor.py +50 -0
- flowbook/util/model_copy.py +218 -0
- flowbook/util/nb_diff.py +98 -0
- flowbook/util/notebook_analysis.py +306 -0
- flowbook/util/notebook_to_python.py +159 -0
- flowbook/util/output.py +392 -0
- flowbook/util/prompts.py +97 -0
- flowbook/util/prompts.yaml +437 -0
- flowbook/util/tests/__init__.py +1 -0
- flowbook/util/tests/test_cell_ids.py +303 -0
- flowbook/util/tests/test_cell_index.py +131 -0
- flowbook/util/tests/test_dependencies.py +1962 -0
- flowbook/util/tests/test_gpu_memory.py +202 -0
- flowbook/util/tests/test_liveness.py +740 -0
- flowbook/util/tests/test_notebook_analysis.py +440 -0
- flowbook/util/tests/test_notebook_to_python.py +366 -0
- flowbook/util/text.py +384 -0
- flowbook_python-0.1.2.data/data/etc/jupyter/jupyter_server_config.d/flowbook.json +7 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/install.json +5 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/package.json +239 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/schemas/flowbook/package.json.orig +234 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/schemas/flowbook/plugin.json +18 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/728.b1df4bca1a3305d0d0a7.js +1 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/873.3edec525c5c79ec55cd6.js +1 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/905.94c2bfb401597cc2a103.js +2 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/905.94c2bfb401597cc2a103.js.LICENSE.txt +29 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/951.ba84389925d6a0676e79.js +1 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/remoteEntry.9c89c62fdbe6db112e2d.js +1 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/style.js +4 -0
- flowbook_python-0.1.2.data/data/share/jupyter/labextensions/flowbook/static/third-party-licenses.json +112 -0
- flowbook_python-0.1.2.data/data/share/jupyter/nbi_extensions/flowbook/extension.json +1 -0
- flowbook_python-0.1.2.dist-info/METADATA +289 -0
- flowbook_python-0.1.2.dist-info/RECORD +315 -0
- {flowbook_python-0.0.1.dist-info → flowbook_python-0.1.2.dist-info}/WHEEL +1 -1
- flowbook_python-0.1.2.dist-info/entry_points.txt +12 -0
- flowbook_python-0.0.1.dist-info/METADATA +0 -61
- flowbook_python-0.0.1.dist-info/RECORD +0 -5
- {flowbook_python-0.0.1.dist-info → flowbook_python-0.1.2.dist-info}/licenses/LICENSE +0 -0
flowbook/__init__.py
CHANGED
|
@@ -1,31 +1,82 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
try:
|
|
2
|
+
from ._version import __version__
|
|
3
|
+
except ImportError:
|
|
4
|
+
# Fallback when using the package in dev mode without installing
|
|
5
|
+
# in editable mode with pip. It is highly recommended to install
|
|
6
|
+
# the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
|
|
7
|
+
import warnings
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
warnings.warn("Importing 'flowbook' outside a proper installation.")
|
|
10
|
+
__version__ = "dev"
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
from jupyter_server.extension.application import ExtensionApp
|
|
13
|
+
from traitlets import Unicode
|
|
14
|
+
from flowbook.util.output import timer
|
|
9
15
|
|
|
10
|
-
__version__ = "0.0.1"
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
class FlowBookExtension(ExtensionApp):
|
|
18
|
+
"""FlowBook server extension."""
|
|
13
19
|
|
|
20
|
+
name = "flowbook"
|
|
21
|
+
load_other_extensions = True
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
print("=" * 60)
|
|
20
|
-
print()
|
|
21
|
-
print("This is a placeholder package to reserve the PyPI name.")
|
|
22
|
-
print("The actual FlowBook project is under development.")
|
|
23
|
-
print()
|
|
24
|
-
print("For more information:")
|
|
25
|
-
print(" GitHub: https://github.com/stephenfreund/FlowBook")
|
|
26
|
-
print()
|
|
27
|
-
print("=" * 60)
|
|
23
|
+
model = Unicode(
|
|
24
|
+
default_value="gpt-4o",
|
|
25
|
+
help="The model to use for the extension",
|
|
26
|
+
).tag(config=True)
|
|
28
27
|
|
|
28
|
+
fast_model = Unicode(
|
|
29
|
+
default_value="gpt-4o-mini",
|
|
30
|
+
help="The fast model to use for the extension",
|
|
31
|
+
).tag(config=True)
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
aliases = {
|
|
34
|
+
"model": "FlowBookExtension.model",
|
|
35
|
+
"fast-model": "FlowBookExtension.fast_model",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def initialize_settings(self):
|
|
39
|
+
"""Initialize settings for the extension."""
|
|
40
|
+
with timer(message="Initializing FlowBook settings..."):
|
|
41
|
+
self.log.info(f"Initializing {self.name} extension")
|
|
42
|
+
self.serverapp.web_app.settings["flowbook"] = {
|
|
43
|
+
"ext": self,
|
|
44
|
+
"model": self.model,
|
|
45
|
+
"fast-model": self.fast_model,
|
|
46
|
+
}
|
|
47
|
+
km = self.serverapp.kernel_manager
|
|
48
|
+
if km.default_kernel_name == "python3":
|
|
49
|
+
km.default_kernel_name = "flowbook_kernel"
|
|
50
|
+
ksm = self.serverapp.kernel_spec_manager
|
|
51
|
+
if not ksm.allowed_kernelspecs:
|
|
52
|
+
ksm.allowed_kernelspecs = {"flowbook_kernel", "python3"}
|
|
53
|
+
make_kernels()
|
|
54
|
+
|
|
55
|
+
def initialize_handlers(self):
|
|
56
|
+
"""Register HTTP handlers for the extension."""
|
|
57
|
+
with timer(message="Initializing FlowBook handlers..."):
|
|
58
|
+
from flowbook.server.handlers import setup_handlers
|
|
59
|
+
setup_handlers(self.serverapp.web_app)
|
|
60
|
+
self.log.info(f"Registered {self.name} server extension handlers")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _jupyter_labextension_paths():
|
|
64
|
+
"""Provide the location of the labextension."""
|
|
65
|
+
with timer(message="JupyterLab extension paths..."):
|
|
66
|
+
return [{"src": "labextension", "dest": "flowbook"}]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _jupyter_server_extension_points():
|
|
70
|
+
"""Define the server extension entry point."""
|
|
71
|
+
with timer(message="Jupyter server extension points..."):
|
|
72
|
+
return [{"module": "flowbook", "app": FlowBookExtension}]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def make_kernels():
|
|
76
|
+
from flowbook.util.kernel_installer import install_kernel_spec
|
|
77
|
+
from pathlib import Path
|
|
78
|
+
|
|
79
|
+
base = Path(__file__).parent
|
|
80
|
+
install_kernel_spec("flowbook_kernel", base / "kernel" / "kernelspec")
|
|
81
|
+
install_kernel_spec("checkpoint_kernel", base / "checkpoint_kernel" / "kernelspec")
|
|
82
|
+
install_kernel_spec("baseline_kernel", base / "baseline_kernel" / "kernelspec")
|
flowbook/__main__.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from typing import List
|
|
3
|
+
from flowbook.util.output import timer
|
|
4
|
+
import argparse
|
|
5
|
+
import asyncio
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from flowbook.kernel_support.experimental_client import FlowbookClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def handle_time(args):
|
|
11
|
+
from nbformat import read
|
|
12
|
+
|
|
13
|
+
with timer(message=f"Timing {args.path}"):
|
|
14
|
+
nb = read(args.path, as_version=4)
|
|
15
|
+
client = FlowbookClient(
|
|
16
|
+
nb,
|
|
17
|
+
kernel_name="flowbook_kernel",
|
|
18
|
+
allow_errors=False,
|
|
19
|
+
timeout=60,
|
|
20
|
+
)
|
|
21
|
+
await client.async_execute()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def make_parser():
|
|
25
|
+
parser = argparse.ArgumentParser(description="FlowBook - A data analysis tool")
|
|
26
|
+
parser.add_argument("--model", default="gpt-4.1-mini", help="Base Model to use")
|
|
27
|
+
parser.add_argument("path", help="Path to the notebook or directory of notebooks")
|
|
28
|
+
|
|
29
|
+
return parser
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def async_main():
|
|
33
|
+
parser = make_parser()
|
|
34
|
+
args = parser.parse_args(sys.argv[1:])
|
|
35
|
+
|
|
36
|
+
await handle_time(args)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def main():
|
|
40
|
+
asyncio.run(async_main())
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
if __name__ == "__main__":
|
|
44
|
+
main()
|
flowbook/_version.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Baseline Kernel - For comparison testing with FlowBook.
|
|
3
|
+
|
|
4
|
+
This package provides a baseline IPython kernel for fair A/B comparison
|
|
5
|
+
with FlowBook. It has standard IPython behavior without reproducibility
|
|
6
|
+
tracking or checkpointing.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
from flowbook.kernel_support.install import install_kernel
|
|
12
|
+
|
|
13
|
+
from flowbook.baseline_kernel.baseline_kernel import (
|
|
14
|
+
BaselineKernel,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"BaselineKernel",
|
|
19
|
+
"install_baseline_kernel",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def install_baseline_kernel() -> str:
|
|
24
|
+
"""
|
|
25
|
+
Install the Baseline kernel spec.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Path to installed kernel spec directory
|
|
29
|
+
"""
|
|
30
|
+
return install_kernel(os.path.dirname(__file__), "baseline_kernel")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Install kernel on import
|
|
34
|
+
try:
|
|
35
|
+
install_baseline_kernel()
|
|
36
|
+
except Exception:
|
|
37
|
+
pass # Don't fail import if kernel install fails
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Entry point for running BaselineKernel as a module."""
|
|
2
|
+
|
|
3
|
+
from ipykernel.kernelapp import IPKernelApp
|
|
4
|
+
from traitlets.config import Config
|
|
5
|
+
|
|
6
|
+
from flowbook.baseline_kernel.baseline_kernel import (
|
|
7
|
+
BaselineKernel,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
config = Config()
|
|
12
|
+
config.IPKernelApp.capture_fd_output = False
|
|
13
|
+
IPKernelApp.launch_instance(kernel_class=BaselineKernel, config=config)
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"""Baseline kernel for fair comparison with FlowBook.
|
|
2
|
+
|
|
3
|
+
This kernel provides the same memory measurement capabilities as FlowBook
|
|
4
|
+
but without any reproducibility tracking, checkpointing, or other FlowBook features.
|
|
5
|
+
It's used for fair A/B comparison of memory overhead.
|
|
6
|
+
|
|
7
|
+
Features:
|
|
8
|
+
- Standard IPython kernel behavior
|
|
9
|
+
- %memory magic command (same as FlowBook)
|
|
10
|
+
- Memory reporting in same format as FlowBook for comparison
|
|
11
|
+
- Kernel-side timing reported via metadata (for fair timing comparison)
|
|
12
|
+
|
|
13
|
+
Does NOT include:
|
|
14
|
+
- Reproducibility tracking
|
|
15
|
+
- Checkpointing
|
|
16
|
+
- Variable access tracking
|
|
17
|
+
- Any FlowBook-specific features
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import os
|
|
21
|
+
import time
|
|
22
|
+
import types
|
|
23
|
+
from typing import Any, Dict, Optional
|
|
24
|
+
|
|
25
|
+
from ipykernel.ipkernel import IPythonKernel
|
|
26
|
+
from flowbook.kernel_support.virtual_fs import VirtualFileSystem
|
|
27
|
+
from IPython.core.magic import line_magic, magics_class, Magics
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@magics_class
|
|
31
|
+
class MemoryMagics(Magics):
|
|
32
|
+
"""Memory magic commands for baseline comparison using HeapSizer."""
|
|
33
|
+
|
|
34
|
+
@line_magic
|
|
35
|
+
def memory(self, line: str) -> None:
|
|
36
|
+
"""Show memory usage using HeapSizer.
|
|
37
|
+
|
|
38
|
+
Usage:
|
|
39
|
+
%memory - Show namespace memory summary
|
|
40
|
+
%memory vars - Show per-variable breakdown
|
|
41
|
+
%memory vars 10 - Show top 10 variables
|
|
42
|
+
"""
|
|
43
|
+
from flowbook.kernel_support.heap_size import HeapSizer
|
|
44
|
+
|
|
45
|
+
args = line.strip().lower().split()
|
|
46
|
+
if not args:
|
|
47
|
+
args = [""]
|
|
48
|
+
|
|
49
|
+
cmd = args[0]
|
|
50
|
+
|
|
51
|
+
if cmd == "" or cmd == "?" or cmd == "status":
|
|
52
|
+
# Show namespace summary
|
|
53
|
+
sizer = HeapSizer()
|
|
54
|
+
user_ns = self.shell.user_ns
|
|
55
|
+
# Filter to user variables
|
|
56
|
+
user_vars = {
|
|
57
|
+
k: v for k, v in user_ns.items()
|
|
58
|
+
if not k.startswith('_') and not isinstance(v, (type, types.FunctionType, types.BuiltinFunctionType, types.ModuleType))
|
|
59
|
+
}
|
|
60
|
+
ns_size = sizer.sizeof_namespace(user_vars)
|
|
61
|
+
print(f"Namespace memory: {ns_size.total_bytes / (1024*1024):.1f} MB")
|
|
62
|
+
print(f"Variables: {len(ns_size.by_variable)}")
|
|
63
|
+
|
|
64
|
+
elif cmd == "vars":
|
|
65
|
+
# Show per-variable breakdown
|
|
66
|
+
limit = 20
|
|
67
|
+
if len(args) > 1:
|
|
68
|
+
try:
|
|
69
|
+
limit = int(args[1])
|
|
70
|
+
except ValueError:
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
sizer = HeapSizer()
|
|
74
|
+
user_ns = self.shell.user_ns
|
|
75
|
+
user_vars = {
|
|
76
|
+
k: v for k, v in user_ns.items()
|
|
77
|
+
if not k.startswith('_') and not isinstance(v, (type, types.FunctionType, types.BuiltinFunctionType, types.ModuleType))
|
|
78
|
+
}
|
|
79
|
+
ns_size = sizer.sizeof_namespace(user_vars)
|
|
80
|
+
|
|
81
|
+
# Build list of (name, type, size)
|
|
82
|
+
var_sizes = []
|
|
83
|
+
for name, size in ns_size.by_variable.items():
|
|
84
|
+
type_name = type(user_vars[name]).__name__
|
|
85
|
+
var_sizes.append((name, type_name, size))
|
|
86
|
+
|
|
87
|
+
# Sort by size descending
|
|
88
|
+
var_sizes.sort(key=lambda x: x[2], reverse=True)
|
|
89
|
+
var_sizes = var_sizes[:limit]
|
|
90
|
+
|
|
91
|
+
# Format output
|
|
92
|
+
print("Variable Type Size")
|
|
93
|
+
print("─" * 50)
|
|
94
|
+
for name, type_name, size in var_sizes:
|
|
95
|
+
size_str = self._format_bytes(size)
|
|
96
|
+
print(f"{name:<16} {type_name:<15} {size_str:>10}")
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
print(f"Unknown command: {cmd}")
|
|
100
|
+
print("Usage: %memory [vars [limit]]")
|
|
101
|
+
|
|
102
|
+
def _format_bytes(self, size: int) -> str:
|
|
103
|
+
"""Format bytes as human-readable string."""
|
|
104
|
+
if size < 1024:
|
|
105
|
+
return f"{size} B"
|
|
106
|
+
elif size < 1024 * 1024:
|
|
107
|
+
return f"{size / 1024:.1f} KB"
|
|
108
|
+
elif size < 1024 * 1024 * 1024:
|
|
109
|
+
return f"{size / (1024 * 1024):.1f} MB"
|
|
110
|
+
else:
|
|
111
|
+
return f"{size / (1024 * 1024 * 1024):.1f} GB"
|
|
112
|
+
|
|
113
|
+
@line_magic
|
|
114
|
+
def diagnostic(self, line: str) -> None:
|
|
115
|
+
"""No-op magic for compatibility with FlowBook notebooks.
|
|
116
|
+
|
|
117
|
+
In FlowBook kernel, %diagnostic marks a cell as diagnostic-only
|
|
118
|
+
(no reproducibility tracking). In baseline kernel, this is a no-op
|
|
119
|
+
since there's no reproducibility tracking anyway.
|
|
120
|
+
"""
|
|
121
|
+
pass
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class BaselineKernel(IPythonKernel):
|
|
126
|
+
"""IPython kernel for baseline comparison with FlowBook.
|
|
127
|
+
|
|
128
|
+
This kernel provides standard IPython behavior with memory introspection
|
|
129
|
+
via HeapSizer, but without any FlowBook features like reproducibility
|
|
130
|
+
tracking or checkpointing.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
implementation = "baseline_kernel"
|
|
134
|
+
implementation_version = "2.0"
|
|
135
|
+
banner = "Baseline Kernel - For comparison testing"
|
|
136
|
+
|
|
137
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
138
|
+
super().__init__(**kwargs)
|
|
139
|
+
self._memory_metadata: Optional[Dict[str, Any]] = None
|
|
140
|
+
|
|
141
|
+
# Virtual filesystem: redirect writes to overlay to preserve real FS
|
|
142
|
+
self._vfs = VirtualFileSystem()
|
|
143
|
+
self._vfs.set_notebook_dir(os.getcwd())
|
|
144
|
+
if os.environ.get("FLOWBOOK_NO_VIRTUAL_FS", "0") == "1" or \
|
|
145
|
+
os.environ.get("FLOWBOOK_VIRTUAL_FS") == "0":
|
|
146
|
+
pass # VFS disabled — writes go to real FS
|
|
147
|
+
else:
|
|
148
|
+
self._vfs.enable()
|
|
149
|
+
self._vfs_namespace_patched = False
|
|
150
|
+
|
|
151
|
+
def start(self) -> None:
|
|
152
|
+
"""Start the kernel and register magic commands."""
|
|
153
|
+
super().start()
|
|
154
|
+
|
|
155
|
+
# Register memory magics
|
|
156
|
+
if self.shell:
|
|
157
|
+
self.shell.register_magics(MemoryMagics)
|
|
158
|
+
self._ensure_vfs_namespace_patched()
|
|
159
|
+
|
|
160
|
+
# Pre-import pandas and enable same options as FlowBook kernel
|
|
161
|
+
# These are set in memory_checkpoint.py for FlowBook - we need them
|
|
162
|
+
# here for fair comparison
|
|
163
|
+
try:
|
|
164
|
+
import pandas as pd
|
|
165
|
+
|
|
166
|
+
# Enable copy-on-write mode for better performance with DataFrame copies
|
|
167
|
+
# (always enabled in pandas >= 3.0, but needs to be set for pandas 2.x)
|
|
168
|
+
if hasattr(pd.options.mode, 'copy_on_write'):
|
|
169
|
+
pd.options.mode.copy_on_write = True
|
|
170
|
+
|
|
171
|
+
# Enable string inference so read_csv() returns StringDtype instead of object dtype
|
|
172
|
+
# (always enabled in pandas >= 3.0, but needs to be set for pandas 2.x)
|
|
173
|
+
if hasattr(pd.options, 'future') and hasattr(pd.options.future, 'infer_string'):
|
|
174
|
+
pd.options.future.infer_string = True
|
|
175
|
+
except ImportError:
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
def _ensure_vfs_namespace_patched(self) -> None:
|
|
179
|
+
"""Patch VFS open into the user namespace if VFS is active."""
|
|
180
|
+
if self._vfs_namespace_patched:
|
|
181
|
+
return
|
|
182
|
+
if self.shell is None:
|
|
183
|
+
return
|
|
184
|
+
if self._vfs.enabled:
|
|
185
|
+
self._vfs.patch_namespace(self.shell.user_global_ns)
|
|
186
|
+
self._vfs_namespace_patched = True
|
|
187
|
+
|
|
188
|
+
def do_shutdown(self, restart: bool) -> dict:
|
|
189
|
+
"""Clean up VFS overlay on shutdown."""
|
|
190
|
+
if self._vfs.enabled:
|
|
191
|
+
self._vfs.disable()
|
|
192
|
+
return super().do_shutdown(restart)
|
|
193
|
+
|
|
194
|
+
async def do_execute(
|
|
195
|
+
self,
|
|
196
|
+
code: str,
|
|
197
|
+
silent: bool,
|
|
198
|
+
store_history: bool = True,
|
|
199
|
+
user_expressions: Optional[Dict[str, Any]] = None,
|
|
200
|
+
allow_stdin: bool = False,
|
|
201
|
+
*,
|
|
202
|
+
cell_id: Optional[str] = None,
|
|
203
|
+
) -> Dict[str, Any]:
|
|
204
|
+
"""Execute code with standard IPython behavior and timing.
|
|
205
|
+
|
|
206
|
+
Reports kernel-side execution time via display_data metadata
|
|
207
|
+
for fair comparison with FlowBook kernel.
|
|
208
|
+
"""
|
|
209
|
+
start_time = time.perf_counter()
|
|
210
|
+
|
|
211
|
+
# Execute code normally (IPythonKernel.do_execute is async)
|
|
212
|
+
result = await super().do_execute(
|
|
213
|
+
code,
|
|
214
|
+
silent,
|
|
215
|
+
store_history,
|
|
216
|
+
user_expressions,
|
|
217
|
+
allow_stdin,
|
|
218
|
+
cell_id=cell_id,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
code_duration_ms = (time.perf_counter() - start_time) * 1000
|
|
222
|
+
|
|
223
|
+
# Emit timing metadata (same pattern as FlowBook kernel)
|
|
224
|
+
if not silent:
|
|
225
|
+
self.send_response(
|
|
226
|
+
self.iopub_socket,
|
|
227
|
+
"display_data",
|
|
228
|
+
{
|
|
229
|
+
"data": {"text/plain": f"✓ Code: {code_duration_ms:.0f} ms"},
|
|
230
|
+
"metadata": {
|
|
231
|
+
"baseline": {
|
|
232
|
+
"code_duration_ms": code_duration_ms,
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
return result
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Checkpoint Kernel - Execution and checkpoint timing measurement.
|
|
3
|
+
|
|
4
|
+
This package provides:
|
|
5
|
+
- CheckpointKernel: IPython kernel that measures execution and checkpoint time
|
|
6
|
+
- CheckpointKernelClient: Client that sends cell_id with executions
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
from flowbook.kernel_support.install import install_kernel
|
|
12
|
+
|
|
13
|
+
from flowbook.checkpoint_kernel.checkpoint_client import CheckpointKernelClient
|
|
14
|
+
from flowbook.checkpoint_kernel.checkpoint_kernel import CheckpointKernel
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"CheckpointKernel",
|
|
18
|
+
"CheckpointKernelClient",
|
|
19
|
+
"install_checkpoint_kernel",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def install_checkpoint_kernel() -> str:
|
|
24
|
+
"""
|
|
25
|
+
Install the Checkpoint kernel spec.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Path to installed kernel spec directory
|
|
29
|
+
"""
|
|
30
|
+
return install_kernel(os.path.dirname(__file__), "checkpoint_kernel")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Install kernel on import
|
|
34
|
+
try:
|
|
35
|
+
install_checkpoint_kernel()
|
|
36
|
+
except Exception:
|
|
37
|
+
pass # Don't fail import if kernel install fails
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Entry point for running CheckpointKernel as a module."""
|
|
2
|
+
|
|
3
|
+
from ipykernel.kernelapp import IPKernelApp
|
|
4
|
+
from traitlets.config import Config
|
|
5
|
+
|
|
6
|
+
from flowbook.checkpoint_kernel.checkpoint_kernel import CheckpointKernel
|
|
7
|
+
|
|
8
|
+
if __name__ == "__main__":
|
|
9
|
+
config = Config()
|
|
10
|
+
config.IPKernelApp.capture_fd_output = False
|
|
11
|
+
IPKernelApp.launch_instance(kernel_class=CheckpointKernel, config=config)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CheckpointKernelClient - Client that sends cell_id with executions.
|
|
3
|
+
|
|
4
|
+
Extends BaseFlowbookClient to inject cell_id into execution requests.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from flowbook.kernel_support.base_client import BaseFlowbookClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CheckpointKernelClient(BaseFlowbookClient):
|
|
11
|
+
"""
|
|
12
|
+
Kernel client that sends cell_id with executions.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
client = CheckpointKernelClient()
|
|
16
|
+
client.execute(code, cell_id='cell_abc')
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
pass
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CheckpointKernel - IPython kernel that measures cell execution and checkpoint time.
|
|
3
|
+
|
|
4
|
+
This is a minimal kernel that:
|
|
5
|
+
1. Measures cell execution time
|
|
6
|
+
2. Takes a checkpoint after each execution
|
|
7
|
+
3. Measures checkpoint (commit) time
|
|
8
|
+
4. Reports timing via flowbook_update IOPub messages
|
|
9
|
+
|
|
10
|
+
No reproducibility tracking, no variable tracking - just execution and checkpoint timing.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import time
|
|
14
|
+
from typing import Optional
|
|
15
|
+
|
|
16
|
+
from ipykernel.kernelapp import IPKernelApp
|
|
17
|
+
|
|
18
|
+
from flowbook.kernel.protocol import IOPUB_MSG_TYPE
|
|
19
|
+
from flowbook.kernel_support.base_kernel import BaseFlowbookKernel
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CheckpointKernel(BaseFlowbookKernel):
|
|
23
|
+
"""
|
|
24
|
+
IPython kernel with checkpoint timing measurement.
|
|
25
|
+
|
|
26
|
+
Features:
|
|
27
|
+
- Measures cell execution time
|
|
28
|
+
- Measures checkpoint (state save) time
|
|
29
|
+
- Reports timing via flowbook_update IOPub messages
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
implementation = "checkpoint_kernel"
|
|
33
|
+
implementation_version = "0.1"
|
|
34
|
+
banner = "FlowBook Checkpoint Kernel - Execution and checkpoint timing"
|
|
35
|
+
|
|
36
|
+
def __init__(self, **kwargs):
|
|
37
|
+
super().__init__(**kwargs)
|
|
38
|
+
|
|
39
|
+
# Expose checkpoint object to user code for rerun trials
|
|
40
|
+
self.shell.user_ns["_flowbook_checkpoint"] = self._checkpoint
|
|
41
|
+
|
|
42
|
+
async def _do_execute_impl(
|
|
43
|
+
self,
|
|
44
|
+
code: str,
|
|
45
|
+
silent: bool,
|
|
46
|
+
store_history: bool,
|
|
47
|
+
user_expressions: Optional[dict],
|
|
48
|
+
allow_stdin: bool,
|
|
49
|
+
cell_meta: Optional[dict],
|
|
50
|
+
) -> dict:
|
|
51
|
+
"""
|
|
52
|
+
Execute code and measure timing.
|
|
53
|
+
"""
|
|
54
|
+
self._ensure_fs_magics()
|
|
55
|
+
self._ensure_vfs_namespace_patched()
|
|
56
|
+
|
|
57
|
+
# For empty code or pure magic, still report timing (with 0 values)
|
|
58
|
+
is_trivial = not code.strip() or self._is_pure_magic(code)
|
|
59
|
+
|
|
60
|
+
# Measure cell execution time
|
|
61
|
+
exec_start = time.perf_counter()
|
|
62
|
+
result = await self._ipython_do_execute(
|
|
63
|
+
code,
|
|
64
|
+
silent,
|
|
65
|
+
store_history,
|
|
66
|
+
user_expressions,
|
|
67
|
+
allow_stdin,
|
|
68
|
+
cell_meta=cell_meta,
|
|
69
|
+
cell_id=self._cell_id,
|
|
70
|
+
)
|
|
71
|
+
exec_end = time.perf_counter()
|
|
72
|
+
|
|
73
|
+
# For trivial cells, report 0 timings and skip checkpoint
|
|
74
|
+
if is_trivial:
|
|
75
|
+
cell_runtime_s = 0.0
|
|
76
|
+
commit_time_s = 0.0
|
|
77
|
+
else:
|
|
78
|
+
cell_runtime_s = exec_end - exec_start
|
|
79
|
+
|
|
80
|
+
# Measure checkpoint time
|
|
81
|
+
commit_start = time.perf_counter()
|
|
82
|
+
_, uncopyable = self._take_checkpoint(f"post_{self._cell_id}")
|
|
83
|
+
# Checkpoint kernel uses old behavior: remove uncopyable vars
|
|
84
|
+
for k in uncopyable:
|
|
85
|
+
if k in self.shell.user_ns:
|
|
86
|
+
del self.shell.user_ns[k]
|
|
87
|
+
commit_end = time.perf_counter()
|
|
88
|
+
commit_time_s = commit_end - commit_start
|
|
89
|
+
|
|
90
|
+
# Check for execution errors
|
|
91
|
+
error_msg = None
|
|
92
|
+
if result.get("status") == "error":
|
|
93
|
+
error_msg = result.get("evalue", "Unknown error")
|
|
94
|
+
|
|
95
|
+
# Send timing metadata
|
|
96
|
+
if not silent:
|
|
97
|
+
msg = {
|
|
98
|
+
"type": "checkpoint_timing",
|
|
99
|
+
"cell_id": self._cell_id or "",
|
|
100
|
+
"execution_count": self.execution_count,
|
|
101
|
+
"cell_runtime_s": cell_runtime_s,
|
|
102
|
+
"commit_time_s": commit_time_s,
|
|
103
|
+
}
|
|
104
|
+
if error_msg:
|
|
105
|
+
msg["error"] = error_msg
|
|
106
|
+
self.send_response(
|
|
107
|
+
self.iopub_socket,
|
|
108
|
+
IOPUB_MSG_TYPE,
|
|
109
|
+
{"flowbook": msg},
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Display timing info
|
|
113
|
+
self._display.display_icon_and_text(
|
|
114
|
+
"ok" if error_msg is None else "error",
|
|
115
|
+
f"Run: {cell_runtime_s*1000:.1f}ms | Commit: {commit_time_s*1000:.1f}ms",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
return result
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# Entry point
|
|
122
|
+
if __name__ == "__main__":
|
|
123
|
+
IPKernelApp.launch_instance(kernel_class=CheckpointKernel)
|
flowbook/cli/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI tools for FlowBook."""
|