scitex 2.8.1__py3-none-any.whl → 2.10.0__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 (415) hide show
  1. scitex/__init__.py +15 -7
  2. scitex/__version__.py +1 -2
  3. scitex/_install_guide.py +250 -0
  4. scitex/_optional_deps.py +206 -39
  5. scitex/ai/_gen_ai/_Groq.py +2 -4
  6. scitex/ai/_gen_ai/_OpenAI.py +5 -2
  7. scitex/ai/_gen_ai/_Perplexity.py +20 -6
  8. scitex/audio/__init__.py +24 -15
  9. scitex/audio/_cross_process_lock.py +139 -0
  10. scitex/audio/_mcp_handlers.py +256 -0
  11. scitex/audio/_mcp_tool_schemas.py +203 -0
  12. scitex/audio/engines/elevenlabs_engine.py +5 -2
  13. scitex/audio/mcp_server.py +98 -457
  14. scitex/bridge/__init__.py +30 -19
  15. scitex/bridge/_figrecipe.py +245 -0
  16. scitex/bridge/_helpers.py +2 -1
  17. scitex/bridge/_plt_vis.py +23 -10
  18. scitex/bridge/_stats_plt.py +18 -5
  19. scitex/bridge/_stats_vis.py +16 -2
  20. scitex/browser/__init__.py +84 -44
  21. scitex/browser/automation/__init__.py +5 -1
  22. scitex/browser/core/BrowserMixin.py +17 -4
  23. scitex/browser/core/__init__.py +11 -2
  24. scitex/browser/remote/CaptchaHandler.py +1 -1
  25. scitex/browser/remote/ZenRowsAPIClient.py +1 -1
  26. scitex/capture/grid.py +487 -0
  27. scitex/capture/mcp_handlers.py +401 -0
  28. scitex/capture/mcp_tool_defs.py +192 -0
  29. scitex/capture/mcp_tools.py +241 -0
  30. scitex/capture/mcp_utils.py +30 -0
  31. scitex/cli/convert.py +421 -0
  32. scitex/cli/main.py +6 -4
  33. scitex/datetime/__init__.py +46 -0
  34. scitex/datetime/_linspace.py +100 -0
  35. scitex/datetime/_normalize_timestamp.py +306 -0
  36. scitex/db/_delete_duplicates.py +4 -4
  37. scitex/db/_sqlite3/_delete_duplicates.py +11 -2
  38. scitex/dev/plt/__init__.py +61 -62
  39. scitex/dev/plt/demo_plotters/__init__.py +0 -0
  40. scitex/dev/plt/demo_plotters/plot_mpl_axhline.py +28 -0
  41. scitex/dev/plt/demo_plotters/plot_mpl_axhspan.py +28 -0
  42. scitex/dev/plt/demo_plotters/plot_mpl_axvline.py +28 -0
  43. scitex/dev/plt/demo_plotters/plot_mpl_axvspan.py +28 -0
  44. scitex/dev/plt/demo_plotters/plot_mpl_bar.py +29 -0
  45. scitex/dev/plt/demo_plotters/plot_mpl_barh.py +29 -0
  46. scitex/dev/plt/demo_plotters/plot_mpl_boxplot.py +28 -0
  47. scitex/dev/plt/demo_plotters/plot_mpl_contour.py +31 -0
  48. scitex/dev/plt/demo_plotters/plot_mpl_contourf.py +31 -0
  49. scitex/dev/plt/demo_plotters/plot_mpl_errorbar.py +30 -0
  50. scitex/dev/plt/demo_plotters/plot_mpl_eventplot.py +28 -0
  51. scitex/dev/plt/demo_plotters/plot_mpl_fill.py +30 -0
  52. scitex/dev/plt/demo_plotters/plot_mpl_fill_between.py +31 -0
  53. scitex/dev/plt/demo_plotters/plot_mpl_hexbin.py +28 -0
  54. scitex/dev/plt/demo_plotters/plot_mpl_hist.py +28 -0
  55. scitex/dev/plt/demo_plotters/plot_mpl_hist2d.py +28 -0
  56. scitex/dev/plt/demo_plotters/plot_mpl_imshow.py +29 -0
  57. scitex/dev/plt/demo_plotters/plot_mpl_pcolormesh.py +31 -0
  58. scitex/dev/plt/demo_plotters/plot_mpl_pie.py +29 -0
  59. scitex/dev/plt/demo_plotters/plot_mpl_plot.py +29 -0
  60. scitex/dev/plt/demo_plotters/plot_mpl_quiver.py +31 -0
  61. scitex/dev/plt/demo_plotters/plot_mpl_scatter.py +28 -0
  62. scitex/dev/plt/demo_plotters/plot_mpl_stackplot.py +31 -0
  63. scitex/dev/plt/demo_plotters/plot_mpl_stem.py +29 -0
  64. scitex/dev/plt/demo_plotters/plot_mpl_step.py +29 -0
  65. scitex/dev/plt/demo_plotters/plot_mpl_violinplot.py +28 -0
  66. scitex/dev/plt/demo_plotters/plot_sns_barplot.py +29 -0
  67. scitex/dev/plt/demo_plotters/plot_sns_boxplot.py +29 -0
  68. scitex/dev/plt/demo_plotters/plot_sns_heatmap.py +28 -0
  69. scitex/dev/plt/demo_plotters/plot_sns_histplot.py +29 -0
  70. scitex/dev/plt/demo_plotters/plot_sns_kdeplot.py +29 -0
  71. scitex/dev/plt/demo_plotters/plot_sns_lineplot.py +31 -0
  72. scitex/dev/plt/demo_plotters/plot_sns_scatterplot.py +29 -0
  73. scitex/dev/plt/demo_plotters/plot_sns_stripplot.py +29 -0
  74. scitex/dev/plt/demo_plotters/plot_sns_swarmplot.py +29 -0
  75. scitex/dev/plt/demo_plotters/plot_sns_violinplot.py +29 -0
  76. scitex/dev/plt/demo_plotters/plot_stx_bar.py +29 -0
  77. scitex/dev/plt/demo_plotters/plot_stx_barh.py +29 -0
  78. scitex/dev/plt/demo_plotters/plot_stx_box.py +28 -0
  79. scitex/dev/plt/demo_plotters/plot_stx_boxplot.py +28 -0
  80. scitex/dev/plt/demo_plotters/plot_stx_conf_mat.py +28 -0
  81. scitex/dev/plt/demo_plotters/plot_stx_contour.py +31 -0
  82. scitex/dev/plt/demo_plotters/plot_stx_ecdf.py +28 -0
  83. scitex/dev/plt/demo_plotters/plot_stx_errorbar.py +30 -0
  84. scitex/dev/plt/demo_plotters/plot_stx_fill_between.py +31 -0
  85. scitex/dev/plt/demo_plotters/plot_stx_fillv.py +28 -0
  86. scitex/dev/plt/demo_plotters/plot_stx_heatmap.py +28 -0
  87. scitex/dev/plt/demo_plotters/plot_stx_image.py +28 -0
  88. scitex/dev/plt/demo_plotters/plot_stx_imshow.py +28 -0
  89. scitex/dev/plt/demo_plotters/plot_stx_joyplot.py +28 -0
  90. scitex/dev/plt/demo_plotters/plot_stx_kde.py +28 -0
  91. scitex/dev/plt/demo_plotters/plot_stx_line.py +28 -0
  92. scitex/dev/plt/demo_plotters/plot_stx_mean_ci.py +28 -0
  93. scitex/dev/plt/demo_plotters/plot_stx_mean_std.py +28 -0
  94. scitex/dev/plt/demo_plotters/plot_stx_median_iqr.py +28 -0
  95. scitex/dev/plt/demo_plotters/plot_stx_raster.py +28 -0
  96. scitex/dev/plt/demo_plotters/plot_stx_rectangle.py +28 -0
  97. scitex/dev/plt/demo_plotters/plot_stx_scatter.py +29 -0
  98. scitex/dev/plt/demo_plotters/plot_stx_shaded_line.py +29 -0
  99. scitex/dev/plt/demo_plotters/plot_stx_violin.py +28 -0
  100. scitex/dev/plt/demo_plotters/plot_stx_violinplot.py +28 -0
  101. scitex/dev/plt/mpl/get_dir_ax.py +46 -0
  102. scitex/dev/plt/mpl/get_signatures.py +176 -0
  103. scitex/dev/plt/mpl/get_signatures_details.py +522 -0
  104. scitex/dict/_pop_keys.py +1 -7
  105. scitex/dsp/__init__.py +15 -10
  106. scitex/dsp/add_noise.py +5 -2
  107. scitex/dsp/example.py +35 -22
  108. scitex/dsp/filt.py +8 -3
  109. scitex/dsp/reference.py +3 -2
  110. scitex/dsp/utils/__init__.py +2 -1
  111. scitex/dsp/utils/_differential_bandpass_filters.py +14 -4
  112. scitex/dt/__init__.py +39 -2
  113. scitex/errors.py +82 -521
  114. scitex/fig/__init__.py +4 -4
  115. scitex/fig/editor/edit/panel_loader.py +1 -1
  116. scitex/fig/io/_bundle.py +7 -7
  117. scitex/fts/README.md +262 -0
  118. scitex/fts/TODO.md +66 -0
  119. scitex/fts/__init__.py +90 -0
  120. scitex/fts/_bundle/README_IN_BUNDLE.md +102 -0
  121. scitex/fts/_bundle/_FTS.py +657 -0
  122. scitex/fts/_bundle/__init__.py +38 -0
  123. scitex/fts/_bundle/_children.py +216 -0
  124. scitex/fts/_bundle/_conversion/__init__.py +15 -0
  125. scitex/fts/_bundle/_conversion/_bundle2dict.py +44 -0
  126. scitex/fts/_bundle/_conversion/_dict2bundle.py +50 -0
  127. scitex/fts/_bundle/_dataclasses/_Axes.py +57 -0
  128. scitex/fts/_bundle/_dataclasses/_BBox.py +54 -0
  129. scitex/fts/_bundle/_dataclasses/_ColumnDef.py +72 -0
  130. scitex/fts/_bundle/_dataclasses/_DataFormat.py +40 -0
  131. scitex/fts/_bundle/_dataclasses/_DataInfo.py +135 -0
  132. scitex/fts/_bundle/_dataclasses/_DataSource.py +44 -0
  133. scitex/fts/_bundle/_dataclasses/_Node.py +319 -0
  134. scitex/fts/_bundle/_dataclasses/_NodeRefs.py +45 -0
  135. scitex/fts/_bundle/_dataclasses/_SizeMM.py +38 -0
  136. scitex/fts/_bundle/_dataclasses/__init__.py +35 -0
  137. scitex/fts/_bundle/_extractors/__init__.py +32 -0
  138. scitex/fts/_bundle/_extractors/_extract_bar.py +131 -0
  139. scitex/fts/_bundle/_extractors/_extract_line.py +71 -0
  140. scitex/fts/_bundle/_extractors/_extract_scatter.py +79 -0
  141. scitex/fts/_bundle/_loader.py +134 -0
  142. scitex/fts/_bundle/_mpl_helpers.py +389 -0
  143. scitex/fts/_bundle/_saver.py +269 -0
  144. scitex/fts/_bundle/_storage.py +200 -0
  145. scitex/fts/_bundle/_utils/__init__.py +55 -0
  146. scitex/fts/_bundle/_utils/_const.py +26 -0
  147. scitex/fts/_bundle/_utils/_errors.py +73 -0
  148. scitex/fts/_bundle/_utils/_generate.py +21 -0
  149. scitex/fts/_bundle/_utils/_types.py +76 -0
  150. scitex/fts/_bundle/_validation.py +434 -0
  151. scitex/fts/_bundle/_zipbundle.py +165 -0
  152. scitex/fts/_fig/__init__.py +22 -0
  153. scitex/fts/_fig/_backend/__init__.py +53 -0
  154. scitex/fts/_fig/_backend/_export.py +165 -0
  155. scitex/fts/_fig/_backend/_parser.py +188 -0
  156. scitex/fts/_fig/_backend/_render.py +538 -0
  157. scitex/fts/_fig/_composite.py +345 -0
  158. scitex/fts/_fig/_dataclasses/_ChannelEncoding.py +46 -0
  159. scitex/fts/_fig/_dataclasses/_Encoding.py +82 -0
  160. scitex/fts/_fig/_dataclasses/_Theme.py +441 -0
  161. scitex/fts/_fig/_dataclasses/_TraceEncoding.py +52 -0
  162. scitex/fts/_fig/_dataclasses/__init__.py +47 -0
  163. scitex/fts/_fig/_editor/__init__.py +14 -0
  164. scitex/fts/_fig/_editor/_cui/__init__.py +33 -0
  165. scitex/fts/_fig/_editor/_cui/_backend_detector.py +39 -0
  166. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +366 -0
  167. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +175 -0
  168. scitex/fts/_fig/_editor/_cui/_manual_handler.py +52 -0
  169. scitex/fts/_fig/_editor/_cui/_panel_loader.py +246 -0
  170. scitex/fts/_fig/_editor/_cui/_path_resolver.py +66 -0
  171. scitex/fts/_fig/_editor/_defaults.py +300 -0
  172. scitex/fts/_fig/_editor/_gui/__init__.py +11 -0
  173. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +20 -0
  174. scitex/fts/_fig/_editor/_gui/_flask_editor/_bbox.py +1339 -0
  175. scitex/fts/_fig/_editor/_gui/_flask_editor/_core.py +1688 -0
  176. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +664 -0
  177. scitex/fts/_fig/_editor/_gui/_flask_editor/_renderer.py +853 -0
  178. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +79 -0
  179. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +41 -0
  180. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +16 -0
  181. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +85 -0
  182. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +217 -0
  183. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +93 -0
  184. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +57 -0
  185. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +112 -0
  186. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +59 -0
  187. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +212 -0
  188. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/canvas.css +176 -0
  189. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +190 -0
  190. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +59 -0
  191. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +45 -0
  192. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +95 -0
  193. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +101 -0
  194. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +138 -0
  195. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +31 -0
  196. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +7 -0
  197. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +56 -0
  198. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +78 -0
  199. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +314 -0
  200. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +107 -0
  201. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +54 -0
  202. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +172 -0
  203. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +258 -0
  204. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +48 -0
  205. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +71 -0
  206. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +288 -0
  207. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +143 -0
  208. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +245 -0
  209. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +992 -0
  210. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +339 -0
  211. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +286 -0
  212. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +371 -0
  213. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +293 -0
  214. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +426 -0
  215. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +152 -0
  216. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +265 -0
  217. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +184 -0
  218. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +57 -0
  219. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +100 -0
  220. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +34 -0
  221. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +124 -0
  222. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +851 -0
  223. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +4932 -0
  224. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +1657 -0
  225. scitex/fts/_fig/_editor/_gui/_flask_editor.py +36 -0
  226. scitex/fts/_fig/_models/_Annotations.py +115 -0
  227. scitex/fts/_fig/_models/_Axes.py +152 -0
  228. scitex/fts/_fig/_models/_Figure.py +138 -0
  229. scitex/fts/_fig/_models/_Guides.py +104 -0
  230. scitex/fts/_fig/_models/_Plot.py +123 -0
  231. scitex/fts/_fig/_models/_Styles.py +245 -0
  232. scitex/fts/_fig/_models/__init__.py +80 -0
  233. scitex/fts/_fig/_models/_plot_types/__init__.py +156 -0
  234. scitex/fts/_fig/_models/_plot_types/_bar.py +43 -0
  235. scitex/fts/_fig/_models/_plot_types/_box.py +38 -0
  236. scitex/fts/_fig/_models/_plot_types/_distribution.py +36 -0
  237. scitex/fts/_fig/_models/_plot_types/_errorbar.py +60 -0
  238. scitex/fts/_fig/_models/_plot_types/_histogram.py +30 -0
  239. scitex/fts/_fig/_models/_plot_types/_image.py +61 -0
  240. scitex/fts/_fig/_models/_plot_types/_line.py +57 -0
  241. scitex/fts/_fig/_models/_plot_types/_scatter.py +30 -0
  242. scitex/fts/_fig/_models/_plot_types/_seaborn.py +121 -0
  243. scitex/fts/_fig/_models/_plot_types/_violin.py +36 -0
  244. scitex/fts/_fig/_utils/__init__.py +129 -0
  245. scitex/fts/_fig/_utils/_auto_layout.py +127 -0
  246. scitex/fts/_fig/_utils/_calc_bounds.py +111 -0
  247. scitex/fts/_fig/_utils/_const_sizes.py +48 -0
  248. scitex/fts/_fig/_utils/_convert_coords.py +77 -0
  249. scitex/fts/_fig/_utils/_get_template.py +178 -0
  250. scitex/fts/_fig/_utils/_normalize.py +73 -0
  251. scitex/fts/_fig/_utils/_plot_layout.py +397 -0
  252. scitex/fts/_fig/_utils/_validate.py +197 -0
  253. scitex/fts/_kinds/__init__.py +45 -0
  254. scitex/fts/_kinds/_figure/__init__.py +19 -0
  255. scitex/fts/_kinds/_figure/_composite.py +345 -0
  256. scitex/fts/_kinds/_plot/__init__.py +25 -0
  257. scitex/fts/_kinds/_plot/_backend/__init__.py +53 -0
  258. scitex/fts/_kinds/_plot/_backend/_export.py +165 -0
  259. scitex/fts/_kinds/_plot/_backend/_parser.py +188 -0
  260. scitex/fts/_kinds/_plot/_backend/_render.py +538 -0
  261. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +46 -0
  262. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +82 -0
  263. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +441 -0
  264. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +52 -0
  265. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +47 -0
  266. scitex/fts/_kinds/_plot/_models/_Annotations.py +115 -0
  267. scitex/fts/_kinds/_plot/_models/_Axes.py +152 -0
  268. scitex/fts/_kinds/_plot/_models/_Figure.py +138 -0
  269. scitex/fts/_kinds/_plot/_models/_Guides.py +104 -0
  270. scitex/fts/_kinds/_plot/_models/_Plot.py +123 -0
  271. scitex/fts/_kinds/_plot/_models/_Styles.py +245 -0
  272. scitex/fts/_kinds/_plot/_models/__init__.py +80 -0
  273. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +156 -0
  274. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +43 -0
  275. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +38 -0
  276. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +36 -0
  277. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +60 -0
  278. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +30 -0
  279. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +61 -0
  280. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +57 -0
  281. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +30 -0
  282. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +121 -0
  283. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +36 -0
  284. scitex/fts/_kinds/_plot/_utils/__init__.py +129 -0
  285. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +127 -0
  286. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +111 -0
  287. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +48 -0
  288. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +77 -0
  289. scitex/fts/_kinds/_plot/_utils/_get_template.py +178 -0
  290. scitex/fts/_kinds/_plot/_utils/_normalize.py +73 -0
  291. scitex/fts/_kinds/_plot/_utils/_plot_layout.py +397 -0
  292. scitex/fts/_kinds/_plot/_utils/_validate.py +197 -0
  293. scitex/fts/_kinds/_shape/__init__.py +141 -0
  294. scitex/fts/_kinds/_stats/__init__.py +56 -0
  295. scitex/fts/_kinds/_stats/_dataclasses/_Stats.py +423 -0
  296. scitex/fts/_kinds/_stats/_dataclasses/__init__.py +48 -0
  297. scitex/fts/_kinds/_table/__init__.py +72 -0
  298. scitex/fts/_kinds/_table/_latex/__init__.py +93 -0
  299. scitex/fts/_kinds/_table/_latex/_editor/__init__.py +11 -0
  300. scitex/fts/_kinds/_table/_latex/_editor/_app.py +725 -0
  301. scitex/fts/_kinds/_table/_latex/_export.py +279 -0
  302. scitex/fts/_kinds/_table/_latex/_figure_exporter.py +153 -0
  303. scitex/fts/_kinds/_table/_latex/_stats_formatter.py +274 -0
  304. scitex/fts/_kinds/_table/_latex/_table_exporter.py +362 -0
  305. scitex/fts/_kinds/_table/_latex/_utils.py +369 -0
  306. scitex/fts/_kinds/_table/_latex/_validator.py +445 -0
  307. scitex/fts/_kinds/_text/__init__.py +77 -0
  308. scitex/fts/_schemas/data_info.schema.json +75 -0
  309. scitex/fts/_schemas/encoding.schema.json +90 -0
  310. scitex/fts/_schemas/node.schema.json +145 -0
  311. scitex/fts/_schemas/render_manifest.schema.json +62 -0
  312. scitex/fts/_schemas/stats.schema.json +132 -0
  313. scitex/fts/_schemas/theme.schema.json +141 -0
  314. scitex/fts/_stats/__init__.py +48 -0
  315. scitex/fts/_stats/_dataclasses/_Stats.py +423 -0
  316. scitex/fts/_stats/_dataclasses/__init__.py +48 -0
  317. scitex/fts/_tables/__init__.py +65 -0
  318. scitex/fts/_tables/_latex/__init__.py +93 -0
  319. scitex/fts/_tables/_latex/_editor/__init__.py +11 -0
  320. scitex/fts/_tables/_latex/_editor/_app.py +725 -0
  321. scitex/fts/_tables/_latex/_export.py +279 -0
  322. scitex/fts/_tables/_latex/_figure_exporter.py +153 -0
  323. scitex/fts/_tables/_latex/_stats_formatter.py +274 -0
  324. scitex/fts/_tables/_latex/_table_exporter.py +362 -0
  325. scitex/fts/_tables/_latex/_utils.py +369 -0
  326. scitex/fts/_tables/_latex/_validator.py +445 -0
  327. scitex/gen/__init__.py +66 -25
  328. scitex/gen/misc.py +28 -0
  329. scitex/io/__init__.py +47 -32
  330. scitex/io/_load.py +87 -36
  331. scitex/io/_load_modules/__init__.py +10 -7
  332. scitex/io/_load_modules/_pandas.py +6 -1
  333. scitex/io/_save.py +299 -1556
  334. scitex/io/_save_modules/__init__.py +76 -19
  335. scitex/io/_save_modules/_figure_utils.py +90 -0
  336. scitex/io/_save_modules/_image_csv.py +497 -0
  337. scitex/io/_save_modules/_legends.py +91 -0
  338. scitex/io/_save_modules/_pltz_bundle.py +356 -0
  339. scitex/io/_save_modules/_pltz_stx.py +536 -0
  340. scitex/io/_save_modules/_stx_bundle.py +104 -0
  341. scitex/io/_save_modules/_symlink.py +96 -0
  342. scitex/io/_save_modules/_yaml.py +1 -1
  343. scitex/io/_save_modules/_zarr.py +64 -18
  344. scitex/io/bundle/README.md +212 -0
  345. scitex/io/bundle/__init__.py +110 -0
  346. scitex/io/{_bundle.py → bundle/_core.py} +168 -97
  347. scitex/io/bundle/_nested.py +713 -0
  348. scitex/io/bundle/_types.py +74 -0
  349. scitex/io/{_zip_bundle.py → bundle/_zip.py} +93 -45
  350. scitex/io/utils/h5_to_zarr.py +1 -1
  351. scitex/logging/__init__.py +108 -13
  352. scitex/logging/_errors.py +508 -0
  353. scitex/logging/_formatters.py +30 -6
  354. scitex/logging/_warnings.py +261 -0
  355. scitex/plt/__init__.py +4 -1
  356. scitex/plt/_figrecipe.py +236 -0
  357. scitex/plt/_subplots/_AxisWrapper.py +6 -0
  358. scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +112 -1
  359. scitex/plt/_subplots/_FigWrapper.py +15 -0
  360. scitex/plt/_subplots/_SubplotsWrapper.py +125 -489
  361. scitex/plt/_subplots/_export_as_csv.py +11 -0
  362. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +2 -0
  363. scitex/plt/_subplots/_export_as_csv_formatters/_format_pcolormesh.py +66 -0
  364. scitex/plt/_subplots/_export_as_csv_formatters/_format_stackplot.py +62 -0
  365. scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +208 -0
  366. scitex/plt/_subplots/_fonts.py +71 -0
  367. scitex/plt/_subplots/_mm_layout.py +282 -0
  368. scitex/plt/gallery/__init__.py +99 -2
  369. scitex/plt/styles/_plot_postprocess.py +3 -1
  370. scitex/plt/utils/_configure_mpl.py +16 -19
  371. scitex/repro/_RandomStateManager.py +13 -8
  372. scitex/resource/__init__.py +19 -1
  373. scitex/resource/_utils/_get_env_info.py +13 -25
  374. scitex/schema/__init__.py +149 -160
  375. scitex/schema/_encoding.py +273 -0
  376. scitex/schema/_figure_elements.py +406 -0
  377. scitex/schema/_theme.py +360 -0
  378. scitex/schema/_validation.py +0 -98
  379. scitex/scholar/__init__.py +56 -14
  380. scitex/scholar/auth/ScholarAuthManager.py +1 -1
  381. scitex/scholar/auth/__init__.py +11 -2
  382. scitex/scholar/auth/providers/BaseAuthenticator.py +1 -1
  383. scitex/scholar/auth/providers/EZProxyAuthenticator.py +1 -1
  384. scitex/scholar/auth/providers/OpenAthensAuthenticator.py +1 -1
  385. scitex/scholar/auth/providers/ShibbolethAuthenticator.py +1 -1
  386. scitex/scholar/config/ScholarConfig.py +1 -1
  387. scitex/scholar/core/Scholar.py +1 -1
  388. scitex/session/_decorator.py +18 -16
  389. scitex/session/_lifecycle.py +9 -11
  390. scitex/session/template.py +9 -8
  391. scitex/sh/test_sh.py +72 -0
  392. scitex/sh/test_sh_simple.py +61 -0
  393. scitex/stats/__init__.py +221 -97
  394. scitex/stats/_schema.py +21 -22
  395. scitex/stats/descriptive/_circular.py +212 -351
  396. scitex/stats/descriptive/_describe.py +81 -132
  397. scitex/stats/descriptive/_nan.py +205 -433
  398. scitex/stats/descriptive/_real.py +127 -141
  399. scitex/str/_format_plot_text.py +5 -5
  400. scitex/str/_latex.py +26 -84
  401. scitex/str/_latex_fallback.py +53 -47
  402. scitex/web/_search_pubmed.py +5 -4
  403. scitex/writer/tests/test_diff_between.py +451 -0
  404. scitex/writer/tests/test_document_section.py +311 -0
  405. scitex/writer/tests/test_document_workflow.py +393 -0
  406. scitex/writer/tests/test_writer.py +361 -0
  407. scitex/writer/tests/test_writer_integration.py +303 -0
  408. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/METADATA +364 -181
  409. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/RECORD +412 -97
  410. scitex/scholar/docs/to_claude/guidelines/examples/mgmt/ARCHITECTURE_EXAMPLE.md +0 -905
  411. scitex/scholar/docs/to_claude/guidelines/examples/mgmt/BULLETIN_BOARD_EXAMPLE.md +0 -99
  412. scitex/scholar/docs/to_claude/guidelines/examples/mgmt/PROJECT_DESCRIPTION_EXAMPLE.md +0 -96
  413. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/WHEEL +0 -0
  414. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/entry_points.txt +0 -0
  415. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-16 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/bundle/_types.py
