scitex 2.0.0__py2.py3-none-any.whl → 2.1.0__py2.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.
- scitex/__init__.py +53 -15
- scitex/__main__.py +72 -26
- scitex/__version__.py +1 -1
- scitex/_sh.py +145 -23
- scitex/ai/__init__.py +30 -16
- scitex/ai/_gen_ai/_Anthropic.py +5 -7
- scitex/ai/_gen_ai/_BaseGenAI.py +2 -2
- scitex/ai/_gen_ai/_DeepSeek.py +10 -2
- scitex/ai/_gen_ai/_Google.py +2 -2
- scitex/ai/_gen_ai/_Llama.py +2 -2
- scitex/ai/_gen_ai/_OpenAI.py +2 -2
- scitex/ai/_gen_ai/_PARAMS.py +51 -65
- scitex/ai/_gen_ai/_Perplexity.py +2 -2
- scitex/ai/_gen_ai/__init__.py +25 -14
- scitex/ai/_gen_ai/_format_output_func.py +4 -4
- scitex/ai/classification/{classifier_server.py → Classifier.py} +5 -5
- scitex/ai/classification/CrossValidationExperiment.py +374 -0
- scitex/ai/classification/__init__.py +43 -4
- scitex/ai/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ai/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ai/classification/reporters/__init__.py +11 -0
- scitex/ai/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ai/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ai/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ai/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ai/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ai/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ai/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ai/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ai/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ai/classification/timeseries/__init__.py +39 -0
- scitex/ai/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ai/clustering/_umap.py +2 -2
- scitex/ai/feature_extraction/vit.py +1 -0
- scitex/ai/feature_selection/__init__.py +30 -0
- scitex/ai/feature_selection/feature_selection.py +364 -0
- scitex/ai/loss/multi_task_loss.py +1 -1
- scitex/ai/metrics/__init__.py +51 -4
- scitex/ai/metrics/_calc_bacc.py +61 -0
- scitex/ai/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ai/metrics/_calc_clf_report.py +78 -0
- scitex/ai/metrics/_calc_conf_mat.py +93 -0
- scitex/ai/metrics/_calc_feature_importance.py +183 -0
- scitex/ai/metrics/_calc_mcc.py +61 -0
- scitex/ai/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ai/metrics/_calc_roc_auc.py +110 -0
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ai/metrics/{silhoute_score_block.py → _calc_silhouette_score.py} +15 -8
- scitex/ai/metrics/_normalize_labels.py +83 -0
- scitex/ai/plt/__init__.py +47 -8
- scitex/ai/plt/{_conf_mat.py → _plot_conf_mat.py} +158 -87
- scitex/ai/plt/_plot_feature_importance.py +323 -0
- scitex/ai/plt/_plot_learning_curve.py +345 -0
- scitex/ai/plt/_plot_optuna_study.py +225 -0
- scitex/ai/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ai/plt/_plot_roc_curve.py +255 -0
- scitex/ai/training/{learning_curve_logger.py → _LearningCurveLogger.py} +197 -213
- scitex/ai/training/__init__.py +2 -2
- scitex/ai/utils/grid_search.py +3 -3
- scitex/benchmark/__init__.py +52 -0
- scitex/benchmark/benchmark.py +400 -0
- scitex/benchmark/monitor.py +370 -0
- scitex/benchmark/profiler.py +297 -0
- scitex/browser/__init__.py +48 -0
- scitex/browser/automation/CookieHandler.py +216 -0
- scitex/browser/automation/__init__.py +7 -0
- scitex/browser/collaboration/__init__.py +55 -0
- scitex/browser/collaboration/auth_helpers.py +94 -0
- scitex/browser/collaboration/collaborative_agent.py +136 -0
- scitex/browser/collaboration/credential_manager.py +188 -0
- scitex/browser/collaboration/interactive_panel.py +400 -0
- scitex/browser/collaboration/persistent_browser.py +170 -0
- scitex/browser/collaboration/shared_session.py +383 -0
- scitex/browser/collaboration/standard_interactions.py +246 -0
- scitex/browser/collaboration/visual_feedback.py +181 -0
- scitex/browser/core/BrowserMixin.py +326 -0
- scitex/browser/core/ChromeProfileManager.py +446 -0
- scitex/browser/core/__init__.py +9 -0
- scitex/browser/debugging/__init__.py +18 -0
- scitex/browser/debugging/_browser_logger.py +657 -0
- scitex/browser/debugging/_highlight_element.py +143 -0
- scitex/browser/debugging/_show_grid.py +154 -0
- scitex/browser/interaction/__init__.py +24 -0
- scitex/browser/interaction/click_center.py +149 -0
- scitex/browser/interaction/click_with_fallbacks.py +206 -0
- scitex/browser/interaction/close_popups.py +498 -0
- scitex/browser/interaction/fill_with_fallbacks.py +209 -0
- scitex/browser/pdf/__init__.py +14 -0
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +200 -0
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +198 -0
- scitex/browser/remote/CaptchaHandler.py +434 -0
- scitex/browser/remote/ZenRowsAPIClient.py +347 -0
- scitex/browser/remote/ZenRowsBrowserManager.py +570 -0
- scitex/browser/remote/__init__.py +11 -0
- scitex/browser/stealth/HumanBehavior.py +344 -0
- scitex/browser/stealth/StealthManager.py +1008 -0
- scitex/browser/stealth/__init__.py +9 -0
- scitex/browser/template.py +122 -0
- scitex/capture/__init__.py +110 -0
- scitex/capture/__main__.py +25 -0
- scitex/capture/capture.py +848 -0
- scitex/capture/cli.py +233 -0
- scitex/capture/gif.py +344 -0
- scitex/capture/mcp_server.py +961 -0
- scitex/capture/session.py +70 -0
- scitex/capture/utils.py +705 -0
- scitex/cli/__init__.py +17 -0
- scitex/cli/cloud.py +447 -0
- scitex/cli/main.py +42 -0
- scitex/cli/scholar.py +280 -0
- scitex/context/_suppress_output.py +5 -3
- scitex/db/__init__.py +30 -3
- scitex/db/__main__.py +75 -0
- scitex/db/_check_health.py +381 -0
- scitex/db/_delete_duplicates.py +25 -386
- scitex/db/_inspect.py +335 -114
- scitex/db/_inspect_optimized.py +301 -0
- scitex/db/{_PostgreSQL.py → _postgresql/_PostgreSQL.py} +3 -3
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BackupMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BatchMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BlobMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ConnectionMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_MaintenanceMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_QueryMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_SchemaMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TransactionMixin.py +1 -1
- scitex/db/_postgresql/__init__.py +6 -0
- scitex/db/_sqlite3/_SQLite3.py +210 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin.py +581 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin_v01-need-_hash-col.py +517 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_BatchMixin.py +1 -1
- scitex/db/_sqlite3/_SQLite3Mixins/_BlobMixin.py +281 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin.py +548 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin_v01-indentation-issues.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ConnectionMixin.py +29 -13
- scitex/db/_sqlite3/_SQLite3Mixins/_GitMixin.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ImportExportMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_IndexMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_MaintenanceMixin.py +2 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_QueryMixin.py +37 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_RowMixin.py +46 -6
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TableMixin.py +56 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TransactionMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/__init__.py +14 -2
- scitex/db/_sqlite3/__init__.py +7 -0
- scitex/db/_sqlite3/_delete_duplicates.py +274 -0
- scitex/decorators/__init__.py +2 -0
- scitex/decorators/_cache_disk.py +13 -5
- scitex/decorators/_cache_disk_async.py +49 -0
- scitex/decorators/_deprecated.py +175 -10
- scitex/decorators/_timeout.py +1 -1
- scitex/dev/_analyze_code_flow.py +2 -2
- scitex/dict/_DotDict.py +73 -15
- scitex/dict/_DotDict_v01-not-handling-recursive-instantiations.py +442 -0
- scitex/dict/_DotDict_v02-not-serializing-Path-object.py +446 -0
- scitex/dict/__init__.py +2 -0
- scitex/dict/_flatten.py +27 -0
- scitex/dsp/_crop.py +2 -2
- scitex/dsp/_demo_sig.py +2 -2
- scitex/dsp/_detect_ripples.py +2 -2
- scitex/dsp/_hilbert.py +2 -2
- scitex/dsp/_listen.py +6 -6
- scitex/dsp/_modulation_index.py +2 -2
- scitex/dsp/_pac.py +1 -1
- scitex/dsp/_psd.py +2 -2
- scitex/dsp/_resample.py +2 -1
- scitex/dsp/_time.py +3 -2
- scitex/dsp/_wavelet.py +3 -2
- scitex/dsp/add_noise.py +2 -2
- scitex/dsp/example.py +1 -0
- scitex/dsp/filt.py +10 -9
- scitex/dsp/template.py +3 -2
- scitex/dsp/utils/_differential_bandpass_filters.py +1 -1
- scitex/dsp/utils/pac.py +2 -2
- scitex/dt/_normalize_timestamp.py +432 -0
- scitex/errors.py +572 -0
- scitex/gen/_DimHandler.py +2 -2
- scitex/gen/__init__.py +37 -7
- scitex/gen/_deprecated_close.py +80 -0
- scitex/gen/_deprecated_start.py +26 -0
- scitex/gen/_detect_environment.py +152 -0
- scitex/gen/_detect_notebook_path.py +169 -0
- scitex/gen/_embed.py +6 -2
- scitex/gen/_get_notebook_path.py +257 -0
- scitex/gen/_less.py +1 -1
- scitex/gen/_list_packages.py +2 -2
- scitex/gen/_norm.py +44 -9
- scitex/gen/_norm_cache.py +269 -0
- scitex/gen/_src.py +3 -5
- scitex/gen/_title_case.py +3 -3
- scitex/io/__init__.py +28 -6
- scitex/io/_glob.py +13 -7
- scitex/io/_load.py +108 -21
- scitex/io/_load_cache.py +303 -0
- scitex/io/_load_configs.py +40 -15
- scitex/io/{_H5Explorer.py → _load_modules/_H5Explorer.py} +80 -17
- scitex/io/_load_modules/_ZarrExplorer.py +114 -0
- scitex/io/_load_modules/_bibtex.py +207 -0
- scitex/io/_load_modules/_hdf5.py +53 -178
- scitex/io/_load_modules/_json.py +5 -3
- scitex/io/_load_modules/_pdf.py +871 -16
- scitex/io/_load_modules/_sqlite3.py +15 -0
- scitex/io/_load_modules/_txt.py +41 -12
- scitex/io/_load_modules/_yaml.py +4 -3
- scitex/io/_load_modules/_zarr.py +126 -0
- scitex/io/_save.py +429 -171
- scitex/io/_save_modules/__init__.py +6 -0
- scitex/io/_save_modules/_bibtex.py +194 -0
- scitex/io/_save_modules/_csv.py +8 -4
- scitex/io/_save_modules/_excel.py +174 -15
- scitex/io/_save_modules/_hdf5.py +251 -226
- scitex/io/_save_modules/_image.py +1 -3
- scitex/io/_save_modules/_json.py +49 -4
- scitex/io/_save_modules/_listed_dfs_as_csv.py +1 -3
- scitex/io/_save_modules/_listed_scalars_as_csv.py +1 -3
- scitex/io/_save_modules/_tex.py +277 -0
- scitex/io/_save_modules/_yaml.py +42 -3
- scitex/io/_save_modules/_zarr.py +160 -0
- scitex/io/utils/__init__.py +20 -0
- scitex/io/utils/h5_to_zarr.py +616 -0
- scitex/linalg/_geometric_median.py +6 -2
- scitex/{gen/_tee.py → logging/_Tee.py} +43 -84
- scitex/logging/__init__.py +122 -0
- scitex/logging/_config.py +158 -0
- scitex/logging/_context.py +103 -0
- scitex/logging/_formatters.py +128 -0
- scitex/logging/_handlers.py +64 -0
- scitex/logging/_levels.py +35 -0
- scitex/logging/_logger.py +163 -0
- scitex/logging/_print_capture.py +95 -0
- scitex/ml/__init__.py +69 -0
- scitex/{ai/genai/anthropic.py → ml/_gen_ai/_Anthropic.py} +13 -19
- scitex/{ai/genai/base_genai.py → ml/_gen_ai/_BaseGenAI.py} +5 -5
- scitex/{ai/genai/deepseek.py → ml/_gen_ai/_DeepSeek.py} +11 -16
- scitex/{ai/genai/google.py → ml/_gen_ai/_Google.py} +7 -15
- scitex/{ai/genai/groq.py → ml/_gen_ai/_Groq.py} +1 -8
- scitex/{ai/genai/llama.py → ml/_gen_ai/_Llama.py} +3 -16
- scitex/{ai/genai/openai.py → ml/_gen_ai/_OpenAI.py} +3 -3
- scitex/{ai/genai/params.py → ml/_gen_ai/_PARAMS.py} +51 -65
- scitex/{ai/genai/perplexity.py → ml/_gen_ai/_Perplexity.py} +3 -14
- scitex/ml/_gen_ai/__init__.py +43 -0
- scitex/{ai/genai/calc_cost.py → ml/_gen_ai/_calc_cost.py} +1 -1
- scitex/{ai/genai/format_output_func.py → ml/_gen_ai/_format_output_func.py} +4 -4
- scitex/{ai/genai/genai_factory.py → ml/_gen_ai/_genai_factory.py} +8 -8
- scitex/ml/activation/__init__.py +8 -0
- scitex/ml/activation/_define.py +11 -0
- scitex/{ai/classifier_server.py → ml/classification/Classifier.py} +5 -5
- scitex/ml/classification/CrossValidationExperiment.py +374 -0
- scitex/ml/classification/__init__.py +46 -0
- scitex/ml/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ml/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ml/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ml/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ml/classification/reporters/__init__.py +11 -0
- scitex/ml/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ml/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ml/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ml/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ml/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ml/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ml/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ml/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ml/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ml/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ml/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ml/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ml/classification/timeseries/__init__.py +39 -0
- scitex/ml/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ml/clustering/__init__.py +11 -0
- scitex/ml/clustering/_pca.py +115 -0
- scitex/ml/clustering/_umap.py +376 -0
- scitex/ml/feature_extraction/__init__.py +56 -0
- scitex/ml/feature_extraction/vit.py +149 -0
- scitex/ml/feature_selection/__init__.py +30 -0
- scitex/ml/feature_selection/feature_selection.py +364 -0
- scitex/ml/loss/_L1L2Losses.py +34 -0
- scitex/ml/loss/__init__.py +12 -0
- scitex/ml/loss/multi_task_loss.py +47 -0
- scitex/ml/metrics/__init__.py +56 -0
- scitex/ml/metrics/_calc_bacc.py +61 -0
- scitex/ml/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ml/metrics/_calc_clf_report.py +78 -0
- scitex/ml/metrics/_calc_conf_mat.py +93 -0
- scitex/ml/metrics/_calc_feature_importance.py +183 -0
- scitex/ml/metrics/_calc_mcc.py +61 -0
- scitex/ml/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ml/metrics/_calc_roc_auc.py +110 -0
- scitex/ml/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ml/metrics/_calc_silhouette_score.py +503 -0
- scitex/ml/metrics/_normalize_labels.py +83 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ml/optim/__init__.py +13 -0
- scitex/ml/optim/_get_set.py +31 -0
- scitex/ml/optim/_optimizers.py +71 -0
- scitex/ml/plt/__init__.py +60 -0
- scitex/ml/plt/_plot_conf_mat.py +663 -0
- scitex/ml/plt/_plot_feature_importance.py +323 -0
- scitex/ml/plt/_plot_learning_curve.py +345 -0
- scitex/ml/plt/_plot_optuna_study.py +225 -0
- scitex/ml/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ml/plt/_plot_roc_curve.py +255 -0
- scitex/ml/sk/__init__.py +11 -0
- scitex/ml/sk/_clf.py +58 -0
- scitex/ml/sk/_to_sktime.py +100 -0
- scitex/ml/sklearn/__init__.py +26 -0
- scitex/ml/sklearn/clf.py +58 -0
- scitex/ml/sklearn/to_sktime.py +100 -0
- scitex/{ai/training/early_stopping.py → ml/training/_EarlyStopping.py} +1 -2
- scitex/{ai → ml/training}/_LearningCurveLogger.py +198 -242
- scitex/ml/training/__init__.py +7 -0
- scitex/ml/utils/__init__.py +22 -0
- scitex/ml/utils/_check_params.py +50 -0
- scitex/ml/utils/_default_dataset.py +46 -0
- scitex/ml/utils/_format_samples_for_sktime.py +26 -0
- scitex/ml/utils/_label_encoder.py +134 -0
- scitex/ml/utils/_merge_labels.py +22 -0
- scitex/ml/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ml/utils/_under_sample.py +51 -0
- scitex/ml/utils/_verify_n_gpus.py +16 -0
- scitex/ml/utils/grid_search.py +148 -0
- scitex/nn/_BNet.py +15 -9
- scitex/nn/_Filters.py +2 -2
- scitex/nn/_ModulationIndex.py +2 -2
- scitex/nn/_PAC.py +1 -1
- scitex/nn/_Spectrogram.py +12 -3
- scitex/nn/__init__.py +9 -10
- scitex/path/__init__.py +18 -0
- scitex/path/_clean.py +4 -0
- scitex/path/_find.py +9 -4
- scitex/path/_symlink.py +348 -0
- scitex/path/_version.py +4 -3
- scitex/pd/__init__.py +2 -0
- scitex/pd/_get_unique.py +99 -0
- scitex/plt/__init__.py +114 -5
- scitex/plt/_subplots/_AxesWrapper.py +1 -3
- scitex/plt/_subplots/_AxisWrapper.py +7 -3
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +47 -13
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +160 -2
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +26 -4
- scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +322 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +1 -0
- scitex/plt/_subplots/_FigWrapper.py +62 -6
- scitex/plt/_subplots/_export_as_csv.py +43 -27
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +5 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +81 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +20 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +35 -18
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +15 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +35 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +6 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_text.py +60 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters.py +56 -59
- scitex/plt/ax/_style/_hide_spines.py +1 -3
- scitex/plt/ax/_style/_rotate_labels.py +180 -76
- scitex/plt/ax/_style/_rotate_labels_v01.py +248 -0
- scitex/plt/ax/_style/_set_meta.py +11 -4
- scitex/plt/ax/_style/_set_supxyt.py +3 -3
- scitex/plt/ax/_style/_set_xyt.py +3 -3
- scitex/plt/ax/_style/_share_axes.py +2 -2
- scitex/plt/color/__init__.py +4 -4
- scitex/plt/color/{_get_colors_from_cmap.py → _get_colors_from_conf_matap.py} +7 -7
- scitex/plt/utils/_configure_mpl.py +99 -86
- scitex/plt/utils/_histogram_utils.py +1 -3
- scitex/plt/utils/_is_valid_axis.py +1 -3
- scitex/plt/utils/_scitex_config.py +1 -0
- scitex/repro/__init__.py +75 -0
- scitex/{reproduce → repro}/_gen_ID.py +1 -1
- scitex/{reproduce → repro}/_gen_timestamp.py +1 -1
- scitex/repro_rng/_RandomStateManager.py +590 -0
- scitex/repro_rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/repro_rng/__init__.py +39 -0
- scitex/reproduce/__init__.py +25 -13
- scitex/reproduce/_hash_array.py +22 -0
- scitex/resource/_get_processor_usages.py +4 -4
- scitex/resource/_get_specs.py +2 -2
- scitex/resource/_log_processor_usages.py +2 -2
- scitex/rng/_RandomStateManager.py +590 -0
- scitex/rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/rng/__init__.py +39 -0
- scitex/scholar/__init__.py +309 -19
- scitex/scholar/__main__.py +319 -0
- scitex/scholar/auth/ScholarAuthManager.py +308 -0
- scitex/scholar/auth/__init__.py +12 -0
- scitex/scholar/auth/core/AuthenticationGateway.py +473 -0
- scitex/scholar/auth/core/BrowserAuthenticator.py +386 -0
- scitex/scholar/auth/core/StrategyResolver.py +309 -0
- scitex/scholar/auth/core/__init__.py +16 -0
- scitex/scholar/auth/gateway/_OpenURLLinkFinder.py +120 -0
- scitex/scholar/auth/gateway/_OpenURLResolver.py +209 -0
- scitex/scholar/auth/gateway/__init__.py +38 -0
- scitex/scholar/auth/gateway/_resolve_functions.py +101 -0
- scitex/scholar/auth/providers/BaseAuthenticator.py +166 -0
- scitex/scholar/auth/providers/EZProxyAuthenticator.py +484 -0
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +619 -0
- scitex/scholar/auth/providers/ShibbolethAuthenticator.py +686 -0
- scitex/scholar/auth/providers/__init__.py +18 -0
- scitex/scholar/auth/session/AuthCacheManager.py +189 -0
- scitex/scholar/auth/session/SessionManager.py +159 -0
- scitex/scholar/auth/session/__init__.py +11 -0
- scitex/scholar/auth/sso/BaseSSOAutomator.py +373 -0
- scitex/scholar/auth/sso/OpenAthensSSOAutomator.py +378 -0
- scitex/scholar/auth/sso/SSOAutomator.py +180 -0
- scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +380 -0
- scitex/scholar/auth/sso/__init__.py +15 -0
- scitex/scholar/browser/ScholarBrowserManager.py +705 -0
- scitex/scholar/browser/__init__.py +38 -0
- scitex/scholar/browser/utils/__init__.py +13 -0
- scitex/scholar/browser/utils/click_and_wait.py +205 -0
- scitex/scholar/browser/utils/close_unwanted_pages.py +140 -0
- scitex/scholar/browser/utils/wait_redirects.py +732 -0
- scitex/scholar/config/PublisherRules.py +132 -0
- scitex/scholar/config/ScholarConfig.py +126 -0
- scitex/scholar/config/__init__.py +17 -0
- scitex/scholar/core/Paper.py +627 -0
- scitex/scholar/core/Papers.py +722 -0
- scitex/scholar/core/Scholar.py +1975 -0
- scitex/scholar/core/__init__.py +9 -0
- scitex/scholar/impact_factor/ImpactFactorEngine.py +204 -0
- scitex/scholar/impact_factor/__init__.py +20 -0
- scitex/scholar/impact_factor/estimation/ImpactFactorEstimationEngine.py +0 -0
- scitex/scholar/impact_factor/estimation/__init__.py +40 -0
- scitex/scholar/impact_factor/estimation/build_database.py +0 -0
- scitex/scholar/impact_factor/estimation/core/__init__.py +28 -0
- scitex/scholar/impact_factor/estimation/core/cache_manager.py +523 -0
- scitex/scholar/impact_factor/estimation/core/calculator.py +355 -0
- scitex/scholar/impact_factor/estimation/core/journal_matcher.py +428 -0
- scitex/scholar/integration/__init__.py +59 -0
- scitex/scholar/integration/base.py +502 -0
- scitex/scholar/integration/mendeley/__init__.py +22 -0
- scitex/scholar/integration/mendeley/exporter.py +166 -0
- scitex/scholar/integration/mendeley/importer.py +236 -0
- scitex/scholar/integration/mendeley/linker.py +79 -0
- scitex/scholar/integration/mendeley/mapper.py +212 -0
- scitex/scholar/integration/zotero/__init__.py +27 -0
- scitex/scholar/integration/zotero/__main__.py +264 -0
- scitex/scholar/integration/zotero/exporter.py +351 -0
- scitex/scholar/integration/zotero/importer.py +372 -0
- scitex/scholar/integration/zotero/linker.py +415 -0
- scitex/scholar/integration/zotero/mapper.py +286 -0
- scitex/scholar/metadata_engines/ScholarEngine.py +588 -0
- scitex/scholar/metadata_engines/__init__.py +21 -0
- scitex/scholar/metadata_engines/individual/ArXivEngine.py +397 -0
- scitex/scholar/metadata_engines/individual/CrossRefEngine.py +274 -0
- scitex/scholar/metadata_engines/individual/CrossRefLocalEngine.py +263 -0
- scitex/scholar/metadata_engines/individual/OpenAlexEngine.py +350 -0
- scitex/scholar/metadata_engines/individual/PubMedEngine.py +329 -0
- scitex/scholar/metadata_engines/individual/SemanticScholarEngine.py +438 -0
- scitex/scholar/metadata_engines/individual/URLDOIEngine.py +410 -0
- scitex/scholar/metadata_engines/individual/_BaseDOIEngine.py +487 -0
- scitex/scholar/metadata_engines/individual/__init__.py +7 -0
- scitex/scholar/metadata_engines/utils/_PubMedConverter.py +469 -0
- scitex/scholar/metadata_engines/utils/_URLDOIExtractor.py +283 -0
- scitex/scholar/metadata_engines/utils/__init__.py +30 -0
- scitex/scholar/metadata_engines/utils/_metadata2bibtex.py +103 -0
- scitex/scholar/metadata_engines/utils/_standardize_metadata.py +376 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +579 -0
- scitex/scholar/pdf_download/__init__.py +5 -0
- scitex/scholar/pdf_download/strategies/__init__.py +38 -0
- scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +376 -0
- scitex/scholar/pdf_download/strategies/direct_download.py +131 -0
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +167 -0
- scitex/scholar/pdf_download/strategies/manual_download_utils.py +996 -0
- scitex/scholar/pdf_download/strategies/response_body.py +207 -0
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +364 -0
- scitex/scholar/pipelines/ScholarPipelineParallel.py +478 -0
- scitex/scholar/pipelines/ScholarPipelineSingle.py +767 -0
- scitex/scholar/pipelines/__init__.py +49 -0
- scitex/scholar/storage/BibTeXHandler.py +1018 -0
- scitex/scholar/storage/PaperIO.py +468 -0
- scitex/scholar/storage/ScholarLibrary.py +182 -0
- scitex/scholar/storage/_DeduplicationManager.py +548 -0
- scitex/scholar/storage/_LibraryCacheManager.py +724 -0
- scitex/scholar/storage/_LibraryManager.py +1835 -0
- scitex/scholar/storage/__init__.py +28 -0
- scitex/scholar/url_finder/ScholarURLFinder.py +379 -0
- scitex/scholar/url_finder/__init__.py +7 -0
- scitex/scholar/url_finder/strategies/__init__.py +33 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_direct_links.py +261 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_dropdown.py +67 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_href.py +204 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_navigation.py +256 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_publisher_patterns.py +165 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_zotero_translators.py +163 -0
- scitex/scholar/url_finder/strategies/find_supplementary_urls_by_href.py +70 -0
- scitex/scholar/utils/__init__.py +22 -0
- scitex/scholar/utils/bibtex/__init__.py +9 -0
- scitex/scholar/utils/bibtex/_parse_bibtex.py +71 -0
- scitex/scholar/utils/cleanup/__init__.py +8 -0
- scitex/scholar/utils/cleanup/_cleanup_scholar_processes.py +96 -0
- scitex/scholar/utils/cleanup/cleanup_old_extractions.py +117 -0
- scitex/scholar/utils/text/_TextNormalizer.py +407 -0
- scitex/scholar/utils/text/__init__.py +9 -0
- scitex/scholar/zotero/__init__.py +38 -0
- scitex/session/__init__.py +51 -0
- scitex/session/_lifecycle.py +736 -0
- scitex/session/_manager.py +102 -0
- scitex/session/template.py +122 -0
- scitex/stats/__init__.py +30 -26
- scitex/stats/correct/__init__.py +21 -0
- scitex/stats/correct/_correct_bonferroni.py +551 -0
- scitex/stats/correct/_correct_fdr.py +634 -0
- scitex/stats/correct/_correct_holm.py +548 -0
- scitex/stats/correct/_correct_sidak.py +499 -0
- scitex/stats/descriptive/__init__.py +85 -0
- scitex/stats/descriptive/_circular.py +540 -0
- scitex/stats/descriptive/_describe.py +219 -0
- scitex/stats/descriptive/_nan.py +518 -0
- scitex/stats/descriptive/_real.py +189 -0
- scitex/stats/effect_sizes/__init__.py +41 -0
- scitex/stats/effect_sizes/_cliffs_delta.py +325 -0
- scitex/stats/effect_sizes/_cohens_d.py +342 -0
- scitex/stats/effect_sizes/_epsilon_squared.py +315 -0
- scitex/stats/effect_sizes/_eta_squared.py +302 -0
- scitex/stats/effect_sizes/_prob_superiority.py +296 -0
- scitex/stats/posthoc/__init__.py +19 -0
- scitex/stats/posthoc/_dunnett.py +463 -0
- scitex/stats/posthoc/_games_howell.py +383 -0
- scitex/stats/posthoc/_tukey_hsd.py +367 -0
- scitex/stats/power/__init__.py +19 -0
- scitex/stats/power/_power.py +433 -0
- scitex/stats/template.py +119 -0
- scitex/stats/utils/__init__.py +62 -0
- scitex/stats/utils/_effect_size.py +985 -0
- scitex/stats/utils/_formatters.py +270 -0
- scitex/stats/utils/_normalizers.py +927 -0
- scitex/stats/utils/_power.py +433 -0
- scitex/stats_v01/_EffectSizeCalculator.py +488 -0
- scitex/stats_v01/_StatisticalValidator.py +411 -0
- scitex/stats_v01/__init__.py +60 -0
- scitex/stats_v01/_additional_tests.py +415 -0
- scitex/{stats → stats_v01}/_p2stars.py +19 -5
- scitex/stats_v01/_two_sample_tests.py +141 -0
- scitex/stats_v01/desc/__init__.py +83 -0
- scitex/stats_v01/desc/_circular.py +540 -0
- scitex/stats_v01/desc/_describe.py +219 -0
- scitex/stats_v01/desc/_nan.py +518 -0
- scitex/{stats/desc/_nan.py → stats_v01/desc/_nan_v01-20250920_145731.py} +23 -12
- scitex/stats_v01/desc/_real.py +189 -0
- scitex/stats_v01/tests/__corr_test_optimized.py +221 -0
- scitex/stats_v01/tests/_corr_test_optimized.py +179 -0
- scitex/str/__init__.py +1 -3
- scitex/str/_clean_path.py +6 -2
- scitex/str/_latex_fallback.py +267 -160
- scitex/str/_parse.py +44 -36
- scitex/str/_printc.py +1 -3
- scitex/template/__init__.py +87 -0
- scitex/template/_create_project.py +267 -0
- scitex/template/create_pip_project.py +80 -0
- scitex/template/create_research.py +80 -0
- scitex/template/create_singularity.py +80 -0
- scitex/units.py +291 -0
- scitex/utils/_compress_hdf5.py +14 -3
- scitex/utils/_email.py +21 -2
- scitex/utils/_grid.py +6 -4
- scitex/utils/_notify.py +13 -10
- scitex/utils/_verify_scitex_format.py +589 -0
- scitex/utils/_verify_scitex_format_v01.py +370 -0
- scitex/utils/template.py +122 -0
- scitex/web/_search_pubmed.py +62 -16
- scitex-2.1.0.dist-info/LICENSE +21 -0
- scitex-2.1.0.dist-info/METADATA +677 -0
- scitex-2.1.0.dist-info/RECORD +919 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/WHEEL +1 -1
- scitex-2.1.0.dist-info/entry_points.txt +3 -0
- scitex/ai/__Classifiers.py +0 -101
- scitex/ai/classification/classification_reporter.py +0 -1137
- scitex/ai/classification/classifiers.py +0 -101
- scitex/ai/classification_reporter.py +0 -1161
- scitex/ai/genai/__init__.py +0 -277
- scitex/ai/genai/anthropic_provider.py +0 -320
- scitex/ai/genai/anthropic_refactored.py +0 -109
- scitex/ai/genai/auth_manager.py +0 -200
- scitex/ai/genai/base_provider.py +0 -291
- scitex/ai/genai/chat_history.py +0 -307
- scitex/ai/genai/cost_tracker.py +0 -276
- scitex/ai/genai/deepseek_provider.py +0 -251
- scitex/ai/genai/google_provider.py +0 -228
- scitex/ai/genai/groq_provider.py +0 -248
- scitex/ai/genai/image_processor.py +0 -250
- scitex/ai/genai/llama_provider.py +0 -214
- scitex/ai/genai/mock_provider.py +0 -127
- scitex/ai/genai/model_registry.py +0 -304
- scitex/ai/genai/openai_provider.py +0 -293
- scitex/ai/genai/perplexity_provider.py +0 -205
- scitex/ai/genai/provider_base.py +0 -302
- scitex/ai/genai/provider_factory.py +0 -370
- scitex/ai/genai/response_handler.py +0 -235
- scitex/ai/layer/_Pass.py +0 -21
- scitex/ai/layer/__init__.py +0 -10
- scitex/ai/layer/_switch.py +0 -8
- scitex/ai/metrics/_bACC.py +0 -51
- scitex/ai/plt/_learning_curve.py +0 -194
- scitex/ai/plt/_optuna_study.py +0 -111
- scitex/ai/plt/aucs/__init__.py +0 -2
- scitex/ai/plt/aucs/example.py +0 -60
- scitex/ai/plt/aucs/pre_rec_auc.py +0 -223
- scitex/ai/plt/aucs/roc_auc.py +0 -246
- scitex/ai/sampling/undersample.py +0 -29
- scitex/db/_SQLite3.py +0 -2136
- scitex/db/_SQLite3Mixins/_BlobMixin.py +0 -229
- scitex/gen/_close.py +0 -222
- scitex/gen/_start.py +0 -451
- scitex/general/__init__.py +0 -5
- scitex/io/_load_modules/_db.py +0 -24
- scitex/life/__init__.py +0 -10
- scitex/life/_monitor_rain.py +0 -49
- scitex/reproduce/_fix_seeds.py +0 -45
- scitex/res/__init__.py +0 -5
- scitex/scholar/_local_search.py +0 -454
- scitex/scholar/_paper.py +0 -244
- scitex/scholar/_pdf_downloader.py +0 -325
- scitex/scholar/_search.py +0 -393
- scitex/scholar/_vector_search.py +0 -370
- scitex/scholar/_web_sources.py +0 -457
- scitex/stats/desc/__init__.py +0 -40
- scitex-2.0.0.dist-info/METADATA +0 -307
- scitex-2.0.0.dist-info/RECORD +0 -572
- scitex-2.0.0.dist-info/licenses/LICENSE +0 -7
- /scitex/ai/{act → activation}/__init__.py +0 -0
- /scitex/ai/{act → activation}/_define.py +0 -0
- /scitex/ai/{early_stopping.py → training/_EarlyStopping.py} +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ImportExportMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_IndexMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_RowMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TableMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/__init__.py +0 -0
- /scitex/{stats → stats_v01}/_calc_partial_corr.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_describe_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_multiple_corrections.py +0 -0
- /scitex/{stats → stats_v01}/_nan_stats.py +0 -0
- /scitex/{stats → stats_v01}/_p2stars_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_statistical_tests.py +0 -0
- /scitex/{stats/desc/_describe.py → stats_v01/desc/_describe_v01-20250920_145731.py} +0 -0
- /scitex/{stats/desc/_real.py → stats_v01/desc/_real_v01-20250920_145731.py} +0 -0
- /scitex/{stats → stats_v01}/multiple/__init__.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_bonferroni_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_fdr_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_multicompair.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_single.py +0 -0
- /scitex/{stats → stats_v01}/tests/__init__.py +0 -0
- /scitex/{stats → stats_v01}/tests/_brunner_munzel_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_nocorrelation_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_smirnov_grubbs.py +0 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-08-22 17:05:52 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex_repo/src/scitex/gen/_deprecated_close.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import os
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
+
# ----------------------------------------
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Deprecated wrapper for the old scitex.gen.close function.
|
|
14
|
+
|
|
15
|
+
This module provides backward compatibility by forwarding calls to the new
|
|
16
|
+
scitex.session.close function while showing deprecation warnings.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from ..decorators._deprecated import deprecated
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@deprecated(
|
|
23
|
+
"Use scitex.session.close instead. The old interface will be removed in a future version."
|
|
24
|
+
)
|
|
25
|
+
def close(*args, **kwargs):
|
|
26
|
+
"""Deprecated close function - use scitex.session.close instead.
|
|
27
|
+
|
|
28
|
+
This function provides backward compatibility for existing code that uses
|
|
29
|
+
scitex.gen.close(). It forwards all calls to the new scitex.session.close()
|
|
30
|
+
function while displaying a deprecation warning.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
*args : tuple
|
|
35
|
+
Positional arguments passed to scitex.session.close()
|
|
36
|
+
**kwargs : dict
|
|
37
|
+
Keyword arguments passed to scitex.session.close()
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
Any
|
|
42
|
+
Same return value as scitex.session.close()
|
|
43
|
+
"""
|
|
44
|
+
# Import here to avoid circular dependencies
|
|
45
|
+
from ..session import close as session_close
|
|
46
|
+
|
|
47
|
+
return session_close(*args, **kwargs)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@deprecated(
|
|
51
|
+
"Use scitex.session.running2finished instead. The old interface will be removed in a future version."
|
|
52
|
+
)
|
|
53
|
+
def running2finished(*args, **kwargs):
|
|
54
|
+
"""Deprecated running2finished function - use scitex.session.running2finished instead.
|
|
55
|
+
|
|
56
|
+
This function provides backward compatibility for existing code that uses
|
|
57
|
+
scitex.gen.running2finished(). It forwards all calls to the new
|
|
58
|
+
scitex.session.running2finished() function while displaying a deprecation warning.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
*args : tuple
|
|
63
|
+
Positional arguments passed to scitex.session.running2finished()
|
|
64
|
+
**kwargs : dict
|
|
65
|
+
Keyword arguments passed to scitex.session.running2finished()
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
Any
|
|
70
|
+
Same return value as scitex.session.running2finished()
|
|
71
|
+
"""
|
|
72
|
+
# Import here to avoid circular dependencies
|
|
73
|
+
from ..session import running2finished as session_running2finished
|
|
74
|
+
|
|
75
|
+
return session_running2finished(*args, **kwargs)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
__all__ = ["close", "running2finished"]
|
|
79
|
+
|
|
80
|
+
# EOF
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# File: /home/ywatanabe/proj/SciTeX-Code/src/scitex/gen/_deprecated_start.py
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Deprecated wrapper for the old scitex.gen.start function.
|
|
7
|
+
|
|
8
|
+
This module provides backward compatibility by forwarding calls to the new
|
|
9
|
+
scitex.session.start function while showing deprecation warnings.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from ..decorators._deprecated import deprecated
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@deprecated(
|
|
16
|
+
reason="Use scitex.session.start instead. The old interface will be removed in a future version.",
|
|
17
|
+
forward_to="..session.start"
|
|
18
|
+
)
|
|
19
|
+
def start(*args, **kwargs):
|
|
20
|
+
"""This docstring will be auto-generated by the @deprecated decorator."""
|
|
21
|
+
# This function body will never be executed due to forwarding
|
|
22
|
+
# but we need a placeholder implementation
|
|
23
|
+
raise NotImplementedError("This function should be forwarded by the @deprecated decorator")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
__all__ = ['start']
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-07-04 11:20:00 (ywatanabe)"
|
|
4
|
+
# File: ./src/scitex/gen/_detect_environment.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Enhanced environment detection for SciTeX.
|
|
8
|
+
|
|
9
|
+
Provides better discrimination between:
|
|
10
|
+
- Python scripts
|
|
11
|
+
- IPython console
|
|
12
|
+
- Jupyter notebooks
|
|
13
|
+
- Interactive Python
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import sys
|
|
18
|
+
from typing import Literal, Tuple
|
|
19
|
+
|
|
20
|
+
__all__ = ['detect_environment', 'get_output_directory']
|
|
21
|
+
|
|
22
|
+
EnvironmentType = Literal['script', 'jupyter', 'ipython', 'interactive', 'unknown']
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def detect_environment() -> EnvironmentType:
|
|
26
|
+
"""
|
|
27
|
+
Detect the current execution environment.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
EnvironmentType
|
|
32
|
+
One of: 'script', 'jupyter', 'ipython', 'interactive', 'unknown'
|
|
33
|
+
|
|
34
|
+
Examples
|
|
35
|
+
--------
|
|
36
|
+
>>> env = detect_environment()
|
|
37
|
+
>>> print(f"Running in: {env}")
|
|
38
|
+
Running in: script
|
|
39
|
+
"""
|
|
40
|
+
# Check for Jupyter notebook
|
|
41
|
+
if 'ipykernel' in sys.modules:
|
|
42
|
+
try:
|
|
43
|
+
ip = get_ipython()
|
|
44
|
+
if ip and type(ip).__name__ == 'ZMQInteractiveShell':
|
|
45
|
+
return 'jupyter'
|
|
46
|
+
except NameError:
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
# Check for IPython console
|
|
50
|
+
try:
|
|
51
|
+
ip = get_ipython()
|
|
52
|
+
if ip and type(ip).__name__ == 'TerminalInteractiveShell':
|
|
53
|
+
return 'ipython'
|
|
54
|
+
except NameError:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
# Check for regular Python script
|
|
58
|
+
if sys.argv and sys.argv[0] and sys.argv[0].endswith('.py'):
|
|
59
|
+
return 'script'
|
|
60
|
+
|
|
61
|
+
# Check for interactive Python
|
|
62
|
+
if hasattr(sys, 'ps1'):
|
|
63
|
+
return 'interactive'
|
|
64
|
+
|
|
65
|
+
return 'unknown'
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_output_directory(specified_path: str, env_type: EnvironmentType = None) -> Tuple[str, bool]:
|
|
69
|
+
"""
|
|
70
|
+
Get the appropriate output directory based on environment.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
specified_path : str
|
|
75
|
+
The path specified by the user
|
|
76
|
+
env_type : EnvironmentType, optional
|
|
77
|
+
Override environment detection
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
tuple[str, bool]
|
|
82
|
+
(output_directory, should_use_temp)
|
|
83
|
+
|
|
84
|
+
Examples
|
|
85
|
+
--------
|
|
86
|
+
>>> output_dir, use_temp = get_output_directory("data.csv")
|
|
87
|
+
>>> print(f"Save to: {output_dir}, Temp: {use_temp}")
|
|
88
|
+
Save to: ./script_out/data.csv, Temp: False
|
|
89
|
+
"""
|
|
90
|
+
import inspect
|
|
91
|
+
|
|
92
|
+
if env_type is None:
|
|
93
|
+
env_type = detect_environment()
|
|
94
|
+
|
|
95
|
+
# For absolute paths, use as-is
|
|
96
|
+
if specified_path.startswith('/'):
|
|
97
|
+
return specified_path, False
|
|
98
|
+
|
|
99
|
+
# Get base directory based on environment
|
|
100
|
+
if env_type == 'script':
|
|
101
|
+
# Use script location
|
|
102
|
+
try:
|
|
103
|
+
script_path = inspect.stack()[1].filename
|
|
104
|
+
if script_path and not script_path.startswith('<'):
|
|
105
|
+
script_dir = os.path.dirname(os.path.abspath(script_path))
|
|
106
|
+
script_name = os.path.splitext(os.path.basename(script_path))[0]
|
|
107
|
+
base_dir = os.path.join(script_dir, f"{script_name}_out")
|
|
108
|
+
return os.path.join(base_dir, specified_path), False
|
|
109
|
+
except:
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
elif env_type == 'jupyter':
|
|
113
|
+
# For Jupyter, use current working directory with subdirectory
|
|
114
|
+
# This keeps outputs near the notebook
|
|
115
|
+
base_dir = os.path.join(os.getcwd(), 'notebook_outputs')
|
|
116
|
+
return os.path.join(base_dir, specified_path), False
|
|
117
|
+
|
|
118
|
+
elif env_type in ['ipython', 'interactive']:
|
|
119
|
+
# Use temp directory for console sessions
|
|
120
|
+
user = os.getenv('USER', 'unknown')
|
|
121
|
+
base_dir = f'/tmp/{user}/{env_type}'
|
|
122
|
+
return os.path.join(base_dir, specified_path), True
|
|
123
|
+
|
|
124
|
+
# Fallback: use current directory
|
|
125
|
+
return os.path.join('./output', specified_path), False
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def is_notebook() -> bool:
|
|
129
|
+
"""Check if running in Jupyter notebook."""
|
|
130
|
+
return detect_environment() == 'jupyter'
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def is_ipython() -> bool:
|
|
134
|
+
"""Check if running in IPython (console or notebook)."""
|
|
135
|
+
return detect_environment() in ['jupyter', 'ipython']
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def is_script() -> bool:
|
|
139
|
+
"""Check if running as a script."""
|
|
140
|
+
return detect_environment() == 'script'
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# Backward compatibility
|
|
144
|
+
def is_ipython_legacy() -> bool:
|
|
145
|
+
"""Legacy IPython detection for compatibility."""
|
|
146
|
+
try:
|
|
147
|
+
__IPYTHON__
|
|
148
|
+
return True
|
|
149
|
+
except NameError:
|
|
150
|
+
return False
|
|
151
|
+
|
|
152
|
+
# EOF
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-07-04 11:22:00 (ywatanabe)"
|
|
4
|
+
# File: ./src/scitex/gen/_detect_notebook_path.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Detect Jupyter notebook filename for consistent output paths.
|
|
8
|
+
|
|
9
|
+
When running in a notebook like ./examples/analysis.ipynb,
|
|
10
|
+
outputs should go to ./examples/analysis_out/
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import json
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
__all__ = ['get_notebook_path', 'get_notebook_output_dir']
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_notebook_path() -> Optional[str]:
|
|
21
|
+
"""
|
|
22
|
+
Get the path of the currently running Jupyter notebook.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
Optional[str]
|
|
27
|
+
Path to the notebook file, or None if not in a notebook
|
|
28
|
+
|
|
29
|
+
Examples
|
|
30
|
+
--------
|
|
31
|
+
>>> path = get_notebook_path()
|
|
32
|
+
>>> print(path)
|
|
33
|
+
./examples/my_analysis.ipynb
|
|
34
|
+
"""
|
|
35
|
+
try:
|
|
36
|
+
# Method 1: Try to get from IPython
|
|
37
|
+
ip = get_ipython()
|
|
38
|
+
|
|
39
|
+
# Check if we're in a notebook
|
|
40
|
+
if not (ip and type(ip).__name__ == 'ZMQInteractiveShell'):
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
# Method 2: Check IPython's notebook_name
|
|
44
|
+
if hasattr(ip, 'notebook_name'):
|
|
45
|
+
return ip.notebook_name
|
|
46
|
+
|
|
47
|
+
# Method 3: Try to get from kernel connection file
|
|
48
|
+
import re
|
|
49
|
+
import glob
|
|
50
|
+
|
|
51
|
+
# Get kernel ID from the current session
|
|
52
|
+
kernel_id = re.search(
|
|
53
|
+
r'kernel-(.*?)\.json',
|
|
54
|
+
ip.config['IPKernelApp']['connection_file']
|
|
55
|
+
).group(1)
|
|
56
|
+
|
|
57
|
+
# Search for notebook sessions
|
|
58
|
+
runtime_dir = os.environ.get('JUPYTER_RUNTIME_DIR',
|
|
59
|
+
os.path.expanduser('~/.local/share/jupyter/runtime'))
|
|
60
|
+
|
|
61
|
+
for nbserver in glob.glob(os.path.join(runtime_dir, 'nbserver-*.json')):
|
|
62
|
+
try:
|
|
63
|
+
with open(nbserver, 'r') as f:
|
|
64
|
+
server_info = json.load(f)
|
|
65
|
+
|
|
66
|
+
# Check notebook sessions
|
|
67
|
+
import requests
|
|
68
|
+
sessions_url = f"{server_info['url']}api/sessions?token={server_info.get('token', '')}"
|
|
69
|
+
response = requests.get(sessions_url)
|
|
70
|
+
|
|
71
|
+
if response.status_code == 200:
|
|
72
|
+
sessions = response.json()
|
|
73
|
+
for session in sessions:
|
|
74
|
+
if session['kernel']['id'] == kernel_id:
|
|
75
|
+
# Found our notebook!
|
|
76
|
+
notebook_path = session['notebook']['path']
|
|
77
|
+
return notebook_path
|
|
78
|
+
except:
|
|
79
|
+
continue
|
|
80
|
+
|
|
81
|
+
# Method 4: Try JavaScript bridge (if available)
|
|
82
|
+
try:
|
|
83
|
+
from IPython.display import Javascript, display
|
|
84
|
+
import time
|
|
85
|
+
|
|
86
|
+
# This won't work in papermill, but works in interactive notebooks
|
|
87
|
+
display(Javascript('''
|
|
88
|
+
IPython.notebook.kernel.execute(
|
|
89
|
+
`__notebook_path__ = '${IPython.notebook.notebook_path}'`
|
|
90
|
+
);
|
|
91
|
+
'''))
|
|
92
|
+
|
|
93
|
+
# Brief pause for JS execution
|
|
94
|
+
time.sleep(0.1)
|
|
95
|
+
|
|
96
|
+
if '__notebook_path__' in globals():
|
|
97
|
+
return globals()['__notebook_path__']
|
|
98
|
+
except:
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
except Exception:
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_notebook_output_dir(notebook_path: Optional[str] = None) -> Optional[str]:
|
|
108
|
+
"""
|
|
109
|
+
Get the output directory for a notebook.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
notebook_path : Optional[str]
|
|
114
|
+
Path to notebook, or None to auto-detect
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
Optional[str]
|
|
119
|
+
Output directory path like ./examples/analysis_out/
|
|
120
|
+
|
|
121
|
+
Examples
|
|
122
|
+
--------
|
|
123
|
+
>>> output_dir = get_notebook_output_dir()
|
|
124
|
+
>>> print(output_dir)
|
|
125
|
+
./examples/analysis_out/
|
|
126
|
+
|
|
127
|
+
>>> output_dir = get_notebook_output_dir('./docs/tutorial.ipynb')
|
|
128
|
+
>>> print(output_dir)
|
|
129
|
+
./docs/tutorial_out/
|
|
130
|
+
"""
|
|
131
|
+
if notebook_path is None:
|
|
132
|
+
notebook_path = get_notebook_path()
|
|
133
|
+
|
|
134
|
+
if not notebook_path:
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
# Get directory and base name
|
|
138
|
+
notebook_dir = os.path.dirname(notebook_path) or '.'
|
|
139
|
+
notebook_base = os.path.splitext(os.path.basename(notebook_path))[0]
|
|
140
|
+
|
|
141
|
+
# Create output directory path
|
|
142
|
+
output_dir = os.path.join(notebook_dir, f"{notebook_base}_out")
|
|
143
|
+
|
|
144
|
+
return output_dir
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def detect_notebook_from_cwd() -> Optional[str]:
|
|
148
|
+
"""
|
|
149
|
+
Fallback: Try to detect notebook from current working directory.
|
|
150
|
+
|
|
151
|
+
If there's exactly one .ipynb file in the current directory,
|
|
152
|
+
assume that's the running notebook.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
Optional[str]
|
|
157
|
+
Path to notebook or None
|
|
158
|
+
"""
|
|
159
|
+
import glob
|
|
160
|
+
|
|
161
|
+
notebooks = glob.glob('*.ipynb')
|
|
162
|
+
|
|
163
|
+
# Only use this method if there's exactly one notebook
|
|
164
|
+
if len(notebooks) == 1:
|
|
165
|
+
return notebooks[0]
|
|
166
|
+
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
# EOF
|
scitex/gen/_embed.py
CHANGED
|
@@ -63,13 +63,17 @@ def embed():
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
if __name__ == "__main__":
|
|
66
|
+
import sys
|
|
67
|
+
import matplotlib.pyplot as plt
|
|
68
|
+
import scitex
|
|
69
|
+
|
|
66
70
|
# Start
|
|
67
|
-
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.
|
|
71
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(sys, plt)
|
|
68
72
|
|
|
69
73
|
embed()
|
|
70
74
|
|
|
71
75
|
# Close
|
|
72
|
-
scitex.
|
|
76
|
+
scitex.session.close(CONFIG)
|
|
73
77
|
|
|
74
78
|
# EOF
|
|
75
79
|
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-07-04 12:00:00 (ywatanabe)"
|
|
4
|
+
# File: ./src/scitex/gen/_get_notebook_path.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Get the current Jupyter notebook path.
|
|
8
|
+
|
|
9
|
+
This module provides functions to detect and retrieve the path
|
|
10
|
+
of the currently running Jupyter notebook.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import json
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
__all__ = ['get_notebook_path', 'get_notebook_name']
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_notebook_path() -> Optional[str]:
|
|
21
|
+
"""
|
|
22
|
+
Get the full path of the current Jupyter notebook.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
Optional[str]
|
|
27
|
+
Full path to the notebook file, or None if not in a notebook
|
|
28
|
+
|
|
29
|
+
Examples
|
|
30
|
+
--------
|
|
31
|
+
>>> path = get_notebook_path()
|
|
32
|
+
>>> if path:
|
|
33
|
+
... print(f"Running in notebook: {path}")
|
|
34
|
+
"""
|
|
35
|
+
try:
|
|
36
|
+
# Try to get from IPython
|
|
37
|
+
from IPython import get_ipython
|
|
38
|
+
ip = get_ipython()
|
|
39
|
+
|
|
40
|
+
if not ip:
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
# Check if we're in a notebook
|
|
44
|
+
if type(ip).__name__ != 'ZMQInteractiveShell':
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
# Try multiple methods to get the notebook path
|
|
48
|
+
|
|
49
|
+
# Method 1: From IPython's config
|
|
50
|
+
if hasattr(ip, 'config') and hasattr(ip.config, 'IPKernelApp'):
|
|
51
|
+
connection_file = ip.config.IPKernelApp.connection_file
|
|
52
|
+
if connection_file:
|
|
53
|
+
# Extract kernel ID from connection file
|
|
54
|
+
kernel_id = os.path.basename(connection_file).split('-', 1)[1].replace('.json', '')
|
|
55
|
+
|
|
56
|
+
# Try to get notebook path from Jupyter server
|
|
57
|
+
notebook_path = _get_notebook_from_server(kernel_id)
|
|
58
|
+
if notebook_path:
|
|
59
|
+
return os.path.abspath(notebook_path)
|
|
60
|
+
|
|
61
|
+
# Method 2: From environment variable (JupyterLab sets this)
|
|
62
|
+
if 'JPY_SESSION_NAME' in os.environ:
|
|
63
|
+
session_name = os.environ['JPY_SESSION_NAME']
|
|
64
|
+
if session_name.endswith('.ipynb'):
|
|
65
|
+
return os.path.abspath(session_name)
|
|
66
|
+
|
|
67
|
+
# Method 3: From notebook's metadata
|
|
68
|
+
try:
|
|
69
|
+
# This works in some notebook environments
|
|
70
|
+
import ipykernel
|
|
71
|
+
import notebook
|
|
72
|
+
from notebook.notebookapp import list_running_servers
|
|
73
|
+
|
|
74
|
+
for server in list_running_servers():
|
|
75
|
+
response = _get_notebook_list(server['url'], server.get('token', ''))
|
|
76
|
+
if response:
|
|
77
|
+
for session in response:
|
|
78
|
+
if session['kernel']['id'] == kernel_id:
|
|
79
|
+
return os.path.join(server['notebook_dir'], session['notebook']['path'])
|
|
80
|
+
except:
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _get_notebook_from_server(kernel_id: str) -> Optional[str]:
|
|
90
|
+
"""Try to get notebook path from Jupyter server API."""
|
|
91
|
+
try:
|
|
92
|
+
import requests
|
|
93
|
+
from notebook.notebookapp import list_running_servers
|
|
94
|
+
|
|
95
|
+
for server in list_running_servers():
|
|
96
|
+
url = f"{server['url']}api/sessions"
|
|
97
|
+
token = server.get('token', '')
|
|
98
|
+
|
|
99
|
+
if token:
|
|
100
|
+
headers = {'Authorization': f'token {token}'}
|
|
101
|
+
response = requests.get(url, headers=headers)
|
|
102
|
+
else:
|
|
103
|
+
response = requests.get(url)
|
|
104
|
+
|
|
105
|
+
if response.status_code == 200:
|
|
106
|
+
sessions = response.json()
|
|
107
|
+
for session in sessions:
|
|
108
|
+
if session['kernel']['id'] == kernel_id:
|
|
109
|
+
return session['notebook']['path']
|
|
110
|
+
except:
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _get_notebook_list(server_url: str, token: str) -> Optional[list]:
|
|
117
|
+
"""Get list of running notebooks from server."""
|
|
118
|
+
try:
|
|
119
|
+
import requests
|
|
120
|
+
url = f"{server_url}api/sessions"
|
|
121
|
+
|
|
122
|
+
if token:
|
|
123
|
+
headers = {'Authorization': f'token {token}'}
|
|
124
|
+
response = requests.get(url, headers=headers)
|
|
125
|
+
else:
|
|
126
|
+
response = requests.get(url)
|
|
127
|
+
|
|
128
|
+
if response.status_code == 200:
|
|
129
|
+
return response.json()
|
|
130
|
+
except:
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def get_notebook_name() -> Optional[str]:
|
|
137
|
+
"""
|
|
138
|
+
Get just the name of the current notebook (without path).
|
|
139
|
+
|
|
140
|
+
Returns
|
|
141
|
+
-------
|
|
142
|
+
Optional[str]
|
|
143
|
+
Notebook filename, or None if not in a notebook
|
|
144
|
+
|
|
145
|
+
Examples
|
|
146
|
+
--------
|
|
147
|
+
>>> name = get_notebook_name()
|
|
148
|
+
>>> if name:
|
|
149
|
+
... print(f"Notebook: {name}")
|
|
150
|
+
"""
|
|
151
|
+
notebook_path = get_notebook_path()
|
|
152
|
+
if notebook_path:
|
|
153
|
+
return os.path.basename(notebook_path)
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_notebook_directory() -> Optional[str]:
|
|
158
|
+
"""
|
|
159
|
+
Get the directory containing the current notebook.
|
|
160
|
+
|
|
161
|
+
Returns
|
|
162
|
+
-------
|
|
163
|
+
Optional[str]
|
|
164
|
+
Directory path, or None if not in a notebook
|
|
165
|
+
"""
|
|
166
|
+
notebook_path = get_notebook_path()
|
|
167
|
+
if notebook_path:
|
|
168
|
+
return os.path.dirname(os.path.abspath(notebook_path))
|
|
169
|
+
return None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# Simpler fallback method for when advanced detection fails
|
|
173
|
+
def get_notebook_info_simple() -> tuple[Optional[str], Optional[str]]:
|
|
174
|
+
"""
|
|
175
|
+
Simple method to get notebook info using current working directory.
|
|
176
|
+
|
|
177
|
+
Returns
|
|
178
|
+
-------
|
|
179
|
+
tuple[Optional[str], Optional[str]]
|
|
180
|
+
(notebook_name, notebook_directory)
|
|
181
|
+
"""
|
|
182
|
+
try:
|
|
183
|
+
# In Jupyter, __file__ is not defined but we can use inspect
|
|
184
|
+
import inspect
|
|
185
|
+
import re
|
|
186
|
+
|
|
187
|
+
# Get the call stack and look for notebook indicators
|
|
188
|
+
for frame_info in inspect.stack():
|
|
189
|
+
filename = frame_info.filename
|
|
190
|
+
if filename:
|
|
191
|
+
# Check for ipynb in the filename
|
|
192
|
+
if filename.endswith('.ipynb'):
|
|
193
|
+
return os.path.basename(filename), os.path.dirname(os.path.abspath(filename))
|
|
194
|
+
|
|
195
|
+
# Look for notebook execution patterns in the filename
|
|
196
|
+
# Jupyter often uses patterns like <ipython-input-...> or kernel UUIDs
|
|
197
|
+
if '<ipython-input' in filename or 'ipykernel_' in filename:
|
|
198
|
+
# We're definitely in a notebook, need to find which one
|
|
199
|
+
break
|
|
200
|
+
|
|
201
|
+
# If we can't find it in stack, check if we're in a notebook environment
|
|
202
|
+
from IPython import get_ipython
|
|
203
|
+
ip = get_ipython()
|
|
204
|
+
|
|
205
|
+
if ip and type(ip).__name__ == 'ZMQInteractiveShell':
|
|
206
|
+
# We're in a notebook but can't determine the name from stack
|
|
207
|
+
# Try multiple strategies to find the notebook name
|
|
208
|
+
|
|
209
|
+
# Strategy 1: Check IPython's config for hints
|
|
210
|
+
if hasattr(ip, 'config') and hasattr(ip.config, 'IPKernelApp'):
|
|
211
|
+
if hasattr(ip.config.IPKernelApp, 'connection_file'):
|
|
212
|
+
conn_file = ip.config.IPKernelApp.connection_file
|
|
213
|
+
# Sometimes the connection file path contains hints about the notebook
|
|
214
|
+
if conn_file and '.ipynb' in conn_file:
|
|
215
|
+
match = re.search(r'([^/]+)\.ipynb', conn_file)
|
|
216
|
+
if match:
|
|
217
|
+
return match.group(0), os.getcwd()
|
|
218
|
+
|
|
219
|
+
# Strategy 2: Check environment variables
|
|
220
|
+
for env_var in ['JUPYTER_NOTEBOOK_NAME', 'JPY_SESSION_NAME', 'NOTEBOOK_NAME']:
|
|
221
|
+
if env_var in os.environ:
|
|
222
|
+
notebook_name = os.environ[env_var]
|
|
223
|
+
if notebook_name.endswith('.ipynb'):
|
|
224
|
+
return notebook_name, os.getcwd()
|
|
225
|
+
|
|
226
|
+
# Strategy 3: Look for recently modified .ipynb files in current directory
|
|
227
|
+
cwd = os.getcwd()
|
|
228
|
+
try:
|
|
229
|
+
# Get all .ipynb files with their modification times
|
|
230
|
+
notebook_files = []
|
|
231
|
+
for file in os.listdir(cwd):
|
|
232
|
+
if file.endswith('.ipynb') and not file.startswith('.') and not file.endswith('_test_output.ipynb'):
|
|
233
|
+
file_path = os.path.join(cwd, file)
|
|
234
|
+
mtime = os.path.getmtime(file_path)
|
|
235
|
+
notebook_files.append((file, mtime))
|
|
236
|
+
|
|
237
|
+
# Sort by modification time (most recent first)
|
|
238
|
+
notebook_files.sort(key=lambda x: x[1], reverse=True)
|
|
239
|
+
|
|
240
|
+
if notebook_files:
|
|
241
|
+
# Return the most recently modified notebook
|
|
242
|
+
# This is a good heuristic as the currently running notebook
|
|
243
|
+
# is likely to have been saved recently
|
|
244
|
+
return notebook_files[0][0], cwd
|
|
245
|
+
except:
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
# If no notebook found, return generic name
|
|
249
|
+
return "untitled.ipynb", cwd
|
|
250
|
+
|
|
251
|
+
except:
|
|
252
|
+
pass
|
|
253
|
+
|
|
254
|
+
return None, None
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# EOF
|