fiddler-client 3.5.0.dev1__tar.gz → 3.5.0.dev2__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 (119) hide show
  1. {fiddler_client-3.5.0.dev1/fiddler_client.egg-info → fiddler_client-3.5.0.dev2}/PKG-INFO +1 -1
  2. fiddler_client-3.5.0.dev2/fiddler/VERSION +1 -0
  3. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/libs/http_client.py +0 -22
  4. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/packtools/project_attributions_helpers.py +8 -10
  5. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/model.py +1 -1
  6. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/logger.py +0 -7
  7. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2/fiddler_client.egg-info}/PKG-INFO +1 -1
  8. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler_client.egg-info/SOURCES.txt +0 -2
  9. fiddler_client-3.5.0.dev1/fiddler/VERSION +0 -1
  10. fiddler_client-3.5.0.dev1/fiddler/libs/aws.py +0 -95
  11. fiddler_client-3.5.0.dev1/fiddler/tests/test_sagemaker_auth.py +0 -75
  12. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/LICENSE.txt +0 -0
  13. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/MANIFEST.in +0 -0
  14. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/PUBLIC.md +0 -0
  15. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/README.md +0 -0
  16. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/__init__.py +0 -0
  17. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/configs.py +0 -0
  18. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/connection.py +0 -0
  19. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/__init__.py +0 -0
  20. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/alert_rule.py +0 -0
  21. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/baseline.py +0 -0
  22. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/common.py +0 -0
  23. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/dataset.py +0 -0
  24. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/events.py +0 -0
  25. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/job.py +0 -0
  26. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/model.py +0 -0
  27. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/model_deployment.py +0 -0
  28. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/constants/xai.py +0 -0
  29. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/decorators.py +0 -0
  30. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/__init__.py +0 -0
  31. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/alert_record.py +0 -0
  32. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/alert_rule.py +0 -0
  33. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/base.py +0 -0
  34. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/baseline.py +0 -0
  35. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/custom_expression.py +0 -0
  36. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/dataset.py +0 -0
  37. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/events.py +0 -0
  38. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/file.py +0 -0
  39. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/job.py +0 -0
  40. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/model.py +0 -0
  41. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/model_artifact.py +0 -0
  42. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/model_deployment.py +0 -0
  43. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/organization.py +0 -0
  44. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/project.py +0 -0
  45. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/surrogate.py +0 -0
  46. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/user.py +0 -0
  47. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/webhook.py +0 -0
  48. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/entities/xai.py +0 -0
  49. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/exceptions.py +0 -0
  50. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/libs/__init__.py +0 -0
  51. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/libs/json_encoder.py +0 -0
  52. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/libs/semver.py +0 -0
  53. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/packtools/__init__.py +0 -0
  54. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/packtools/gem.py +0 -0
  55. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/packtools/keras_ig_helpers.py +0 -0
  56. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/packtools/template_model.py +0 -0
  57. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/__init__.py +0 -0
  58. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/alert_record.py +0 -0
  59. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/alert_rule.py +0 -0
  60. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/base.py +0 -0
  61. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/baseline.py +0 -0
  62. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/custom_expression.py +0 -0
  63. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/custom_features.py +0 -0
  64. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/dataset.py +0 -0
  65. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/events.py +0 -0
  66. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/file.py +0 -0
  67. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/filter_query.py +0 -0
  68. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/job.py +0 -0
  69. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/model_deployment.py +0 -0
  70. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/model_schema.py +0 -0
  71. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/model_spec.py +0 -0
  72. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/model_task_params.py +0 -0
  73. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/organization.py +0 -0
  74. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/project.py +0 -0
  75. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/response.py +0 -0
  76. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/server_info.py +0 -0
  77. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/user.py +0 -0
  78. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/webhook.py +0 -0
  79. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/xai.py +0 -0
  80. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/schemas/xai_params.py +0 -0
  81. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/__init__.py +0 -0
  82. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/__init__.py +0 -0
  83. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_alert_record.py +0 -0
  84. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_alert_rule.py +0 -0
  85. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_baseline.py +0 -0
  86. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_custom_metric.py +0 -0
  87. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_dataset.py +0 -0
  88. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_events.py +0 -0
  89. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_files.py +0 -0
  90. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_generate_model.py +0 -0
  91. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_job.py +0 -0
  92. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_mixin.py +0 -0
  93. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_model.py +0 -0
  94. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_model_artifact.py +0 -0
  95. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_model_deployment.py +0 -0
  96. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_model_surrogate.py +0 -0
  97. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_project.py +0 -0
  98. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_segment.py +0 -0
  99. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_webhook.py +0 -0
  100. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/apis/test_xai.py +0 -0
  101. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/conftest.py +0 -0
  102. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/constants.py +0 -0
  103. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/test_connection.py +0 -0
  104. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/test_json_encoder.py +0 -0
  105. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/test_logger.py +0 -0
  106. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/test_utils.py +0 -0
  107. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/tests/utils.py +0 -0
  108. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/__init__.py +0 -0
  109. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/decorators.py +0 -0
  110. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/helpers.py +0 -0
  111. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/model_generator.py +0 -0
  112. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/validations.py +0 -0
  113. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/utils/version.py +0 -0
  114. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler/version.py +0 -0
  115. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler_client.egg-info/dependency_links.txt +0 -0
  116. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler_client.egg-info/requires.txt +0 -0
  117. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/fiddler_client.egg-info/top_level.txt +0 -0
  118. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/setup.cfg +0 -0
  119. {fiddler_client-3.5.0.dev1 → fiddler_client-3.5.0.dev2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fiddler-client
3
- Version: 3.5.0.dev1
3
+ Version: 3.5.0.dev2
4
4
  Summary: Python client for Fiddler Platform
5
5
  Home-page: https://fiddler.ai
6
6
  Author: Fiddler Labs
@@ -0,0 +1 @@
1
+ 3.5.0.dev2
@@ -8,7 +8,6 @@ import requests
8
8
  import simplejson
9
9
  from requests.adapters import HTTPAdapter
10
10
 
11
- import fiddler.libs.aws
12
11
  from fiddler.constants.common import JSON_CONTENT_TYPE
13
12
  from fiddler.exceptions import ( # pylint: disable=redefined-builtin
14
13
  ConnError,
@@ -21,15 +20,6 @@ from fiddler.utils.logger import get_logger
21
20
  logger = get_logger(__name__)
22
21
 
23
22
 
24
- # Note(JP): this is doing conditional runtime modification for AWS Hadron /
25
- # SageMaker, depending on
26
- # - environment variables set by the user
27
- # - importability of the AWS sagemaker Python SDK
28
- # TODO: type annotation w/o having to import PartnerAppAuthProvider? This thing
29
- # is either None or an instantiated auth provider.
30
- _AWS_SM_AUTH_PROVIDER = fiddler.libs.aws.conditionally_init_aws_sm_auth() # type: ignore
31
-
32
-
33
23
  class RequestClient:
34
24
  def __init__(
35
25
  self,
@@ -44,23 +34,11 @@ class RequestClient:
44
34
  self.headers = headers
45
35
  self.headers.update({'Content-Type': JSON_CONTENT_TYPE})
46
36
  self.session = requests.Session()
47
-
48
- # Note(JP): from the AWS SageMaker partner app guide.
49
- if _AWS_SM_AUTH_PROVIDER is not None:
50
- # Get callback class (`RequestsAuth` type`) from SM auth provider,
51
- # and decorate the `requests` session object with that. This is
52
- # enabling the magic of automatically mutating request headers.
53
- # Among others, this injects the SigV4 header.
54
- self.session.auth = _AWS_SM_AUTH_PROVIDER.get_auth()
55
-
56
37
  self.session.verify = verify
57
38
  adapter = HTTPAdapter(
58
39
  pool_connections=25,
59
40
  pool_maxsize=25,
60
41
  )
61
-
62
- # Does mounting the custom HTTP adapter revert the session.auth
63
- # change from above?
64
42
  self.session.mount(self.base_url, adapter)
65
43
 
66
44
  def call(
@@ -159,9 +159,9 @@ class IGTextAttributionsTF2Keras:
159
159
  att, word_tokens, tokenizer, embedding_name, feature_label
160
160
  )
161
161
  gem_container = gem.GEMContainer(contents=[gem_text])
162
- explanations_by_output[self.output_cols[output_field_index]] = (
163
- gem_container.render()
164
- )
162
+ explanations_by_output[
163
+ self.output_cols[output_field_index]
164
+ ] = gem_container.render()
165
165
 
166
166
  return explanations_by_output
167
167
 
@@ -195,12 +195,10 @@ class IGTabularAttributions:
195
195
  'Parameter attr_input_names_mapping cannot be empty when IG is enabled.'
196
196
  )
197
197
  for output_field_index, att in enumerate(attributions):
198
- explanations_by_output[self.output_cols[output_field_index]] = (
199
- get_tabular_attributions_for_output(
200
- self.input_df,
201
- att,
202
- attr_input_names_mapping=attr_input_names_mapping,
203
- )
198
+ explanations_by_output[
199
+ self.output_cols[output_field_index]
200
+ ] = get_tabular_attributions_for_output(
201
+ self.input_df, att, attr_input_names_mapping=attr_input_names_mapping
204
202
  )
205
203
  return explanations_by_output
206
204
 
@@ -388,7 +386,7 @@ def xgb_shap_transform_scale(
388
386
  base_value = 1 / (1 + np.exp(-untransformed_base_value))
389
387
 
390
388
  # Computing the original_explanation_distance to construct the distance_coefficient later on
391
- original_explanation_distance = np.sum(shap_values) # type: ignore
389
+ original_explanation_distance = np.sum(shap_values)
392
390
 
393
391
  # Computing the distance between the model_prediction and the transformed base_value
394
392
  distance_to_explain = model_prediction - base_value
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
  from typing import Dict, List, Optional
3
3
  from uuid import UUID
4
4
 
5
- from pydantic.fields import Field
5
+ from pydantic.v1 import Field
6
6
 
7
7
  from fiddler.schemas.base import BaseModel
8
8
  from fiddler.schemas.model_schema import ModelSchema
@@ -8,13 +8,6 @@ from fiddler.constants.common import LOG_FORMAT, LOGGER_NAME
8
8
  def get_logger(name: str) -> Logger:
9
9
  """Get logger instance"""
10
10
  logger: Logger = logging.getLogger(name)
11
-
12
- # Note(JP): this assumes that get_logger() is only called once per name.
13
- # Typically, the null handler is added to stop propagation of log messages
14
- # to user's stderr in case they do _not_ configure a logging outlet (think:
15
- # the null handler stops propagation into the "last resort handler").
16
- # Future: the null handler only needs to be added _once_ to the fiddler-client
17
- # logger hierarchy (to the top-level logger).
18
11
  logger.addHandler(logging.NullHandler())
19
12
  return logger
20
13
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fiddler-client
3
- Version: 3.5.0.dev1
3
+ Version: 3.5.0.dev2
4
4
  Summary: Python client for Fiddler Platform
5
5
  Home-page: https://fiddler.ai
6
6
  Author: Fiddler Labs
@@ -40,7 +40,6 @@ fiddler/entities/user.py
40
40
  fiddler/entities/webhook.py
41
41
  fiddler/entities/xai.py
42
42
  fiddler/libs/__init__.py
43
- fiddler/libs/aws.py
44
43
  fiddler/libs/http_client.py
45
44
  fiddler/libs/json_encoder.py
46
45
  fiddler/libs/semver.py
@@ -80,7 +79,6 @@ fiddler/tests/constants.py
80
79
  fiddler/tests/test_connection.py
81
80
  fiddler/tests/test_json_encoder.py
82
81
  fiddler/tests/test_logger.py
83
- fiddler/tests/test_sagemaker_auth.py
84
82
  fiddler/tests/test_utils.py
85
83
  fiddler/tests/utils.py
86
84
  fiddler/tests/apis/__init__.py
@@ -1 +0,0 @@
1
- 3.5.0.dev1
@@ -1,95 +0,0 @@
1
- # type: ignore
2
- # TODO: do type-checking soon: https://github.com/fiddler-anyprem/hadron/issues/25
3
-
4
- # Note(JP): allow for type hints using strings (so that for example
5
- # "PartnerAppAuthProvider" can be used as a type hint w/o having to import the
6
- # class).
7
- from __future__ import annotations
8
-
9
- import os
10
- from collections import namedtuple
11
- from typing import Optional
12
-
13
- from fiddler.exceptions import BaseError
14
- from fiddler.utils.logger import get_logger
15
-
16
- logger = get_logger(__name__)
17
-
18
- AwsSageMakerAuthConfig = namedtuple('AwsSageMakerAuthConfig', ['arn', 'url'])
19
-
20
-
21
- def _read_env_for_aws_sagemaker_or_raise() -> Optional[AwsSageMakerAuthConfig]:
22
- """
23
-
24
- Raise `fiddler.exceptions.BaseError` when the environment appears to be
25
- misconfigured.
26
- """
27
- av = os.getenv("AWS_PARTNER_APP_AUTH")
28
-
29
- if av is None:
30
- return None
31
-
32
- if av.lower().strip() != "true":
33
- return None
34
-
35
- # User has declared intent: activate SageMaker authentication. Require
36
- # other environment variables to be set.
37
- keys = ("AWS_PARTNER_APP_ARN", "AWS_PARTNER_APP_URL")
38
- for k in keys:
39
- errmsg = f"AWS_PARTNER_APP_AUTH is set to `{av}`, but {k} is not set"
40
- if os.getenv(k) is None:
41
- # Future: maybe have a ConfigError type?
42
- raise BaseError(errmsg)
43
-
44
- # Future: potentially do validation for got error messages, but be sure
45
- # that the validation isn't getting in the way, _ever_.
46
-
47
- # Remove leading and trailing whitespace: that's a safe operation, and
48
- # always a user/config "error". That we can correct for.
49
- arn = os.getenv("AWS_PARTNER_APP_ARN").strip() # type: ignore[union-attr]
50
- url = os.getenv("AWS_PARTNER_APP_URL").strip() # type: ignore[union-attr]
51
- return AwsSageMakerAuthConfig(arn, url)
52
-
53
-
54
- def _import_sm_sdk(c: AwsSageMakerAuthConfig): # -> "PartnerAppAuthProvider":
55
- """
56
- Return `sagemaker.PartnerAppAuthProvider` instance or raise an exception.
57
- """
58
- try:
59
- from sagemaker import PartnerAppAuthProvider
60
- except Exception as exc:
61
- errmsg = (
62
- f"The AWS_PARTNER_APP_* environment variables are set, but "
63
- f"importing a dependency failed: {exc}"
64
- )
65
- raise BaseError(errmsg)
66
-
67
- # Note(JP): can initialization of this auth provider object fail? Does it
68
- # use Internet resources? Update 1: this call is expected to fail with e.g.
69
- # `ValueError: Must specify a valid AWS_PARTNER_APP_ARN environment
70
- # variable` when this env var is not set. Update 2: this does indeed deeper
71
- # validation of the user-given config values. May throw for example
72
- # "ValueError: Must specify a valid AWS_PARTNER_APP_ARN environment
73
- # variable" when something non-ARN-looking has been provided. That is, we
74
- # can (and should) skip validating these env var values and lave this job
75
- # to the SM SDK.
76
- p = PartnerAppAuthProvider()
77
- logger.info("initialized AWS SageMaker authentication provider: %s", p)
78
- return p
79
-
80
-
81
- def conditionally_init_aws_sm_auth(): # -> Optional["PartnerAppAuthProvider"]:
82
- """
83
- Return `None` or `PartnerAppAuthProvider` instance.
84
-
85
- Raise an exception upon configuration error or when dependencies are
86
- missing.
87
- """
88
- aws_sm_auth_cfg = _read_env_for_aws_sagemaker_or_raise()
89
-
90
- logger.debug("auth config: %s", aws_sm_auth_cfg)
91
- if aws_sm_auth_cfg is not None:
92
- return _import_sm_sdk(aws_sm_auth_cfg)
93
-
94
- # Just to make this expected case explicit.
95
- return None
@@ -1,75 +0,0 @@
1
- import os
2
- import re
3
-
4
-
5
- import pytest
6
- import responses
7
- from responses import matchers
8
-
9
- from fiddler.entities.model import Model
10
- from fiddler.tests.constants import MODEL_ID, URL
11
- from fiddler.tests.apis.test_model import API_RESPONSE_200
12
-
13
-
14
- # Perform this test only if AWS_* env vars are set (so that this executes in a
15
- # controlled environment, and skipped as part of general unit test suite
16
- # invocation)
17
- @pytest.mark.skipif(
18
- os.getenv("AWS_PARTNER_APP_AUTH") is None, reason="AWS_* env vars not set"
19
- )
20
- @responses.activate
21
- def test_header_mutation() -> None:
22
- """
23
- Assume that the outer environment has set these environment variables:
24
-
25
- AWS_ACCESS_KEY_ID=dummykey
26
- AWS_SECRET_ACCESS_KEY=dummysecret
27
- AWS_PARTNER_APP_ARN=arn:aws:sagemaker:us-west-2:123456789012:partner-app/Partner/app-678901234567
28
- AWS_PARTNER_APP_URL=https://app-678901234567.us-west-2.mlapp.sagemaker.aws
29
-
30
- Note: boto.credentials is not affected by monkeypatch.setenv.
31
- fiddler-client initialization happens before entering this test, and
32
- the AWS_PARTNER_* vars need to be set _before_ entering this test.
33
- """
34
-
35
- arn = (
36
- "arn:aws:sagemaker:us-west-2:123456789012:partner-app/Partner/app-678901234567"
37
- )
38
-
39
- responses.get(
40
- url=f'{URL}/v3/models/{MODEL_ID}',
41
- json=API_RESPONSE_200,
42
- match=[
43
- # regex-based header matching was added in
44
- # https://github.com/getsentry/responses/pull/663 which is also the
45
- # best documentation for that feature.
46
- matchers.header_matcher(
47
- {
48
- # Note(JP): note how the dummy AWS_ACCESS_KEY_ID appears in
49
- # the value -- the sagemaker wrapper creates a new
50
- # Authorization header value with a SigV4 signature, using
51
- # AWS credentials.
52
- 'Authorization': re.compile(
53
- r'AWS4-HMAC-SHA256 Credential=dummykey/.+'
54
- ),
55
- # The sagemaker wrapper moves the original Authorization
56
- # header here. In this test suite we typically set the
57
- # value 'Bearer footoken'.
58
- 'X-Amz-Partner-App-Authorization': 'Bearer footoken',
59
- 'X-Amz-Target': 'SageMaker.CallPartnerAppApi',
60
- 'X-Mlapp-Sm-App-Server-Arn': arn,
61
- # These two remaining headers are by default set by the
62
- # client.
63
- 'Content-Type': 'application/json',
64
- 'X-Fiddler-Client-Name': 'python-sdk',
65
- }
66
- ),
67
- ],
68
- )
69
-
70
- # This call fails if it does not result in an HTTP request that matches
71
- # the pattern/structure defined with the `responses.get(...)` call above.
72
- # The error will say "the call doesn't match any registered mock" and
73
- # the detailed exception message allows for inspecting the headers seen
74
- # vs. the headers expected.
75
- Model.get(id_=MODEL_ID)