5
+
6
+ """
7
+ SciTeX Bundle Types and Constants.
8
+
9
+ Defines bundle types, extensions, and error classes used across the bundle module.
10
+ """
11
+
12
+ from typing import Tuple
13
+
14
+ __all__ = [
15
+ "BundleType",
16
+ "BundleError",
17
+ "BundleValidationError",
18
+ "BundleNotFoundError",
19
+ "NestedBundleNotFoundError",
20
+ "EXTENSIONS",
21
+ "FIGZ",
22
+ "PLTZ",
23
+ "STATSZ",
24
+ ]
25
+
26
+ # Bundle extensions
27
+ EXTENSIONS: Tuple[str, ...] = (".figz", ".pltz", ".statsz")
28
+
29
+ # Bundle type constants (for convenience)
30
+ FIGZ = "figz"
31
+ PLTZ = "pltz"
32
+ STATSZ = "statsz"
33
+
34
+
35
+ class BundleType:
36
+ """Bundle type constants.
37
+
38
+ Usage:
39
+ from scitex.io.bundle import BundleType
40
+
41
+ if bundle_type == BundleType.FIGZ:
42
+ ...
43
+ """
44
+
45
+ FIGZ = "figz"
46
+ PLTZ = "pltz"
47
+ STATSZ = "statsz"
48
+
49
+
50
+ class BundleError(Exception):
51
+ """Base exception for bundle operations."""
52
+
53
+ pass
54
+
55
+
56
+ class BundleValidationError(BundleError, ValueError):
57
+ """Error raised when bundle validation fails."""
58
+
59
+ pass
60
+
61
+
62
+ class BundleNotFoundError(BundleError, FileNotFoundError):
63
+ """Error raised when a bundle is not found."""
64
+
65
+ pass
66
+
67
+
68
+ class NestedBundleNotFoundError(BundleNotFoundError):
69
+ """Error raised when a nested bundle or file within it is not found."""
70
+
71
+ pass
72
+
73
+
74
+ # EOF
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
- # Timestamp: "2025-12-14 (ywatanabe)"
4
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/_zip_bundle.py
3
+ # Timestamp: "2025-12-16 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/bundle/_zip.py
5
5
 
