scitex 2.0.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (572) hide show
  1. scitex/__init__.py +73 -0
  2. scitex/__main__.py +89 -0
  3. scitex/__version__.py +14 -0
  4. scitex/_sh.py +59 -0
  5. scitex/ai/_LearningCurveLogger.py +583 -0
  6. scitex/ai/__Classifiers.py +101 -0
  7. scitex/ai/__init__.py +55 -0
  8. scitex/ai/_gen_ai/_Anthropic.py +173 -0
  9. scitex/ai/_gen_ai/_BaseGenAI.py +336 -0
  10. scitex/ai/_gen_ai/_DeepSeek.py +175 -0
  11. scitex/ai/_gen_ai/_Google.py +161 -0
  12. scitex/ai/_gen_ai/_Groq.py +97 -0
  13. scitex/ai/_gen_ai/_Llama.py +142 -0
  14. scitex/ai/_gen_ai/_OpenAI.py +230 -0
  15. scitex/ai/_gen_ai/_PARAMS.py +565 -0
  16. scitex/ai/_gen_ai/_Perplexity.py +191 -0
  17. scitex/ai/_gen_ai/__init__.py +32 -0
  18. scitex/ai/_gen_ai/_calc_cost.py +78 -0
  19. scitex/ai/_gen_ai/_format_output_func.py +183 -0
  20. scitex/ai/_gen_ai/_genai_factory.py +71 -0
  21. scitex/ai/act/__init__.py +8 -0
  22. scitex/ai/act/_define.py +11 -0
  23. scitex/ai/classification/__init__.py +7 -0
  24. scitex/ai/classification/classification_reporter.py +1137 -0
  25. scitex/ai/classification/classifier_server.py +131 -0
  26. scitex/ai/classification/classifiers.py +101 -0
  27. scitex/ai/classification_reporter.py +1161 -0
  28. scitex/ai/classifier_server.py +131 -0
  29. scitex/ai/clustering/__init__.py +11 -0
  30. scitex/ai/clustering/_pca.py +115 -0
  31. scitex/ai/clustering/_umap.py +376 -0
  32. scitex/ai/early_stopping.py +149 -0
  33. scitex/ai/feature_extraction/__init__.py +56 -0
  34. scitex/ai/feature_extraction/vit.py +148 -0
  35. scitex/ai/genai/__init__.py +277 -0
  36. scitex/ai/genai/anthropic.py +177 -0
  37. scitex/ai/genai/anthropic_provider.py +320 -0
  38. scitex/ai/genai/anthropic_refactored.py +109 -0
  39. scitex/ai/genai/auth_manager.py +200 -0
  40. scitex/ai/genai/base_genai.py +336 -0
  41. scitex/ai/genai/base_provider.py +291 -0
  42. scitex/ai/genai/calc_cost.py +78 -0
  43. scitex/ai/genai/chat_history.py +307 -0
  44. scitex/ai/genai/cost_tracker.py +276 -0
  45. scitex/ai/genai/deepseek.py +188 -0
  46. scitex/ai/genai/deepseek_provider.py +251 -0
  47. scitex/ai/genai/format_output_func.py +183 -0
  48. scitex/ai/genai/genai_factory.py +71 -0
  49. scitex/ai/genai/google.py +169 -0
  50. scitex/ai/genai/google_provider.py +228 -0
  51. scitex/ai/genai/groq.py +104 -0
  52. scitex/ai/genai/groq_provider.py +248 -0
  53. scitex/ai/genai/image_processor.py +250 -0
  54. scitex/ai/genai/llama.py +155 -0
  55. scitex/ai/genai/llama_provider.py +214 -0
  56. scitex/ai/genai/mock_provider.py +127 -0
  57. scitex/ai/genai/model_registry.py +304 -0
  58. scitex/ai/genai/openai.py +230 -0
  59. scitex/ai/genai/openai_provider.py +293 -0
  60. scitex/ai/genai/params.py +565 -0
  61. scitex/ai/genai/perplexity.py +202 -0
  62. scitex/ai/genai/perplexity_provider.py +205 -0
  63. scitex/ai/genai/provider_base.py +302 -0
  64. scitex/ai/genai/provider_factory.py +370 -0
  65. scitex/ai/genai/response_handler.py +235 -0
  66. scitex/ai/layer/_Pass.py +21 -0
  67. scitex/ai/layer/__init__.py +10 -0
  68. scitex/ai/layer/_switch.py +8 -0
  69. scitex/ai/loss/_L1L2Losses.py +34 -0
  70. scitex/ai/loss/__init__.py +12 -0
  71. scitex/ai/loss/multi_task_loss.py +47 -0
  72. scitex/ai/metrics/__init__.py +9 -0
  73. scitex/ai/metrics/_bACC.py +51 -0
  74. scitex/ai/metrics/silhoute_score_block.py +496 -0
  75. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
  76. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
  77. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
  78. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
  79. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
  80. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
  81. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
  82. scitex/ai/optim/__init__.py +13 -0
  83. scitex/ai/optim/_get_set.py +31 -0
  84. scitex/ai/optim/_optimizers.py +71 -0
  85. scitex/ai/plt/__init__.py +21 -0
  86. scitex/ai/plt/_conf_mat.py +592 -0
  87. scitex/ai/plt/_learning_curve.py +194 -0
  88. scitex/ai/plt/_optuna_study.py +111 -0
  89. scitex/ai/plt/aucs/__init__.py +2 -0
  90. scitex/ai/plt/aucs/example.py +60 -0
  91. scitex/ai/plt/aucs/pre_rec_auc.py +223 -0
  92. scitex/ai/plt/aucs/roc_auc.py +246 -0
  93. scitex/ai/sampling/undersample.py +29 -0
  94. scitex/ai/sk/__init__.py +11 -0
  95. scitex/ai/sk/_clf.py +58 -0
  96. scitex/ai/sk/_to_sktime.py +100 -0
  97. scitex/ai/sklearn/__init__.py +26 -0
  98. scitex/ai/sklearn/clf.py +58 -0
  99. scitex/ai/sklearn/to_sktime.py +100 -0
  100. scitex/ai/training/__init__.py +7 -0
  101. scitex/ai/training/early_stopping.py +150 -0
  102. scitex/ai/training/learning_curve_logger.py +555 -0
  103. scitex/ai/utils/__init__.py +22 -0
  104. scitex/ai/utils/_check_params.py +50 -0
  105. scitex/ai/utils/_default_dataset.py +46 -0
  106. scitex/ai/utils/_format_samples_for_sktime.py +26 -0
  107. scitex/ai/utils/_label_encoder.py +134 -0
  108. scitex/ai/utils/_merge_labels.py +22 -0
  109. scitex/ai/utils/_sliding_window_data_augmentation.py +11 -0
  110. scitex/ai/utils/_under_sample.py +51 -0
  111. scitex/ai/utils/_verify_n_gpus.py +16 -0
  112. scitex/ai/utils/grid_search.py +148 -0
  113. scitex/context/__init__.py +9 -0
  114. scitex/context/_suppress_output.py +38 -0
  115. scitex/db/_BaseMixins/_BaseBackupMixin.py +30 -0
  116. scitex/db/_BaseMixins/_BaseBatchMixin.py +31 -0
  117. scitex/db/_BaseMixins/_BaseBlobMixin.py +81 -0
  118. scitex/db/_BaseMixins/_BaseConnectionMixin.py +43 -0
  119. scitex/db/_BaseMixins/_BaseImportExportMixin.py +39 -0
  120. scitex/db/_BaseMixins/_BaseIndexMixin.py +29 -0
  121. scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +33 -0
  122. scitex/db/_BaseMixins/_BaseQueryMixin.py +52 -0
  123. scitex/db/_BaseMixins/_BaseRowMixin.py +32 -0
  124. scitex/db/_BaseMixins/_BaseSchemaMixin.py +44 -0
  125. scitex/db/_BaseMixins/_BaseTableMixin.py +66 -0
  126. scitex/db/_BaseMixins/_BaseTransactionMixin.py +52 -0
  127. scitex/db/_BaseMixins/__init__.py +30 -0
  128. scitex/db/_PostgreSQL.py +126 -0
  129. scitex/db/_PostgreSQLMixins/_BackupMixin.py +166 -0
  130. scitex/db/_PostgreSQLMixins/_BatchMixin.py +82 -0
  131. scitex/db/_PostgreSQLMixins/_BlobMixin.py +231 -0
  132. scitex/db/_PostgreSQLMixins/_ConnectionMixin.py +92 -0
  133. scitex/db/_PostgreSQLMixins/_ImportExportMixin.py +59 -0
  134. scitex/db/_PostgreSQLMixins/_IndexMixin.py +64 -0
  135. scitex/db/_PostgreSQLMixins/_MaintenanceMixin.py +175 -0
  136. scitex/db/_PostgreSQLMixins/_QueryMixin.py +108 -0
  137. scitex/db/_PostgreSQLMixins/_RowMixin.py +75 -0
  138. scitex/db/_PostgreSQLMixins/_SchemaMixin.py +126 -0
  139. scitex/db/_PostgreSQLMixins/_TableMixin.py +176 -0
  140. scitex/db/_PostgreSQLMixins/_TransactionMixin.py +57 -0
  141. scitex/db/_PostgreSQLMixins/__init__.py +34 -0
  142. scitex/db/_SQLite3.py +2136 -0
  143. scitex/db/_SQLite3Mixins/_BatchMixin.py +243 -0
  144. scitex/db/_SQLite3Mixins/_BlobMixin.py +229 -0
  145. scitex/db/_SQLite3Mixins/_ConnectionMixin.py +108 -0
  146. scitex/db/_SQLite3Mixins/_ImportExportMixin.py +80 -0
  147. scitex/db/_SQLite3Mixins/_IndexMixin.py +32 -0
  148. scitex/db/_SQLite3Mixins/_MaintenanceMixin.py +176 -0
  149. scitex/db/_SQLite3Mixins/_QueryMixin.py +83 -0
  150. scitex/db/_SQLite3Mixins/_RowMixin.py +75 -0
  151. scitex/db/_SQLite3Mixins/_TableMixin.py +183 -0
  152. scitex/db/_SQLite3Mixins/_TransactionMixin.py +71 -0
  153. scitex/db/_SQLite3Mixins/__init__.py +30 -0
  154. scitex/db/__init__.py +14 -0
  155. scitex/db/_delete_duplicates.py +397 -0
  156. scitex/db/_inspect.py +163 -0
  157. scitex/decorators/__init__.py +54 -0
  158. scitex/decorators/_auto_order.py +172 -0
  159. scitex/decorators/_batch_fn.py +127 -0
  160. scitex/decorators/_cache_disk.py +32 -0
  161. scitex/decorators/_cache_mem.py +12 -0
  162. scitex/decorators/_combined.py +98 -0
  163. scitex/decorators/_converters.py +282 -0
  164. scitex/decorators/_deprecated.py +26 -0
  165. scitex/decorators/_not_implemented.py +30 -0
  166. scitex/decorators/_numpy_fn.py +86 -0
  167. scitex/decorators/_pandas_fn.py +121 -0
  168. scitex/decorators/_preserve_doc.py +19 -0
  169. scitex/decorators/_signal_fn.py +95 -0
  170. scitex/decorators/_timeout.py +55 -0
  171. scitex/decorators/_torch_fn.py +136 -0
  172. scitex/decorators/_wrap.py +39 -0
  173. scitex/decorators/_xarray_fn.py +88 -0
  174. scitex/dev/__init__.py +15 -0
  175. scitex/dev/_analyze_code_flow.py +284 -0
  176. scitex/dev/_reload.py +59 -0
  177. scitex/dict/_DotDict.py +442 -0
  178. scitex/dict/__init__.py +18 -0
  179. scitex/dict/_listed_dict.py +42 -0
  180. scitex/dict/_pop_keys.py +36 -0
  181. scitex/dict/_replace.py +13 -0
  182. scitex/dict/_safe_merge.py +62 -0
  183. scitex/dict/_to_str.py +32 -0
  184. scitex/dsp/__init__.py +72 -0
  185. scitex/dsp/_crop.py +122 -0
  186. scitex/dsp/_demo_sig.py +331 -0
  187. scitex/dsp/_detect_ripples.py +212 -0
  188. scitex/dsp/_ensure_3d.py +18 -0
  189. scitex/dsp/_hilbert.py +78 -0
  190. scitex/dsp/_listen.py +702 -0
  191. scitex/dsp/_misc.py +30 -0
  192. scitex/dsp/_mne.py +32 -0
  193. scitex/dsp/_modulation_index.py +79 -0
  194. scitex/dsp/_pac.py +319 -0
  195. scitex/dsp/_psd.py +102 -0
  196. scitex/dsp/_resample.py +65 -0
  197. scitex/dsp/_time.py +36 -0
  198. scitex/dsp/_transform.py +68 -0
  199. scitex/dsp/_wavelet.py +212 -0
  200. scitex/dsp/add_noise.py +111 -0
  201. scitex/dsp/example.py +253 -0
  202. scitex/dsp/filt.py +155 -0
  203. scitex/dsp/norm.py +18 -0
  204. scitex/dsp/params.py +51 -0
  205. scitex/dsp/reference.py +43 -0
  206. scitex/dsp/template.py +25 -0
  207. scitex/dsp/utils/__init__.py +15 -0
  208. scitex/dsp/utils/_differential_bandpass_filters.py +120 -0
  209. scitex/dsp/utils/_ensure_3d.py +18 -0
  210. scitex/dsp/utils/_ensure_even_len.py +10 -0
  211. scitex/dsp/utils/_zero_pad.py +48 -0
  212. scitex/dsp/utils/filter.py +408 -0
  213. scitex/dsp/utils/pac.py +177 -0
  214. scitex/dt/__init__.py +8 -0
  215. scitex/dt/_linspace.py +130 -0
  216. scitex/etc/__init__.py +15 -0
  217. scitex/etc/wait_key.py +34 -0
  218. scitex/gen/_DimHandler.py +196 -0
  219. scitex/gen/_TimeStamper.py +244 -0
  220. scitex/gen/__init__.py +95 -0
  221. scitex/gen/_alternate_kwarg.py +13 -0
  222. scitex/gen/_cache.py +11 -0
  223. scitex/gen/_check_host.py +34 -0
  224. scitex/gen/_ci.py +12 -0
  225. scitex/gen/_close.py +222 -0
  226. scitex/gen/_embed.py +78 -0
  227. scitex/gen/_inspect_module.py +257 -0
  228. scitex/gen/_is_ipython.py +12 -0
  229. scitex/gen/_less.py +48 -0
  230. scitex/gen/_list_packages.py +139 -0
  231. scitex/gen/_mat2py.py +88 -0
  232. scitex/gen/_norm.py +170 -0
  233. scitex/gen/_paste.py +18 -0
  234. scitex/gen/_print_config.py +84 -0
  235. scitex/gen/_shell.py +48 -0
  236. scitex/gen/_src.py +111 -0
  237. scitex/gen/_start.py +451 -0
  238. scitex/gen/_symlink.py +55 -0
  239. scitex/gen/_symlog.py +27 -0
  240. scitex/gen/_tee.py +238 -0
  241. scitex/gen/_title2path.py +60 -0
  242. scitex/gen/_title_case.py +88 -0
  243. scitex/gen/_to_even.py +84 -0
  244. scitex/gen/_to_odd.py +34 -0
  245. scitex/gen/_to_rank.py +39 -0
  246. scitex/gen/_transpose.py +37 -0
  247. scitex/gen/_type.py +78 -0
  248. scitex/gen/_var_info.py +73 -0
  249. scitex/gen/_wrap.py +17 -0
  250. scitex/gen/_xml2dict.py +76 -0
  251. scitex/gen/misc.py +730 -0
  252. scitex/gen/path.py +0 -0
  253. scitex/general/__init__.py +5 -0
  254. scitex/gists/_SigMacro_processFigure_S.py +128 -0
  255. scitex/gists/_SigMacro_toBlue.py +172 -0
  256. scitex/gists/__init__.py +12 -0
  257. scitex/io/_H5Explorer.py +292 -0
  258. scitex/io/__init__.py +82 -0
  259. scitex/io/_cache.py +101 -0
  260. scitex/io/_flush.py +24 -0
  261. scitex/io/_glob.py +103 -0
  262. scitex/io/_json2md.py +113 -0
  263. scitex/io/_load.py +168 -0
  264. scitex/io/_load_configs.py +146 -0
  265. scitex/io/_load_modules/__init__.py +38 -0
  266. scitex/io/_load_modules/_catboost.py +66 -0
  267. scitex/io/_load_modules/_con.py +20 -0
  268. scitex/io/_load_modules/_db.py +24 -0
  269. scitex/io/_load_modules/_docx.py +42 -0
  270. scitex/io/_load_modules/_eeg.py +110 -0
  271. scitex/io/_load_modules/_hdf5.py +196 -0
  272. scitex/io/_load_modules/_image.py +19 -0
  273. scitex/io/_load_modules/_joblib.py +19 -0
  274. scitex/io/_load_modules/_json.py +18 -0
  275. scitex/io/_load_modules/_markdown.py +103 -0
  276. scitex/io/_load_modules/_matlab.py +37 -0
  277. scitex/io/_load_modules/_numpy.py +39 -0
  278. scitex/io/_load_modules/_optuna.py +155 -0
  279. scitex/io/_load_modules/_pandas.py +69 -0
  280. scitex/io/_load_modules/_pdf.py +31 -0
  281. scitex/io/_load_modules/_pickle.py +24 -0
  282. scitex/io/_load_modules/_torch.py +16 -0
  283. scitex/io/_load_modules/_txt.py +126 -0
  284. scitex/io/_load_modules/_xml.py +49 -0
  285. scitex/io/_load_modules/_yaml.py +23 -0
  286. scitex/io/_mv_to_tmp.py +19 -0
  287. scitex/io/_path.py +286 -0
  288. scitex/io/_reload.py +78 -0
  289. scitex/io/_save.py +539 -0
  290. scitex/io/_save_modules/__init__.py +66 -0
  291. scitex/io/_save_modules/_catboost.py +22 -0
  292. scitex/io/_save_modules/_csv.py +89 -0
  293. scitex/io/_save_modules/_excel.py +49 -0
  294. scitex/io/_save_modules/_hdf5.py +249 -0
  295. scitex/io/_save_modules/_html.py +48 -0
  296. scitex/io/_save_modules/_image.py +140 -0
  297. scitex/io/_save_modules/_joblib.py +25 -0
  298. scitex/io/_save_modules/_json.py +25 -0
  299. scitex/io/_save_modules/_listed_dfs_as_csv.py +57 -0
  300. scitex/io/_save_modules/_listed_scalars_as_csv.py +42 -0
  301. scitex/io/_save_modules/_matlab.py +24 -0
  302. scitex/io/_save_modules/_mp4.py +29 -0
  303. scitex/io/_save_modules/_numpy.py +57 -0
  304. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +38 -0
  305. scitex/io/_save_modules/_pickle.py +45 -0
  306. scitex/io/_save_modules/_plotly.py +27 -0
  307. scitex/io/_save_modules/_text.py +23 -0
  308. scitex/io/_save_modules/_torch.py +26 -0
  309. scitex/io/_save_modules/_yaml.py +29 -0
  310. scitex/life/__init__.py +10 -0
  311. scitex/life/_monitor_rain.py +49 -0
  312. scitex/linalg/__init__.py +17 -0
  313. scitex/linalg/_distance.py +63 -0
  314. scitex/linalg/_geometric_median.py +64 -0
  315. scitex/linalg/_misc.py +73 -0
  316. scitex/nn/_AxiswiseDropout.py +27 -0
  317. scitex/nn/_BNet.py +126 -0
  318. scitex/nn/_BNet_Res.py +164 -0
  319. scitex/nn/_ChannelGainChanger.py +44 -0
  320. scitex/nn/_DropoutChannels.py +50 -0
  321. scitex/nn/_Filters.py +489 -0
  322. scitex/nn/_FreqGainChanger.py +110 -0
  323. scitex/nn/_GaussianFilter.py +48 -0
  324. scitex/nn/_Hilbert.py +111 -0
  325. scitex/nn/_MNet_1000.py +157 -0
  326. scitex/nn/_ModulationIndex.py +221 -0
  327. scitex/nn/_PAC.py +414 -0
  328. scitex/nn/_PSD.py +40 -0
  329. scitex/nn/_ResNet1D.py +120 -0
  330. scitex/nn/_SpatialAttention.py +25 -0
  331. scitex/nn/_Spectrogram.py +161 -0
  332. scitex/nn/_SwapChannels.py +50 -0
  333. scitex/nn/_TransposeLayer.py +19 -0
  334. scitex/nn/_Wavelet.py +183 -0
  335. scitex/nn/__init__.py +63 -0
  336. scitex/os/__init__.py +8 -0
  337. scitex/os/_mv.py +50 -0
  338. scitex/parallel/__init__.py +8 -0
  339. scitex/parallel/_run.py +151 -0
  340. scitex/path/__init__.py +33 -0
  341. scitex/path/_clean.py +52 -0
  342. scitex/path/_find.py +108 -0
  343. scitex/path/_get_module_path.py +51 -0
  344. scitex/path/_get_spath.py +35 -0
  345. scitex/path/_getsize.py +18 -0
  346. scitex/path/_increment_version.py +87 -0
  347. scitex/path/_mk_spath.py +51 -0
  348. scitex/path/_path.py +19 -0
  349. scitex/path/_split.py +23 -0
  350. scitex/path/_this_path.py +19 -0
  351. scitex/path/_version.py +101 -0
  352. scitex/pd/__init__.py +41 -0
  353. scitex/pd/_find_indi.py +126 -0
  354. scitex/pd/_find_pval.py +113 -0
  355. scitex/pd/_force_df.py +154 -0
  356. scitex/pd/_from_xyz.py +71 -0
  357. scitex/pd/_ignore_SettingWithCopyWarning.py +34 -0
  358. scitex/pd/_melt_cols.py +81 -0
  359. scitex/pd/_merge_columns.py +221 -0
  360. scitex/pd/_mv.py +63 -0
  361. scitex/pd/_replace.py +62 -0
  362. scitex/pd/_round.py +93 -0
  363. scitex/pd/_slice.py +63 -0
  364. scitex/pd/_sort.py +91 -0
  365. scitex/pd/_to_numeric.py +53 -0
  366. scitex/pd/_to_xy.py +59 -0
  367. scitex/pd/_to_xyz.py +110 -0
  368. scitex/plt/__init__.py +36 -0
  369. scitex/plt/_subplots/_AxesWrapper.py +182 -0
  370. scitex/plt/_subplots/_AxisWrapper.py +249 -0
  371. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +414 -0
  372. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +896 -0
  373. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +368 -0
  374. scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +185 -0
  375. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +16 -0
  376. scitex/plt/_subplots/_FigWrapper.py +226 -0
  377. scitex/plt/_subplots/_SubplotsWrapper.py +171 -0
  378. scitex/plt/_subplots/__init__.py +111 -0
  379. scitex/plt/_subplots/_export_as_csv.py +232 -0
  380. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +61 -0
  381. scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +90 -0
  382. scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +49 -0
  383. scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +46 -0
  384. scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +39 -0
  385. scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +125 -0
  386. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +72 -0
  387. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +34 -0
  388. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +36 -0
  389. scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +79 -0
  390. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -0
  391. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +32 -0
  392. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +79 -0
  393. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +75 -0
  394. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +64 -0
  395. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +44 -0
  396. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +70 -0
  397. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +66 -0
  398. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +95 -0
  399. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +67 -0
  400. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +52 -0
  401. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +46 -0
  402. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +46 -0
  403. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +46 -0
  404. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +46 -0
  405. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +44 -0
  406. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +103 -0
  407. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +82 -0
  408. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +58 -0
  409. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +117 -0
  410. scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +30 -0
  411. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +51 -0
  412. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +93 -0
  413. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +94 -0
  414. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +92 -0
  415. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +65 -0
  416. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +59 -0
  417. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +58 -0
  418. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +45 -0
  419. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +70 -0
  420. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +75 -0
  421. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +75 -0
  422. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +155 -0
  423. scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +64 -0
  424. scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +77 -0
  425. scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +210 -0
  426. scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +342 -0
  427. scitex/plt/_subplots/_export_as_csv_formatters.py +115 -0
  428. scitex/plt/_tpl.py +28 -0
  429. scitex/plt/ax/__init__.py +114 -0
  430. scitex/plt/ax/_plot/__init__.py +53 -0
  431. scitex/plt/ax/_plot/_plot_circular_hist.py +124 -0
  432. scitex/plt/ax/_plot/_plot_conf_mat.py +136 -0
  433. scitex/plt/ax/_plot/_plot_cube.py +57 -0
  434. scitex/plt/ax/_plot/_plot_ecdf.py +84 -0
  435. scitex/plt/ax/_plot/_plot_fillv.py +55 -0
  436. scitex/plt/ax/_plot/_plot_heatmap.py +266 -0
  437. scitex/plt/ax/_plot/_plot_image.py +94 -0
  438. scitex/plt/ax/_plot/_plot_joyplot.py +76 -0
  439. scitex/plt/ax/_plot/_plot_raster.py +172 -0
  440. scitex/plt/ax/_plot/_plot_rectangle.py +69 -0
  441. scitex/plt/ax/_plot/_plot_scatter_hist.py +133 -0
  442. scitex/plt/ax/_plot/_plot_shaded_line.py +142 -0
  443. scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +221 -0
  444. scitex/plt/ax/_plot/_plot_violin.py +343 -0
  445. scitex/plt/ax/_style/__init__.py +38 -0
  446. scitex/plt/ax/_style/_add_marginal_ax.py +44 -0
  447. scitex/plt/ax/_style/_add_panel.py +92 -0
  448. scitex/plt/ax/_style/_extend.py +64 -0
  449. scitex/plt/ax/_style/_force_aspect.py +37 -0
  450. scitex/plt/ax/_style/_format_label.py +23 -0
  451. scitex/plt/ax/_style/_hide_spines.py +84 -0
  452. scitex/plt/ax/_style/_map_ticks.py +182 -0
  453. scitex/plt/ax/_style/_rotate_labels.py +215 -0
  454. scitex/plt/ax/_style/_sci_note.py +279 -0
  455. scitex/plt/ax/_style/_set_log_scale.py +299 -0
  456. scitex/plt/ax/_style/_set_meta.py +261 -0
  457. scitex/plt/ax/_style/_set_n_ticks.py +37 -0
  458. scitex/plt/ax/_style/_set_size.py +16 -0
  459. scitex/plt/ax/_style/_set_supxyt.py +116 -0
  460. scitex/plt/ax/_style/_set_ticks.py +276 -0
  461. scitex/plt/ax/_style/_set_xyt.py +121 -0
  462. scitex/plt/ax/_style/_share_axes.py +264 -0
  463. scitex/plt/ax/_style/_shift.py +139 -0
  464. scitex/plt/ax/_style/_show_spines.py +333 -0
  465. scitex/plt/color/_PARAMS.py +70 -0
  466. scitex/plt/color/__init__.py +52 -0
  467. scitex/plt/color/_add_hue_col.py +41 -0
  468. scitex/plt/color/_colors.py +205 -0
  469. scitex/plt/color/_get_colors_from_cmap.py +134 -0
  470. scitex/plt/color/_interpolate.py +29 -0
  471. scitex/plt/color/_vizualize_colors.py +54 -0
  472. scitex/plt/utils/__init__.py +44 -0
  473. scitex/plt/utils/_calc_bacc_from_conf_mat.py +46 -0
  474. scitex/plt/utils/_calc_nice_ticks.py +101 -0
  475. scitex/plt/utils/_close.py +68 -0
  476. scitex/plt/utils/_colorbar.py +96 -0
  477. scitex/plt/utils/_configure_mpl.py +295 -0
  478. scitex/plt/utils/_histogram_utils.py +132 -0
  479. scitex/plt/utils/_im2grid.py +70 -0
  480. scitex/plt/utils/_is_valid_axis.py +78 -0
  481. scitex/plt/utils/_mk_colorbar.py +65 -0
  482. scitex/plt/utils/_mk_patches.py +26 -0
  483. scitex/plt/utils/_scientific_captions.py +638 -0
  484. scitex/plt/utils/_scitex_config.py +223 -0
  485. scitex/reproduce/__init__.py +14 -0
  486. scitex/reproduce/_fix_seeds.py +45 -0
  487. scitex/reproduce/_gen_ID.py +55 -0
  488. scitex/reproduce/_gen_timestamp.py +35 -0
  489. scitex/res/__init__.py +5 -0
  490. scitex/resource/__init__.py +13 -0
  491. scitex/resource/_get_processor_usages.py +281 -0
  492. scitex/resource/_get_specs.py +280 -0
  493. scitex/resource/_log_processor_usages.py +190 -0
  494. scitex/resource/_utils/__init__.py +31 -0
  495. scitex/resource/_utils/_get_env_info.py +481 -0
  496. scitex/resource/limit_ram.py +33 -0
  497. scitex/scholar/__init__.py +24 -0
  498. scitex/scholar/_local_search.py +454 -0
  499. scitex/scholar/_paper.py +244 -0
  500. scitex/scholar/_pdf_downloader.py +325 -0
  501. scitex/scholar/_search.py +393 -0
  502. scitex/scholar/_vector_search.py +370 -0
  503. scitex/scholar/_web_sources.py +457 -0
  504. scitex/stats/__init__.py +31 -0
  505. scitex/stats/_calc_partial_corr.py +17 -0
  506. scitex/stats/_corr_test_multi.py +94 -0
  507. scitex/stats/_corr_test_wrapper.py +115 -0
  508. scitex/stats/_describe_wrapper.py +90 -0
  509. scitex/stats/_multiple_corrections.py +63 -0
  510. scitex/stats/_nan_stats.py +93 -0
  511. scitex/stats/_p2stars.py +116 -0
  512. scitex/stats/_p2stars_wrapper.py +56 -0
  513. scitex/stats/_statistical_tests.py +73 -0
  514. scitex/stats/desc/__init__.py +40 -0
  515. scitex/stats/desc/_describe.py +189 -0
  516. scitex/stats/desc/_nan.py +289 -0
  517. scitex/stats/desc/_real.py +94 -0
  518. scitex/stats/multiple/__init__.py +14 -0
  519. scitex/stats/multiple/_bonferroni_correction.py +72 -0
  520. scitex/stats/multiple/_fdr_correction.py +400 -0
  521. scitex/stats/multiple/_multicompair.py +28 -0
  522. scitex/stats/tests/__corr_test.py +277 -0
  523. scitex/stats/tests/__corr_test_multi.py +343 -0
  524. scitex/stats/tests/__corr_test_single.py +277 -0
  525. scitex/stats/tests/__init__.py +22 -0
  526. scitex/stats/tests/_brunner_munzel_test.py +192 -0
  527. scitex/stats/tests/_nocorrelation_test.py +28 -0
  528. scitex/stats/tests/_smirnov_grubbs.py +98 -0
  529. scitex/str/__init__.py +113 -0
  530. scitex/str/_clean_path.py +75 -0
  531. scitex/str/_color_text.py +52 -0
  532. scitex/str/_decapitalize.py +58 -0
  533. scitex/str/_factor_out_digits.py +281 -0
  534. scitex/str/_format_plot_text.py +498 -0
  535. scitex/str/_grep.py +48 -0
  536. scitex/str/_latex.py +155 -0
  537. scitex/str/_latex_fallback.py +471 -0
  538. scitex/str/_mask_api.py +39 -0
  539. scitex/str/_mask_api_key.py +8 -0
  540. scitex/str/_parse.py +158 -0
  541. scitex/str/_print_block.py +47 -0
  542. scitex/str/_print_debug.py +68 -0
  543. scitex/str/_printc.py +62 -0
  544. scitex/str/_readable_bytes.py +38 -0
  545. scitex/str/_remove_ansi.py +23 -0
  546. scitex/str/_replace.py +134 -0
  547. scitex/str/_search.py +125 -0
  548. scitex/str/_squeeze_space.py +36 -0
  549. scitex/tex/__init__.py +10 -0
  550. scitex/tex/_preview.py +103 -0
  551. scitex/tex/_to_vec.py +116 -0
  552. scitex/torch/__init__.py +18 -0
  553. scitex/torch/_apply_to.py +34 -0
  554. scitex/torch/_nan_funcs.py +77 -0
  555. scitex/types/_ArrayLike.py +44 -0
  556. scitex/types/_ColorLike.py +21 -0
  557. scitex/types/__init__.py +14 -0
  558. scitex/types/_is_listed_X.py +70 -0
  559. scitex/utils/__init__.py +22 -0
  560. scitex/utils/_compress_hdf5.py +116 -0
  561. scitex/utils/_email.py +120 -0
  562. scitex/utils/_grid.py +148 -0
  563. scitex/utils/_notify.py +247 -0
  564. scitex/utils/_search.py +121 -0
  565. scitex/web/__init__.py +38 -0
  566. scitex/web/_search_pubmed.py +438 -0
  567. scitex/web/_summarize_url.py +158 -0
  568. scitex-2.0.0.dist-info/METADATA +307 -0
  569. scitex-2.0.0.dist-info/RECORD +572 -0
  570. scitex-2.0.0.dist-info/WHEEL +6 -0
  571. scitex-2.0.0.dist-info/licenses/LICENSE +7 -0
  572. scitex-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-02-26 09:02:48 (ywatanabe)"
