arize 8.0.0b2__tar.gz → 8.0.0b4__tar.gz
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.
- {arize-8.0.0b2 → arize-8.0.0b4}/.gitignore +1 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/PKG-INFO +10 -2
- arize-8.0.0b4/pyproject.toml +290 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/__init__.py +8 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/client.py +18 -17
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/parsers/tracing_data_parser.py +9 -4
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/validation.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_flight/client.py +33 -13
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_lazy.py +37 -2
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/client.py +61 -35
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/config.py +168 -14
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/config.py +1 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/client.py +32 -19
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/auto_generator.py +14 -7
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/base_generators.py +15 -9
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/cv_generators.py +2 -2
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/nlp_generators.py +8 -8
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/tabular_generators.py +5 -5
- arize-8.0.0b4/src/arize/exceptions/config.py +22 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/parameters.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/values.py +8 -5
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/__init__.py +4 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/client.py +17 -11
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/base.py +6 -3
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/executors.py +6 -4
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/rate_limiters.py +3 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/types.py +7 -5
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/utils.py +7 -5
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/functions.py +111 -48
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/tracing.py +4 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/types.py +31 -26
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/logging.py +53 -32
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/batch_validation/validator.py +82 -70
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/bounded_executor.py +25 -6
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/casting.py +45 -27
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/client.py +35 -28
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/proto.py +16 -17
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/stream_validation.py +63 -25
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/surrogate_explainer/mimic.py +15 -7
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/types.py +26 -12
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/pre_releases.py +7 -6
- arize-8.0.0b4/src/arize/py.typed +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/regions.py +10 -10
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/client.py +113 -21
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/conversion.py +7 -5
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/dataframe_form_validation.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/value_validation.py +11 -14
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/dataframe_form_validation.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/value_validation.py +10 -13
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/value_validation.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/argument_validation.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/dataframe_form_validation.py +1 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/value_validation.py +23 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/arrow.py +37 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/online_tasks/dataframe_preprocessor.py +8 -4
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/proto.py +0 -1
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/types.py +6 -6
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/version.py +1 -1
- arize-8.0.0b2/pyproject.toml +0 -170
- {arize-8.0.0b2 → arize-8.0.0b4}/LICENSE +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/NOTICE +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/README.md +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_client_factory.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/parsers/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_flight/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_flight/types.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/datasets_api.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/experiments_api.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/projects_api.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api_client.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/configuration.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/exceptions.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset_example.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset_example_update.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset_version.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_create_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_examples_insert_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_examples_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_examples_update_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiment.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiment_run.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiment_run_create.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiments_create_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiments_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiments_runs_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/pagination_metadata.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/problem.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/project.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/projects_create_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/projects_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/rest.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset_example.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset_example_update.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset_version.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_api.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_create_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_examples_insert_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_examples_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_examples_update_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiment.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiment_run.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiment_run_create.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_api.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_create_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_runs_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_pagination_metadata.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_problem.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_project.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_projects_api.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_projects_create_request.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_projects_list200_response.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client_README.md +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/flight/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/flight/flight_pb2.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/rec/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/rec/public_pb2.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/ml.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/model_mapping.json +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/openinference.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/pyarrow.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/spans.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/errors.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/constants.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/errors.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/usecases.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/auth.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/base.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/models.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/spaces.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/types.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/exceptions.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/batch_validation/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/batch_validation/errors.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/surrogate_explainer/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/projects/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/projects/client.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/columns.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/annotations_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/argument_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/errors.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/dataframe_form_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/evals_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/dataframe_form_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/spans_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/value_validation.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/cache.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/dataframe.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/online_tasks/__init__.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/openinference_conversion.py +0 -0
- {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/size.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arize
|
|
3
|
-
Version: 8.0.
|
|
3
|
+
Version: 8.0.0b4
|
|
4
4
|
Summary: A helper library to interact with Arize AI APIs
|
|
5
5
|
Project-URL: Homepage, https://arize.com
|
|
6
6
|
Project-URL: Documentation, https://docs.arize.com/arize
|
|
@@ -44,8 +44,16 @@ Requires-Dist: typing-extensions<5,>=4.7.1
|
|
|
44
44
|
Requires-Dist: urllib3<3,>=2.1.0
|
|
45
45
|
Requires-Dist: wrapt<2.0.0,>=1.0.0
|
|
46
46
|
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: mypy==1.19.1; extra == 'dev'
|
|
48
|
+
Requires-Dist: pandas-stubs>=2.2.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: pytest-cov==6.0.0; extra == 'dev'
|
|
47
50
|
Requires-Dist: pytest==8.4.2; extra == 'dev'
|
|
48
|
-
Requires-Dist: ruff==0.
|
|
51
|
+
Requires-Dist: ruff==0.14.9; extra == 'dev'
|
|
52
|
+
Requires-Dist: taskipy<2,>=1.14.1; extra == 'dev'
|
|
53
|
+
Requires-Dist: types-python-dateutil>=2.9.0; extra == 'dev'
|
|
54
|
+
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
|
|
55
|
+
Requires-Dist: types-tabulate>=0.9.0; extra == 'dev'
|
|
56
|
+
Requires-Dist: types-tqdm>=4.66.0; extra == 'dev'
|
|
49
57
|
Provides-Extra: embeddings
|
|
50
58
|
Requires-Dist: datasets!=2.14.*,<3,>=2.8; extra == 'embeddings'
|
|
51
59
|
Requires-Dist: pillow<11,>=8.4.0; extra == 'embeddings'
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "arize"
|
|
3
|
+
description = "A helper library to interact with Arize AI APIs"
|
|
4
|
+
readme = "README.md"
|
|
5
|
+
requires-python = ">=3.10"
|
|
6
|
+
license = { text = "Apache-2.0" }
|
|
7
|
+
license-files = ["LICENSE", "NOTICE"]
|
|
8
|
+
keywords = [
|
|
9
|
+
"Arize",
|
|
10
|
+
"Observability",
|
|
11
|
+
"Monitoring",
|
|
12
|
+
"Explainability",
|
|
13
|
+
"Tracing",
|
|
14
|
+
"LLM",
|
|
15
|
+
"Evaluations",
|
|
16
|
+
]
|
|
17
|
+
authors = [{ name = "Arize AI", email = "support@arize.com" }]
|
|
18
|
+
maintainers = [{ name = "Arize AI", email = "support@arize.com" }]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 3 - Alpha",
|
|
21
|
+
"Programming Language :: Python",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Intended Audience :: Developers",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
29
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
|
+
"Topic :: System :: Logging",
|
|
31
|
+
"Topic :: System :: Monitoring",
|
|
32
|
+
]
|
|
33
|
+
dependencies = [
|
|
34
|
+
"numpy>=2.0.0",
|
|
35
|
+
"openinference-semantic-conventions>=0.1.25, <1",
|
|
36
|
+
"opentelemetry-exporter-otlp-proto-common>=1.38.0",
|
|
37
|
+
"opentelemetry-exporter-otlp-proto-grpc>=1.38.0",
|
|
38
|
+
"opentelemetry-sdk>=1.38.0",
|
|
39
|
+
"opentelemetry-semantic-conventions>=0.43b0, <1",
|
|
40
|
+
"pandas>=2.0.0, <3",
|
|
41
|
+
"protobuf>=4.21.0, <6",
|
|
42
|
+
"pyarrow>=0.15.0",
|
|
43
|
+
"pydantic>=2, <3",
|
|
44
|
+
"python-dateutil>=2.8.2, <3",
|
|
45
|
+
"requests>=2.0.0, <3",
|
|
46
|
+
"requests_futures>=1.0.0, <2",
|
|
47
|
+
"tqdm>4, <5", # For progress bars
|
|
48
|
+
"typing-extensions>=4.7.1, <5",
|
|
49
|
+
"urllib3>=2.1.0, <3",
|
|
50
|
+
"wrapt>=1.0.0, <2.0.0",
|
|
51
|
+
]
|
|
52
|
+
dynamic = ["version"]
|
|
53
|
+
|
|
54
|
+
[project.optional-dependencies]
|
|
55
|
+
dev = [
|
|
56
|
+
"mypy==1.19.1",
|
|
57
|
+
"pandas-stubs>=2.2.0",
|
|
58
|
+
"pytest-cov==6.0.0",
|
|
59
|
+
"pytest==8.4.2",
|
|
60
|
+
"ruff==0.14.9",
|
|
61
|
+
"taskipy>=1.14.1, <2",
|
|
62
|
+
"types-python-dateutil>=2.9.0",
|
|
63
|
+
"types-requests>=2.31.0",
|
|
64
|
+
"types-tabulate>=0.9.0",
|
|
65
|
+
"types-tqdm>=4.66.0",
|
|
66
|
+
]
|
|
67
|
+
otel = [
|
|
68
|
+
"arize-otel>=0.11.0, <1",
|
|
69
|
+
]
|
|
70
|
+
mimic = [
|
|
71
|
+
"interpret-community[mimic]>=0.22.0,<1",
|
|
72
|
+
]
|
|
73
|
+
embeddings = [
|
|
74
|
+
"Pillow>=8.4.0, <11",
|
|
75
|
+
"datasets>=2.8, <3, !=2.14.*",
|
|
76
|
+
"tokenizers>=0.13, <1",
|
|
77
|
+
"torch>=1.13, <3",
|
|
78
|
+
"transformers>=4.25, <5",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[project.urls]
|
|
82
|
+
Homepage = "https://arize.com"
|
|
83
|
+
Documentation = "https://docs.arize.com/arize"
|
|
84
|
+
Issues = "https://github.com/Arize-ai/client_python/issues"
|
|
85
|
+
Source = "https://github.com/Arize-ai/client_python"
|
|
86
|
+
Changelog = "https://github.com/Arize-ai/client_python/blob/main/CHANGELOG.md"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
[build-system]
|
|
90
|
+
requires = ["hatchling"]
|
|
91
|
+
build-backend = "hatchling.build"
|
|
92
|
+
|
|
93
|
+
[tool.hatch.version]
|
|
94
|
+
path = "src/arize/version.py"
|
|
95
|
+
|
|
96
|
+
[tool.hatch.build]
|
|
97
|
+
only-packages = true
|
|
98
|
+
|
|
99
|
+
[tool.hatch.build.targets.wheel]
|
|
100
|
+
packages = ["src/arize"]
|
|
101
|
+
|
|
102
|
+
[tool.hatch.build.targets.sdist]
|
|
103
|
+
exclude = ["tests", "docs"]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
[tool.black]
|
|
107
|
+
include = '\.pyi?$'
|
|
108
|
+
exclude = '(_pb2\.py$|docs/source/.*\.py)'
|
|
109
|
+
|
|
110
|
+
[tool.ruff]
|
|
111
|
+
target-version = "py310"
|
|
112
|
+
line-length = 80
|
|
113
|
+
exclude = [
|
|
114
|
+
"dist/",
|
|
115
|
+
"testing_notebooks/",
|
|
116
|
+
"__pycache__",
|
|
117
|
+
"src/arize/_generated/**/*.py",
|
|
118
|
+
"*_pb2.py*",
|
|
119
|
+
"*_pb2_grpc.py*",
|
|
120
|
+
"*.pyi",
|
|
121
|
+
"docs/",
|
|
122
|
+
]
|
|
123
|
+
[tool.ruff.format]
|
|
124
|
+
docstring-code-format = true
|
|
125
|
+
line-ending = "native"
|
|
126
|
+
|
|
127
|
+
[tool.ruff.lint]
|
|
128
|
+
select = [
|
|
129
|
+
# Core correctness & style
|
|
130
|
+
# ------------------------
|
|
131
|
+
"E", # pycodestyle errors (syntax, indentation, whitespace)
|
|
132
|
+
"W", # pycodestyle warnings (less severe style issues)
|
|
133
|
+
"F", # Pyflakes (unused imports, undefined names, etc.)
|
|
134
|
+
"UP", # pyupgrade (modernize syntax for your Python version)
|
|
135
|
+
"B", # flake8-bugbear (likely bugs and design problems)
|
|
136
|
+
"SIM", # flake8-simplify (simpler / clearer code patterns)
|
|
137
|
+
"I", # isort (import ordering)
|
|
138
|
+
|
|
139
|
+
# Typing & documentation
|
|
140
|
+
# ------------------------
|
|
141
|
+
"ANN", # flake8-annotations (enforce type annotations)
|
|
142
|
+
"D", # pydocstyle (docstring conventions for public APIs)
|
|
143
|
+
"TCH", # flake8-type-checking (TYPE_CHECKING import hygiene)
|
|
144
|
+
|
|
145
|
+
# Recommended for SDKs
|
|
146
|
+
# ------------------------
|
|
147
|
+
"RUF", # Ruff-native rules (high-signal correctness & footguns)
|
|
148
|
+
"C4", # flake8-comprehensions (cleaner comprehensions)
|
|
149
|
+
"PIE", # flake8-pie (small correctness & readability improvements)
|
|
150
|
+
"PERF", # perflint (common performance pitfalls)
|
|
151
|
+
"DTZ", # flake8-datetimez (timezone-aware datetime usage)
|
|
152
|
+
"TRY", # tryceratops (better exception handling patterns)
|
|
153
|
+
"RET", # flake8-return (return consistency)
|
|
154
|
+
"S", # flake8-bandit (basic security issues; tune via ignores)
|
|
155
|
+
]
|
|
156
|
+
ignore = [
|
|
157
|
+
"TRY003", # Put long / detailed messages inside the exception class
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
[tool.ruff.lint.per-file-ignores]
|
|
161
|
+
"tests/**/*.py" = [
|
|
162
|
+
"D104", # Missing docstring in public package
|
|
163
|
+
"DTZ001", # Allow naive datetime usage in tests
|
|
164
|
+
"S101", # Allow assert statements in tests
|
|
165
|
+
"S108", # Allow insecure usage of temporary file or directory
|
|
166
|
+
"TRY301", # Allow generic exception catching in tests
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
[tool.ruff.lint.isort]
|
|
170
|
+
force-wrap-aliases = true
|
|
171
|
+
|
|
172
|
+
[tool.ruff.lint.pycodestyle]
|
|
173
|
+
max-doc-length = 110
|
|
174
|
+
max-line-length = 110
|
|
175
|
+
|
|
176
|
+
[tool.ruff.lint.pydocstyle]
|
|
177
|
+
convention = "google"
|
|
178
|
+
|
|
179
|
+
[tool.ruff.lint.pyupgrade]
|
|
180
|
+
keep-runtime-typing = true
|
|
181
|
+
|
|
182
|
+
[tool.mypy]
|
|
183
|
+
python_version = "3.10"
|
|
184
|
+
warn_unused_configs = true
|
|
185
|
+
exclude = ["testing_notebooks/", "src/arize/_generated/", "tests/"]
|
|
186
|
+
# Incrementally enable strict type checking by uncommenting checks from bottom to top.
|
|
187
|
+
# Fix foundational issues (imports, syntax) before type definitions, then signatures, then implementations.
|
|
188
|
+
disable_error_code = []
|
|
189
|
+
|
|
190
|
+
# Ignore missing imports for libraries without type stubs
|
|
191
|
+
[[tool.mypy.overrides]]
|
|
192
|
+
module = [
|
|
193
|
+
"pyarrow.*",
|
|
194
|
+
"google.protobuf.*",
|
|
195
|
+
"wrapt.*",
|
|
196
|
+
"datasets.*",
|
|
197
|
+
"requests_futures.*",
|
|
198
|
+
"interpret_community.*",
|
|
199
|
+
"sklearn.*",
|
|
200
|
+
]
|
|
201
|
+
ignore_missing_imports = true
|
|
202
|
+
|
|
203
|
+
[tool.pytest.ini_options]
|
|
204
|
+
# Directory where pytest will search for tests
|
|
205
|
+
testpaths = ["tests"]
|
|
206
|
+
# Patterns for discovering test files (files matching these patterns will be collected)
|
|
207
|
+
python_files = ["test_*.py", "*_test.py"]
|
|
208
|
+
# Patterns for discovering test classes (classes matching this pattern will be collected)
|
|
209
|
+
python_classes = ["Test*"]
|
|
210
|
+
# Patterns for discovering test functions (functions matching this pattern will be collected)
|
|
211
|
+
python_functions = ["test_*"]
|
|
212
|
+
# Directories and patterns to ignore during test collection
|
|
213
|
+
norecursedirs = [
|
|
214
|
+
"testing_notebooks",
|
|
215
|
+
".*",
|
|
216
|
+
"build",
|
|
217
|
+
"dist",
|
|
218
|
+
"*.egg"
|
|
219
|
+
]
|
|
220
|
+
# Additional command-line options to always apply when running pytest
|
|
221
|
+
addopts = [
|
|
222
|
+
"-v", # Verbose: show individual test names as they run
|
|
223
|
+
"--strict-markers", # Error on undefined markers (prevents typos like @pytest.mark.slo instead of @pytest.mark.slow)
|
|
224
|
+
"--tb=short", # Shorter tracebacks: show only the failure point without full stack
|
|
225
|
+
"--durations=10", # Show the 10 slowest tests at the end (helps identify performance bottlenecks)
|
|
226
|
+
]
|
|
227
|
+
# Custom markers that can be used to categorize tests (use with @pytest.mark.marker_name)
|
|
228
|
+
markers = [
|
|
229
|
+
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
230
|
+
"integration: marks tests as integration tests",
|
|
231
|
+
"unit: marks tests as unit tests",
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
[tool.coverage.run]
|
|
235
|
+
source = ["src/arize"]
|
|
236
|
+
omit = [
|
|
237
|
+
"*/tests/*",
|
|
238
|
+
"*/testing_notebooks/*",
|
|
239
|
+
"*/_generated/*",
|
|
240
|
+
"*/__pycache__/*",
|
|
241
|
+
"*/site-packages/*",
|
|
242
|
+
# Exclude other src/arize modules. TODO(Kiko): Remove them progressively.
|
|
243
|
+
"src/arize/constants/*",
|
|
244
|
+
"src/arize/datasets/*",
|
|
245
|
+
"src/arize/embeddings/*",
|
|
246
|
+
"src/arize/exceptions/*",
|
|
247
|
+
"src/arize/experiments/*",
|
|
248
|
+
"src/arize/ml/*",
|
|
249
|
+
"src/arize/projects/*",
|
|
250
|
+
"src/arize/spans/*",
|
|
251
|
+
"src/arize/utils/*",
|
|
252
|
+
]
|
|
253
|
+
# Enable branch coverage (measures whether all branches of if/else/try/except are tested)
|
|
254
|
+
# Without this, only line coverage is measured
|
|
255
|
+
branch = true
|
|
256
|
+
|
|
257
|
+
[tool.coverage.report]
|
|
258
|
+
# Number of decimal places to show in coverage percentages (e.g., 85.47% instead of 85%)
|
|
259
|
+
precision = 2
|
|
260
|
+
# Show line numbers for lines that are missing coverage in the report
|
|
261
|
+
show_missing = true
|
|
262
|
+
# If true, files with 100% coverage would be hidden from the report
|
|
263
|
+
skip_covered = false
|
|
264
|
+
# Minimum coverage percentage required (build fails if total coverage is below this)
|
|
265
|
+
fail_under = 90
|
|
266
|
+
# Lines matching these patterns are excluded from coverage measurement
|
|
267
|
+
exclude_lines = [
|
|
268
|
+
"pragma: no cover",
|
|
269
|
+
"def __repr__",
|
|
270
|
+
"raise AssertionError",
|
|
271
|
+
"raise NotImplementedError",
|
|
272
|
+
"if __name__ == .__main__.:",
|
|
273
|
+
"if TYPE_CHECKING:",
|
|
274
|
+
"@abstractmethod",
|
|
275
|
+
"@abc.abstractmethod",
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
[tool.coverage.html]
|
|
279
|
+
# Directory where HTML coverage reports will be generated (browsable in a web browser)
|
|
280
|
+
directory = "htmlcov"
|
|
281
|
+
|
|
282
|
+
[tool.taskipy.tasks]
|
|
283
|
+
lint = { cmd = "ruff format . && ruff check --fix .", cwd = ".", help = "Run ruff to format and lint the package." }
|
|
284
|
+
type-check = {cmd = "mypy --no-incremental --show-traceback --config-file pyproject.toml .", cwd = ".", help = "Run mypy for type checking."}
|
|
285
|
+
test = {cmd = "pytest --cov .", cwd = ".", help = "Run the test suite with coverage."}
|
|
286
|
+
# Exclusive for CI
|
|
287
|
+
ci-format = { cmd = "ruff format --check .", cwd = ".", help = "Run ruff to check formatting of the package during CI." }
|
|
288
|
+
ci-lint = { cmd = "ruff check .", cwd = ".", help = "Run ruff to check linting rules of the package during CI." }
|
|
289
|
+
ci-type-check = {cmd = "mypy --no-incremental --show-traceback --config-file pyproject.toml .", cwd = ".", help = "Run mypy for type checking during CI."}
|
|
290
|
+
ci-test = {cmd = "pytest --cov --cov-report=term-missing --cov-report=html .", cwd = ".", help = "Run the test suite with coverage during CI."}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
from collections.abc import Mapping
|
|
5
|
+
from typing import Literal, cast
|
|
5
6
|
|
|
6
7
|
from arize._generated.api_client import models
|
|
7
8
|
from arize.client import ArizeClient
|
|
@@ -82,7 +83,11 @@ def make_to_df(field_name: str) -> object:
|
|
|
82
83
|
|
|
83
84
|
# Drop None/NaN columns if requested
|
|
84
85
|
if exclude_none in ("any", "all", True):
|
|
85
|
-
drop_how
|
|
86
|
+
drop_how: Literal["any", "all"] = (
|
|
87
|
+
"all"
|
|
88
|
+
if exclude_none is True
|
|
89
|
+
else cast("Literal['any', 'all']", exclude_none)
|
|
90
|
+
)
|
|
86
91
|
df.dropna(axis=1, how=drop_how, inplace=True)
|
|
87
92
|
|
|
88
93
|
if convert_dtypes:
|
|
@@ -92,6 +97,8 @@ def make_to_df(field_name: str) -> object:
|
|
|
92
97
|
return to_df
|
|
93
98
|
|
|
94
99
|
|
|
100
|
+
# Monkey-patch convenience methods onto generated response models
|
|
101
|
+
# Type ignore comments needed: mypy can't verify runtime attribute additions
|
|
95
102
|
models.DatasetsList200Response.to_df = make_to_df("datasets") # type: ignore[attr-defined]
|
|
96
103
|
models.DatasetsExamplesList200Response.to_df = make_to_df("examples") # type: ignore[attr-defined]
|
|
97
104
|
models.ExperimentsList200Response.to_df = make_to_df("experiments") # type: ignore[attr-defined]
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# type: ignore[pb2]
|
|
2
1
|
import logging
|
|
3
2
|
from dataclasses import dataclass
|
|
4
3
|
from datetime import datetime
|
|
@@ -41,7 +40,7 @@ class ArizeExportClient:
|
|
|
41
40
|
batch_id: str = "",
|
|
42
41
|
include_actuals: bool = False,
|
|
43
42
|
stream_chunk_size: int | None = None,
|
|
44
|
-
) ->
|
|
43
|
+
) -> pd.DataFrame:
|
|
45
44
|
"""Exports data of a specific model in the Arize platform to a pandas dataframe.
|
|
46
45
|
|
|
47
46
|
The export covers a defined time interval and model environment, and can
|
|
@@ -237,6 +236,22 @@ class ArizeExportClient:
|
|
|
237
236
|
columns: list | None = None,
|
|
238
237
|
stream_chunk_size: int | None = None,
|
|
239
238
|
) -> tuple[flight.FlightStreamReader | None, int]:
|
|
239
|
+
# Validate inputs first before creating logging context
|
|
240
|
+
validate_input_type(space_id, "space_id", str)
|
|
241
|
+
validate_input_type(model_id, "model_id", str)
|
|
242
|
+
validate_input_type(environment, "environment", Environments)
|
|
243
|
+
validate_input_type(include_actuals, "include_actuals", bool)
|
|
244
|
+
validate_input_type(start_time, "start_time", datetime)
|
|
245
|
+
validate_input_type(end_time, "end_time", datetime)
|
|
246
|
+
validate_input_type(model_version, "model_version", str)
|
|
247
|
+
validate_input_type(batch_id, "batch_id", str)
|
|
248
|
+
validate_input_type(where, "where", str)
|
|
249
|
+
validate_input_type(columns, "columns", list, allow_none=True)
|
|
250
|
+
validate_input_type(
|
|
251
|
+
stream_chunk_size, "stream_chunk_size", int, allow_none=True
|
|
252
|
+
)
|
|
253
|
+
validate_start_end_time(start_time, end_time)
|
|
254
|
+
|
|
240
255
|
# Bind common context for this operation
|
|
241
256
|
log = CtxAdapter(
|
|
242
257
|
logger,
|
|
@@ -258,20 +273,6 @@ class ArizeExportClient:
|
|
|
258
273
|
},
|
|
259
274
|
)
|
|
260
275
|
log.debug("Getting stream reader...")
|
|
261
|
-
validate_input_type(space_id, "space_id", str)
|
|
262
|
-
validate_input_type(model_id, "model_id", str)
|
|
263
|
-
validate_input_type(environment, "environment", Environments)
|
|
264
|
-
validate_input_type(include_actuals, "include_actuals", bool)
|
|
265
|
-
validate_input_type(start_time, "start_time", datetime)
|
|
266
|
-
validate_input_type(end_time, "end_time", datetime)
|
|
267
|
-
validate_input_type(model_version, "model_version", str)
|
|
268
|
-
validate_input_type(batch_id, "batch_id", str)
|
|
269
|
-
validate_input_type(where, "where", str)
|
|
270
|
-
validate_input_type(columns, "columns", list, allow_none=True)
|
|
271
|
-
validate_input_type(
|
|
272
|
-
stream_chunk_size, "stream_chunk_size", int, allow_none=True
|
|
273
|
-
)
|
|
274
|
-
validate_start_end_time(start_time, end_time)
|
|
275
276
|
|
|
276
277
|
# Create query descriptor
|
|
277
278
|
query_descriptor = flight_pb2.RecordQueryDescriptor(
|
|
@@ -300,7 +301,7 @@ class ArizeExportClient:
|
|
|
300
301
|
try:
|
|
301
302
|
flight_info = self.flight_client.get_flight_info(
|
|
302
303
|
flight.FlightDescriptor.for_command(
|
|
303
|
-
json_format.MessageToJson(query_descriptor)
|
|
304
|
+
json_format.MessageToJson(query_descriptor)
|
|
304
305
|
),
|
|
305
306
|
)
|
|
306
307
|
logger.info("Fetching data...")
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import Any, TypeGuard
|
|
3
5
|
|
|
4
6
|
import numpy as np
|
|
5
7
|
import pandas as pd
|
|
@@ -28,7 +30,10 @@ logger = logging.getLogger(__name__)
|
|
|
28
30
|
# of the error is on the data; It should not prevent a user from continuing to use the data
|
|
29
31
|
class OtelTracingDataTransformer:
|
|
30
32
|
def _apply_column_transformation(
|
|
31
|
-
self,
|
|
33
|
+
self,
|
|
34
|
+
df: pd.DataFrame,
|
|
35
|
+
col_name: str,
|
|
36
|
+
transform_func: Callable[[Any], Any],
|
|
32
37
|
) -> str | None:
|
|
33
38
|
"""Apply a transformation to a column and return error message if it fails."""
|
|
34
39
|
try:
|
|
@@ -89,7 +94,7 @@ class OtelTracingDataTransformer:
|
|
|
89
94
|
if col.name in df.columns
|
|
90
95
|
]
|
|
91
96
|
for col_name in dirty_string_column_names:
|
|
92
|
-
df[col_name] = df[col_name].apply(self._clean_json_string)
|
|
97
|
+
df[col_name] = df[col_name].apply(self._clean_json_string) # type: ignore[arg-type]
|
|
93
98
|
|
|
94
99
|
# Convert timestamp columns to datetime objects
|
|
95
100
|
timestamp_column_names: list[str] = [
|
|
@@ -102,7 +107,7 @@ class OtelTracingDataTransformer:
|
|
|
102
107
|
]
|
|
103
108
|
for col_name in timestamp_column_names:
|
|
104
109
|
df[col_name] = df[col_name].apply(
|
|
105
|
-
self._convert_timestamp_to_datetime
|
|
110
|
+
self._convert_timestamp_to_datetime # type: ignore[arg-type]
|
|
106
111
|
)
|
|
107
112
|
|
|
108
113
|
for err in errors:
|
|
@@ -138,7 +143,7 @@ class OtelTracingDataTransformer:
|
|
|
138
143
|
return None
|
|
139
144
|
return None
|
|
140
145
|
|
|
141
|
-
def _is_non_empty_string(self, value: object) ->
|
|
146
|
+
def _is_non_empty_string(self, value: object) -> TypeGuard[str]:
|
|
142
147
|
return isinstance(value, str) and value != ""
|
|
143
148
|
|
|
144
149
|
def _deserialize_json_string_to_dict(self, value: str) -> object:
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
# type: ignore[pb2]
|
|
2
1
|
from __future__ import annotations
|
|
3
2
|
|
|
4
3
|
import base64
|
|
5
4
|
import logging
|
|
6
5
|
from dataclasses import dataclass, field
|
|
7
6
|
from enum import Enum
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
7
|
+
from typing import TYPE_CHECKING, TypeAlias
|
|
9
8
|
|
|
10
9
|
from google.protobuf import json_format
|
|
11
10
|
from pyarrow import flight
|
|
@@ -20,15 +19,15 @@ from arize.version import __version__
|
|
|
20
19
|
|
|
21
20
|
if TYPE_CHECKING:
|
|
22
21
|
import types
|
|
23
|
-
from collections.abc import
|
|
22
|
+
from collections.abc import Iterator
|
|
24
23
|
|
|
25
24
|
import pandas as pd
|
|
26
25
|
import pyarrow as pa
|
|
27
26
|
|
|
28
27
|
|
|
29
|
-
BytesPair = tuple[bytes, bytes]
|
|
30
|
-
Headers = list[BytesPair]
|
|
31
|
-
FlightPostArrowFileResponse = (
|
|
28
|
+
BytesPair: TypeAlias = tuple[bytes, bytes]
|
|
29
|
+
Headers: TypeAlias = list[BytesPair]
|
|
30
|
+
FlightPostArrowFileResponse: TypeAlias = (
|
|
32
31
|
flight_pb2.WriteSpanEvaluationResponse
|
|
33
32
|
| flight_pb2.WriteSpanAnnotationResponse
|
|
34
33
|
| flight_pb2.WriteSpanAttributesMetadataResponse
|
|
@@ -90,7 +89,11 @@ class ArizeFlightClient:
|
|
|
90
89
|
# ---------- Connection management ----------
|
|
91
90
|
|
|
92
91
|
def _ensure_client(self) -> flight.FlightClient:
|
|
93
|
-
"""Lazily initialize and return the underlying Flight client connection.
|
|
92
|
+
"""Lazily initialize and return the underlying Flight client connection.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
flight.FlightClient: The initialized Apache Arrow Flight client.
|
|
96
|
+
"""
|
|
94
97
|
client = object.__getattribute__(self, "_client")
|
|
95
98
|
if client is not None:
|
|
96
99
|
return client
|
|
@@ -135,7 +138,11 @@ class ArizeFlightClient:
|
|
|
135
138
|
# ---------- methods simple passthrough wrappers ----------
|
|
136
139
|
|
|
137
140
|
def get_flight_info(self, *args: object, **kwargs: object) -> object:
|
|
138
|
-
"""Get flight information. Passthrough to underlying Flight client with auth options.
|
|
141
|
+
"""Get flight information. Passthrough to underlying Flight client with auth options.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
object: FlightInfo object containing metadata about the requested data stream.
|
|
145
|
+
"""
|
|
139
146
|
client = self._ensure_client()
|
|
140
147
|
kwargs.setdefault("options", self.call_options)
|
|
141
148
|
return client.get_flight_info(*args, **kwargs)
|
|
@@ -146,6 +153,9 @@ class ArizeFlightClient:
|
|
|
146
153
|
"""Retrieve data stream via Flight DoGet.
|
|
147
154
|
|
|
148
155
|
Passthrough to underlying Flight client with auth options.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
flight.FlightStreamReader: A stream reader for retrieving Arrow record batches.
|
|
149
159
|
"""
|
|
150
160
|
client = self._ensure_client()
|
|
151
161
|
kwargs.setdefault("options", self.call_options)
|
|
@@ -153,10 +163,15 @@ class ArizeFlightClient:
|
|
|
153
163
|
|
|
154
164
|
def do_put(
|
|
155
165
|
self, *args: object, **kwargs: object
|
|
156
|
-
) -> [flight.FlightStreamWriter, flight.FlightMetadataReader]:
|
|
166
|
+
) -> tuple[flight.FlightStreamWriter, flight.FlightMetadataReader]:
|
|
157
167
|
"""Upload data stream via Flight DoPut.
|
|
158
168
|
|
|
159
169
|
Passthrough to underlying Flight client with auth options.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
tuple[flight.FlightStreamWriter, flight.FlightMetadataReader]: A tuple containing
|
|
173
|
+
a stream writer for uploading Arrow record batches and a metadata reader for
|
|
174
|
+
receiving server responses.
|
|
160
175
|
"""
|
|
161
176
|
client = self._ensure_client()
|
|
162
177
|
kwargs.setdefault("options", self.call_options)
|
|
@@ -164,10 +179,13 @@ class ArizeFlightClient:
|
|
|
164
179
|
|
|
165
180
|
def do_action(
|
|
166
181
|
self, *args: object, **kwargs: object
|
|
167
|
-
) ->
|
|
182
|
+
) -> Iterator[flight.Result]:
|
|
168
183
|
"""Execute an action via Flight DoAction.
|
|
169
184
|
|
|
170
185
|
Passthrough to underlying Flight client with auth options.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Iterable[flight.Result]: An iterable of Result objects from the action execution.
|
|
171
189
|
"""
|
|
172
190
|
client = self._ensure_client()
|
|
173
191
|
kwargs.setdefault("options", self.call_options)
|
|
@@ -210,6 +228,10 @@ class ArizeFlightClient:
|
|
|
210
228
|
FlightRequestType.ANNOTATION,
|
|
211
229
|
FlightRequestType.METADATA,
|
|
212
230
|
):
|
|
231
|
+
if project_name is None:
|
|
232
|
+
raise ValueError(
|
|
233
|
+
f"project_name is required for {request_type.name} request type"
|
|
234
|
+
)
|
|
213
235
|
proto_schema = get_pb_schema_tracing(project_name=project_name)
|
|
214
236
|
base64_schema = base64.b64encode(proto_schema.SerializeToString())
|
|
215
237
|
pa_schema = append_to_pyarrow_metadata(
|
|
@@ -260,8 +282,6 @@ class ArizeFlightClient:
|
|
|
260
282
|
case FlightRequestType.LOG_EXPERIMENT_DATA:
|
|
261
283
|
res = flight_pb2.PostExperimentDataResponse()
|
|
262
284
|
res.ParseFromString(flight_response.to_pybytes())
|
|
263
|
-
case _:
|
|
264
|
-
raise ValueError(f"Unsupported request_type: {request_type}")
|
|
265
285
|
return res
|
|
266
286
|
|
|
267
287
|
# ---------- dataset methods ----------
|
|
@@ -271,7 +291,7 @@ class ArizeFlightClient:
|
|
|
271
291
|
space_id: str,
|
|
272
292
|
dataset_name: str,
|
|
273
293
|
pa_table: pa.Table,
|
|
274
|
-
) -> str:
|
|
294
|
+
) -> str | None:
|
|
275
295
|
"""Create a new dataset via Flight DoPut.
|
|
276
296
|
|
|
277
297
|
Args:
|
|
@@ -52,7 +52,7 @@ class LazySubclientsMixin:
|
|
|
52
52
|
# Determine which parameters this subclient needs
|
|
53
53
|
# and build kwargs accordingly
|
|
54
54
|
sig = inspect.signature(klass.__init__)
|
|
55
|
-
kwargs = {}
|
|
55
|
+
kwargs: dict[str, object] = {}
|
|
56
56
|
if "sdk_config" in sig.parameters:
|
|
57
57
|
kwargs["sdk_config"] = self.sdk_config
|
|
58
58
|
if "generated_client" in sig.parameters:
|
|
@@ -72,7 +72,14 @@ class OptionalDependencyError(ImportError): ...
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def _can_import(module_name: str) -> bool:
|
|
75
|
-
"""Check if a module can be imported without raising an exception.
|
|
75
|
+
"""Check if a module can be imported without raising an exception.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
module_name: The fully qualified module name to check (e.g., 'numpy', 'sklearn.preprocessing').
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
bool: True if the module can be imported successfully, False otherwise.
|
|
82
|
+
"""
|
|
76
83
|
try:
|
|
77
84
|
import_module(module_name)
|
|
78
85
|
except Exception:
|
|
@@ -86,6 +93,18 @@ def require(
|
|
|
86
93
|
required: tuple[str, ...],
|
|
87
94
|
pkgname: str = "arize",
|
|
88
95
|
) -> None:
|
|
96
|
+
"""Ensure required optional dependencies are installed, raising an error if missing.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
extra_key: The extras group key for pip install (e.g., 'mimic', 'embeddings').
|
|
100
|
+
Used in the error message to guide users.
|
|
101
|
+
required: Tuple of required module names to check for availability.
|
|
102
|
+
pkgname: The package name for installation instructions. Defaults to 'arize'.
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
OptionalDependencyError: If any of the required modules cannot be imported.
|
|
106
|
+
The error message includes pip install instructions with the extras group.
|
|
107
|
+
"""
|
|
89
108
|
if not required:
|
|
90
109
|
return
|
|
91
110
|
missing = [p for p in required if not _can_import(p)]
|
|
@@ -97,6 +116,22 @@ def require(
|
|
|
97
116
|
|
|
98
117
|
|
|
99
118
|
def _dynamic_import(modname: str, retries: int = 2) -> types.ModuleType:
|
|
119
|
+
"""Dynamically import a module with retry logic and sys.modules cleanup on failure.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
modname: The fully qualified module name to import.
|
|
123
|
+
retries: Number of import attempts to make. Must be > 0. Defaults to 2.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
types.ModuleType: The successfully imported module.
|
|
127
|
+
|
|
128
|
+
Raises:
|
|
129
|
+
ValueError: If retries is <= 0.
|
|
130
|
+
ModuleNotFoundError: If the module cannot be found after all retry attempts.
|
|
131
|
+
ImportError: If the module import fails after all retry attempts.
|
|
132
|
+
KeyError: If a key error occurs during import after all retry attempts.
|
|
133
|
+
"""
|
|
134
|
+
|
|
100
135
|
def _attempt_import(remaining_attempts: int) -> types.ModuleType:
|
|
101
136
|
try:
|
|
102
137
|
return import_module(modname)
|