6
6
  """
7
7
  SciTeX ZipBundle - In-memory zip archive handler with atomic writes.
@@ -21,14 +21,15 @@ import shutil
21
21
  import tempfile
22
22
  import zipfile
23
23
  from pathlib import Path
24
- from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Union
24
+ from typing import Any, Dict, Iterator, List, Optional, Union
25
25
 
26
26
  import pandas as pd
27
27
 
28
28
  __all__ = [
29
29
  "ZipBundle",
30
- "open_bundle",
31
- "create_bundle",
30
+ "open",
31
+ "create",
32
+ "zip_directory",
32
33
  ]
33
34
 
34
35
 
@@ -75,14 +76,14 @@ class ZipBundle:
75
76
  self.mode = mode
76
77
  self.compression = compression
77
78
  self._zipfile: Optional[zipfile.ZipFile] = None
78
- self._cache: Dict[str, bytes] = {} # Cache for read files
79
- self._pending_writes: Dict[str, bytes] = {} # Pending writes for atomic commit
79
+ self._cache: Dict[str, bytes] = {}
80
+ self._pending_writes: Dict[str, bytes] = {}
80
81
  self._temp_path: Optional[Path] = None
81
82
  self._closed = False
82
83
 
83
84
  def __enter__(self) -> "ZipBundle":
84
85
  """Enter context manager."""
85
- self.open()
86
+ self._open()
86
87
  return self
87
88
 
88
89
  def __exit__(self, exc_type, exc_val, exc_tb) -> None:
@@ -91,22 +92,19 @@ class ZipBundle:
91
92
  self._atomic_commit()
92
93
  self.close()
93
94
 
94
- def open(self) -> None:
95
+ def _open(self) -> None:
95
96
  """Open the zip bundle."""
96
97
  if self.mode == "r":
97
98
  if not self.path.exists():
98
99
  raise FileNotFoundError(f"Bundle not found: {self.path}")
99
100
  self._zipfile = zipfile.ZipFile(self.path, "r")
100
101
  elif self.mode == "w":
101
- # Create new archive (write to temp, commit on close)
102
102
  self._temp_path = Path(tempfile.mktemp(suffix=self.path.suffix))
103
103
  self._zipfile = zipfile.ZipFile(
104
104
  self._temp_path, "w", self.compression
105
105
  )
106
106
  elif self.mode == "a":
107
- # Append mode: read existing, write to temp, commit atomically
108
107
  if self.path.exists():
109
- # Load existing contents into cache
110
108
  with zipfile.ZipFile(self.path, "r") as zf:
111
109
  for name in zf.namelist():
112
110
  self._cache[name] = zf.read(name)
@@ -122,27 +120,18 @@ class ZipBundle:
122
120
  if self._zipfile and not self._closed:
123
121
  self._zipfile.close()
124
122
  self._closed = True
125
- # Clean up temp file if not committed (error case)
126
123
  if self._temp_path and self._temp_path.exists():
127
124
  if self.mode in ("w", "a") and not self.path.exists():
128
- # Commit wasn't called, clean up
129
125
  self._temp_path.unlink()
130
126
 
131
127
  def _atomic_commit(self) -> None:
132
- """Atomically commit writes by renaming temp file.
133
-
134
- This ensures the bundle is never in an inconsistent state.
135
- Either the old file exists completely, or the new one does.
136
- """
128
+ """Atomically commit writes by renaming temp file."""
137
129
  if self._temp_path is None:
138
130
  return
139
131
 
140
- # Write all pending and cached content to the temp zip
141
132
  self._zipfile.close()
142
133
  self._closed = True
143
134
 
144
- # Atomic rename (works on same filesystem)
145
- # On Windows, we need to remove target first
146
135
  if os.name == "nt" and self.path.exists():
147
136
  backup_path = self.path.with_suffix(self.path.suffix + ".bak")
148
137
  self.path.rename(backup_path)
@@ -150,11 +139,9 @@ class ZipBundle:
150
139
  self._temp_path.rename(self.path)
151
140
  backup_path.unlink()
152
141
  except Exception:
153
- # Restore backup on failure
154
142
  backup_path.rename(self.path)
155
143
  raise
156
144
  else:
157
- # Unix: atomic rename
158
145
  self._temp_path.rename(self.path)
159
146
 
160
147
  # =========================================================================
@@ -166,7 +153,6 @@ class ZipBundle:
166
153
  if self.mode == "r":
167
154
  return self._zipfile.namelist()
168
155
  else:
169
- # Include both cached and pending writes
170
156
  names = set(self._cache.keys())
171
157
  names.update(self._pending_writes.keys())
172
158
  return sorted(names)
@@ -192,25 +178,19 @@ class ZipBundle:
192
178
  Returns:
193
179
  File contents as bytes.
194
180
  """
