scitex 2.14.0__py3-none-any.whl → 2.15.3__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 +71 -17
- scitex/_env_loader.py +156 -0
- scitex/_mcp_resources/__init__.py +37 -0
- scitex/_mcp_resources/_cheatsheet.py +135 -0
- scitex/_mcp_resources/_figrecipe.py +138 -0
- scitex/_mcp_resources/_formats.py +102 -0
- scitex/_mcp_resources/_modules.py +337 -0
- scitex/_mcp_resources/_session.py +149 -0
- scitex/_mcp_tools/__init__.py +4 -0
- scitex/_mcp_tools/audio.py +66 -0
- scitex/_mcp_tools/diagram.py +11 -95
- scitex/_mcp_tools/introspect.py +210 -0
- scitex/_mcp_tools/plt.py +260 -305
- scitex/_mcp_tools/scholar.py +74 -0
- scitex/_mcp_tools/social.py +27 -0
- scitex/_mcp_tools/template.py +24 -0
- scitex/_mcp_tools/writer.py +17 -210
- scitex/ai/_gen_ai/_PARAMS.py +10 -7
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
- scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
- scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
- scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
- scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
- scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
- scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
- scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
- scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +30 -1550
- scitex/ai/classification/timeseries/_sliding_window_core.py +467 -0
- scitex/ai/classification/timeseries/_sliding_window_plotting.py +369 -0
- scitex/audio/README.md +40 -36
- scitex/audio/__init__.py +129 -61
- scitex/audio/_branding.py +185 -0
- scitex/audio/_mcp/__init__.py +32 -0
- scitex/audio/_mcp/handlers.py +59 -6
- scitex/audio/_mcp/speak_handlers.py +238 -0
- scitex/audio/_relay.py +225 -0
- scitex/audio/_tts.py +18 -10
- scitex/audio/engines/base.py +17 -10
- scitex/audio/engines/elevenlabs_engine.py +7 -2
- scitex/audio/mcp_server.py +228 -75
- scitex/canvas/README.md +1 -1
- scitex/canvas/editor/_dearpygui/__init__.py +25 -0
- scitex/canvas/editor/_dearpygui/_editor.py +147 -0
- scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
- scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
- scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
- scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
- scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
- scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
- scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
- scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
- scitex/canvas/editor/_dearpygui/_selection.py +295 -0
- scitex/canvas/editor/_dearpygui/_state.py +93 -0
- scitex/canvas/editor/_dearpygui/_utils.py +61 -0
- scitex/canvas/editor/flask_editor/_core/__init__.py +27 -0
- scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py +200 -0
- scitex/canvas/editor/flask_editor/_core/_editor.py +173 -0
- scitex/canvas/editor/flask_editor/_core/_export_helpers.py +353 -0
- scitex/canvas/editor/flask_editor/_core/_routes_basic.py +190 -0
- scitex/canvas/editor/flask_editor/_core/_routes_export.py +332 -0
- scitex/canvas/editor/flask_editor/_core/_routes_panels.py +252 -0
- scitex/canvas/editor/flask_editor/_core/_routes_save.py +218 -0
- scitex/canvas/editor/flask_editor/_core.py +25 -1684
- scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
- scitex/cli/__init__.py +38 -43
- scitex/cli/audio.py +160 -41
- scitex/cli/capture.py +133 -20
- scitex/cli/introspect.py +488 -0
- scitex/cli/main.py +200 -109
- scitex/cli/mcp.py +60 -34
- scitex/cli/plt.py +414 -0
- scitex/cli/repro.py +15 -8
- scitex/cli/resource.py +15 -8
- scitex/cli/scholar/__init__.py +154 -8
- scitex/cli/scholar/_crossref_scitex.py +296 -0
- scitex/cli/scholar/_fetch.py +25 -3
- scitex/cli/social.py +355 -0
- scitex/cli/stats.py +136 -11
- scitex/cli/template.py +129 -12
- scitex/cli/tex.py +15 -8
- scitex/cli/writer.py +49 -299
- scitex/cloud/__init__.py +41 -2
- scitex/config/README.md +1 -1
- scitex/config/__init__.py +16 -2
- scitex/config/_env_registry.py +256 -0
- scitex/context/__init__.py +22 -0
- scitex/dev/__init__.py +20 -1
- scitex/diagram/__init__.py +42 -19
- scitex/diagram/mcp_server.py +13 -125
- scitex/gen/__init__.py +50 -14
- scitex/gen/_list_packages.py +4 -4
- scitex/introspect/__init__.py +82 -0
- scitex/introspect/_call_graph.py +303 -0
- scitex/introspect/_class_hierarchy.py +163 -0
- scitex/introspect/_core.py +41 -0
- scitex/introspect/_docstring.py +131 -0
- scitex/introspect/_examples.py +113 -0
- scitex/introspect/_imports.py +271 -0
- scitex/{gen/_inspect_module.py → introspect/_list_api.py} +48 -56
- scitex/introspect/_mcp/__init__.py +41 -0
- scitex/introspect/_mcp/handlers.py +233 -0
- scitex/introspect/_members.py +155 -0
- scitex/introspect/_resolve.py +89 -0
- scitex/introspect/_signature.py +131 -0
- scitex/introspect/_source.py +80 -0
- scitex/introspect/_type_hints.py +172 -0
- scitex/io/_save.py +1 -2
- scitex/io/bundle/README.md +1 -1
- scitex/logging/_formatters.py +19 -9
- scitex/mcp_server.py +98 -5
- scitex/os/__init__.py +4 -0
- scitex/{gen → os}/_check_host.py +4 -5
- scitex/plt/__init__.py +245 -550
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
- scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/plt/gallery/README.md +1 -1
- scitex/plt/utils/_hitmap/__init__.py +82 -0
- scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
- scitex/plt/utils/_hitmap/_color_application.py +346 -0
- scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
- scitex/plt/utils/_hitmap/_constants.py +40 -0
- scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
- scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
- scitex/plt/utils/_hitmap/_query.py +113 -0
- scitex/plt/utils/_hitmap.py +46 -1616
- scitex/plt/utils/_metadata/__init__.py +80 -0
- scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
- scitex/plt/utils/_metadata/_artists/_base.py +195 -0
- scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
- scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
- scitex/plt/utils/_metadata/_artists/_images.py +80 -0
- scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
- scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
- scitex/plt/utils/_metadata/_artists/_text.py +106 -0
- scitex/plt/utils/_metadata/_csv.py +416 -0
- scitex/plt/utils/_metadata/_detect.py +225 -0
- scitex/plt/utils/_metadata/_legend.py +127 -0
- scitex/plt/utils/_metadata/_rounding.py +117 -0
- scitex/plt/utils/_metadata/_verification.py +202 -0
- scitex/schema/README.md +1 -1
- scitex/scholar/__init__.py +8 -0
- scitex/scholar/_mcp/crossref_handlers.py +265 -0
- scitex/scholar/core/Scholar.py +63 -1700
- scitex/scholar/core/_mixins/__init__.py +36 -0
- scitex/scholar/core/_mixins/_enrichers.py +270 -0
- scitex/scholar/core/_mixins/_library_handlers.py +100 -0
- scitex/scholar/core/_mixins/_loaders.py +103 -0
- scitex/scholar/core/_mixins/_pdf_download.py +375 -0
- scitex/scholar/core/_mixins/_pipeline.py +312 -0
- scitex/scholar/core/_mixins/_project_handlers.py +125 -0
- scitex/scholar/core/_mixins/_savers.py +69 -0
- scitex/scholar/core/_mixins/_search.py +103 -0
- scitex/scholar/core/_mixins/_services.py +88 -0
- scitex/scholar/core/_mixins/_url_finding.py +105 -0
- scitex/scholar/crossref_scitex.py +367 -0
- scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/scholar/examples/00_run_all.sh +120 -0
- scitex/scholar/jobs/_executors.py +27 -3
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
- scitex/scholar/pdf_download/_cli.py +154 -0
- scitex/scholar/pdf_download/strategies/__init__.py +11 -8
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
- scitex/scholar/pipelines/ScholarPipelineParallel.py +80 -138
- scitex/scholar/pipelines/ScholarPipelineSingle.py +43 -63
- scitex/scholar/pipelines/_single_steps.py +71 -36
- scitex/scholar/storage/_LibraryManager.py +97 -1695
- scitex/scholar/storage/_mixins/__init__.py +30 -0
- scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
- scitex/scholar/storage/_mixins/_library_operations.py +218 -0
- scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
- scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
- scitex/scholar/storage/_mixins/_resolution.py +376 -0
- scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
- scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
- scitex/security/README.md +3 -3
- scitex/session/README.md +1 -1
- scitex/session/__init__.py +26 -7
- scitex/session/_decorator.py +1 -1
- scitex/sh/README.md +1 -1
- scitex/sh/__init__.py +7 -4
- scitex/social/__init__.py +155 -0
- scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/stats/_mcp/_handlers/__init__.py +31 -0
- scitex/stats/_mcp/_handlers/_corrections.py +113 -0
- scitex/stats/_mcp/_handlers/_descriptive.py +78 -0
- scitex/stats/_mcp/_handlers/_effect_size.py +106 -0
- scitex/stats/_mcp/_handlers/_format.py +94 -0
- scitex/stats/_mcp/_handlers/_normality.py +110 -0
- scitex/stats/_mcp/_handlers/_posthoc.py +224 -0
- scitex/stats/_mcp/_handlers/_power.py +247 -0
- scitex/stats/_mcp/_handlers/_recommend.py +102 -0
- scitex/stats/_mcp/_handlers/_run_test.py +279 -0
- scitex/stats/_mcp/_handlers/_stars.py +48 -0
- scitex/stats/_mcp/handlers.py +19 -1171
- scitex/stats/auto/_stat_style.py +175 -0
- scitex/stats/auto/_style_definitions.py +411 -0
- scitex/stats/auto/_styles.py +22 -620
- scitex/stats/descriptive/__init__.py +11 -8
- scitex/stats/descriptive/_ci.py +39 -0
- scitex/stats/power/_power.py +15 -4
- scitex/str/__init__.py +2 -1
- scitex/str/_title_case.py +63 -0
- scitex/template/README.md +1 -1
- scitex/template/__init__.py +25 -10
- scitex/template/_code_templates.py +147 -0
- scitex/template/_mcp/handlers.py +81 -0
- scitex/template/_mcp/tool_schemas.py +55 -0
- scitex/template/_templates/__init__.py +51 -0
- scitex/template/_templates/audio.py +233 -0
- scitex/template/_templates/canvas.py +312 -0
- scitex/template/_templates/capture.py +268 -0
- scitex/template/_templates/config.py +43 -0
- scitex/template/_templates/diagram.py +294 -0
- scitex/template/_templates/io.py +107 -0
- scitex/template/_templates/module.py +53 -0
- scitex/template/_templates/plt.py +202 -0
- scitex/template/_templates/scholar.py +267 -0
- scitex/template/_templates/session.py +130 -0
- scitex/template/_templates/session_minimal.py +43 -0
- scitex/template/_templates/session_plot.py +67 -0
- scitex/template/_templates/session_stats.py +77 -0
- scitex/template/_templates/stats.py +323 -0
- scitex/template/_templates/writer.py +296 -0
- scitex/template/clone_writer_directory.py +5 -5
- scitex/ui/_backends/_email.py +10 -2
- scitex/ui/_backends/_webhook.py +5 -1
- scitex/web/_search_pubmed.py +10 -6
- scitex/writer/README.md +1 -1
- scitex/writer/__init__.py +43 -34
- scitex/writer/_mcp/handlers.py +11 -744
- scitex/writer/_mcp/tool_schemas.py +5 -335
- scitex-2.15.3.dist-info/METADATA +667 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/RECORD +241 -120
- scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
- scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
- scitex/diagram/_compile.py +0 -312
- scitex/diagram/_diagram.py +0 -355
- scitex/diagram/_mcp/__init__.py +0 -4
- scitex/diagram/_mcp/handlers.py +0 -400
- scitex/diagram/_mcp/tool_schemas.py +0 -157
- scitex/diagram/_presets.py +0 -173
- scitex/diagram/_schema.py +0 -182
- scitex/diagram/_split.py +0 -278
- scitex/gen/_ci.py +0 -12
- scitex/gen/_title_case.py +0 -89
- scitex/plt/_mcp/__init__.py +0 -4
- scitex/plt/_mcp/_handlers_annotation.py +0 -102
- scitex/plt/_mcp/_handlers_figure.py +0 -195
- scitex/plt/_mcp/_handlers_plot.py +0 -252
- scitex/plt/_mcp/_handlers_style.py +0 -219
- scitex/plt/_mcp/handlers.py +0 -74
- scitex/plt/_mcp/tool_schemas.py +0 -497
- scitex/plt/mcp_server.py +0 -231
- scitex/scholar/examples/SUGGESTIONS.md +0 -865
- scitex/scholar/examples/dev.py +0 -38
- scitex-2.14.0.dist-info/METADATA +0 -1238
- /scitex/{gen → context}/_detect_environment.py +0 -0
- /scitex/{gen → context}/_get_notebook_path.py +0 -0
- /scitex/{gen/_shell.py → sh/_shell_legacy.py} +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/WHEEL +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/entry_points.txt +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/licenses/LICENSE +0 -0
scitex/__init__.py
CHANGED
|
@@ -29,19 +29,9 @@ warnings.filterwarnings("default", category=DeprecationWarning, module="scitex.*
|
|
|
29
29
|
# Version
|
|
30
30
|
from .__version__ import __version__
|
|
31
31
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# Sentinel object for decorator-injected parameters
|
|
37
|
-
class _InjectedSentinel:
|
|
38
|
-
"""Sentinel value indicating a parameter will be injected by a decorator"""
|
|
39
|
-
|
|
40
|
-
def __repr__(self):
|
|
41
|
-
return "<INJECTED>"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
INJECTED = _InjectedSentinel()
|
|
32
|
+
# BACKWARD COMPATIBILITY: Deprecated items accessible via __getattr__
|
|
33
|
+
# These are handled at the end of this file after lazy modules are defined
|
|
34
|
+
_DEPRECATED_ATTRS = {"INJECTED", "show_install_guide", "Diagram"}
|
|
45
35
|
|
|
46
36
|
|
|
47
37
|
# Lazy loading for all modules
|
|
@@ -196,6 +186,56 @@ config = _LazyModule("config")
|
|
|
196
186
|
audio = _LazyModule("audio")
|
|
197
187
|
msword = _LazyModule("msword")
|
|
198
188
|
fts = _LazyModule("fts") # Bundle schemas module
|
|
189
|
+
social = _LazyModule("social") # Social media integration (socialia wrapper)
|
|
190
|
+
diagram = _LazyModule("diagram") # Diagram creation (delegates to figrecipe)
|
|
191
|
+
introspect = _LazyModule("introspect") # Python introspection utilities
|
|
192
|
+
sh = _LazyModule("sh") # Shell command execution
|
|
193
|
+
os = _LazyModule("os") # OS utilities (file operations)
|
|
194
|
+
cv = _LazyModule("cv") # Computer vision utilities
|
|
195
|
+
ui = _LazyModule("ui") # User interface utilities
|
|
196
|
+
git = _LazyModule("git") # Git operations
|
|
197
|
+
schema = _LazyModule("schema") # Data schema utilities
|
|
198
|
+
canvas = _LazyModule("canvas") # Canvas utilities for figure composition
|
|
199
|
+
security = _LazyModule("security") # Security utilities
|
|
200
|
+
benchmark = _LazyModule("benchmark") # Benchmarking utilities
|
|
201
|
+
bridge = _LazyModule("bridge") # Bridge utilities
|
|
202
|
+
browser = _LazyModule("browser") # Browser automation
|
|
203
|
+
compat = _LazyModule("compat") # Compatibility utilities
|
|
204
|
+
cli = _LazyModule("cli") # Command-line interface
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# BACKWARD COMPATIBILITY: Module-level __getattr__ for deprecated attributes
|
|
208
|
+
def __getattr__(name):
|
|
209
|
+
"""Handle deprecated attributes with warnings."""
|
|
210
|
+
if name == "INJECTED":
|
|
211
|
+
warnings.warn(
|
|
212
|
+
"scitex.INJECTED is deprecated, use scitex.session.INJECTED instead",
|
|
213
|
+
DeprecationWarning,
|
|
214
|
+
stacklevel=2,
|
|
215
|
+
)
|
|
216
|
+
from .session import INJECTED
|
|
217
|
+
|
|
218
|
+
return INJECTED
|
|
219
|
+
if name == "show_install_guide":
|
|
220
|
+
warnings.warn(
|
|
221
|
+
"scitex.show_install_guide() is deprecated, use scitex.dev.show_install_guide() instead",
|
|
222
|
+
DeprecationWarning,
|
|
223
|
+
stacklevel=2,
|
|
224
|
+
)
|
|
225
|
+
from .dev import show_install_guide
|
|
226
|
+
|
|
227
|
+
return show_install_guide
|
|
228
|
+
if name == "Diagram":
|
|
229
|
+
warnings.warn(
|
|
230
|
+
"scitex.Diagram is deprecated, use scitex.diagram.Diagram instead",
|
|
231
|
+
DeprecationWarning,
|
|
232
|
+
stacklevel=2,
|
|
233
|
+
)
|
|
234
|
+
from .diagram import Diagram
|
|
235
|
+
|
|
236
|
+
return Diagram
|
|
237
|
+
raise AttributeError(f"module 'scitex' has no attribute '{name}'")
|
|
238
|
+
|
|
199
239
|
|
|
200
240
|
# Centralized path configuration - eager loaded for convenience
|
|
201
241
|
# Usage: scitex.PATHS.logs, scitex.PATHS.cache, etc.
|
|
@@ -213,6 +253,7 @@ if _os.environ.get("SCITEX_CLOUD_CODE_WORKSPACE") == "true":
|
|
|
213
253
|
pass # Silently fail if matplotlib not available
|
|
214
254
|
|
|
215
255
|
__all__ = [
|
|
256
|
+
# Core modules
|
|
216
257
|
"io",
|
|
217
258
|
"gen",
|
|
218
259
|
"plt",
|
|
@@ -224,7 +265,6 @@ __all__ = [
|
|
|
224
265
|
"path",
|
|
225
266
|
"dict",
|
|
226
267
|
"decorators",
|
|
227
|
-
"__version__",
|
|
228
268
|
"sh",
|
|
229
269
|
"errors",
|
|
230
270
|
"units",
|
|
@@ -248,7 +288,7 @@ __all__ = [
|
|
|
248
288
|
"linalg",
|
|
249
289
|
"parallel",
|
|
250
290
|
"datetime",
|
|
251
|
-
"dt",
|
|
291
|
+
"dt",
|
|
252
292
|
"types",
|
|
253
293
|
"utils",
|
|
254
294
|
"etc",
|
|
@@ -260,9 +300,23 @@ __all__ = [
|
|
|
260
300
|
"audio",
|
|
261
301
|
"msword",
|
|
262
302
|
"fts",
|
|
263
|
-
"
|
|
303
|
+
"social",
|
|
304
|
+
"diagram",
|
|
305
|
+
"introspect",
|
|
306
|
+
"os",
|
|
307
|
+
"cv",
|
|
308
|
+
"ui",
|
|
309
|
+
"git",
|
|
310
|
+
"schema",
|
|
311
|
+
"canvas",
|
|
312
|
+
"security",
|
|
313
|
+
"benchmark",
|
|
314
|
+
"bridge",
|
|
315
|
+
"browser",
|
|
316
|
+
"compat",
|
|
317
|
+
"cli",
|
|
264
318
|
"PATHS",
|
|
265
|
-
"
|
|
319
|
+
"__version__",
|
|
266
320
|
]
|
|
267
321
|
|
|
268
322
|
# EOF
|
scitex/_env_loader.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-24
|
|
3
|
+
# File: src/scitex/_env_loader.py
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Environment variable loader for SCITEX_ENV_SRC.
|
|
7
|
+
|
|
8
|
+
Parses and loads bash-compatible .src files containing environment variable definitions.
|
|
9
|
+
Supports both directory paths (all *.src files) and single file paths.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
import re
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Dict, List
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
# Pattern to match: export VAR=value or VAR=value (with optional quotes)
|
|
23
|
+
_ENV_PATTERN = re.compile(r"^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _parse_value(value: str) -> str:
|
|
27
|
+
"""Parse a bash-style value, handling quotes and escapes."""
|
|
28
|
+
value = value.strip()
|
|
29
|
+
|
|
30
|
+
# Handle double-quoted strings
|
|
31
|
+
if value.startswith('"') and value.endswith('"'):
|
|
32
|
+
value = value[1:-1]
|
|
33
|
+
# Unescape common bash escapes
|
|
34
|
+
value = value.replace('\\"', '"')
|
|
35
|
+
value = value.replace("\\$", "$")
|
|
36
|
+
value = value.replace("\\\\", "\\")
|
|
37
|
+
# Handle single-quoted strings (no escaping in bash single quotes)
|
|
38
|
+
elif value.startswith("'") and value.endswith("'"):
|
|
39
|
+
value = value[1:-1]
|
|
40
|
+
|
|
41
|
+
# Expand $VAR and ${VAR} references
|
|
42
|
+
def expand_var(match):
|
|
43
|
+
var_name = match.group(1) or match.group(2)
|
|
44
|
+
return os.environ.get(var_name, "")
|
|
45
|
+
|
|
46
|
+
value = re.sub(r"\$\{([^}]+)\}|\$([A-Za-z_][A-Za-z0-9_]*)", expand_var, value)
|
|
47
|
+
|
|
48
|
+
return value
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def parse_src_file(filepath: Path) -> Dict[str, str]:
|
|
52
|
+
"""
|
|
53
|
+
Parse a bash-compatible .src file and extract environment variables.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
filepath : Path
|
|
58
|
+
Path to the .src file.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
dict
|
|
63
|
+
Dictionary of variable names to values.
|
|
64
|
+
"""
|
|
65
|
+
env_vars = {}
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
with open(filepath) as f:
|
|
69
|
+
for line_num, line in enumerate(f, 1):
|
|
70
|
+
line = line.strip()
|
|
71
|
+
|
|
72
|
+
# Skip empty lines and comments
|
|
73
|
+
if not line or line.startswith("#"):
|
|
74
|
+
continue
|
|
75
|
+
|
|
76
|
+
match = _ENV_PATTERN.match(line)
|
|
77
|
+
if match:
|
|
78
|
+
name, value = match.groups()
|
|
79
|
+
env_vars[name] = _parse_value(value)
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logger.warning(f"Failed to parse {filepath}: {e}")
|
|
83
|
+
|
|
84
|
+
return env_vars
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def load_env_from_path(path: str) -> Dict[str, str]:
|
|
88
|
+
"""
|
|
89
|
+
Load environment variables from a file or directory.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
path : str
|
|
94
|
+
Path to a .src file or directory containing .src files.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
dict
|
|
99
|
+
All loaded environment variables.
|
|
100
|
+
"""
|
|
101
|
+
loaded = {}
|
|
102
|
+
path_obj = Path(path).expanduser()
|
|
103
|
+
|
|
104
|
+
if not path_obj.exists():
|
|
105
|
+
logger.warning(f"SCITEX_ENV_SRC path does not exist: {path}")
|
|
106
|
+
return loaded
|
|
107
|
+
|
|
108
|
+
files_to_load: List[Path] = []
|
|
109
|
+
|
|
110
|
+
if path_obj.is_dir():
|
|
111
|
+
# Load all .src files in directory
|
|
112
|
+
files_to_load = sorted(path_obj.glob("*.src"))
|
|
113
|
+
elif path_obj.is_file():
|
|
114
|
+
files_to_load = [path_obj]
|
|
115
|
+
else:
|
|
116
|
+
logger.warning(f"SCITEX_ENV_SRC is not a file or directory: {path}")
|
|
117
|
+
return loaded
|
|
118
|
+
|
|
119
|
+
for src_file in files_to_load:
|
|
120
|
+
env_vars = parse_src_file(src_file)
|
|
121
|
+
if env_vars:
|
|
122
|
+
logger.info(f"Loaded {len(env_vars)} vars from {src_file.name}")
|
|
123
|
+
loaded.update(env_vars)
|
|
124
|
+
|
|
125
|
+
return loaded
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def load_scitex_env() -> int:
|
|
129
|
+
"""
|
|
130
|
+
Load environment variables from SCITEX_ENV_SRC if set.
|
|
131
|
+
|
|
132
|
+
This function should be called early in the MCP server startup.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
int
|
|
137
|
+
Number of environment variables loaded.
|
|
138
|
+
"""
|
|
139
|
+
env_src = os.environ.get("SCITEX_ENV_SRC")
|
|
140
|
+
|
|
141
|
+
if not env_src:
|
|
142
|
+
return 0
|
|
143
|
+
|
|
144
|
+
loaded = load_env_from_path(env_src)
|
|
145
|
+
|
|
146
|
+
# Apply to current process environment
|
|
147
|
+
for name, value in loaded.items():
|
|
148
|
+
os.environ[name] = value
|
|
149
|
+
|
|
150
|
+
if loaded:
|
|
151
|
+
logger.info(f"SCITEX_ENV_SRC: Loaded {len(loaded)} environment variables")
|
|
152
|
+
|
|
153
|
+
return len(loaded)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# EOF
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-20
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/__init__.py
|
|
4
|
+
"""MCP Resources for SciTeX - Dynamic documentation for AI agents.
|
|
5
|
+
|
|
6
|
+
This module provides MCP resources that expose SciTeX documentation,
|
|
7
|
+
patterns, and examples to AI agents for code generation guidance.
|
|
8
|
+
|
|
9
|
+
Resources:
|
|
10
|
+
- scitex://cheatsheet - Quick reference for all core patterns
|
|
11
|
+
- scitex://session-tree - Output directory structure explanation
|
|
12
|
+
- scitex://module/{name} - Module-specific documentation (io, plt, stats, scholar, session)
|
|
13
|
+
- scitex://io-formats - Supported file formats
|
|
14
|
+
- scitex://figrecipe-spec - Figure recipe specification
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from ._cheatsheet import register_cheatsheet_resources
|
|
20
|
+
from ._figrecipe import register_figrecipe_resources
|
|
21
|
+
from ._formats import register_format_resources
|
|
22
|
+
from ._modules import register_module_resources
|
|
23
|
+
from ._session import register_session_resources
|
|
24
|
+
|
|
25
|
+
__all__ = ["register_resources"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def register_resources(mcp) -> None:
|
|
29
|
+
"""Register all MCP resources with the FastMCP server."""
|
|
30
|
+
register_cheatsheet_resources(mcp)
|
|
31
|
+
register_session_resources(mcp)
|
|
32
|
+
register_module_resources(mcp)
|
|
33
|
+
register_format_resources(mcp)
|
|
34
|
+
register_figrecipe_resources(mcp)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# EOF
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-20
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/_cheatsheet.py
|
|
4
|
+
"""Core SciTeX cheatsheet resource for AI agents."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
__all__ = ["register_cheatsheet_resources"]
|
|
9
|
+
|
|
10
|
+
CHEATSHEET = """\
|
|
11
|
+
# SciTeX Cheatsheet for AI Agents
|
|
12
|
+
=================================
|
|
13
|
+
|
|
14
|
+
## Import Pattern (ALWAYS use this)
|
|
15
|
+
```python
|
|
16
|
+
import scitex as stx
|
|
17
|
+
import numpy as np
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 1. @stx.session - Reproducible Experiment Tracking
|
|
21
|
+
|
|
22
|
+
The MOST IMPORTANT pattern. Wrap your main function with @stx.session:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
@stx.session
|
|
26
|
+
def main(
|
|
27
|
+
# User parameters (become CLI arguments automatically)
|
|
28
|
+
input_file="data.csv", # --input-file (default: data.csv)
|
|
29
|
+
n_samples=100, # --n-samples (default: 100)
|
|
30
|
+
|
|
31
|
+
# INJECTED parameters (auto-provided by session)
|
|
32
|
+
CONFIG=stx.INJECTED, # Session config with ID, paths
|
|
33
|
+
plt=stx.INJECTED, # Pre-configured matplotlib
|
|
34
|
+
COLORS=stx.INJECTED, # Color palette
|
|
35
|
+
rng=stx.INJECTED, # Seeded random generator
|
|
36
|
+
logger=stx.INJECTED, # Session logger
|
|
37
|
+
):
|
|
38
|
+
\"\"\"This docstring becomes --help description.\"\"\"
|
|
39
|
+
|
|
40
|
+
# Your analysis code here
|
|
41
|
+
data = stx.io.load(input_file)
|
|
42
|
+
results = process(data, n_samples)
|
|
43
|
+
|
|
44
|
+
# Save outputs (automatically to session directory)
|
|
45
|
+
stx.io.save(results, "results.csv")
|
|
46
|
+
stx.io.save(fig, "plot.png", symlink_to="./data")
|
|
47
|
+
|
|
48
|
+
return 0 # Exit status
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main() # CLI mode when no args passed
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 2. stx.io - Universal File I/O (30+ formats)
|
|
55
|
+
|
|
56
|
+
ALWAYS use stx.io.save() and stx.io.load() for file operations:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
# Saving - extension determines format automatically
|
|
60
|
+
stx.io.save(df, "data.csv") # DataFrame -> CSV
|
|
61
|
+
stx.io.save(arr, "data.npy") # NumPy array
|
|
62
|
+
stx.io.save(obj, "data.pkl") # Any Python object
|
|
63
|
+
stx.io.save(fig, "plot.png") # Figure + auto CSV
|
|
64
|
+
|
|
65
|
+
# Loading - format auto-detected
|
|
66
|
+
data = stx.io.load("data.csv")
|
|
67
|
+
|
|
68
|
+
# With options
|
|
69
|
+
stx.io.save(fig, "plot.png",
|
|
70
|
+
metadata={"exp": "exp01"}, # Embedded metadata
|
|
71
|
+
symlink_to="./data", # Create symlink
|
|
72
|
+
verbose=True, # Log messages
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
IMPORTANT: stx.io.save shows logging messages:
|
|
77
|
+
```
|
|
78
|
+
SUCC: Saved to: ./script_out/results.csv (4.0 KiB)
|
|
79
|
+
SUCC: Symlinked: ./script_out/results.csv -> ./data/results.csv
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 3. stx.plt - Publication-Ready Figures (Auto CSV Export)
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
fig, ax = stx.plt.subplots()
|
|
86
|
+
|
|
87
|
+
# Use stx_ prefixed methods for auto CSV export
|
|
88
|
+
ax.stx_line(x, y, label="Signal") # Tracked: exports to CSV
|
|
89
|
+
ax.stx_scatter(x, y) # Tracked
|
|
90
|
+
|
|
91
|
+
# Set labels with convenience method
|
|
92
|
+
ax.set_xyt("X axis", "Y axis", "Title")
|
|
93
|
+
|
|
94
|
+
# Save figure -> creates BOTH plot.png AND plot.csv
|
|
95
|
+
stx.io.save(fig, "plot.png")
|
|
96
|
+
fig.close()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 4. stx.stats - Publication Statistics (23 tests)
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
result = stx.stats.test_ttest_ind(group1, group2, return_as="dataframe")
|
|
103
|
+
# Returns: p-value, Cohen's d, 95% CI, normality check, power analysis
|
|
104
|
+
|
|
105
|
+
result = stx.stats.test_anova(*groups, return_as="latex")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 5. stx.scholar - Literature Management
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
scitex scholar bibtex papers.bib --project myresearch --num-workers 8
|
|
112
|
+
# Enriches BibTeX with abstracts, DOIs, impact factors, downloads PDFs
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Quick Tips
|
|
116
|
+
|
|
117
|
+
1. ALWAYS use `import scitex as stx`
|
|
118
|
+
2. ALWAYS wrap main functions with `@stx.session`
|
|
119
|
+
3. ALWAYS use `stx.io.save()` and `stx.io.load()` for files
|
|
120
|
+
4. ALWAYS use `stx.plt.subplots()` for figures
|
|
121
|
+
5. ALWAYS use `ax.stx_*` methods for auto CSV export
|
|
122
|
+
6. ALWAYS return exit status (0 for success) from main
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def register_cheatsheet_resources(mcp) -> None:
|
|
127
|
+
"""Register cheatsheet resource."""
|
|
128
|
+
|
|
129
|
+
@mcp.resource("scitex://cheatsheet")
|
|
130
|
+
def cheatsheet() -> str:
|
|
131
|
+
"""Complete SciTeX quick reference for AI code generation."""
|
|
132
|
+
return CHEATSHEET
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# EOF
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-20
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/_figrecipe.py
|
|
4
|
+
"""Figrecipe integration documentation for stx.plt MCP tools."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
__all__ = ["register_figrecipe_resources"]
|
|
9
|
+
|
|
10
|
+
FIGRECIPE_INTEGRATION = """\
|
|
11
|
+
# stx.plt - Powered by FigRecipe
|
|
12
|
+
=================================
|
|
13
|
+
|
|
14
|
+
stx.plt provides publication-ready figures with **automatic reproducibility**.
|
|
15
|
+
It's built on FigRecipe, which records all matplotlib calls to YAML recipes.
|
|
16
|
+
|
|
17
|
+
## Using stx.plt in @stx.session
|
|
18
|
+
```python
|
|
19
|
+
@stx.session
|
|
20
|
+
def main(plt=stx.INJECTED, COLORS=stx.INJECTED):
|
|
21
|
+
fig, ax = stx.plt.subplots()
|
|
22
|
+
|
|
23
|
+
# Use stx_ prefixed methods for auto CSV export
|
|
24
|
+
ax.stx_line(x, y, color=COLORS.blue, label="data")
|
|
25
|
+
ax.set_xyt("X", "Y", "Title")
|
|
26
|
+
|
|
27
|
+
# Save creates: plot.png + plot.csv (data)
|
|
28
|
+
stx.io.save(fig, "plot.png", symlink_to="./data")
|
|
29
|
+
fig.close()
|
|
30
|
+
return 0
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Output Files from stx.io.save(fig, ...)
|
|
34
|
+
```
|
|
35
|
+
script_out/
|
|
36
|
+
├── plot.png # Image file
|
|
37
|
+
├── plot.csv # Extracted plot data (auto-generated)
|
|
38
|
+
└── plot.yaml # FigRecipe recipe (if using fr.save directly)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Tracked Methods (stx_ prefix)
|
|
42
|
+
These methods track data for automatic CSV export:
|
|
43
|
+
- ax.stx_line(x, y)
|
|
44
|
+
- ax.stx_scatter(x, y)
|
|
45
|
+
- ax.stx_bar(x, height)
|
|
46
|
+
- ax.stx_errorbar(x, y, yerr)
|
|
47
|
+
- ax.stx_hist(data, bins)
|
|
48
|
+
- ax.stx_boxplot(data)
|
|
49
|
+
- ax.stx_violinplot(data)
|
|
50
|
+
- ax.stx_imshow(matrix)
|
|
51
|
+
|
|
52
|
+
## MCP Declarative Spec (via plt_plot tool)
|
|
53
|
+
|
|
54
|
+
### RECOMMENDED: CSV Column Input
|
|
55
|
+
Use CSV files - enables code to write data, MCP to visualize:
|
|
56
|
+
```yaml
|
|
57
|
+
plots:
|
|
58
|
+
- type: scatter
|
|
59
|
+
data_file: results.csv # CSV from your analysis
|
|
60
|
+
x: time # Column name (string)
|
|
61
|
+
y: measurement # Column name
|
|
62
|
+
color: blue
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Workflow**: Python writes CSV → MCP reads columns → Creates figure
|
|
66
|
+
|
|
67
|
+
### Alternative: Inline Data (simple cases only)
|
|
68
|
+
```yaml
|
|
69
|
+
plots:
|
|
70
|
+
- type: line
|
|
71
|
+
x: [1, 2, 3, 4, 5] # Inline array (less flexible)
|
|
72
|
+
y: [1, 4, 9, 16, 25]
|
|
73
|
+
color: blue
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Full Example
|
|
77
|
+
```yaml
|
|
78
|
+
figure:
|
|
79
|
+
width_mm: 85 # Nature single-column width
|
|
80
|
+
height_mm: 60
|
|
81
|
+
plots:
|
|
82
|
+
- type: scatter
|
|
83
|
+
data_file: experiment.csv
|
|
84
|
+
x: time_hours
|
|
85
|
+
y: concentration_mm
|
|
86
|
+
color: blue
|
|
87
|
+
label: "Data"
|
|
88
|
+
xlabel: "Time (h)"
|
|
89
|
+
ylabel: "Concentration (mM)"
|
|
90
|
+
title: "Enzyme Kinetics"
|
|
91
|
+
legend: true
|
|
92
|
+
stat_annotations:
|
|
93
|
+
- x1: 1
|
|
94
|
+
x2: 3
|
|
95
|
+
p_value: 0.01
|
|
96
|
+
style: stars
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Statistical Annotations
|
|
100
|
+
```python
|
|
101
|
+
# Method 1: Via stx.plt (Python API)
|
|
102
|
+
ax.add_stat_annotation(x1=0, x2=1, p_value=0.01, style="stars")
|
|
103
|
+
|
|
104
|
+
# Method 2: Via MCP spec (declarative)
|
|
105
|
+
stat_annotations:
|
|
106
|
+
- x1: 0
|
|
107
|
+
x2: 1
|
|
108
|
+
p_value: 0.01 # Converts to ** automatically
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Color Palette (COLORS=stx.INJECTED)
|
|
112
|
+
```python
|
|
113
|
+
COLORS.blue, COLORS.red, COLORS.green, COLORS.orange
|
|
114
|
+
COLORS.purple, COLORS.navy, COLORS.pink, COLORS.brown
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## For Detailed FigRecipe Documentation
|
|
118
|
+
See figrecipe MCP resources directly:
|
|
119
|
+
- figrecipe://cheatsheet - Quick reference
|
|
120
|
+
- figrecipe://api/core - Full API documentation
|
|
121
|
+
- figrecipe://mcp-spec - Declarative spec format
|
|
122
|
+
|
|
123
|
+
## Supported Plot Types
|
|
124
|
+
line, scatter, bar, barh, hist, boxplot, violinplot, imshow, heatmap,
|
|
125
|
+
errorbar, fill_between, contour, contourf, pie, stem
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def register_figrecipe_resources(mcp) -> None:
|
|
130
|
+
"""Register figrecipe integration resource."""
|
|
131
|
+
|
|
132
|
+
@mcp.resource("scitex://plt-figrecipe")
|
|
133
|
+
def figrecipe_integration() -> str:
|
|
134
|
+
"""stx.plt integration with FigRecipe for reproducible figures."""
|
|
135
|
+
return FIGRECIPE_INTEGRATION
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# EOF
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-20
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/_formats.py
|
|
4
|
+
"""IO format documentation resource."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
__all__ = ["register_format_resources"]
|
|
9
|
+
|
|
10
|
+
IO_FORMATS = """\
|
|
11
|
+
# stx.io Supported Formats
|
|
12
|
+
===========================
|
|
13
|
+
|
|
14
|
+
## Data Formats
|
|
15
|
+
|
|
16
|
+
| Extension | Type | Save | Load | Notes |
|
|
17
|
+
|-----------|------|:----:|:----:|-------|
|
|
18
|
+
| .csv | DataFrame/Array | ✓ | ✓ | Comma-separated |
|
|
19
|
+
| .tsv | DataFrame/Array | ✓ | ✓ | Tab-separated |
|
|
20
|
+
| .xlsx | DataFrame | ✓ | ✓ | Excel workbook |
|
|
21
|
+
| .json | Dict/List | ✓ | ✓ | JSON format |
|
|
22
|
+
| .yaml/.yml | Dict/List | ✓ | ✓ | YAML format |
|
|
23
|
+
| .pkl/.pickle | Any | ✓ | ✓ | Python pickle |
|
|
24
|
+
| .npy | Array | ✓ | ✓ | NumPy array |
|
|
25
|
+
| .npz | Dict[Array] | ✓ | ✓ | Compressed NumPy |
|
|
26
|
+
| .h5/.hdf5 | Array/Dict | ✓ | ✓ | HDF5 format |
|
|
27
|
+
| .zarr | Array | ✓ | ✓ | Zarr array |
|
|
28
|
+
| .parquet | DataFrame | ✓ | ✓ | Apache Parquet |
|
|
29
|
+
| .feather | DataFrame | ✓ | ✓ | Feather format |
|
|
30
|
+
|
|
31
|
+
## Image Formats
|
|
32
|
+
|
|
33
|
+
| Extension | Type | Save | Load | Notes |
|
|
34
|
+
|-----------|------|:----:|:----:|-------|
|
|
35
|
+
| .png | Figure/Array | ✓ | ✓ | Lossless, metadata |
|
|
36
|
+
| .jpg/.jpeg | Figure/Array | ✓ | ✓ | Lossy, metadata |
|
|
37
|
+
| .tiff/.tif | Figure/Array | ✓ | ✓ | Scientific imaging |
|
|
38
|
+
| .pdf | Figure | ✓ | ✓ | Vector format |
|
|
39
|
+
| .svg | Figure | ✓ | - | Vector format |
|
|
40
|
+
|
|
41
|
+
## Scientific Formats
|
|
42
|
+
|
|
43
|
+
| Extension | Type | Load | Notes |
|
|
44
|
+
|-----------|------|:----:|-------|
|
|
45
|
+
| .edf | EEG | ✓ | European Data Format |
|
|
46
|
+
| .fif | MNE | ✓ | MNE-Python |
|
|
47
|
+
| .set | EEGLAB | ✓ | EEGLAB format |
|
|
48
|
+
| .mat | MATLAB | ✓ | MATLAB files |
|
|
49
|
+
|
|
50
|
+
## PyTorch Formats
|
|
51
|
+
|
|
52
|
+
| Extension | Type | Save | Load |
|
|
53
|
+
|-----------|------|:----:|:----:|
|
|
54
|
+
| .pt | Tensor/Model | ✓ | ✓ |
|
|
55
|
+
| .pth | Model | ✓ | ✓ |
|
|
56
|
+
|
|
57
|
+
## Usage Notes
|
|
58
|
+
|
|
59
|
+
1. **Extension determines handler**: `stx.io.save(df, "data.csv")` uses CSV
|
|
60
|
+
2. **Metadata embedding**: PNG/JPEG support embedded metadata
|
|
61
|
+
3. **Figure auto-CSV**: Saving figures also exports plotted data as CSV
|
|
62
|
+
4. **Symlink support**: `symlink_to="./data"` creates symlinks
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import scitex as stx
|
|
68
|
+
import pandas as pd
|
|
69
|
+
import numpy as np
|
|
70
|
+
|
|
71
|
+
# DataFrame
|
|
72
|
+
df = pd.DataFrame({"x": [1, 2], "y": [3, 4]})
|
|
73
|
+
stx.io.save(df, "data.csv")
|
|
74
|
+
stx.io.save(df, "data.parquet")
|
|
75
|
+
|
|
76
|
+
# NumPy
|
|
77
|
+
arr = np.random.randn(100, 100)
|
|
78
|
+
stx.io.save(arr, "array.npy")
|
|
79
|
+
stx.io.save(arr, "array.npz")
|
|
80
|
+
|
|
81
|
+
# Any Python object
|
|
82
|
+
stx.io.save({"config": "value"}, "config.yaml")
|
|
83
|
+
stx.io.save(complex_obj, "obj.pkl")
|
|
84
|
+
|
|
85
|
+
# Figure with auto-CSV
|
|
86
|
+
fig, ax = stx.plt.subplots()
|
|
87
|
+
ax.stx_line([1, 2, 3], [4, 5, 6])
|
|
88
|
+
stx.io.save(fig, "plot.png") # Creates plot.png + plot.csv
|
|
89
|
+
```
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def register_format_resources(mcp) -> None:
|
|
94
|
+
"""Register IO formats resource."""
|
|
95
|
+
|
|
96
|
+
@mcp.resource("scitex://io-formats")
|
|
97
|
+
def io_formats() -> str:
|
|
98
|
+
"""List all supported file formats for stx.io."""
|
|
99
|
+
return IO_FORMATS
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# EOF
|