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.
- scitex/__init__.py +73 -0
- scitex/__main__.py +89 -0
- scitex/__version__.py +14 -0
- scitex/_sh.py +59 -0
- scitex/ai/_LearningCurveLogger.py +583 -0
- scitex/ai/__Classifiers.py +101 -0
- scitex/ai/__init__.py +55 -0
- scitex/ai/_gen_ai/_Anthropic.py +173 -0
- scitex/ai/_gen_ai/_BaseGenAI.py +336 -0
- scitex/ai/_gen_ai/_DeepSeek.py +175 -0
- scitex/ai/_gen_ai/_Google.py +161 -0
- scitex/ai/_gen_ai/_Groq.py +97 -0
- scitex/ai/_gen_ai/_Llama.py +142 -0
- scitex/ai/_gen_ai/_OpenAI.py +230 -0
- scitex/ai/_gen_ai/_PARAMS.py +565 -0
- scitex/ai/_gen_ai/_Perplexity.py +191 -0
- scitex/ai/_gen_ai/__init__.py +32 -0
- scitex/ai/_gen_ai/_calc_cost.py +78 -0
- scitex/ai/_gen_ai/_format_output_func.py +183 -0
- scitex/ai/_gen_ai/_genai_factory.py +71 -0
- scitex/ai/act/__init__.py +8 -0
- scitex/ai/act/_define.py +11 -0
- scitex/ai/classification/__init__.py +7 -0
- scitex/ai/classification/classification_reporter.py +1137 -0
- scitex/ai/classification/classifier_server.py +131 -0
- scitex/ai/classification/classifiers.py +101 -0
- scitex/ai/classification_reporter.py +1161 -0
- scitex/ai/classifier_server.py +131 -0
- scitex/ai/clustering/__init__.py +11 -0
- scitex/ai/clustering/_pca.py +115 -0
- scitex/ai/clustering/_umap.py +376 -0
- scitex/ai/early_stopping.py +149 -0
- scitex/ai/feature_extraction/__init__.py +56 -0
- scitex/ai/feature_extraction/vit.py +148 -0
- scitex/ai/genai/__init__.py +277 -0
- scitex/ai/genai/anthropic.py +177 -0
- scitex/ai/genai/anthropic_provider.py +320 -0
- scitex/ai/genai/anthropic_refactored.py +109 -0
- scitex/ai/genai/auth_manager.py +200 -0
- scitex/ai/genai/base_genai.py +336 -0
- scitex/ai/genai/base_provider.py +291 -0
- scitex/ai/genai/calc_cost.py +78 -0
- scitex/ai/genai/chat_history.py +307 -0
- scitex/ai/genai/cost_tracker.py +276 -0
- scitex/ai/genai/deepseek.py +188 -0
- scitex/ai/genai/deepseek_provider.py +251 -0
- scitex/ai/genai/format_output_func.py +183 -0
- scitex/ai/genai/genai_factory.py +71 -0
- scitex/ai/genai/google.py +169 -0
- scitex/ai/genai/google_provider.py +228 -0
- scitex/ai/genai/groq.py +104 -0
- scitex/ai/genai/groq_provider.py +248 -0
- scitex/ai/genai/image_processor.py +250 -0
- scitex/ai/genai/llama.py +155 -0
- scitex/ai/genai/llama_provider.py +214 -0
- scitex/ai/genai/mock_provider.py +127 -0
- scitex/ai/genai/model_registry.py +304 -0
- scitex/ai/genai/openai.py +230 -0
- scitex/ai/genai/openai_provider.py +293 -0
- scitex/ai/genai/params.py +565 -0
- scitex/ai/genai/perplexity.py +202 -0
- scitex/ai/genai/perplexity_provider.py +205 -0
- scitex/ai/genai/provider_base.py +302 -0
- scitex/ai/genai/provider_factory.py +370 -0
- scitex/ai/genai/response_handler.py +235 -0
- scitex/ai/layer/_Pass.py +21 -0
- scitex/ai/layer/__init__.py +10 -0
- scitex/ai/layer/_switch.py +8 -0
- scitex/ai/loss/_L1L2Losses.py +34 -0
- scitex/ai/loss/__init__.py +12 -0
- scitex/ai/loss/multi_task_loss.py +47 -0
- scitex/ai/metrics/__init__.py +9 -0
- scitex/ai/metrics/_bACC.py +51 -0
- scitex/ai/metrics/silhoute_score_block.py +496 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ai/optim/__init__.py +13 -0
- scitex/ai/optim/_get_set.py +31 -0
- scitex/ai/optim/_optimizers.py +71 -0
- scitex/ai/plt/__init__.py +21 -0
- scitex/ai/plt/_conf_mat.py +592 -0
- scitex/ai/plt/_learning_curve.py +194 -0
- scitex/ai/plt/_optuna_study.py +111 -0
- scitex/ai/plt/aucs/__init__.py +2 -0
- scitex/ai/plt/aucs/example.py +60 -0
- scitex/ai/plt/aucs/pre_rec_auc.py +223 -0
- scitex/ai/plt/aucs/roc_auc.py +246 -0
- scitex/ai/sampling/undersample.py +29 -0
- scitex/ai/sk/__init__.py +11 -0
- scitex/ai/sk/_clf.py +58 -0
- scitex/ai/sk/_to_sktime.py +100 -0
- scitex/ai/sklearn/__init__.py +26 -0
- scitex/ai/sklearn/clf.py +58 -0
- scitex/ai/sklearn/to_sktime.py +100 -0
- scitex/ai/training/__init__.py +7 -0
- scitex/ai/training/early_stopping.py +150 -0
- scitex/ai/training/learning_curve_logger.py +555 -0
- scitex/ai/utils/__init__.py +22 -0
- scitex/ai/utils/_check_params.py +50 -0
- scitex/ai/utils/_default_dataset.py +46 -0
- scitex/ai/utils/_format_samples_for_sktime.py +26 -0
- scitex/ai/utils/_label_encoder.py +134 -0
- scitex/ai/utils/_merge_labels.py +22 -0
- scitex/ai/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ai/utils/_under_sample.py +51 -0
- scitex/ai/utils/_verify_n_gpus.py +16 -0
- scitex/ai/utils/grid_search.py +148 -0
- scitex/context/__init__.py +9 -0
- scitex/context/_suppress_output.py +38 -0
- scitex/db/_BaseMixins/_BaseBackupMixin.py +30 -0
- scitex/db/_BaseMixins/_BaseBatchMixin.py +31 -0
- scitex/db/_BaseMixins/_BaseBlobMixin.py +81 -0
- scitex/db/_BaseMixins/_BaseConnectionMixin.py +43 -0
- scitex/db/_BaseMixins/_BaseImportExportMixin.py +39 -0
- scitex/db/_BaseMixins/_BaseIndexMixin.py +29 -0
- scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +33 -0
- scitex/db/_BaseMixins/_BaseQueryMixin.py +52 -0
- scitex/db/_BaseMixins/_BaseRowMixin.py +32 -0
- scitex/db/_BaseMixins/_BaseSchemaMixin.py +44 -0
- scitex/db/_BaseMixins/_BaseTableMixin.py +66 -0
- scitex/db/_BaseMixins/_BaseTransactionMixin.py +52 -0
- scitex/db/_BaseMixins/__init__.py +30 -0
- scitex/db/_PostgreSQL.py +126 -0
- scitex/db/_PostgreSQLMixins/_BackupMixin.py +166 -0
- scitex/db/_PostgreSQLMixins/_BatchMixin.py +82 -0
- scitex/db/_PostgreSQLMixins/_BlobMixin.py +231 -0
- scitex/db/_PostgreSQLMixins/_ConnectionMixin.py +92 -0
- scitex/db/_PostgreSQLMixins/_ImportExportMixin.py +59 -0
- scitex/db/_PostgreSQLMixins/_IndexMixin.py +64 -0
- scitex/db/_PostgreSQLMixins/_MaintenanceMixin.py +175 -0
- scitex/db/_PostgreSQLMixins/_QueryMixin.py +108 -0
- scitex/db/_PostgreSQLMixins/_RowMixin.py +75 -0
- scitex/db/_PostgreSQLMixins/_SchemaMixin.py +126 -0
- scitex/db/_PostgreSQLMixins/_TableMixin.py +176 -0
- scitex/db/_PostgreSQLMixins/_TransactionMixin.py +57 -0
- scitex/db/_PostgreSQLMixins/__init__.py +34 -0
- scitex/db/_SQLite3.py +2136 -0
- scitex/db/_SQLite3Mixins/_BatchMixin.py +243 -0
- scitex/db/_SQLite3Mixins/_BlobMixin.py +229 -0
- scitex/db/_SQLite3Mixins/_ConnectionMixin.py +108 -0
- scitex/db/_SQLite3Mixins/_ImportExportMixin.py +80 -0
- scitex/db/_SQLite3Mixins/_IndexMixin.py +32 -0
- scitex/db/_SQLite3Mixins/_MaintenanceMixin.py +176 -0
- scitex/db/_SQLite3Mixins/_QueryMixin.py +83 -0
- scitex/db/_SQLite3Mixins/_RowMixin.py +75 -0
- scitex/db/_SQLite3Mixins/_TableMixin.py +183 -0
- scitex/db/_SQLite3Mixins/_TransactionMixin.py +71 -0
- scitex/db/_SQLite3Mixins/__init__.py +30 -0
- scitex/db/__init__.py +14 -0
- scitex/db/_delete_duplicates.py +397 -0
- scitex/db/_inspect.py +163 -0
- scitex/decorators/__init__.py +54 -0
- scitex/decorators/_auto_order.py +172 -0
- scitex/decorators/_batch_fn.py +127 -0
- scitex/decorators/_cache_disk.py +32 -0
- scitex/decorators/_cache_mem.py +12 -0
- scitex/decorators/_combined.py +98 -0
- scitex/decorators/_converters.py +282 -0
- scitex/decorators/_deprecated.py +26 -0
- scitex/decorators/_not_implemented.py +30 -0
- scitex/decorators/_numpy_fn.py +86 -0
- scitex/decorators/_pandas_fn.py +121 -0
- scitex/decorators/_preserve_doc.py +19 -0
- scitex/decorators/_signal_fn.py +95 -0
- scitex/decorators/_timeout.py +55 -0
- scitex/decorators/_torch_fn.py +136 -0
- scitex/decorators/_wrap.py +39 -0
- scitex/decorators/_xarray_fn.py +88 -0
- scitex/dev/__init__.py +15 -0
- scitex/dev/_analyze_code_flow.py +284 -0
- scitex/dev/_reload.py +59 -0
- scitex/dict/_DotDict.py +442 -0
- scitex/dict/__init__.py +18 -0
- scitex/dict/_listed_dict.py +42 -0
- scitex/dict/_pop_keys.py +36 -0
- scitex/dict/_replace.py +13 -0
- scitex/dict/_safe_merge.py +62 -0
- scitex/dict/_to_str.py +32 -0
- scitex/dsp/__init__.py +72 -0
- scitex/dsp/_crop.py +122 -0
- scitex/dsp/_demo_sig.py +331 -0
- scitex/dsp/_detect_ripples.py +212 -0
- scitex/dsp/_ensure_3d.py +18 -0
- scitex/dsp/_hilbert.py +78 -0
- scitex/dsp/_listen.py +702 -0
- scitex/dsp/_misc.py +30 -0
- scitex/dsp/_mne.py +32 -0
- scitex/dsp/_modulation_index.py +79 -0
- scitex/dsp/_pac.py +319 -0
- scitex/dsp/_psd.py +102 -0
- scitex/dsp/_resample.py +65 -0
- scitex/dsp/_time.py +36 -0
- scitex/dsp/_transform.py +68 -0
- scitex/dsp/_wavelet.py +212 -0
- scitex/dsp/add_noise.py +111 -0
- scitex/dsp/example.py +253 -0
- scitex/dsp/filt.py +155 -0
- scitex/dsp/norm.py +18 -0
- scitex/dsp/params.py +51 -0
- scitex/dsp/reference.py +43 -0
- scitex/dsp/template.py +25 -0
- scitex/dsp/utils/__init__.py +15 -0
- scitex/dsp/utils/_differential_bandpass_filters.py +120 -0
- scitex/dsp/utils/_ensure_3d.py +18 -0
- scitex/dsp/utils/_ensure_even_len.py +10 -0
- scitex/dsp/utils/_zero_pad.py +48 -0
- scitex/dsp/utils/filter.py +408 -0
- scitex/dsp/utils/pac.py +177 -0
- scitex/dt/__init__.py +8 -0
- scitex/dt/_linspace.py +130 -0
- scitex/etc/__init__.py +15 -0
- scitex/etc/wait_key.py +34 -0
- scitex/gen/_DimHandler.py +196 -0
- scitex/gen/_TimeStamper.py +244 -0
- scitex/gen/__init__.py +95 -0
- scitex/gen/_alternate_kwarg.py +13 -0
- scitex/gen/_cache.py +11 -0
- scitex/gen/_check_host.py +34 -0
- scitex/gen/_ci.py +12 -0
- scitex/gen/_close.py +222 -0
- scitex/gen/_embed.py +78 -0
- scitex/gen/_inspect_module.py +257 -0
- scitex/gen/_is_ipython.py +12 -0
- scitex/gen/_less.py +48 -0
- scitex/gen/_list_packages.py +139 -0
- scitex/gen/_mat2py.py +88 -0
- scitex/gen/_norm.py +170 -0
- scitex/gen/_paste.py +18 -0
- scitex/gen/_print_config.py +84 -0
- scitex/gen/_shell.py +48 -0
- scitex/gen/_src.py +111 -0
- scitex/gen/_start.py +451 -0
- scitex/gen/_symlink.py +55 -0
- scitex/gen/_symlog.py +27 -0
- scitex/gen/_tee.py +238 -0
- scitex/gen/_title2path.py +60 -0
- scitex/gen/_title_case.py +88 -0
- scitex/gen/_to_even.py +84 -0
- scitex/gen/_to_odd.py +34 -0
- scitex/gen/_to_rank.py +39 -0
- scitex/gen/_transpose.py +37 -0
- scitex/gen/_type.py +78 -0
- scitex/gen/_var_info.py +73 -0
- scitex/gen/_wrap.py +17 -0
- scitex/gen/_xml2dict.py +76 -0
- scitex/gen/misc.py +730 -0
- scitex/gen/path.py +0 -0
- scitex/general/__init__.py +5 -0
- scitex/gists/_SigMacro_processFigure_S.py +128 -0
- scitex/gists/_SigMacro_toBlue.py +172 -0
- scitex/gists/__init__.py +12 -0
- scitex/io/_H5Explorer.py +292 -0
- scitex/io/__init__.py +82 -0
- scitex/io/_cache.py +101 -0
- scitex/io/_flush.py +24 -0
- scitex/io/_glob.py +103 -0
- scitex/io/_json2md.py +113 -0
- scitex/io/_load.py +168 -0
- scitex/io/_load_configs.py +146 -0
- scitex/io/_load_modules/__init__.py +38 -0
- scitex/io/_load_modules/_catboost.py +66 -0
- scitex/io/_load_modules/_con.py +20 -0
- scitex/io/_load_modules/_db.py +24 -0
- scitex/io/_load_modules/_docx.py +42 -0
- scitex/io/_load_modules/_eeg.py +110 -0
- scitex/io/_load_modules/_hdf5.py +196 -0
- scitex/io/_load_modules/_image.py +19 -0
- scitex/io/_load_modules/_joblib.py +19 -0
- scitex/io/_load_modules/_json.py +18 -0
- scitex/io/_load_modules/_markdown.py +103 -0
- scitex/io/_load_modules/_matlab.py +37 -0
- scitex/io/_load_modules/_numpy.py +39 -0
- scitex/io/_load_modules/_optuna.py +155 -0
- scitex/io/_load_modules/_pandas.py +69 -0
- scitex/io/_load_modules/_pdf.py +31 -0
- scitex/io/_load_modules/_pickle.py +24 -0
- scitex/io/_load_modules/_torch.py +16 -0
- scitex/io/_load_modules/_txt.py +126 -0
- scitex/io/_load_modules/_xml.py +49 -0
- scitex/io/_load_modules/_yaml.py +23 -0
- scitex/io/_mv_to_tmp.py +19 -0
- scitex/io/_path.py +286 -0
- scitex/io/_reload.py +78 -0
- scitex/io/_save.py +539 -0
- scitex/io/_save_modules/__init__.py +66 -0
- scitex/io/_save_modules/_catboost.py +22 -0
- scitex/io/_save_modules/_csv.py +89 -0
- scitex/io/_save_modules/_excel.py +49 -0
- scitex/io/_save_modules/_hdf5.py +249 -0
- scitex/io/_save_modules/_html.py +48 -0
- scitex/io/_save_modules/_image.py +140 -0
- scitex/io/_save_modules/_joblib.py +25 -0
- scitex/io/_save_modules/_json.py +25 -0
- scitex/io/_save_modules/_listed_dfs_as_csv.py +57 -0
- scitex/io/_save_modules/_listed_scalars_as_csv.py +42 -0
- scitex/io/_save_modules/_matlab.py +24 -0
- scitex/io/_save_modules/_mp4.py +29 -0
- scitex/io/_save_modules/_numpy.py +57 -0
- scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +38 -0
- scitex/io/_save_modules/_pickle.py +45 -0
- scitex/io/_save_modules/_plotly.py +27 -0
- scitex/io/_save_modules/_text.py +23 -0
- scitex/io/_save_modules/_torch.py +26 -0
- scitex/io/_save_modules/_yaml.py +29 -0
- scitex/life/__init__.py +10 -0
- scitex/life/_monitor_rain.py +49 -0
- scitex/linalg/__init__.py +17 -0
- scitex/linalg/_distance.py +63 -0
- scitex/linalg/_geometric_median.py +64 -0
- scitex/linalg/_misc.py +73 -0
- scitex/nn/_AxiswiseDropout.py +27 -0
- scitex/nn/_BNet.py +126 -0
- scitex/nn/_BNet_Res.py +164 -0
- scitex/nn/_ChannelGainChanger.py +44 -0
- scitex/nn/_DropoutChannels.py +50 -0
- scitex/nn/_Filters.py +489 -0
- scitex/nn/_FreqGainChanger.py +110 -0
- scitex/nn/_GaussianFilter.py +48 -0
- scitex/nn/_Hilbert.py +111 -0
- scitex/nn/_MNet_1000.py +157 -0
- scitex/nn/_ModulationIndex.py +221 -0
- scitex/nn/_PAC.py +414 -0
- scitex/nn/_PSD.py +40 -0
- scitex/nn/_ResNet1D.py +120 -0
- scitex/nn/_SpatialAttention.py +25 -0
- scitex/nn/_Spectrogram.py +161 -0
- scitex/nn/_SwapChannels.py +50 -0
- scitex/nn/_TransposeLayer.py +19 -0
- scitex/nn/_Wavelet.py +183 -0
- scitex/nn/__init__.py +63 -0
- scitex/os/__init__.py +8 -0
- scitex/os/_mv.py +50 -0
- scitex/parallel/__init__.py +8 -0
- scitex/parallel/_run.py +151 -0
- scitex/path/__init__.py +33 -0
- scitex/path/_clean.py +52 -0
- scitex/path/_find.py +108 -0
- scitex/path/_get_module_path.py +51 -0
- scitex/path/_get_spath.py +35 -0
- scitex/path/_getsize.py +18 -0
- scitex/path/_increment_version.py +87 -0
- scitex/path/_mk_spath.py +51 -0
- scitex/path/_path.py +19 -0
- scitex/path/_split.py +23 -0
- scitex/path/_this_path.py +19 -0
- scitex/path/_version.py +101 -0
- scitex/pd/__init__.py +41 -0
- scitex/pd/_find_indi.py +126 -0
- scitex/pd/_find_pval.py +113 -0
- scitex/pd/_force_df.py +154 -0
- scitex/pd/_from_xyz.py +71 -0
- scitex/pd/_ignore_SettingWithCopyWarning.py +34 -0
- scitex/pd/_melt_cols.py +81 -0
- scitex/pd/_merge_columns.py +221 -0
- scitex/pd/_mv.py +63 -0
- scitex/pd/_replace.py +62 -0
- scitex/pd/_round.py +93 -0
- scitex/pd/_slice.py +63 -0
- scitex/pd/_sort.py +91 -0
- scitex/pd/_to_numeric.py +53 -0
- scitex/pd/_to_xy.py +59 -0
- scitex/pd/_to_xyz.py +110 -0
- scitex/plt/__init__.py +36 -0
- scitex/plt/_subplots/_AxesWrapper.py +182 -0
- scitex/plt/_subplots/_AxisWrapper.py +249 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +414 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +896 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +368 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +185 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +16 -0
- scitex/plt/_subplots/_FigWrapper.py +226 -0
- scitex/plt/_subplots/_SubplotsWrapper.py +171 -0
- scitex/plt/_subplots/__init__.py +111 -0
- scitex/plt/_subplots/_export_as_csv.py +232 -0
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +61 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +90 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +49 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +39 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +125 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +72 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +34 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +36 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +79 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +32 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +79 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +64 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +44 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +70 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +66 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +95 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +67 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +52 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +44 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +103 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +82 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +58 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +117 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +30 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +51 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +93 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +94 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +92 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +65 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +59 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +58 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +45 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +70 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +155 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +64 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +77 -0
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +210 -0
- scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +342 -0
- scitex/plt/_subplots/_export_as_csv_formatters.py +115 -0
- scitex/plt/_tpl.py +28 -0
- scitex/plt/ax/__init__.py +114 -0
- scitex/plt/ax/_plot/__init__.py +53 -0
- scitex/plt/ax/_plot/_plot_circular_hist.py +124 -0
- scitex/plt/ax/_plot/_plot_conf_mat.py +136 -0
- scitex/plt/ax/_plot/_plot_cube.py +57 -0
- scitex/plt/ax/_plot/_plot_ecdf.py +84 -0
- scitex/plt/ax/_plot/_plot_fillv.py +55 -0
- scitex/plt/ax/_plot/_plot_heatmap.py +266 -0
- scitex/plt/ax/_plot/_plot_image.py +94 -0
- scitex/plt/ax/_plot/_plot_joyplot.py +76 -0
- scitex/plt/ax/_plot/_plot_raster.py +172 -0
- scitex/plt/ax/_plot/_plot_rectangle.py +69 -0
- scitex/plt/ax/_plot/_plot_scatter_hist.py +133 -0
- scitex/plt/ax/_plot/_plot_shaded_line.py +142 -0
- scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +221 -0
- scitex/plt/ax/_plot/_plot_violin.py +343 -0
- scitex/plt/ax/_style/__init__.py +38 -0
- scitex/plt/ax/_style/_add_marginal_ax.py +44 -0
- scitex/plt/ax/_style/_add_panel.py +92 -0
- scitex/plt/ax/_style/_extend.py +64 -0
- scitex/plt/ax/_style/_force_aspect.py +37 -0
- scitex/plt/ax/_style/_format_label.py +23 -0
- scitex/plt/ax/_style/_hide_spines.py +84 -0
- scitex/plt/ax/_style/_map_ticks.py +182 -0
- scitex/plt/ax/_style/_rotate_labels.py +215 -0
- scitex/plt/ax/_style/_sci_note.py +279 -0
- scitex/plt/ax/_style/_set_log_scale.py +299 -0
- scitex/plt/ax/_style/_set_meta.py +261 -0
- scitex/plt/ax/_style/_set_n_ticks.py +37 -0
- scitex/plt/ax/_style/_set_size.py +16 -0
- scitex/plt/ax/_style/_set_supxyt.py +116 -0
- scitex/plt/ax/_style/_set_ticks.py +276 -0
- scitex/plt/ax/_style/_set_xyt.py +121 -0
- scitex/plt/ax/_style/_share_axes.py +264 -0
- scitex/plt/ax/_style/_shift.py +139 -0
- scitex/plt/ax/_style/_show_spines.py +333 -0
- scitex/plt/color/_PARAMS.py +70 -0
- scitex/plt/color/__init__.py +52 -0
- scitex/plt/color/_add_hue_col.py +41 -0
- scitex/plt/color/_colors.py +205 -0
- scitex/plt/color/_get_colors_from_cmap.py +134 -0
- scitex/plt/color/_interpolate.py +29 -0
- scitex/plt/color/_vizualize_colors.py +54 -0
- scitex/plt/utils/__init__.py +44 -0
- scitex/plt/utils/_calc_bacc_from_conf_mat.py +46 -0
- scitex/plt/utils/_calc_nice_ticks.py +101 -0
- scitex/plt/utils/_close.py +68 -0
- scitex/plt/utils/_colorbar.py +96 -0
- scitex/plt/utils/_configure_mpl.py +295 -0
- scitex/plt/utils/_histogram_utils.py +132 -0
- scitex/plt/utils/_im2grid.py +70 -0
- scitex/plt/utils/_is_valid_axis.py +78 -0
- scitex/plt/utils/_mk_colorbar.py +65 -0
- scitex/plt/utils/_mk_patches.py +26 -0
- scitex/plt/utils/_scientific_captions.py +638 -0
- scitex/plt/utils/_scitex_config.py +223 -0
- scitex/reproduce/__init__.py +14 -0
- scitex/reproduce/_fix_seeds.py +45 -0
- scitex/reproduce/_gen_ID.py +55 -0
- scitex/reproduce/_gen_timestamp.py +35 -0
- scitex/res/__init__.py +5 -0
- scitex/resource/__init__.py +13 -0
- scitex/resource/_get_processor_usages.py +281 -0
- scitex/resource/_get_specs.py +280 -0
- scitex/resource/_log_processor_usages.py +190 -0
- scitex/resource/_utils/__init__.py +31 -0
- scitex/resource/_utils/_get_env_info.py +481 -0
- scitex/resource/limit_ram.py +33 -0
- scitex/scholar/__init__.py +24 -0
- scitex/scholar/_local_search.py +454 -0
- scitex/scholar/_paper.py +244 -0
- scitex/scholar/_pdf_downloader.py +325 -0
- scitex/scholar/_search.py +393 -0
- scitex/scholar/_vector_search.py +370 -0
- scitex/scholar/_web_sources.py +457 -0
- scitex/stats/__init__.py +31 -0
- scitex/stats/_calc_partial_corr.py +17 -0
- scitex/stats/_corr_test_multi.py +94 -0
- scitex/stats/_corr_test_wrapper.py +115 -0
- scitex/stats/_describe_wrapper.py +90 -0
- scitex/stats/_multiple_corrections.py +63 -0
- scitex/stats/_nan_stats.py +93 -0
- scitex/stats/_p2stars.py +116 -0
- scitex/stats/_p2stars_wrapper.py +56 -0
- scitex/stats/_statistical_tests.py +73 -0
- scitex/stats/desc/__init__.py +40 -0
- scitex/stats/desc/_describe.py +189 -0
- scitex/stats/desc/_nan.py +289 -0
- scitex/stats/desc/_real.py +94 -0
- scitex/stats/multiple/__init__.py +14 -0
- scitex/stats/multiple/_bonferroni_correction.py +72 -0
- scitex/stats/multiple/_fdr_correction.py +400 -0
- scitex/stats/multiple/_multicompair.py +28 -0
- scitex/stats/tests/__corr_test.py +277 -0
- scitex/stats/tests/__corr_test_multi.py +343 -0
- scitex/stats/tests/__corr_test_single.py +277 -0
- scitex/stats/tests/__init__.py +22 -0
- scitex/stats/tests/_brunner_munzel_test.py +192 -0
- scitex/stats/tests/_nocorrelation_test.py +28 -0
- scitex/stats/tests/_smirnov_grubbs.py +98 -0
- scitex/str/__init__.py +113 -0
- scitex/str/_clean_path.py +75 -0
- scitex/str/_color_text.py +52 -0
- scitex/str/_decapitalize.py +58 -0
- scitex/str/_factor_out_digits.py +281 -0
- scitex/str/_format_plot_text.py +498 -0
- scitex/str/_grep.py +48 -0
- scitex/str/_latex.py +155 -0
- scitex/str/_latex_fallback.py +471 -0
- scitex/str/_mask_api.py +39 -0
- scitex/str/_mask_api_key.py +8 -0
- scitex/str/_parse.py +158 -0
- scitex/str/_print_block.py +47 -0
- scitex/str/_print_debug.py +68 -0
- scitex/str/_printc.py +62 -0
- scitex/str/_readable_bytes.py +38 -0
- scitex/str/_remove_ansi.py +23 -0
- scitex/str/_replace.py +134 -0
- scitex/str/_search.py +125 -0
- scitex/str/_squeeze_space.py +36 -0
- scitex/tex/__init__.py +10 -0
- scitex/tex/_preview.py +103 -0
- scitex/tex/_to_vec.py +116 -0
- scitex/torch/__init__.py +18 -0
- scitex/torch/_apply_to.py +34 -0
- scitex/torch/_nan_funcs.py +77 -0
- scitex/types/_ArrayLike.py +44 -0
- scitex/types/_ColorLike.py +21 -0
- scitex/types/__init__.py +14 -0
- scitex/types/_is_listed_X.py +70 -0
- scitex/utils/__init__.py +22 -0
- scitex/utils/_compress_hdf5.py +116 -0
- scitex/utils/_email.py +120 -0
- scitex/utils/_grid.py +148 -0
- scitex/utils/_notify.py +247 -0
- scitex/utils/_search.py +121 -0
- scitex/web/__init__.py +38 -0
- scitex/web/_search_pubmed.py +438 -0
- scitex/web/_summarize_url.py +158 -0
- scitex-2.0.0.dist-info/METADATA +307 -0
- scitex-2.0.0.dist-info/RECORD +572 -0
- scitex-2.0.0.dist-info/WHEEL +6 -0
- scitex-2.0.0.dist-info/licenses/LICENSE +7 -0
- 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())
|