195
- # Check cache first (for append mode)
196
181
  if name in self._pending_writes:
197
182
  return self._pending_writes[name]
198
183
  if name in self._cache:
199
184
  return self._cache[name]
200
185
 
201
- # Read from zip
202
186
  if self._zipfile is None:
203
187
  raise RuntimeError("Bundle not opened")
204
188
 
205
- # Handle files inside .d directory structure
206
- # Try direct name first, then with .d prefix
207
189
  try:
208
190
  data = self._zipfile.read(name)
209
191
  self._cache[name] = data
210
192
  return data
211
193
  except KeyError:
212
- # Try with directory prefix (e.g., "bundle.pltz.d/spec.json")
213
- # The path.name includes extension, so "foo.pltz" -> "foo.pltz.d"
214
194
  dir_name = self.path.name + ".d"
215
195
  full_name = f"{dir_name}/{name}"
216
196
  try:
@@ -218,11 +198,10 @@ class ZipBundle:
218
198
  self._cache[name] = data
219
199
  return data
220
200
  except KeyError:
221
- # Try to find the .d directory dynamically
222
- # (handles case where pltz was renamed, e.g., panel_A.pltz -> A.pltz
223
- # but internal structure is still panel_A.pltz.d/)
224
201
  for arc_name in self._zipfile.namelist():