4
+ # File: ./src/scitex/ai/_gen_ai/_Anthropic.py
5
+
6
+ THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/ai/_gen_ai/_Anthropic.py"
7
+ #!/usr/bin/env python3
8
+ # -*- coding: utf-8 -*-
9
+ # Time-stamp: "2025-02-26 09:02:48 (ywatanabe)"
10
+ # File: ./scitex_repo/src/scitex/ai/_gen_ai/_Anthropic.py
11
+
12
+ THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/ai/_gen_ai/_Anthropic.py"
13
+
14
+ """
15
+ Functionality:
16
+ - Implements Anthropic AI (Claude) interface
17
+ - Handles both streaming and static text generation
18
+ Input:
19
+ - User prompts and chat history
20
+ - Model configurations and API credentials
21
+ Output:
22
+ - Generated text responses from Claude models
23
+ - Token usage statistics
24
+ Prerequisites:
25
+ - Anthropic API key (ANTHROPIC_API_KEY environment variable)
26
+ - anthropic package
27
+ """
28
+
29
+ """Imports"""
30
+ import os
31
+ import sys
32
+ from typing import Any, Dict, Generator, List, Optional, Union
33
+
34
+ import anthropic
35
+ import matplotlib.pyplot as plt
36
+
37
+ from .base_genai import BaseGenAI
38
+ import re
39
+
40
+
41
+ """Functions & Classes"""
42
+
43
+
44
+ class Anthropic(BaseGenAI):
45
+ def __init__(
46
+ self,
47
+ system_setting: str = "",
48
+ api_key: Optional[str] = os.getenv("ANTHROPIC_API_KEY"),
49
+ model: str = "claude-3-opus-20240229",
50
+ stream: bool = False,
51
+ seed: Optional[int] = None,
52
+ n_keep: int = 1,
53
+ temperature: float = 1.0,
54
+ chat_history: Optional[List[Dict[str, str]]] = None,
55
+ max_tokens: int = 100_000,
56
+ ) -> None:
57
+
58
+ if model == "claude-3-7-sonnet-2025-0219":
59
+ max_tokens = 128_000
60
+
61
+ api_key = api_key or os.getenv("ANTHROPIC_API_KEY")
62
+
63
+ if not api_key:
64
+ raise ValueError("ANTHROPIC_API_KEY environment variable not set")
65
+
66
+ super().__init__(
67
+ system_setting=system_setting,
68
+ model=model,
69
+ api_key=api_key,
70
+ stream=stream,
71
+ n_keep=n_keep,
72
+ temperature=temperature,
73
+ provider="Anthropic",
74
+ chat_history=chat_history,
75
+ max_tokens=max_tokens,
76
+ )
77
+
78
+ def _init_client(self) -> anthropic.Anthropic:
79
+ return anthropic.Anthropic(api_key=self.api_key)
80
+
81
+ def _api_format_history(self, history):
82
+ formatted_history = []
83
+ for msg in history:
84
+ if isinstance(msg["content"], list):
85
+ content = []
86
+ for item in msg["content"]:
87
+ if item["type"] == "text":
88
+ content.append({"type": "text", "text": item["text"]})
89
+ elif item["type"] == "_image":
90
+ content.append(
91
+ {
92
+ "type": "image",
93
+ "source": {
94
+ "type": "base64",
95
+ "media_type": "image/jpeg",
96
+ "data": item["_image"],
97
+ },
98
+ }
99
+ )
100
+ formatted_msg = {"role": msg["role"], "content": content}
101
+ else:
102
+ formatted_msg = {
103
+ "role": msg["role"],
104
+ "content": msg["content"],
105
+ }
106
+ formatted_history.append(formatted_msg)
107
+ return formatted_history
108
+
109
+ def _api_call_static(self) -> str:
110
+ output = self.client.messages.create(
111
+ model=self.model,
112
+ max_tokens=self.max_tokens,
113
+ messages=self.history,
114
+ temperature=self.temperature,
115
+ )
116
+ out_text = output.content[0].text
117
+
118
+ self.input_tokens += output.usage.input_tokens
119
+ self.output_tokens += output.usage.output_tokens
120
+
121
+ return out_text
122
+
123
+ def _api_call_stream(self) -> Generator[str, None, None]:
124
+ with self.client.messages.stream(
125
+ model=self.model,
126
+ max_tokens=self.max_tokens,
127
+ messages=self.history,
128
+ temperature=self.temperature,
129
+ ) as stream:
130
+ for chunk in stream:
131
+ try:
132
+ self.input_tokens += chunk.message.usage.input_tokens
133
+ self.output_tokens += chunk.message.usage.output_tokens
134
+ except AttributeError:
135
+ pass
136
+
137
+ if chunk.type == "content_block_delta":
138
+ yield chunk.delta.text
139
+
140
+
141
+ def main() -> None:
142
+ import scitex
143
+
144
+ ai = scitex.ai.GenAI(
145
+ model="claude-3-5-sonnet-20241022",
146
+ api_key=os.getenv("ANTHROPIC_API_KEY"),
147
+ n_keep=10,
148
+ )
149
+ print(ai("hi"))
150
+ print(ai("My name is Yusuke"))
151
+ print(ai("do you remember my name?"))
152
+
153
+ print(
154
+ ai(
155
+ "hi, could you tell me what is in the pic?",
156
+ images=[
157
+ "/home/ywatanabe/Downloads/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
158
+ ],
159
+ )
160
+ )
161
+ pass
162
+
163
+
164
+ if __name__ == "__main__":
165
+ import scitex
166
+
167
+ CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.gen.start(sys, plt, verbose=False)
168
+ main()
169
+ scitex.gen.close(CONFIG, verbose=False, notify=False)
170
+
171
+
172
+ """
173
+ python src/scitex/ai/_gen_ai/_Anthropic.py
174
+ python -m src.scitex.ai._gen_ai._Anthropic
175
+ """
176
+
177
+ # EOF
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-11-25 12:00:00"
4
+ # Author: Yusuke Watanabe (ywatanabe@alumni.u-tokyo.ac.jp)
5
+ # scitex/src/scitex/ai/genai/anthropic_provider.py
6
+
7
+ """
8
+ Anthropic provider implementation for GenAI.
9
+ """
10
+
11
+ from typing import List, Dict, Any, Optional, Generator
12
+ import logging
13
+
14
+ from .base_provider import BaseProvider, CompletionResponse
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class AnthropicProvider(BaseProvider):
20
+ """
21
+ Anthropic provider implementation.
22
+
23
+ Supports Claude 3 models (Opus, Sonnet, Haiku).
24
+ """
25
+
26
+ SUPPORTED_MODELS = [
27
+ "claude-3-opus-20240229",
28
+ "claude-3-sonnet-20240229",
29
+ "claude-3-haiku-20240307",
30
+ "claude-2.1",
31
+ "claude-2.0",
32
+ "claude-instant-1.2",
33
+ ]
34
+
35
+ DEFAULT_MODEL = "claude-3-sonnet-20240229"
36
+
37
+ def __init__(self, config):
38
+ """Initialize Anthropic provider."""
39
+ self.config = config
40
+ self.api_key = config.api_key
41
+ self.model = config.model or self.DEFAULT_MODEL
42
+ self.kwargs = config.kwargs or {}
43
+
44
+ # Import Anthropic client
45
+ try:
46
+ from anthropic import Anthropic as AnthropicClient
47
+
48
+ self.client = AnthropicClient(api_key=api_key)
49
+ except ImportError:
50
+ raise ImportError(
51
+ "Anthropic package not installed. Install with: pip install anthropic"
52
+ )
53
+
54
+ def complete(self, messages: List[Dict[str, Any]], **kwargs) -> CompletionResponse:
55
+ """
56
+ Generate completion using Anthropic API.
57
+
58
+ Args:
59
+ messages: List of message dictionaries
60
+ **kwargs: Additional parameters (max_tokens, temperature, etc.)
61
+
62
+ Returns:
63
+ CompletionResponse with generated text and usage info
64
+ """
65
+ # Validate messages
66
+ if not self.validate_messages(messages):
67
+ raise ValueError("Invalid message format")
68
+
69
+ # Format messages for Anthropic
70
+ formatted_messages = self.format_messages(messages)
71
+
72
+ # Extract system message if present
73
+ system_message = None
74
+ user_messages = []
75
+
76
+ for msg in formatted_messages:
77
+ if msg["role"] == "system":
78
+ system_message = msg["content"]
79
+ else:
80
+ user_messages.append(msg)
81
+
82
+ # Prepare API parameters
83
+ api_params = {
84
+ "model": self.model,
85
+ "messages": user_messages,
86
+ "max_tokens": kwargs.get("max_tokens", 4096),
87
+ }
88
+
89
+ # Add system message if present
90
+ if system_message:
91
+ api_params["system"] = system_message
92
+
93
+ # Add optional parameters
94
+ for param in ["temperature", "top_p", "top_k", "stop_sequences"]:
95
+ if param in kwargs:
96
+ api_params[param] = kwargs[param]
97
+
98
+ try:
99
+ # Make API call
100
+ response = self.client.messages.create(**api_params)
101
+
102
+ # Extract content
103
+ content = response.content[0].text if response.content else ""
104
+
105
+ # Extract usage
106
+ usage = {
107
+ "prompt_tokens": response.usage.input_tokens,
108
+ "completion_tokens": response.usage.output_tokens,
109
+ "total_tokens": response.usage.input_tokens
110
+ + response.usage.output_tokens,
111
+ }
112
+
113
+ return CompletionResponse(content=content, usage=usage)
114
+
115
+ except Exception as e:
116
+ logger.error(f"Anthropic API error: {str(e)}")
117
+ raise
118
+
119
+ def format_messages(self, messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
120
+ """
121
+ Format messages for Anthropic API.
122
+
123
+ Anthropic expects messages in the format::
124
+
125
+ [
126
+ {"role": "user", "content": "..."},
127
+ {"role": "assistant", "content": "..."}
128
+ ]
129
+
130
+ System messages are passed separately.
131
+
132
+ For images, the content should be a list::
133
+
134
+ {
135
+ "role": "user",
136
+ "content": [
137
+ {"type": "text", "text": "What's in this image?"},
138
+ {"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": "..."}}
139
+ ]
140
+ }
141
+ """
142
+ formatted_messages = []
143
+
144
+ for msg in messages:
145
+ role = msg["role"]
146
+ content = msg["content"]
147
+ images = msg.get("images", [])
148
+
149
+ if images and self.model.startswith("claude-3"):
150
+ # Format with images (only Claude 3 supports images)
151
+ content_parts = [{"type": "text", "text": content}]
152
+
153
+ for img in images:
154
+ if img.startswith("data:"):
155
+ # Extract base64 data
156
+ header, data = img.split(",", 1)
157
+ media_type = header.split(":")[1].split(";")[0]
158
+
159
+ content_parts.append(
160
+ {
161
+ "type": "image",
162
+ "source": {
163
+ "type": "base64",
164
+ "media_type": media_type,
165
+ "data": data,
166
+ },
167
+ }
168
+ )
169
+ else:
170
+ # URL images not directly supported, would need to download first
171
+ logger.warning("URL images not directly supported by Anthropic")
172
+
173
+ formatted_messages.append({"role": role, "content": content_parts})
174
+ else:
175
+ # Regular text message
176
+ formatted_messages.append({"role": role, "content": content})
177
+
178
+ return formatted_messages
179
+
180
+ def validate_messages(self, messages: List[Dict[str, Any]]) -> bool:
181
+ """Validate message format."""
182
+ if not messages:
183
+ return False
184
+
185
+ for msg in messages:
186
+ if not isinstance(msg, dict):
187
+ return False
188
+ if "role" not in msg or "content" not in msg:
189
+ return False
190
+ if msg["role"] not in ["system", "user", "assistant"]:
191
+ return False
192
+
193
+ return True
194
+
195
+ def stream(
196
+ self, messages: List[Dict[str, Any]], **kwargs
197
+ ) -> Generator[str, None, CompletionResponse]:
198
+ """Generate a streaming completion.
199
+
200
+ Args:
201
+ messages: List of messages in standard format
202
+ **kwargs: Additional parameters
203
+
204
+ Yields:
205
+ Text chunks during streaming
206
+
207
+ Returns:
208
+ Final CompletionResponse when complete
209
+ """
210
+ # Validate messages
211
+ if not self.validate_messages(messages):
212
+ raise ValueError("Invalid message format")
213
+
214
+ # Format messages for Anthropic
215
+ formatted_messages = self.format_messages(messages)
216
+
217
+ # Extract system message if present
218
+ system_message = None
219
+ user_messages = []
220
+
221
+ for msg in formatted_messages:
222
+ if msg["role"] == "system":
223
+ system_message = msg["content"]
224
+ else:
225
+ user_messages.append(msg)
226
+
227
+ # Prepare API parameters
228
+ api_params = {
229
+ "model": self.model,
230
+ "messages": user_messages,
231
+ "max_tokens": kwargs.get("max_tokens", 4096),
232
+ "stream": True,
233
+ }
234
+
235
+ # Add system message if present
236
+ if system_message:
237
+ api_params["system"] = system_message
238
+
239
+ # Add optional parameters
240
+ for param in ["temperature", "top_p", "top_k", "stop_sequences"]:
241
+ if param in kwargs:
242
+ api_params[param] = kwargs[param]
243
+
244
+ try:
245
+ # Make streaming API call
246
+ full_content = ""
247
+ prompt_tokens = 0
248
+ completion_tokens = 0
249
+
250
+ with self.client.messages.stream(**api_params) as stream:
251
+ for text in stream.text_stream:
252
+ full_content += text
253
+ yield text
254
+
255
+ # Get final message with usage info
256
+ message = stream.get_final_message()
257
+ if hasattr(message, "usage"):
258
+ prompt_tokens = message.usage.input_tokens
259
+ completion_tokens = message.usage.output_tokens
260
+
261
+ # Return final response
262
+ return CompletionResponse(
263
+ content=full_content,
264
+ usage={
265
+ "prompt_tokens": prompt_tokens,
266
+ "completion_tokens": completion_tokens,
267
+ "total_tokens": prompt_tokens + completion_tokens,
268
+ },
269
+ )
270
+
271
+ except Exception as e:
272
+ logger.error(f"Anthropic streaming error: {str(e)}")
273
+ raise
274
+
275
+ def count_tokens(self, text: str) -> int:
276
+ """Count tokens in the given text.
277
+
278
+ Args:
279
+ text: Text to count tokens for
280
+
281
+ Returns:
282
+ Number of tokens
283
+ """
284
+ try:
285
+ # Anthropic uses its own tokenizer
286
+ return self.client.count_tokens(text)
287
+ except Exception:
288
+ # Fallback: rough estimate (Claude tends to use fewer tokens than GPT)
289
+ return len(text.split()) * 3 // 4
290
+
291
+ @property
292
+ def supports_images(self) -> bool:
293
+ """Check if this provider/model supports image inputs."""
294
+ # Only Claude 3 models support images
295
+ return self.model.startswith("claude-3")
296
+
297
+ @property
298
+ def supports_streaming(self) -> bool:
299
+ """Check if this provider/model supports streaming."""
300
+ return True # All Anthropic models support streaming
301
+
302
+ @property
303
+ def max_context_length(self) -> int:
304
+ """Get maximum context length for this model."""
305
+ context_lengths = {
306
+ "claude-3-opus-20240229": 200000,
307
+ "claude-3-sonnet-20240229": 200000,
308
+ "claude-3-haiku-20240307": 200000,
309
+ "claude-2.1": 200000,
310
+ "claude-2.0": 100000,
311
+ "claude-instant-1.2": 100000,
312
+ }
313
+ return context_lengths.get(self.model, 100000)
314
+
315
+
316
+ # Auto-register when module is imported
317
+ from .base_provider import Provider
318
+ from .provider_factory import register_provider
319
+
320
+ register_provider(Provider.ANTHROPIC.value, AnthropicProvider)
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env python3
2
+ """Refactored Anthropic provider using component architecture."""
3
+
4
+ from typing import List, Dict, Any, Generator
5
+ import anthropic
6
+
7
+ from .provider_base import ProviderBase, ProviderConfig
8
+
9
+
10
+ class AnthropicProvider(ProviderBase):
11
+ """Anthropic (Claude) provider implementation."""
12
+
13
+ def _init_client(self) -> anthropic.Anthropic:
14
+ """Initialize Anthropic client."""
15
+ client_config = self.auth.get_client_config()
16
+ return anthropic.Anthropic(**client_config)
17
+
18
+ def _api_call(self, messages: List[Dict[str, Any]]) -> Any:
19
+ """Make a non-streaming API call to Anthropic."""
20
+ # Extract system prompt if present
21
+ system_prompt = None
22
+ filtered_messages = []
23
+
24
+ for msg in messages:
25
+ if msg["role"] == "system":
26
+ system_prompt = msg["content"]
27
+ else:
28
+ filtered_messages.append(msg)
29
+
30
+ # Make API call
31
+ response = self.client.messages.create(
32
+ model=self.config.model,
33
+ messages=filtered_messages,
34
+ max_tokens=self.config.max_tokens,
35
+ temperature=self.config.temperature,
36
+ system=system_prompt or self.config.system_prompt,
37
+ stream=False,
38
+ )
39
+
40
+ return response
41
+
42
+ def _api_stream(self, messages: List[Dict[str, Any]]) -> Generator[Any, None, None]:
43
+ """Make a streaming API call to Anthropic."""
44
+ # Extract system prompt
45
+ system_prompt = None
46
+ filtered_messages = []
47
+
48
+ for msg in messages:
49
+ if msg["role"] == "system":
50
+ system_prompt = msg["content"]
51
+ else:
52
+ filtered_messages.append(msg)
53
+
54
+ # Make streaming API call
55
+ stream = self.client.messages.create(
56
+ model=self.config.model,
57
+ messages=filtered_messages,
58
+ max_tokens=self.config.max_tokens,
59
+ temperature=self.config.temperature,
60
+ system=system_prompt or self.config.system_prompt,
61
+ stream=True,
62
+ )
63
+
64
+ for chunk in stream:
65
+ yield chunk
66
+
67
+ def _extract_token_counts(self, response: Any) -> tuple[int, int]:
68
+ """Extract token counts from Anthropic response."""
69
+ input_tokens = getattr(response.usage, "input_tokens", 0)
70
+ output_tokens = getattr(response.usage, "output_tokens", 0)
71
+ return input_tokens, output_tokens
72
+
73
+ def count_tokens(self, text: str) -> int:
74
+ """Count tokens using Anthropic's tokenizer."""
75
+ # Anthropic doesn't provide a public tokenizer
76
+ # Use approximation for now
77
+ # Claude's tokenization is roughly 1 token per 3.5 characters
78
+ return len(text) // 3
79
+
80
+
81
+ # Example usage:
82
+ if __name__ == "__main__":
83
+ # Create configuration
84
+ config = ProviderConfig(
85
+ provider="anthropic",
86
+ model="claude-3-opus-20240229",
87
+ system_prompt="You are a helpful assistant.",
88
+ temperature=0.7,
89
+ max_tokens=1024,
90
+ )
91
+
92
+ # Create provider instance
93
+ claude = AnthropicProvider(config)
94
+
95
+ # Use it
96
+ messages = [{"role": "user", "content": "Hello, how are you?"}]
97
+
98
+ # Non-streaming
99
+ response = claude.complete(messages)
100
+ print(response.content)
101
+ print(f"Tokens: {response.input_tokens} in, {response.output_tokens} out")
102
+
103
+ # Streaming
104
+ print("\nStreaming response:")
105
+ for chunk in claude.stream(messages):
106
+ print(chunk, end="", flush=True)
107
+
108
+ # Get cost summary
109
+ print("\n\n" + claude.get_cost_summary())