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.
Files changed (178) hide show
  1. {arize-8.0.0b2 → arize-8.0.0b4}/.gitignore +1 -0
  2. {arize-8.0.0b2 → arize-8.0.0b4}/PKG-INFO +10 -2
  3. arize-8.0.0b4/pyproject.toml +290 -0
  4. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/__init__.py +8 -1
  5. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/client.py +18 -17
  6. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/parsers/tracing_data_parser.py +9 -4
  7. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/validation.py +1 -1
  8. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_flight/client.py +33 -13
  9. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_lazy.py +37 -2
  10. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/client.py +61 -35
  11. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/config.py +168 -14
  12. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/config.py +1 -0
  13. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/client.py +32 -19
  14. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/auto_generator.py +14 -7
  15. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/base_generators.py +15 -9
  16. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/cv_generators.py +2 -2
  17. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/nlp_generators.py +8 -8
  18. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/tabular_generators.py +5 -5
  19. arize-8.0.0b4/src/arize/exceptions/config.py +22 -0
  20. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/parameters.py +1 -1
  21. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/values.py +8 -5
  22. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/__init__.py +4 -0
  23. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/client.py +17 -11
  24. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/base.py +6 -3
  25. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/executors.py +6 -4
  26. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/rate_limiters.py +3 -1
  27. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/types.py +7 -5
  28. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/utils.py +7 -5
  29. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/functions.py +111 -48
  30. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/tracing.py +4 -1
  31. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/types.py +31 -26
  32. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/logging.py +53 -32
  33. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/batch_validation/validator.py +82 -70
  34. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/bounded_executor.py +25 -6
  35. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/casting.py +45 -27
  36. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/client.py +35 -28
  37. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/proto.py +16 -17
  38. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/stream_validation.py +63 -25
  39. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/surrogate_explainer/mimic.py +15 -7
  40. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/types.py +26 -12
  41. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/pre_releases.py +7 -6
  42. arize-8.0.0b4/src/arize/py.typed +0 -0
  43. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/regions.py +10 -10
  44. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/client.py +113 -21
  45. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/conversion.py +7 -5
  46. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/dataframe_form_validation.py +1 -1
  47. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/value_validation.py +11 -14
  48. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/dataframe_form_validation.py +1 -1
  49. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/value_validation.py +10 -13
  50. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/value_validation.py +1 -1
  51. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/argument_validation.py +1 -1
  52. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/dataframe_form_validation.py +1 -1
  53. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/value_validation.py +23 -1
  54. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/arrow.py +37 -1
  55. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/online_tasks/dataframe_preprocessor.py +8 -4
  56. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/proto.py +0 -1
  57. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/types.py +6 -6
  58. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/version.py +1 -1
  59. arize-8.0.0b2/pyproject.toml +0 -170
  60. {arize-8.0.0b2 → arize-8.0.0b4}/LICENSE +0 -0
  61. {arize-8.0.0b2 → arize-8.0.0b4}/NOTICE +0 -0
  62. {arize-8.0.0b2 → arize-8.0.0b4}/README.md +0 -0
  63. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_client_factory.py +0 -0
  64. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/__init__.py +0 -0
  65. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_exporter/parsers/__init__.py +0 -0
  66. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_flight/__init__.py +0 -0
  67. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_flight/types.py +0 -0
  68. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/__init__.py +0 -0
  69. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/__init__.py +0 -0
  70. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/__init__.py +0 -0
  71. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/datasets_api.py +0 -0
  72. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/experiments_api.py +0 -0
  73. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api/projects_api.py +0 -0
  74. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api_client.py +0 -0
  75. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/api_response.py +0 -0
  76. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/configuration.py +0 -0
  77. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/exceptions.py +0 -0
  78. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/__init__.py +0 -0
  79. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset.py +0 -0
  80. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset_example.py +0 -0
  81. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset_example_update.py +0 -0
  82. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/dataset_version.py +0 -0
  83. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_create_request.py +0 -0
  84. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_examples_insert_request.py +0 -0
  85. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_examples_list200_response.py +0 -0
  86. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_examples_update_request.py +0 -0
  87. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/datasets_list200_response.py +0 -0
  88. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiment.py +0 -0
  89. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiment_run.py +0 -0
  90. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiment_run_create.py +0 -0
  91. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiments_create_request.py +0 -0
  92. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiments_list200_response.py +0 -0
  93. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/experiments_runs_list200_response.py +0 -0
  94. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/pagination_metadata.py +0 -0
  95. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/problem.py +0 -0
  96. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/project.py +0 -0
  97. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/projects_create_request.py +0 -0
  98. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/models/projects_list200_response.py +0 -0
  99. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/rest.py +0 -0
  100. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/__init__.py +0 -0
  101. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset.py +0 -0
  102. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset_example.py +0 -0
  103. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset_example_update.py +0 -0
  104. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_dataset_version.py +0 -0
  105. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_api.py +0 -0
  106. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_create_request.py +0 -0
  107. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_examples_insert_request.py +0 -0
  108. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_examples_list200_response.py +0 -0
  109. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_examples_update_request.py +0 -0
  110. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_datasets_list200_response.py +0 -0
  111. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiment.py +0 -0
  112. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiment_run.py +0 -0
  113. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiment_run_create.py +0 -0
  114. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_api.py +0 -0
  115. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_create_request.py +0 -0
  116. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_list200_response.py +0 -0
  117. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_experiments_runs_list200_response.py +0 -0
  118. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_pagination_metadata.py +0 -0
  119. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_problem.py +0 -0
  120. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_project.py +0 -0
  121. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_projects_api.py +0 -0
  122. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_projects_create_request.py +0 -0
  123. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client/test/test_projects_list200_response.py +0 -0
  124. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/api_client_README.md +0 -0
  125. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/__init__.py +0 -0
  126. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/flight/__init__.py +0 -0
  127. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/flight/flight_pb2.py +0 -0
  128. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/rec/__init__.py +0 -0
  129. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/_generated/protocol/rec/public_pb2.py +0 -0
  130. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/__init__.py +0 -0
  131. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/ml.py +0 -0
  132. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/model_mapping.json +0 -0
  133. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/openinference.py +0 -0
  134. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/pyarrow.py +0 -0
  135. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/constants/spans.py +0 -0
  136. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/__init__.py +0 -0
  137. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/errors.py +0 -0
  138. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/datasets/validation.py +0 -0
  139. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/__init__.py +0 -0
  140. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/constants.py +0 -0
  141. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/errors.py +0 -0
  142. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/embeddings/usecases.py +0 -0
  143. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/__init__.py +0 -0
  144. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/auth.py +0 -0
  145. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/base.py +0 -0
  146. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/models.py +0 -0
  147. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/spaces.py +0 -0
  148. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/exceptions/types.py +0 -0
  149. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/__init__.py +0 -0
  150. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/experiments/evaluators/exceptions.py +0 -0
  151. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/__init__.py +0 -0
  152. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/batch_validation/__init__.py +0 -0
  153. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/batch_validation/errors.py +0 -0
  154. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/ml/surrogate_explainer/__init__.py +0 -0
  155. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/projects/__init__.py +0 -0
  156. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/projects/client.py +0 -0
  157. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/__init__.py +0 -0
  158. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/columns.py +0 -0
  159. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/__init__.py +0 -0
  160. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/__init__.py +0 -0
  161. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/annotations/annotations_validation.py +0 -0
  162. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/__init__.py +0 -0
  163. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/argument_validation.py +0 -0
  164. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/common/errors.py +0 -0
  165. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/__init__.py +0 -0
  166. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/dataframe_form_validation.py +0 -0
  167. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/evals/evals_validation.py +0 -0
  168. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/metadata/__init__.py +0 -0
  169. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/__init__.py +0 -0
  170. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/dataframe_form_validation.py +0 -0
  171. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/spans_validation.py +0 -0
  172. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/spans/validation/spans/value_validation.py +0 -0
  173. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/__init__.py +0 -0
  174. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/cache.py +0 -0
  175. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/dataframe.py +0 -0
  176. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/online_tasks/__init__.py +0 -0
  177. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/openinference_conversion.py +0 -0
  178. {arize-8.0.0b2 → arize-8.0.0b4}/src/arize/utils/size.py +0 -0
@@ -41,3 +41,4 @@ docs/_build
41
41
  output/
42
42
 
43
43
  .workon
44
+ .coverage.*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arize
3
- Version: 8.0.0b2
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.13.2; extra == 'dev'
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 = "all" if exclude_none is True else exclude_none
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
- ) -> object:
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) # type: ignore
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, df: pd.DataFrame, col_name: str, transform_func: object
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) -> bool:
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:
@@ -35,7 +35,7 @@ def validate_input_value(
35
35
  if input in choices:
36
36
  return
37
37
  raise ValueError(
38
- f"{input_name} is {input}, but must be one of {', '.join(choices)}"
38
+ f"{input_name} is {input}, but must be one of {', '.join(str(c) for c in choices)}"
39
39
  )
40
40
 
41
41
 
@@ -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 Iterable
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
- ) -> Iterable[flight.Result]:
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)