225
- if arc_name.endswith('.d/' + name) or arc_name.endswith('.d/' + name.replace('/', '/')):
202
+ if arc_name.endswith(".d/" + name) or arc_name.endswith(
203
+ ".d/" + name.replace("/", "/")
204
+ ):
226
205
  data = self._zipfile.read(arc_name)
227
206
  self._cache[name] = data
228
207
  return data
@@ -290,9 +269,7 @@ class ZipBundle:
290
269
  raise RuntimeError("Cannot write in read mode")
291
270
 
292
271
  self._pending_writes[name] = data
293
- self._cache[name] = data # Update cache
294
-
295
- # Write to zip immediately
272
+ self._cache[name] = data
296
273
  self._zipfile.writestr(name, data)
297
274
 
298
275
  def write_text(self, name: str, text: str, encoding: str = "utf-8") -> None:
@@ -343,7 +320,7 @@ class ZipBundle:
343
320
  self.write_bytes(name, data)
344
321
 
345
322
  # =========================================================================
346
- # Convenience methods
323
+ # Convenience properties
347
324
  # =========================================================================
348
325
 
349
326
  @property
@@ -371,9 +348,7 @@ class ZipBundle:
371
348
  return None
372
349
 
373
350
 
374
- def open_bundle(
375
- path: Union[str, Path], mode: str = "r"
376
- ) -> ZipBundle:
351
+ def open(path: Union[str, Path], mode: str = "r") -> ZipBundle:
377
352
  """Open a bundle for reading or writing.
378
353
 
379
354
  Args:
@@ -384,14 +359,14 @@ def open_bundle(
384
359
  ZipBundle instance (use as context manager).
385
360
 
386
361
  Example:
387
- with open_bundle("figure.figz") as bundle:
362
+ with open("figure.figz") as bundle:
388
363
  spec = bundle.spec
389
364
  data = bundle.data
390
365
  """
