scitex 2.14.0__py3-none-any.whl → 2.15.1__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 +47 -0
- 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 +191 -0
- scitex/_mcp_tools/plt.py +260 -305
- scitex/_mcp_tools/scholar.py +74 -0
- scitex/_mcp_tools/social.py +244 -0
- scitex/_mcp_tools/writer.py +21 -204
- 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/audio/README.md +40 -36
- scitex/audio/__init__.py +127 -59
- 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/engines/elevenlabs_engine.py +6 -1
- 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/templates/__init__.py +32 -70
- scitex/cli/__init__.py +38 -43
- scitex/cli/audio.py +76 -27
- scitex/cli/capture.py +13 -20
- scitex/cli/introspect.py +443 -0
- scitex/cli/main.py +198 -109
- scitex/cli/mcp.py +60 -34
- scitex/cli/scholar/__init__.py +8 -0
- scitex/cli/scholar/_crossref_scitex.py +296 -0
- scitex/cli/scholar/_fetch.py +25 -3
- scitex/cli/social.py +314 -0
- scitex/cli/writer.py +117 -0
- scitex/config/README.md +1 -1
- scitex/config/__init__.py +16 -2
- scitex/config/_env_registry.py +191 -0
- scitex/diagram/__init__.py +42 -19
- scitex/diagram/mcp_server.py +13 -125
- scitex/introspect/__init__.py +75 -0
- scitex/introspect/_call_graph.py +303 -0
- scitex/introspect/_class_hierarchy.py +163 -0
- scitex/introspect/_core.py +42 -0
- scitex/introspect/_docstring.py +131 -0
- scitex/introspect/_examples.py +113 -0
- scitex/introspect/_imports.py +271 -0
- scitex/introspect/_mcp/__init__.py +37 -0
- scitex/introspect/_mcp/handlers.py +208 -0
- scitex/introspect/_members.py +151 -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/bundle/README.md +1 -1
- scitex/mcp_server.py +98 -5
- scitex/plt/__init__.py +248 -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/scholar/url_finder/.tmp/open_url/KNOWN_RESOLVERS.py +462 -0
- scitex/scholar/url_finder/.tmp/open_url/README.md +223 -0
- scitex/scholar/url_finder/.tmp/open_url/_DOIToURLResolver.py +694 -0
- scitex/scholar/url_finder/.tmp/open_url/_OpenURLResolver.py +1160 -0
- scitex/scholar/url_finder/.tmp/open_url/_ResolverLinkFinder.py +344 -0
- scitex/scholar/url_finder/.tmp/open_url/__init__.py +24 -0
- scitex/security/README.md +3 -3
- scitex/session/README.md +1 -1
- scitex/sh/README.md +1 -1
- scitex/social/__init__.py +153 -0
- scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/template/README.md +1 -1
- scitex/template/clone_writer_directory.py +5 -5
- scitex/writer/README.md +1 -1
- scitex/writer/_mcp/handlers.py +11 -744
- scitex/writer/_mcp/tool_schemas.py +5 -335
- scitex-2.15.1.dist-info/METADATA +648 -0
- {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/RECORD +166 -111
- scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
- scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
- scitex/dev/plt/data/mpl/PLOTTING_FUNCTIONS.yaml +0 -90
- scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES.yaml +0 -1571
- scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES_DETAILED.yaml +0 -6262
- scitex/dev/plt/data/mpl/SIGNATURES_FLATTENED.yaml +0 -1274
- scitex/dev/plt/data/mpl/dir_ax.txt +0 -459
- 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/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/data/.gitkeep +0 -0
- scitex/scholar/data/README.md +0 -44
- scitex/scholar/data/bib_files/bibliography.bib +0 -1952
- scitex/scholar/data/bib_files/neurovista.bib +0 -277
- scitex/scholar/data/bib_files/neurovista_enriched.bib +0 -441
- scitex/scholar/data/bib_files/neurovista_enriched_enriched.bib +0 -441
- scitex/scholar/data/bib_files/neurovista_processed.bib +0 -338
- scitex/scholar/data/bib_files/openaccess.bib +0 -89
- scitex/scholar/data/bib_files/pac-seizure_prediction_enriched.bib +0 -2178
- scitex/scholar/data/bib_files/pac.bib +0 -698
- scitex/scholar/data/bib_files/pac_enriched.bib +0 -1061
- scitex/scholar/data/bib_files/pac_processed.bib +0 -0
- scitex/scholar/data/bib_files/pac_titles.txt +0 -75
- scitex/scholar/data/bib_files/paywalled.bib +0 -98
- scitex/scholar/data/bib_files/related-papers-by-coauthors.bib +0 -58
- scitex/scholar/data/bib_files/related-papers-by-coauthors_enriched.bib +0 -87
- scitex/scholar/data/bib_files/seizure_prediction.bib +0 -694
- scitex/scholar/data/bib_files/seizure_prediction_processed.bib +0 -0
- scitex/scholar/data/bib_files/test_complete_enriched.bib +0 -437
- scitex/scholar/data/bib_files/test_final_enriched.bib +0 -437
- scitex/scholar/data/bib_files/test_seizure.bib +0 -46
- scitex/scholar/data/impact_factor/JCR_IF_2022.xlsx +0 -0
- scitex/scholar/data/impact_factor/JCR_IF_2024.db +0 -0
- scitex/scholar/data/impact_factor/JCR_IF_2024.xlsx +0 -0
- scitex/scholar/data/impact_factor/JCR_IF_2024_v01.db +0 -0
- scitex/scholar/data/impact_factor.db +0 -0
- scitex/scholar/examples/SUGGESTIONS.md +0 -865
- scitex/scholar/examples/dev.py +0 -38
- scitex-2.14.0.dist-info/METADATA +0 -1238
- {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/WHEEL +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/entry_points.txt +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/licenses/LICENSE +0 -0
scitex/__init__.py
CHANGED
|
@@ -196,6 +196,50 @@ config = _LazyModule("config")
|
|
|
196
196
|
audio = _LazyModule("audio")
|
|
197
197
|
msword = _LazyModule("msword")
|
|
198
198
|
fts = _LazyModule("fts") # Bundle schemas module
|
|
199
|
+
social = _LazyModule("social") # Social media integration (socialia wrapper)
|
|
200
|
+
diagram = _LazyModule("diagram") # Diagram creation (delegates to figrecipe)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# Lazy Diagram class - delegates to figrecipe.Diagram
|
|
204
|
+
class _LazyDiagram:
|
|
205
|
+
"""Lazy loader for Diagram class from figrecipe."""
|
|
206
|
+
|
|
207
|
+
_class = None
|
|
208
|
+
|
|
209
|
+
def __new__(cls, *args, **kwargs):
|
|
210
|
+
if cls._class is None:
|
|
211
|
+
try:
|
|
212
|
+
from figrecipe import Diagram as _FigrecipeDiagram
|
|
213
|
+
|
|
214
|
+
cls._class = _FigrecipeDiagram
|
|
215
|
+
except ImportError:
|
|
216
|
+
# Fallback to scitex's own implementation if figrecipe not available
|
|
217
|
+
from scitex.diagram._diagram import Diagram as _ScitexDiagram
|
|
218
|
+
|
|
219
|
+
cls._class = _ScitexDiagram
|
|
220
|
+
return cls._class(*args, **kwargs)
|
|
221
|
+
|
|
222
|
+
@classmethod
|
|
223
|
+
def from_yaml(cls, *args, **kwargs):
|
|
224
|
+
if cls._class is None:
|
|
225
|
+
cls.__new__(cls) # Trigger lazy load
|
|
226
|
+
return cls._class.from_yaml(*args, **kwargs)
|
|
227
|
+
|
|
228
|
+
@classmethod
|
|
229
|
+
def from_mermaid(cls, *args, **kwargs):
|
|
230
|
+
if cls._class is None:
|
|
231
|
+
cls.__new__(cls) # Trigger lazy load
|
|
232
|
+
return cls._class.from_mermaid(*args, **kwargs)
|
|
233
|
+
|
|
234
|
+
@classmethod
|
|
235
|
+
def from_dict(cls, *args, **kwargs):
|
|
236
|
+
if cls._class is None:
|
|
237
|
+
cls.__new__(cls) # Trigger lazy load
|
|
238
|
+
return cls._class.from_dict(*args, **kwargs)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
Diagram = _LazyDiagram
|
|
242
|
+
|
|
199
243
|
|
|
200
244
|
# Centralized path configuration - eager loaded for convenience
|
|
201
245
|
# Usage: scitex.PATHS.logs, scitex.PATHS.cache, etc.
|
|
@@ -261,6 +305,9 @@ __all__ = [
|
|
|
261
305
|
"msword",
|
|
262
306
|
"fts",
|
|
263
307
|
"fsb", # Legacy alias
|
|
308
|
+
"social", # Social media integration
|
|
309
|
+
"diagram", # Diagram module (delegates to figrecipe)
|
|
310
|
+
"Diagram", # Diagram class (from figrecipe)
|
|
264
311
|
"PATHS",
|
|
265
312
|
"INJECTED",
|
|
266
313
|
]
|
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
|