scitex 2.15.1__py3-none-any.whl → 2.15.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. scitex/__init__.py +68 -61
  2. scitex/_mcp_tools/introspect.py +42 -23
  3. scitex/_mcp_tools/template.py +24 -0
  4. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +30 -1550
  5. scitex/ai/classification/timeseries/_sliding_window_core.py +467 -0
  6. scitex/ai/classification/timeseries/_sliding_window_plotting.py +369 -0
  7. scitex/audio/__init__.py +2 -2
  8. scitex/audio/_tts.py +18 -10
  9. scitex/audio/engines/base.py +17 -10
  10. scitex/audio/engines/elevenlabs_engine.py +1 -1
  11. scitex/canvas/editor/flask_editor/_core/__init__.py +27 -0
  12. scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py +200 -0
  13. scitex/canvas/editor/flask_editor/_core/_editor.py +173 -0
  14. scitex/canvas/editor/flask_editor/_core/_export_helpers.py +353 -0
  15. scitex/canvas/editor/flask_editor/_core/_routes_basic.py +190 -0
  16. scitex/canvas/editor/flask_editor/_core/_routes_export.py +332 -0
  17. scitex/canvas/editor/flask_editor/_core/_routes_panels.py +252 -0
  18. scitex/canvas/editor/flask_editor/_core/_routes_save.py +218 -0
  19. scitex/canvas/editor/flask_editor/_core.py +25 -1684
  20. scitex/cli/introspect.py +112 -74
  21. scitex/cli/main.py +2 -0
  22. scitex/cli/plt.py +357 -0
  23. scitex/cli/repro.py +15 -8
  24. scitex/cli/resource.py +15 -8
  25. scitex/cli/scholar/__init__.py +15 -8
  26. scitex/cli/social.py +6 -6
  27. scitex/cli/stats.py +15 -8
  28. scitex/cli/template.py +129 -12
  29. scitex/cli/tex.py +15 -8
  30. scitex/cli/writer.py +15 -8
  31. scitex/cloud/__init__.py +41 -2
  32. scitex/config/_env_registry.py +84 -19
  33. scitex/context/__init__.py +22 -0
  34. scitex/dev/__init__.py +20 -1
  35. scitex/gen/__init__.py +50 -14
  36. scitex/gen/_list_packages.py +4 -4
  37. scitex/introspect/__init__.py +16 -9
  38. scitex/introspect/_core.py +7 -8
  39. scitex/{gen/_inspect_module.py → introspect/_list_api.py} +43 -54
  40. scitex/introspect/_mcp/__init__.py +10 -6
  41. scitex/introspect/_mcp/handlers.py +37 -12
  42. scitex/introspect/_members.py +7 -3
  43. scitex/introspect/_signature.py +3 -3
  44. scitex/introspect/_source.py +2 -2
  45. scitex/io/_save.py +1 -2
  46. scitex/logging/_formatters.py +19 -9
  47. scitex/mcp_server.py +1 -1
  48. scitex/os/__init__.py +4 -0
  49. scitex/{gen → os}/_check_host.py +4 -5
  50. scitex/plt/__init__.py +11 -14
  51. scitex/session/__init__.py +26 -7
  52. scitex/session/_decorator.py +1 -1
  53. scitex/sh/__init__.py +7 -4
  54. scitex/social/__init__.py +10 -8
  55. scitex/stats/_mcp/_handlers/__init__.py +31 -0
  56. scitex/stats/_mcp/_handlers/_corrections.py +113 -0
  57. scitex/stats/_mcp/_handlers/_descriptive.py +78 -0
  58. scitex/stats/_mcp/_handlers/_effect_size.py +106 -0
  59. scitex/stats/_mcp/_handlers/_format.py +94 -0
  60. scitex/stats/_mcp/_handlers/_normality.py +110 -0
  61. scitex/stats/_mcp/_handlers/_posthoc.py +224 -0
  62. scitex/stats/_mcp/_handlers/_power.py +247 -0
  63. scitex/stats/_mcp/_handlers/_recommend.py +102 -0
  64. scitex/stats/_mcp/_handlers/_run_test.py +279 -0
  65. scitex/stats/_mcp/_handlers/_stars.py +48 -0
  66. scitex/stats/_mcp/handlers.py +19 -1171
  67. scitex/stats/auto/_stat_style.py +175 -0
  68. scitex/stats/auto/_style_definitions.py +411 -0
  69. scitex/stats/auto/_styles.py +22 -620
  70. scitex/stats/descriptive/__init__.py +11 -8
  71. scitex/stats/descriptive/_ci.py +39 -0
  72. scitex/stats/power/_power.py +15 -4
  73. scitex/str/__init__.py +2 -1
  74. scitex/str/_title_case.py +63 -0
  75. scitex/template/__init__.py +25 -10
  76. scitex/template/_code_templates.py +147 -0
  77. scitex/template/_mcp/handlers.py +81 -0
  78. scitex/template/_mcp/tool_schemas.py +55 -0
  79. scitex/template/_templates/__init__.py +51 -0
  80. scitex/template/_templates/audio.py +233 -0
  81. scitex/template/_templates/canvas.py +312 -0
  82. scitex/template/_templates/capture.py +268 -0
  83. scitex/template/_templates/config.py +43 -0
  84. scitex/template/_templates/diagram.py +294 -0
  85. scitex/template/_templates/io.py +107 -0
  86. scitex/template/_templates/module.py +53 -0
  87. scitex/template/_templates/plt.py +202 -0
  88. scitex/template/_templates/scholar.py +267 -0
  89. scitex/template/_templates/session.py +130 -0
  90. scitex/template/_templates/session_minimal.py +43 -0
  91. scitex/template/_templates/session_plot.py +67 -0
  92. scitex/template/_templates/session_stats.py +77 -0
  93. scitex/template/_templates/stats.py +323 -0
  94. scitex/template/_templates/writer.py +296 -0
  95. scitex/ui/_backends/_email.py +10 -2
  96. scitex/ui/_backends/_webhook.py +5 -1
  97. scitex/web/_search_pubmed.py +10 -6
  98. {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/METADATA +1 -1
  99. {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/RECORD +105 -64
  100. scitex/gen/_ci.py +0 -12
  101. scitex/gen/_title_case.py +0 -89
  102. /scitex/{gen → context}/_detect_environment.py +0 -0
  103. /scitex/{gen → context}/_get_notebook_path.py +0 -0
  104. /scitex/{gen/_shell.py → sh/_shell_legacy.py} +0 -0
  105. {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/WHEEL +0 -0
  106. {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/entry_points.txt +0 -0
  107. {scitex-2.15.1.dist-info → scitex-2.15.2.dist-info}/licenses/LICENSE +0 -0
scitex/dev/__init__.py CHANGED
@@ -1,20 +1,39 @@
1
1
  #!/usr/bin/env python3
2
- """Scitex dev module."""
2
+ """Scitex dev module - Development and debugging utilities."""
3
3
 
4
4
  # Pyproject utilities (lazy import to avoid tomlkit dependency)
5
+ # Installation guide utilities (moved from root scitex module)
6
+ from .._install_guide import (
7
+ MODULE_REQUIREMENTS,
8
+ check_module_deps,
9
+ require_module,
10
+ requires,
11
+ show_install_guide,
12
+ warn_module_deps,
13
+ )
5
14
  from . import _pyproject as pyproject
6
15
  from . import cv
7
16
  from ._analyze_code_flow import CodeFlowAnalyzer, analyze_code_flow, main, parse_args
8
17
  from ._reload import reload, reload_auto, reload_stop
9
18
 
10
19
  __all__ = [
20
+ # Code flow analysis
11
21
  "CodeFlowAnalyzer",
12
22
  "analyze_code_flow",
13
23
  "main",
14
24
  "parse_args",
25
+ # Hot reloading
15
26
  "reload",
16
27
  "reload_auto",
17
28
  "reload_stop",
29
+ # Submodules
18
30
  "pyproject",
19
31
  "cv",
32
+ # Installation guide utilities
33
+ "show_install_guide",
34
+ "check_module_deps",
35
+ "require_module",
36
+ "requires",
37
+ "warn_module_deps",
38
+ "MODULE_REQUIREMENTS",
20
39
  ]
scitex/gen/__init__.py CHANGED
@@ -1,15 +1,45 @@
1
1
  #!/usr/bin/env python3
2
- """Scitex gen module."""
2
+ """Scitex gen module.
3
+
4
+ NOTE: This module is being refactored. Many functions are being moved to
5
+ more appropriate locations. For backward compatibility, they are re-exported
6
+ here with deprecation warnings.
7
+
8
+ Recommended imports:
9
+ - ci -> scitex.stats.descriptive.ci
10
+ - check_host, is_host, verify_host -> scitex.os
11
+ - detect_environment, is_notebook, is_script -> scitex.context
12
+ - list_api -> scitex.introspect
13
+ - run_shellcommand, run_shellscript -> scitex.sh
14
+ - xml2dict, XmlDictConfig, XmlListConfig -> scitex.io
15
+ - title_case -> scitex.str
16
+ - symlink -> scitex.path
17
+ """
18
+
19
+ import warnings
20
+
21
+
22
+ def _deprecation_warning(old_path, new_path):
23
+ warnings.warn(
24
+ f"{old_path} is deprecated, use {new_path} instead",
25
+ DeprecationWarning,
26
+ stacklevel=3,
27
+ )
28
+
29
+
30
+ # ci -> scitex.stats.descriptive.ci (with re-export for backward compat)
31
+ from scitex.stats.descriptive import ci
3
32
 
4
33
  # Optional: DimHandler requires torch
5
34
  try:
6
35
  from ._DimHandler import DimHandler
7
36
  except ImportError:
8
37
  DimHandler = None
38
+ # check_host moved to scitex.os (re-export for backward compatibility)
39
+ from scitex.os import check_host, is_host, verify_host
40
+
9
41
  from ._alternate_kwarg import alternate_kwarg
10
42
  from ._cache import cache
11
- from ._check_host import check_host, is_host, verify_host
12
- from ._ci import ci
13
43
  from ._deprecated_close import (
14
44
  close as _deprecated_close,
15
45
  )
@@ -27,7 +57,9 @@ try:
27
57
  from ._embed import embed
28
58
  except ImportError:
29
59
  embed = None
30
- from ._inspect_module import inspect_module
60
+ # list_api moved to scitex.introspect (re-export for backward compatibility)
61
+ from scitex.introspect import list_api
62
+
31
63
  from ._is_ipython import is_ipython, is_script
32
64
  from ._less import less
33
65
  from ._list_packages import list_packages, main
@@ -51,9 +83,11 @@ except ImportError:
51
83
  to_nanz = None
52
84
  to_z = None
53
85
  unbias = None
86
+ # shell functions moved to scitex.sh (re-export for backward compatibility)
87
+ from scitex.sh import run_shellcommand, run_shellscript
88
+
54
89
  from ._paste import paste
55
90
  from ._print_config import print_config, print_config_main
56
- from ._shell import run_shellcommand, run_shellscript
57
91
  from ._src import src
58
92
  from ._TimeStamper import TimeStamper
59
93
 
@@ -62,20 +96,23 @@ start = _deprecated_start
62
96
  close = _deprecated_close
63
97
  running2finished = _deprecated_running2finished
64
98
 
65
- from ._detect_environment import (
99
+ # environment detection moved to scitex.context (re-export for backward compatibility)
100
+ from scitex.context import (
66
101
  detect_environment,
67
- get_output_directory,
68
- is_notebook,
69
- )
70
- from ._get_notebook_path import (
71
102
  get_notebook_directory,
103
+ get_notebook_info_simple,
72
104
  get_notebook_name,
73
105
  get_notebook_path,
106
+ get_output_directory,
107
+ is_notebook,
74
108
  )
109
+
110
+ # title_case moved to scitex.str (re-export for backward compatibility)
111
+ from scitex.str import title_case
112
+
75
113
  from ._symlink import symlink
76
114
  from ._symlog import symlog
77
115
  from ._title2path import title2path
78
- from ._title_case import main, title_case
79
116
  from ._to_even import to_even
80
117
  from ._to_odd import to_odd
81
118
 
@@ -99,10 +136,9 @@ except ImportError:
99
136
  pass # Already set to None above
100
137
  from ._wrap import wrap
101
138
  from ._xml2dict import XmlDictConfig, XmlListConfig, xml2dict
102
- from .misc import float_linspace
103
139
 
104
140
  # Import from misc module
105
- from .misc import connect_nums
141
+ from .misc import connect_nums, float_linspace
106
142
 
107
143
  __all__ = [
108
144
  "ArrayLike",
@@ -122,7 +158,7 @@ __all__ = [
122
158
  "dir2npy",
123
159
  "embed",
124
160
  "float_linspace",
125
- "inspect_module",
161
+ "list_api",
126
162
  "is_host",
127
163
  "is_ipython",
128
164
  "is_script",
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Time-stamp: "2024-11-03 02:11:54 (ywatanabe)"
4
3
  # File: ./scitex_repo/src/scitex/gen/_list_packages.py
5
4
  """
@@ -25,8 +24,6 @@ except ImportError:
25
24
  # Fallback for older Python versions
26
25
  from importlib_metadata import distributions
27
26
 
28
- from ._inspect_module import inspect_module
29
-
30
27
 
31
28
  def list_packages(
32
29
  max_depth: int = 1,
@@ -80,10 +77,12 @@ def list_packages(
80
77
  pkg for pkg in installed_packages if pkg not in safelist
81
78
  ]
82
79
 
80
+ from scitex.introspect import list_api
81
+
83
82
  all_dfs = []
84
83
  for package_name in installed_packages:
85
84
  try:
86
- df = inspect_module(
85
+ df = list_api(
87
86
  package_name,
88
87
  docstring=False, # Speed up by skipping docstrings
89
88
  print_output=False,
@@ -116,6 +115,7 @@ def main() -> Optional[int]:
116
115
 
117
116
  if __name__ == "__main__":
118
117
  import matplotlib.pyplot as plt
118
+
119
119
  import scitex
120
120
 
121
121
  CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(
@@ -7,11 +7,14 @@ Introspection utilities for Python packages.
7
7
 
8
8
  Provides IPython-like introspection capabilities for any Python package.
9
9
 
10
+ IPython-style shortcuts:
11
+ - q: Function/class signature with type hints (like `func?`)
12
+ - qq: Full source code (like `func??`)
13
+ - dir: List attributes/methods (like `dir()`)
14
+ - list_api: Recursive module API tree
15
+
10
16
  Basic Introspection:
11
- - get_signature: Function/class signature with type hints (like `func?`)
12
17
  - get_docstring: Docstring extraction with parsing
13
- - get_source: Full source code (like `func??`)
14
- - list_members: List attributes/methods (like `dir()`)
15
18
  - get_exports: Module's __all__ contents
16
19
  - find_examples: Find usage examples in tests/examples
17
20
 
@@ -27,6 +30,8 @@ Advanced Introspection:
27
30
  """
28
31
 
29
32
  from ._core import (
33
+ # IPython-style names
34
+ dir,
30
35
  # Basic
31
36
  find_examples,
32
37
  # Advanced - Call graph
@@ -42,20 +47,22 @@ from ._core import (
42
47
  get_function_calls,
43
48
  get_imports,
44
49
  get_mro,
45
- get_signature,
46
- get_source,
47
50
  get_type_hints_detailed,
48
51
  get_type_info,
49
- list_members,
52
+ q,
53
+ qq,
50
54
  resolve_object,
51
55
  )
56
+ from ._list_api import list_api
52
57
 
53
58
  __all__ = [
59
+ # IPython-style names
60
+ "q",
61
+ "qq",
62
+ "dir",
63
+ "list_api",
54
64
  # Basic
55
- "get_signature",
56
65
  "get_docstring",
57
- "get_source",
58
- "list_members",
59
66
  "get_exports",
60
67
  "find_examples",
61
68
  "resolve_object",
@@ -4,25 +4,24 @@
4
4
 
5
5
  """Core introspection module - re-exports all utilities."""
6
6
 
7
- # Basic introspection
8
- # Advanced introspection
9
7
  from ._call_graph import get_call_graph, get_function_calls
10
8
  from ._class_hierarchy import get_class_hierarchy, get_mro
11
9
  from ._docstring import get_docstring
12
10
  from ._examples import find_examples
13
11
  from ._imports import get_dependencies, get_imports
14
- from ._members import get_exports, list_members
12
+ from ._members import dir, get_exports
15
13
  from ._resolve import get_type_info, resolve_object
16
- from ._signature import get_signature
17
- from ._source import get_source
14
+ from ._signature import q
15
+ from ._source import qq
18
16
  from ._type_hints import get_class_annotations, get_type_hints_detailed
19
17
 
20
18
  __all__ = [
19
+ # IPython-style names
20
+ "q", # signature (like func?)
21
+ "qq", # source (like func??)
22
+ "dir", # members (like dir())
21
23
  # Basic
22
- "get_signature",
23
24
  "get_docstring",
24
- "get_source",
25
- "list_members",
26
25
  "get_exports",
27
26
  "find_examples",
28
27
  "resolve_object",
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Time-stamp: "2024-11-07 18:58:55 (ywatanabe)"
4
- # File: ./scitex_repo/src/scitex/gen/_inspect_module.py
2
+ # Timestamp: 2025-01-27
3
+ # File: /home/ywatanabe/proj/scitex-python/src/scitex/introspect/_list_api.py
4
+
5
+ """Module API listing utilities."""
5
6
 
6
7
  import inspect
7
8
  import sys
8
9
  import warnings
9
10
  from typing import Any, List, Optional, Set, Union
10
11
 
11
- import scitex
12
12
  import pandas as pd
13
13
 
14
14
 
15
- def inspect_module(
15
+ def list_api(
16
16
  module: Union[str, Any],
17
17
  columns: List[str] = ["Type", "Name", "Docstring", "Depth"],
18
18
  prefix: str = "",
@@ -26,41 +26,14 @@ def inspect_module(
26
26
  drop_duplicates: bool = True,
27
27
  root_only: bool = False,
28
28
  ) -> pd.DataFrame:
29
- return _inspect_module(
30
- module=module,
31
- prefix=prefix,
32
- max_depth=max_depth,
33
- visited=visited,
34
- docstring=docstring,
35
- tree=tree,
36
- current_depth=current_depth,
37
- print_output=print_output,
38
- skip_depwarnings=skip_depwarnings,
39
- drop_duplicates=drop_duplicates,
40
- root_only=root_only,
41
- )[columns]
42
-
29
+ """
30
+ List the API of a module recursively and return as a DataFrame.
43
31
 
44
- def _inspect_module(
45
- module: Union[str, Any],
46
- columns: List[str] = ["Type", "Name", "Docstring", "Depth"],
47
- prefix: str = "",
48
- max_depth: int = 5,
49
- visited: Optional[Set[str]] = None,
50
- docstring: bool = False,
51
- tree: bool = True,
52
- current_depth: int = 0,
53
- print_output: bool = False,
54
- skip_depwarnings: bool = True,
55
- drop_duplicates: bool = True,
56
- root_only: bool = False,
57
- ) -> pd.DataFrame:
58
- """List the contents of a module recursively and return as a DataFrame.
32
+ Like a recursive `dir()` that shows the entire module tree.
59
33
 
60
34
  Example
61
35
  -------
62
- >>>
63
- >>> df = inspect_module(scitex)
36
+ >>> df = list_api(scitex)
64
37
  >>> print(df)
65
38
  Type Name Docstring Depth
66
39
  0 M scitex Module description 0
@@ -100,6 +73,36 @@ def _inspect_module(
100
73
  pd.DataFrame
101
74
  Module structure with specified columns
102
75
  """
76
+ return _list_api_impl(
77
+ module=module,
78
+ prefix=prefix,
79
+ max_depth=max_depth,
80
+ visited=visited,
81
+ docstring=docstring,
82
+ tree=tree,
83
+ current_depth=current_depth,
84
+ print_output=print_output,
85
+ skip_depwarnings=skip_depwarnings,
86
+ drop_duplicates=drop_duplicates,
87
+ root_only=root_only,
88
+ )[columns]
89
+
90
+
91
+ def _list_api_impl(
92
+ module: Union[str, Any],
93
+ columns: List[str] = ["Type", "Name", "Docstring", "Depth"],
94
+ prefix: str = "",
95
+ max_depth: int = 5,
96
+ visited: Optional[Set[str]] = None,
97
+ docstring: bool = False,
98
+ tree: bool = True,
99
+ current_depth: int = 0,
100
+ print_output: bool = False,
101
+ skip_depwarnings: bool = True,
102
+ drop_duplicates: bool = True,
103
+ root_only: bool = False,
104
+ ) -> pd.DataFrame:
105
+ """Internal implementation of list_api."""
103
106
  if skip_depwarnings:
104
107
  warnings.filterwarnings("ignore", category=DeprecationWarning)
105
108
  warnings.filterwarnings("ignore", category=UserWarning)
@@ -150,7 +153,7 @@ def _inspect_module(
150
153
  )
151
154
  )
152
155
  try:
153
- sub_df = _inspect_module(
156
+ sub_df = _list_api_impl(
154
157
  obj,
155
158
  columns=columns,
156
159
  prefix=full_path,
@@ -235,22 +238,8 @@ def _print_module_contents(df: pd.DataFrame) -> None:
235
238
 
236
239
 
237
240
  if __name__ == "__main__":
241
+ import scitex
242
+
238
243
  sys.setrecursionlimit(10_000)
239
- df = inspect_module(scitex, docstring=True, print_output=False, columns=["Name"])
244
+ df = list_api(scitex, docstring=True, print_output=False, columns=["Name"])
240
245
  print(scitex.pd.round(df))
241
- # Name
242
- # 0 scitex
243
- # 1 scitex.ai
244
- # 3 scitex.ai.ClassificationReporter
245
- # 4 scitex.ai.ClassifierServer
246
- # 5 scitex.ai.EarlyStopping
247
- # ... ...
248
- # 5373 scitex.typing
249
- # 5375 scitex.typing.Any
250
- # 5376 scitex.typing.Iterable
251
- # 5377 scitex.web
252
- # 5379 scitex.web.summarize_url
253
-
254
- # [5361 rows x 1 columns]
255
-
256
- # EOF
@@ -9,23 +9,27 @@ from .handlers import (
9
9
  call_graph_handler,
10
10
  class_hierarchy_handler,
11
11
  dependencies_handler,
12
+ # IPython-style names
13
+ dir_handler,
12
14
  # Basic
13
15
  docstring_handler,
14
16
  examples_handler,
15
17
  exports_handler,
16
18
  imports_handler,
17
- members_handler,
18
- signature_handler,
19
- source_handler,
19
+ list_api_handler,
20
+ q_handler,
21
+ qq_handler,
20
22
  type_hints_handler,
21
23
  )
22
24
 
23
25
  __all__ = [
26
+ # IPython-style names
27
+ "q_handler",
28
+ "qq_handler",
29
+ "dir_handler",
30
+ "list_api_handler",
24
31
  # Basic
25
- "signature_handler",
26
32
  "docstring_handler",
27
- "source_handler",
28
- "members_handler",
29
33
  "exports_handler",
30
34
  "examples_handler",
31
35
  # Advanced
@@ -9,16 +9,16 @@ from __future__ import annotations
9
9
  from typing import Literal
10
10
 
11
11
 
12
- async def signature_handler(
12
+ async def q_handler(
13
13
  dotted_path: str,
14
14
  include_defaults: bool = True,
15
15
  include_annotations: bool = True,
16
16
  ) -> dict:
17
- """Get the signature of a function, method, or class."""
17
+ """Get the signature of a function, method, or class (like IPython's func?)."""
18
18
  try:
19
- from .. import get_signature
19
+ from .. import q
20
20
 
21
- result = get_signature(
21
+ result = q(
22
22
  dotted_path,
23
23
  include_defaults=include_defaults,
24
24
  include_annotations=include_annotations,
@@ -42,16 +42,16 @@ async def docstring_handler(
42
42
  return {"success": False, "error": str(e)}
43
43
 
44
44
 
45
- async def source_handler(
45
+ async def qq_handler(
46
46
  dotted_path: str,
47
47
  max_lines: int | None = None,
48
48
  include_decorators: bool = True,
49
49
  ) -> dict:
50
- """Get the source code of a Python object."""
50
+ """Get the source code of a Python object (like IPython's func??)."""
51
51
  try:
52
- from .. import get_source
52
+ from .. import qq
53
53
 
54
- result = get_source(
54
+ result = qq(
55
55
  dotted_path,
56
56
  max_lines=max_lines,
57
57
  include_decorators=include_decorators,
@@ -61,17 +61,17 @@ async def source_handler(
61
61
  return {"success": False, "error": str(e)}
62
62
 
63
63
 
64
- async def members_handler(
64
+ async def dir_handler(
65
65
  dotted_path: str,
66
66
  filter: Literal["all", "public", "private", "dunder"] = "public",
67
67
  kind: Literal["all", "functions", "classes", "data", "modules"] | None = None,
68
68
  include_inherited: bool = False,
69
69
  ) -> dict:
70
- """List members of a module or class."""
70
+ """List members of a module or class (like dir())."""
71
71
  try:
72
- from .. import list_members
72
+ from .. import dir
73
73
 
74
- result = list_members(
74
+ result = dir(
75
75
  dotted_path,
76
76
  filter=filter,
77
77
  kind=kind,
@@ -206,3 +206,28 @@ async def call_graph_handler(
206
206
  return result
207
207
  except Exception as e:
208
208
  return {"success": False, "error": str(e)}
209
+
210
+
211
+ async def list_api_handler(
212
+ dotted_path: str,
213
+ max_depth: int = 5,
214
+ docstring: bool = False,
215
+ root_only: bool = False,
216
+ ) -> dict:
217
+ """List the API tree of a module recursively."""
218
+ try:
219
+ from .. import list_api
220
+
221
+ df = list_api(
222
+ dotted_path,
223
+ max_depth=max_depth,
224
+ docstring=docstring,
225
+ root_only=root_only,
226
+ )
227
+ return {
228
+ "success": True,
229
+ "api": df.to_dict(orient="records"),
230
+ "count": len(df),
231
+ }
232
+ except Exception as e:
233
+ return {"success": False, "error": str(e)}
@@ -6,13 +6,17 @@
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import builtins
9
10
  import inspect
10
11
  from typing import Literal
11
12
 
12
13
  from ._resolve import get_type_info, resolve_object
13
14
 
15
+ # Save reference to built-in dir before shadowing
16
+ _builtin_dir = builtins.dir
14
17
 
15
- def list_members(
18
+
19
+ def dir(
16
20
  dotted_path: str,
17
21
  filter: Literal["all", "public", "private", "dunder"] = "public",
18
22
  kind: Literal["all", "functions", "classes", "data", "modules"] | None = None,
@@ -53,7 +57,7 @@ def list_members(
53
57
  if inspect.isclass(obj) and not include_inherited:
54
58
  member_names = list(obj.__dict__.keys())
55
59
  else:
56
- member_names = dir(obj)
60
+ member_names = _builtin_dir(obj)
57
61
 
58
62
  if filter == "public":
59
63
  member_names = [n for n in member_names if not n.startswith("_")]
@@ -137,7 +141,7 @@ def get_exports(dotted_path: str) -> dict:
137
141
  exports = getattr(obj, "__all__", None)
138
142
 
139
143
  if exports is None:
140
- exports = [n for n in dir(obj) if not n.startswith("_")]
144
+ exports = [n for n in _builtin_dir(obj) if not n.startswith("_")]
141
145
  has_all = False
142
146
  else:
143
147
  has_all = True
@@ -45,7 +45,7 @@ def _build_signature_string(
45
45
  return sig
46
46
 
47
47
 
48
- def get_signature(
48
+ def q(
49
49
  dotted_path: str,
50
50
  include_defaults: bool = True,
51
51
  include_annotations: bool = True,
@@ -53,7 +53,7 @@ def get_signature(
53
53
  """
54
54
  Get the signature of a function, method, or class.
55
55
 
56
- Like IPython's `func?` but returns structured data.
56
+ Like IPython's `func?` (quick info).
57
57
 
58
58
  Parameters
59
59
  ----------
@@ -75,7 +75,7 @@ def get_signature(
75
75
 
76
76
  Examples
77
77
  --------
78
- >>> get_signature("scitex.plt.plot")
78
+ >>> q("scitex.plt.plot")
79
79
  {'name': 'plot', 'signature': 'plot(spec: dict, ...) -> dict', ...}
80
80
  """
81
81
  obj, error = resolve_object(dotted_path)
@@ -11,7 +11,7 @@ import inspect
11
11
  from ._resolve import get_type_info, resolve_object
12
12
 
13
13
 
14
- def get_source(
14
+ def qq(
15
15
  dotted_path: str,
16
16
  max_lines: int | None = None,
17
17
  include_decorators: bool = True,
@@ -19,7 +19,7 @@ def get_source(
19
19
  """
20
20
  Get the source code of a Python object.
21
21
 
22
- Like IPython's `func??`.
22
+ Like IPython's `func??` (full source).
23
23
 
24
24
  Parameters
25
25
  ----------
scitex/io/_save.py CHANGED
@@ -188,8 +188,7 @@ def _determine_save_path(specified_path, use_caller_path):
188
188
  if specified_path.startswith("/"):
189
189
  return specified_path
190
190
 
191
- from scitex.gen._detect_environment import detect_environment
192
- from scitex.gen._get_notebook_path import get_notebook_info_simple
191
+ from scitex.context import detect_environment, get_notebook_info_simple
193
192
 
194
193
  env_type = detect_environment()
195
194