391
366
  return ZipBundle(path, mode=mode)
392
367
 
393
368
 
394
- def create_bundle(
369
+ def create(
395
370
  path: Union[str, Path],
396
371
  spec: Dict[str, Any],
397
372
  data: Optional[pd.DataFrame] = None,
@@ -411,7 +386,7 @@ def create_bundle(
411
386
  Path to created bundle.
412
387
 
413
388
  Example:
414
- create_bundle(
389
+ create(
415
390
  "plot.pltz",
416
391
  spec={"schema": {"name": "scitex.plt", "version": "1.0"}},
417
392
  data=df,
@@ -436,4 +411,77 @@ def create_bundle(
436
411
  return path
437
412
 
438
413
 
414
+ def zip_directory(
415
+ source_dir: Union[str, Path],
416
+ output_path: Optional[Union[str, Path]] = None,
417
+ ) -> Path:
418
+ """Convert a directory bundle (.pltz.d, .figz.d) to a ZIP bundle (.pltz, .figz).
419
+
420
+ Creates a ZIP archive from an existing directory bundle, preserving
421
+ the internal structure. The ZIP file is created atomically using a temp file.
422
+
423
+ Args:
424
+ source_dir: Path to directory bundle (e.g., "panel_A.pltz.d", "figure.figz.d")
425
+ output_path: Optional output ZIP path. If not provided, derives from source_dir
426
+ by replacing .pltz.d -> .pltz or .figz.d -> .figz
427
+
428
+ Returns:
429
+ Path to created ZIP bundle.
430
+
431
+ Raises:
432
+ FileNotFoundError: If source directory doesn't exist.
433
+ ValueError: If source is not a valid bundle directory.
434
+
435
+ Example:
436
+ # Convert panel_A.pltz.d to panel_A.pltz
437
+ zip_path = zip_directory("panel_A.pltz.d")
438
+
439
+ # Convert with custom output path
440
+ zip_path = zip_directory("A.pltz.d", "output/A.pltz")
441
+ """
442
+ source_dir = Path(source_dir)
443
+
444
+ if not source_dir.exists():
445
+ raise FileNotFoundError(f"Source directory not found: {source_dir}")
446
+
447
+ if not source_dir.is_dir():
448
+ raise ValueError(f"Source is not a directory: {source_dir}")
449
+
450
+ if output_path is None:
451
+ dir_name = source_dir.name
452
+ if dir_name.endswith(".pltz.d"):
453
+ zip_name = dir_name.replace(".pltz.d", ".pltz")
454
+ elif dir_name.endswith(".figz.d"):
455
+ zip_name = dir_name.replace(".figz.d", ".figz")
456
+ elif dir_name.endswith(".statsz.d"):
457
+ zip_name = dir_name.replace(".statsz.d", ".statsz")
458
+ else:
459
+ zip_name = dir_name + ".zip"
460
+ output_path = source_dir.parent / zip_name
461
+ else:
462
+ output_path = Path(output_path)
463
+
464
+ output_path.parent.mkdir(parents=True, exist_ok=True)
465
+
466
+ temp_path = Path(tempfile.mktemp(suffix=output_path.suffix))
467
+
468
+ try:
469
+ with zipfile.ZipFile(temp_path, "w", zipfile.ZIP_DEFLATED) as zf:
470
+ for file_path in source_dir.rglob("*"):
471
+ if file_path.is_file():
472
+ arcname = file_path.relative_to(source_dir)
473
+ zf.write(file_path, arcname)
474
+
475
+ if output_path.exists():
476
+ output_path.unlink()
477
+ shutil.move(str(temp_path), str(output_path))
478
+
479
+ except Exception:
480
+ if temp_path.exists():
481
+ temp_path.unlink()
482
+ raise
483
+
484
+ return output_path
485
+
486
+
439
487
  # EOF
@@ -36,7 +36,7 @@ from typing import Optional, Union, Dict, Any, List, Tuple
36
36
  from tqdm import tqdm
37
37
 
38
38
  from scitex import logging
39
- from scitex.errors import (
39
+ from scitex.logging import (
40
40
  IOError as SciTeXIOError,
41
41
  FileFormatError,
42
42
  PathNotFoundError,
@@ -37,16 +37,6 @@ Usage:
37
37
  log_file = logging.get_log_path()
38
38
  """
39
39
 
40
- import warnings
41
-
42
- # Issue deprecation warning when module is imported
43
- warnings.warn(
44
- "scitex.logging is deprecated. Use scitex.logging instead. "
45
- "The scitex.logging module will be removed in a future version.",
46
- DeprecationWarning,
47
- stacklevel=2,
48
- )
49
-
50
40
  import logging as _logging
51
41
 
52
42
  from ._Tee import Tee, tee
@@ -72,6 +62,61 @@ from ._print_capture import (
72
62
  )
73
63
  from ._context import log_to_file
74
64
 
65
+ # Warnings (like Python's warnings module)
66
+ from ._warnings import (
67
+ SciTeXWarning,
68
+ UnitWarning,
69
+ StyleWarning,
70
+ SciTeXDeprecationWarning,
71
+ PerformanceWarning,
72
+ DataLossWarning,
73
+ warn,
74
+ filterwarnings,
75
+ resetwarnings,
76
+ warn_deprecated,
77
+ warn_performance,
78
+ warn_data_loss,
79
+ )
80
+
81
+ # Errors (exceptions)
82
+ from ._errors import (
83
+ SciTeXError,
84
+ ConfigurationError,
85
+ ConfigFileNotFoundError,
86
+ ConfigKeyError,
87
+ IOError,
88
+ FileFormatError,
89
+ SaveError,
90
+ LoadError,
91
+ ScholarError,
92
+ SearchError,
93
+ EnrichmentError,
94
+ PDFDownloadError,
95
+ DOIResolutionError,
96
+ PDFExtractionError,
97
+ BibTeXEnrichmentError,
98
+ TranslatorError,
99
+ AuthenticationError,
100
+ PlottingError,
101
+ FigureNotFoundError,
102
+ AxisError,
103
+ DataError,
104
+ ShapeError,
105
+ DTypeError,
106
+ PathError,
107
+ InvalidPathError,
108
+ PathNotFoundError,
109
+ TemplateError,
110
+ TemplateViolationError,
111
+ NNError,
112
+ ModelError,
113
+ StatsError,
114
+ TestError,
115
+ check_path,
116
+ check_file_exists,
117
+ check_shape_compatibility,
118
+ )
119
+
75
120
  # Re-export standard logging functions for compatibility
76
121
  getLogger = _logging.getLogger
77
122
  basicConfig = _logging.basicConfig
@@ -97,9 +142,9 @@ level = level_map.get(level_by_env, INFO)
97
142
  # Auto-configure logging on import with file logging enabled, print capture disabled by default
98
143
  configure(level=level, enable_file=True, enable_console=True, capture_prints=False)
99
144
 
100
- # Export only essential public functions - minimal API
145
+ # Export public API
101
146
  __all__ = [
102
- # Core logging functions (most commonly used)
147
+ # Core logging functions
103
148
  "getLogger",
104
149
  # Log levels
105
150
  "DEBUG",
@@ -109,13 +154,63 @@ __all__ = [
109
154
  "CRITICAL",
110
155
  "SUCCESS",
111
156
  "FAIL",
112
- # Configuration (minimal set)
157
+ # Configuration
113
158
  "configure",
114
159
  "get_log_path",
115
160
  "Tee",
116
161
  "tee",
117
162
  # Context managers
118
163
  "log_to_file",
164
+ # Warnings (like Python's warnings module)
165
+ "SciTeXWarning",
166
+ "UnitWarning",
167
+ "StyleWarning",
168
+ "SciTeXDeprecationWarning",
169
+ "PerformanceWarning",
170
+ "DataLossWarning",
171
+ "warn",
172
+ "filterwarnings",
173
+ "resetwarnings",
174
+ "warn_deprecated",
175
+ "warn_performance",
176
+ "warn_data_loss",
177
+ # Errors (exceptions)
178
+ "SciTeXError",
179
+ "ConfigurationError",
180
+ "ConfigFileNotFoundError",
181
+ "ConfigKeyError",
182
+ "IOError",
183
+ "FileFormatError",
184
+ "SaveError",
185
+ "LoadError",
186
+ "ScholarError",
187
+ "SearchError",
188
+ "EnrichmentError",
189
+ "PDFDownloadError",
190
+ "DOIResolutionError",
191
+ "PDFExtractionError",
192
+ "BibTeXEnrichmentError",
193
+ "TranslatorError",
194
+ "AuthenticationError",
195
+ "PlottingError",
196
+ "FigureNotFoundError",
197
+ "AxisError",
198
+ "DataError",
199
+ "ShapeError",
200
+ "DTypeError",
201
+ "PathError",
202
+ "InvalidPathError",
203
+ "PathNotFoundError",
204
+ "TemplateError",
205
+ "TemplateViolationError",
206
+ "NNError",
207
+ "ModelError",
208
+ "StatsError",
209
+ "TestError",
210
+ # Validation helpers
211
+ "check_path",
212
+ "check_file_exists",
213
+ "check_shape_compatibility",
119
214
  ]
120
215
 
121
216
  # EOF