levelfour 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- levelfour/__init__.py +495 -0
- levelfour/api_keys/__init__.py +34 -0
- levelfour/api_keys/client.py +337 -0
- levelfour/api_keys/raw_client.py +621 -0
- levelfour/api_keys/types/__init__.py +34 -0
- levelfour/api_keys/types/create_api_key_request_scope.py +5 -0
- levelfour/async_levelfour_client.py +39 -0
- levelfour/base_client.py +346 -0
- levelfour/client.py +54 -0
- levelfour/core/__init__.py +127 -0
- levelfour/core/api_error.py +23 -0
- levelfour/core/client_wrapper.py +105 -0
- levelfour/core/datetime_utils.py +70 -0
- levelfour/core/file.py +67 -0
- levelfour/core/force_multipart.py +18 -0
- levelfour/core/http_client.py +776 -0
- levelfour/core/http_response.py +59 -0
- levelfour/core/http_sse/__init__.py +42 -0
- levelfour/core/http_sse/_api.py +112 -0
- levelfour/core/http_sse/_decoders.py +61 -0
- levelfour/core/http_sse/_exceptions.py +7 -0
- levelfour/core/http_sse/_models.py +17 -0
- levelfour/core/jsonable_encoder.py +108 -0
- levelfour/core/logging.py +107 -0
- levelfour/core/pagination.py +82 -0
- levelfour/core/pydantic_utilities.py +577 -0
- levelfour/core/query_encoder.py +58 -0
- levelfour/core/remove_none_from_dict.py +11 -0
- levelfour/core/request_options.py +35 -0
- levelfour/core/serialization.py +276 -0
- levelfour/errors/__init__.py +40 -0
- levelfour/errors/forbidden_error.py +11 -0
- levelfour/errors/unauthorized_error.py +11 -0
- levelfour/errors/unprocessable_entity_error.py +11 -0
- levelfour/evaluation/__init__.py +4 -0
- levelfour/evaluation/client.py +102 -0
- levelfour/evaluation/raw_client.py +141 -0
- levelfour/exceptions.py +63 -0
- levelfour/health/__init__.py +4 -0
- levelfour/health/client.py +163 -0
- levelfour/health/raw_client.py +164 -0
- levelfour/integrations/__init__.py +0 -0
- levelfour/integrations/django.py +26 -0
- levelfour/integrations/fastapi.py +39 -0
- levelfour/integrations/telemetry.py +66 -0
- levelfour/levelfour_client.py +47 -0
- levelfour/pagination.py +84 -0
- levelfour/pr_analysis/__init__.py +4 -0
- levelfour/pr_analysis/client.py +408 -0
- levelfour/pr_analysis/raw_client.py +620 -0
- levelfour/pr_analysis_actions/__init__.py +4 -0
- levelfour/pr_analysis_actions/client.py +588 -0
- levelfour/pr_analysis_actions/raw_client.py +939 -0
- levelfour/pr_analysis_installations/__init__.py +4 -0
- levelfour/pr_analysis_installations/client.py +470 -0
- levelfour/pr_analysis_installations/raw_client.py +868 -0
- levelfour/providers/__init__.py +34 -0
- levelfour/providers/client.py +1504 -0
- levelfour/providers/raw_client.py +2398 -0
- levelfour/providers/types/__init__.py +36 -0
- levelfour/providers/types/list_spending_breakdown_providers_response.py +11 -0
- levelfour/py.typed +0 -0
- levelfour/recommendations/__init__.py +4 -0
- levelfour/recommendations/client.py +1018 -0
- levelfour/recommendations/raw_client.py +1810 -0
- levelfour/savings/__init__.py +4 -0
- levelfour/savings/client.py +401 -0
- levelfour/savings/raw_client.py +624 -0
- levelfour/spending/__init__.py +34 -0
- levelfour/spending/client.py +437 -0
- levelfour/spending/raw_client.py +684 -0
- levelfour/spending/types/__init__.py +34 -0
- levelfour/spending/types/list_breakdown_spending_response.py +12 -0
- levelfour/types/__init__.py +413 -0
- levelfour/types/accept_terms_data.py +25 -0
- levelfour/types/accept_terms_response.py +27 -0
- levelfour/types/action_request.py +42 -0
- levelfour/types/api_key_created_data.py +28 -0
- levelfour/types/api_key_data.py +27 -0
- levelfour/types/authentication_error.py +5 -0
- levelfour/types/authorization_error.py +5 -0
- levelfour/types/bad_request_error.py +5 -0
- levelfour/types/comparison_item.py +32 -0
- levelfour/types/complete_wizard_data.py +27 -0
- levelfour/types/complete_wizard_response.py +27 -0
- levelfour/types/conflict_error.py +5 -0
- levelfour/types/cost_breakdown_data.py +35 -0
- levelfour/types/cost_breakdown_item.py +71 -0
- levelfour/types/cost_breakdown_raw_data.py +37 -0
- levelfour/types/cost_breakdown_raw_response.py +27 -0
- levelfour/types/cost_breakdown_response.py +27 -0
- levelfour/types/costs_breakdown_chart_data.py +48 -0
- levelfour/types/costs_breakdown_chart_response.py +27 -0
- levelfour/types/costs_breakdown_data_point.py +46 -0
- levelfour/types/costs_breakdown_grouped_chart_data.py +52 -0
- levelfour/types/costs_breakdown_grouped_chart_response.py +27 -0
- levelfour/types/costs_breakdown_grouped_data_point.py +36 -0
- levelfour/types/costs_breakdown_totals.py +41 -0
- levelfour/types/create_api_key_response.py +23 -0
- levelfour/types/daily_spending_breakdown_data.py +42 -0
- levelfour/types/daily_spending_breakdown_response.py +27 -0
- levelfour/types/daily_spending_data_point.py +31 -0
- levelfour/types/dashboard_summary_data.py +72 -0
- levelfour/types/dashboard_summary_response.py +27 -0
- levelfour/types/delete_endpoint_data.py +20 -0
- levelfour/types/delete_endpoint_response.py +23 -0
- levelfour/types/endpoint_data.py +23 -0
- levelfour/types/error_response.py +23 -0
- levelfour/types/error_response_error.py +21 -0
- levelfour/types/evaluation_status_data.py +71 -0
- levelfour/types/evaluation_status_response.py +27 -0
- levelfour/types/execution_log_command.py +21 -0
- levelfour/types/execution_log_entry.py +23 -0
- levelfour/types/execution_step_schema.py +23 -0
- levelfour/types/http_validation_error.py +20 -0
- levelfour/types/implementation_method_data.py +25 -0
- levelfour/types/implementation_method_response.py +27 -0
- levelfour/types/implementation_step.py +27 -0
- levelfour/types/internal_server_error.py +5 -0
- levelfour/types/list_api_keys_data.py +21 -0
- levelfour/types/list_api_keys_response.py +23 -0
- levelfour/types/list_endpoints_response.py +23 -0
- levelfour/types/metric_data_point.py +27 -0
- levelfour/types/metric_series.py +40 -0
- levelfour/types/metric_series_entry.py +25 -0
- levelfour/types/monthly_spending_data.py +27 -0
- levelfour/types/monthly_spending_data_point.py +31 -0
- levelfour/types/monthly_spending_response.py +27 -0
- levelfour/types/not_found_error.py +5 -0
- levelfour/types/pagination_meta.py +51 -0
- levelfour/types/processing_recommendation_item.py +61 -0
- levelfour/types/processing_recommendations_data.py +28 -0
- levelfour/types/processing_recommendations_response.py +27 -0
- levelfour/types/provider.py +46 -0
- levelfour/types/provider_breakdown_data.py +31 -0
- levelfour/types/provider_breakdown_item.py +77 -0
- levelfour/types/provider_breakdown_response.py +27 -0
- levelfour/types/provider_filter_options_data.py +51 -0
- levelfour/types/provider_filter_options_response.py +27 -0
- levelfour/types/provider_potential_savings_summary_data.py +46 -0
- levelfour/types/provider_potential_savings_summary_response.py +27 -0
- levelfour/types/provider_recommendations_summary_data.py +37 -0
- levelfour/types/provider_recommendations_summary_response.py +27 -0
- levelfour/types/provider_saved_summary_data.py +56 -0
- levelfour/types/provider_saved_summary_response.py +27 -0
- levelfour/types/provider_service_breakdown_data.py +65 -0
- levelfour/types/provider_service_breakdown_item.py +72 -0
- levelfour/types/provider_service_breakdown_raw_data.py +62 -0
- levelfour/types/provider_service_breakdown_raw_response.py +27 -0
- levelfour/types/provider_service_breakdown_response.py +27 -0
- levelfour/types/provider_service_costs_breakdown_data.py +62 -0
- levelfour/types/provider_service_costs_breakdown_response.py +27 -0
- levelfour/types/provider_service_costs_data_point.py +36 -0
- levelfour/types/provider_spending.py +61 -0
- levelfour/types/provider_spending_summary_data.py +67 -0
- levelfour/types/provider_spending_summary_response.py +27 -0
- levelfour/types/provider_timeline_data.py +57 -0
- levelfour/types/provider_timeline_response.py +27 -0
- levelfour/types/provider_top_service.py +36 -0
- levelfour/types/providers_summary_data.py +24 -0
- levelfour/types/providers_summary_response.py +27 -0
- levelfour/types/rate_limit_error.py +5 -0
- levelfour/types/recommendation_actions.py +60 -0
- levelfour/types/recommendation_detail.py +42 -0
- levelfour/types/recommendation_detail_response.py +27 -0
- levelfour/types/recommendation_filter_options_data.py +41 -0
- levelfour/types/recommendation_filter_options_response.py +27 -0
- levelfour/types/recommendation_item.py +36 -0
- levelfour/types/recommendation_wizard_data.py +173 -0
- levelfour/types/recommendation_wizard_data_metrics.py +7 -0
- levelfour/types/recommendation_wizard_response.py +27 -0
- levelfour/types/recommendations_breakdown_data.py +26 -0
- levelfour/types/recommendations_breakdown_response.py +27 -0
- levelfour/types/recommendations_overview_data.py +51 -0
- levelfour/types/recommendations_overview_response.py +27 -0
- levelfour/types/register_endpoint_response.py +23 -0
- levelfour/types/resource_change.py +42 -0
- levelfour/types/resource_snapshot.py +21 -0
- levelfour/types/revoke_api_key_data.py +20 -0
- levelfour/types/revoke_api_key_response.py +23 -0
- levelfour/types/risk_assessment.py +29 -0
- levelfour/types/risk_factor.py +27 -0
- levelfour/types/saved_breakdown_data.py +31 -0
- levelfour/types/saved_breakdown_response.py +27 -0
- levelfour/types/saved_by_provider_breakdown_data.py +31 -0
- levelfour/types/saved_by_provider_breakdown_response.py +27 -0
- levelfour/types/saved_by_provider_item.py +76 -0
- levelfour/types/saved_item.py +35 -0
- levelfour/types/saved_provider_summary.py +36 -0
- levelfour/types/saved_summary_data.py +57 -0
- levelfour/types/saved_summary_response.py +27 -0
- levelfour/types/savings_decision_data.py +28 -0
- levelfour/types/savings_decision_response.py +27 -0
- levelfour/types/spending_by_date_item.py +36 -0
- levelfour/types/top_recommendation.py +56 -0
- levelfour/types/trigger_info.py +22 -0
- levelfour/types/update_tag_data.py +20 -0
- levelfour/types/update_tag_response.py +23 -0
- levelfour/types/validation_error.py +24 -0
- levelfour/types/validation_error_loc_item.py +5 -0
- levelfour/webhooks/__init__.py +4 -0
- levelfour/webhooks/client.py +273 -0
- levelfour/webhooks/raw_client.py +483 -0
- levelfour/webhooks/verifier.py +61 -0
- levelfour-0.1.0.dist-info/METADATA +12 -0
- levelfour-0.1.0.dist-info/RECORD +208 -0
- levelfour-0.1.0.dist-info/WHEEL +5 -0
- levelfour-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1810 @@
|
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from json.decoder import JSONDecodeError
|
|
5
|
+
|
|
6
|
+
from ..core.api_error import ApiError
|
|
7
|
+
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
|
|
8
|
+
from ..core.http_response import AsyncHttpResponse, HttpResponse
|
|
9
|
+
from ..core.jsonable_encoder import jsonable_encoder
|
|
10
|
+
from ..core.pagination import AsyncPager, SyncPager
|
|
11
|
+
from ..core.pydantic_utilities import parse_obj_as
|
|
12
|
+
from ..core.request_options import RequestOptions
|
|
13
|
+
from ..errors.forbidden_error import ForbiddenError
|
|
14
|
+
from ..errors.unauthorized_error import UnauthorizedError
|
|
15
|
+
from ..errors.unprocessable_entity_error import UnprocessableEntityError
|
|
16
|
+
from ..types.accept_terms_response import AcceptTermsResponse
|
|
17
|
+
from ..types.authentication_error import AuthenticationError
|
|
18
|
+
from ..types.authorization_error import AuthorizationError
|
|
19
|
+
from ..types.complete_wizard_response import CompleteWizardResponse
|
|
20
|
+
from ..types.http_validation_error import HttpValidationError
|
|
21
|
+
from ..types.implementation_method_response import ImplementationMethodResponse
|
|
22
|
+
from ..types.processing_recommendations_response import ProcessingRecommendationsResponse
|
|
23
|
+
from ..types.providers_summary_response import ProvidersSummaryResponse
|
|
24
|
+
from ..types.recommendation_detail_response import RecommendationDetailResponse
|
|
25
|
+
from ..types.recommendation_item import RecommendationItem
|
|
26
|
+
from ..types.recommendation_wizard_response import RecommendationWizardResponse
|
|
27
|
+
from ..types.recommendations_breakdown_response import RecommendationsBreakdownResponse
|
|
28
|
+
from ..types.recommendations_overview_response import RecommendationsOverviewResponse
|
|
29
|
+
from ..types.savings_decision_response import SavingsDecisionResponse
|
|
30
|
+
from ..types.update_tag_response import UpdateTagResponse
|
|
31
|
+
|
|
32
|
+
# this is used as the default value for optional parameters
|
|
33
|
+
OMIT = typing.cast(typing.Any, ...)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class RawRecommendationsClient:
|
|
37
|
+
def __init__(self, *, client_wrapper: SyncClientWrapper):
|
|
38
|
+
self._client_wrapper = client_wrapper
|
|
39
|
+
|
|
40
|
+
def get_summary(
|
|
41
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
42
|
+
) -> HttpResponse[ProvidersSummaryResponse]:
|
|
43
|
+
"""
|
|
44
|
+
Returns provider-level aggregation for the carousel view (AWS, GCP, Azure, K8s)
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
request_options : typing.Optional[RequestOptions]
|
|
49
|
+
Request-specific configuration.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
HttpResponse[ProvidersSummaryResponse]
|
|
54
|
+
Successful Response
|
|
55
|
+
"""
|
|
56
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
57
|
+
"api/v1/recommendations/summary",
|
|
58
|
+
method="GET",
|
|
59
|
+
request_options=request_options,
|
|
60
|
+
)
|
|
61
|
+
try:
|
|
62
|
+
if 200 <= _response.status_code < 300:
|
|
63
|
+
_data = typing.cast(
|
|
64
|
+
ProvidersSummaryResponse,
|
|
65
|
+
parse_obj_as(
|
|
66
|
+
type_=ProvidersSummaryResponse, # type: ignore
|
|
67
|
+
object_=_response.json(),
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
return HttpResponse(response=_response, data=_data)
|
|
71
|
+
if _response.status_code == 401:
|
|
72
|
+
raise UnauthorizedError(
|
|
73
|
+
headers=dict(_response.headers),
|
|
74
|
+
body=typing.cast(
|
|
75
|
+
AuthenticationError,
|
|
76
|
+
parse_obj_as(
|
|
77
|
+
type_=AuthenticationError, # type: ignore
|
|
78
|
+
object_=_response.json(),
|
|
79
|
+
),
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
if _response.status_code == 403:
|
|
83
|
+
raise ForbiddenError(
|
|
84
|
+
headers=dict(_response.headers),
|
|
85
|
+
body=typing.cast(
|
|
86
|
+
AuthorizationError,
|
|
87
|
+
parse_obj_as(
|
|
88
|
+
type_=AuthorizationError, # type: ignore
|
|
89
|
+
object_=_response.json(),
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
_response_json = _response.json()
|
|
94
|
+
except JSONDecodeError:
|
|
95
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
96
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
97
|
+
|
|
98
|
+
def get_potential_savings_summary(
|
|
99
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
100
|
+
) -> HttpResponse[ProvidersSummaryResponse]:
|
|
101
|
+
"""
|
|
102
|
+
Returns potential savings summary grouped by provider (from dashboard_potential_savings)
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
request_options : typing.Optional[RequestOptions]
|
|
107
|
+
Request-specific configuration.
|
|
108
|
+
|
|
109
|
+
Returns
|
|
110
|
+
-------
|
|
111
|
+
HttpResponse[ProvidersSummaryResponse]
|
|
112
|
+
Successful Response
|
|
113
|
+
"""
|
|
114
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
115
|
+
"api/v1/recommendations/potential-savings/summary",
|
|
116
|
+
method="GET",
|
|
117
|
+
request_options=request_options,
|
|
118
|
+
)
|
|
119
|
+
try:
|
|
120
|
+
if 200 <= _response.status_code < 300:
|
|
121
|
+
_data = typing.cast(
|
|
122
|
+
ProvidersSummaryResponse,
|
|
123
|
+
parse_obj_as(
|
|
124
|
+
type_=ProvidersSummaryResponse, # type: ignore
|
|
125
|
+
object_=_response.json(),
|
|
126
|
+
),
|
|
127
|
+
)
|
|
128
|
+
return HttpResponse(response=_response, data=_data)
|
|
129
|
+
if _response.status_code == 401:
|
|
130
|
+
raise UnauthorizedError(
|
|
131
|
+
headers=dict(_response.headers),
|
|
132
|
+
body=typing.cast(
|
|
133
|
+
AuthenticationError,
|
|
134
|
+
parse_obj_as(
|
|
135
|
+
type_=AuthenticationError, # type: ignore
|
|
136
|
+
object_=_response.json(),
|
|
137
|
+
),
|
|
138
|
+
),
|
|
139
|
+
)
|
|
140
|
+
if _response.status_code == 403:
|
|
141
|
+
raise ForbiddenError(
|
|
142
|
+
headers=dict(_response.headers),
|
|
143
|
+
body=typing.cast(
|
|
144
|
+
AuthorizationError,
|
|
145
|
+
parse_obj_as(
|
|
146
|
+
type_=AuthorizationError, # type: ignore
|
|
147
|
+
object_=_response.json(),
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
_response_json = _response.json()
|
|
152
|
+
except JSONDecodeError:
|
|
153
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
154
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
155
|
+
|
|
156
|
+
def list(
|
|
157
|
+
self,
|
|
158
|
+
*,
|
|
159
|
+
page: typing.Optional[int] = None,
|
|
160
|
+
page_size: typing.Optional[int] = None,
|
|
161
|
+
sort_by: typing.Optional[str] = None,
|
|
162
|
+
sort_order: typing.Optional[str] = None,
|
|
163
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
164
|
+
) -> SyncPager[RecommendationItem, RecommendationsBreakdownResponse]:
|
|
165
|
+
"""
|
|
166
|
+
Returns paginated list of all recommendations with actions
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
page : typing.Optional[int]
|
|
171
|
+
Page number (1-indexed)
|
|
172
|
+
|
|
173
|
+
page_size : typing.Optional[int]
|
|
174
|
+
Items per page (max 100)
|
|
175
|
+
|
|
176
|
+
sort_by : typing.Optional[str]
|
|
177
|
+
Field to sort by (recommendation_id, service, environment, monthly_savings, annual_savings, savings_percentage, analysis_period, created_at)
|
|
178
|
+
|
|
179
|
+
sort_order : typing.Optional[str]
|
|
180
|
+
Sort order (asc or desc)
|
|
181
|
+
|
|
182
|
+
request_options : typing.Optional[RequestOptions]
|
|
183
|
+
Request-specific configuration.
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
SyncPager[RecommendationItem, RecommendationsBreakdownResponse]
|
|
188
|
+
Successful Response
|
|
189
|
+
"""
|
|
190
|
+
page = page if page is not None else 1
|
|
191
|
+
|
|
192
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
193
|
+
"api/v1/recommendations",
|
|
194
|
+
method="GET",
|
|
195
|
+
params={
|
|
196
|
+
"page": page,
|
|
197
|
+
"page_size": page_size,
|
|
198
|
+
"sort_by": sort_by,
|
|
199
|
+
"sort_order": sort_order,
|
|
200
|
+
},
|
|
201
|
+
request_options=request_options,
|
|
202
|
+
)
|
|
203
|
+
try:
|
|
204
|
+
if 200 <= _response.status_code < 300:
|
|
205
|
+
_parsed_response = typing.cast(
|
|
206
|
+
RecommendationsBreakdownResponse,
|
|
207
|
+
parse_obj_as(
|
|
208
|
+
type_=RecommendationsBreakdownResponse, # type: ignore
|
|
209
|
+
object_=_response.json(),
|
|
210
|
+
),
|
|
211
|
+
)
|
|
212
|
+
_items = _parsed_response.data.items if _parsed_response.data is not None else []
|
|
213
|
+
|
|
214
|
+
_has_next = True
|
|
215
|
+
_get_next = lambda: self.list(
|
|
216
|
+
page=page + 1,
|
|
217
|
+
page_size=page_size,
|
|
218
|
+
sort_by=sort_by,
|
|
219
|
+
sort_order=sort_order,
|
|
220
|
+
request_options=request_options,
|
|
221
|
+
)
|
|
222
|
+
return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
|
|
223
|
+
if _response.status_code == 401:
|
|
224
|
+
raise UnauthorizedError(
|
|
225
|
+
headers=dict(_response.headers),
|
|
226
|
+
body=typing.cast(
|
|
227
|
+
AuthenticationError,
|
|
228
|
+
parse_obj_as(
|
|
229
|
+
type_=AuthenticationError, # type: ignore
|
|
230
|
+
object_=_response.json(),
|
|
231
|
+
),
|
|
232
|
+
),
|
|
233
|
+
)
|
|
234
|
+
if _response.status_code == 403:
|
|
235
|
+
raise ForbiddenError(
|
|
236
|
+
headers=dict(_response.headers),
|
|
237
|
+
body=typing.cast(
|
|
238
|
+
AuthorizationError,
|
|
239
|
+
parse_obj_as(
|
|
240
|
+
type_=AuthorizationError, # type: ignore
|
|
241
|
+
object_=_response.json(),
|
|
242
|
+
),
|
|
243
|
+
),
|
|
244
|
+
)
|
|
245
|
+
if _response.status_code == 422:
|
|
246
|
+
raise UnprocessableEntityError(
|
|
247
|
+
headers=dict(_response.headers),
|
|
248
|
+
body=typing.cast(
|
|
249
|
+
HttpValidationError,
|
|
250
|
+
parse_obj_as(
|
|
251
|
+
type_=HttpValidationError, # type: ignore
|
|
252
|
+
object_=_response.json(),
|
|
253
|
+
),
|
|
254
|
+
),
|
|
255
|
+
)
|
|
256
|
+
_response_json = _response.json()
|
|
257
|
+
except JSONDecodeError:
|
|
258
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
259
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
260
|
+
|
|
261
|
+
def get_overview(
|
|
262
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
263
|
+
) -> HttpResponse[RecommendationsOverviewResponse]:
|
|
264
|
+
"""
|
|
265
|
+
Returns recommendations overview metrics across all providers (for dashboard)
|
|
266
|
+
|
|
267
|
+
Parameters
|
|
268
|
+
----------
|
|
269
|
+
request_options : typing.Optional[RequestOptions]
|
|
270
|
+
Request-specific configuration.
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
HttpResponse[RecommendationsOverviewResponse]
|
|
275
|
+
Successful Response
|
|
276
|
+
"""
|
|
277
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
278
|
+
"api/v1/recommendations/overview",
|
|
279
|
+
method="GET",
|
|
280
|
+
request_options=request_options,
|
|
281
|
+
)
|
|
282
|
+
try:
|
|
283
|
+
if 200 <= _response.status_code < 300:
|
|
284
|
+
_data = typing.cast(
|
|
285
|
+
RecommendationsOverviewResponse,
|
|
286
|
+
parse_obj_as(
|
|
287
|
+
type_=RecommendationsOverviewResponse, # type: ignore
|
|
288
|
+
object_=_response.json(),
|
|
289
|
+
),
|
|
290
|
+
)
|
|
291
|
+
return HttpResponse(response=_response, data=_data)
|
|
292
|
+
if _response.status_code == 401:
|
|
293
|
+
raise UnauthorizedError(
|
|
294
|
+
headers=dict(_response.headers),
|
|
295
|
+
body=typing.cast(
|
|
296
|
+
AuthenticationError,
|
|
297
|
+
parse_obj_as(
|
|
298
|
+
type_=AuthenticationError, # type: ignore
|
|
299
|
+
object_=_response.json(),
|
|
300
|
+
),
|
|
301
|
+
),
|
|
302
|
+
)
|
|
303
|
+
if _response.status_code == 403:
|
|
304
|
+
raise ForbiddenError(
|
|
305
|
+
headers=dict(_response.headers),
|
|
306
|
+
body=typing.cast(
|
|
307
|
+
AuthorizationError,
|
|
308
|
+
parse_obj_as(
|
|
309
|
+
type_=AuthorizationError, # type: ignore
|
|
310
|
+
object_=_response.json(),
|
|
311
|
+
),
|
|
312
|
+
),
|
|
313
|
+
)
|
|
314
|
+
_response_json = _response.json()
|
|
315
|
+
except JSONDecodeError:
|
|
316
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
317
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
318
|
+
|
|
319
|
+
def get_processing(
|
|
320
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
321
|
+
) -> HttpResponse[ProcessingRecommendationsResponse]:
|
|
322
|
+
"""
|
|
323
|
+
Returns all recommendations currently in processing status
|
|
324
|
+
|
|
325
|
+
Parameters
|
|
326
|
+
----------
|
|
327
|
+
request_options : typing.Optional[RequestOptions]
|
|
328
|
+
Request-specific configuration.
|
|
329
|
+
|
|
330
|
+
Returns
|
|
331
|
+
-------
|
|
332
|
+
HttpResponse[ProcessingRecommendationsResponse]
|
|
333
|
+
Successful Response
|
|
334
|
+
"""
|
|
335
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
336
|
+
"api/v1/recommendations/processing",
|
|
337
|
+
method="GET",
|
|
338
|
+
request_options=request_options,
|
|
339
|
+
)
|
|
340
|
+
try:
|
|
341
|
+
if 200 <= _response.status_code < 300:
|
|
342
|
+
_data = typing.cast(
|
|
343
|
+
ProcessingRecommendationsResponse,
|
|
344
|
+
parse_obj_as(
|
|
345
|
+
type_=ProcessingRecommendationsResponse, # type: ignore
|
|
346
|
+
object_=_response.json(),
|
|
347
|
+
),
|
|
348
|
+
)
|
|
349
|
+
return HttpResponse(response=_response, data=_data)
|
|
350
|
+
if _response.status_code == 401:
|
|
351
|
+
raise UnauthorizedError(
|
|
352
|
+
headers=dict(_response.headers),
|
|
353
|
+
body=typing.cast(
|
|
354
|
+
AuthenticationError,
|
|
355
|
+
parse_obj_as(
|
|
356
|
+
type_=AuthenticationError, # type: ignore
|
|
357
|
+
object_=_response.json(),
|
|
358
|
+
),
|
|
359
|
+
),
|
|
360
|
+
)
|
|
361
|
+
if _response.status_code == 403:
|
|
362
|
+
raise ForbiddenError(
|
|
363
|
+
headers=dict(_response.headers),
|
|
364
|
+
body=typing.cast(
|
|
365
|
+
AuthorizationError,
|
|
366
|
+
parse_obj_as(
|
|
367
|
+
type_=AuthorizationError, # type: ignore
|
|
368
|
+
object_=_response.json(),
|
|
369
|
+
),
|
|
370
|
+
),
|
|
371
|
+
)
|
|
372
|
+
_response_json = _response.json()
|
|
373
|
+
except JSONDecodeError:
|
|
374
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
375
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
376
|
+
|
|
377
|
+
def get_details(
|
|
378
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
379
|
+
) -> HttpResponse[RecommendationDetailResponse]:
|
|
380
|
+
"""
|
|
381
|
+
Returns complete details for a specific recommendation
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
recommendation_id : str
|
|
386
|
+
|
|
387
|
+
request_options : typing.Optional[RequestOptions]
|
|
388
|
+
Request-specific configuration.
|
|
389
|
+
|
|
390
|
+
Returns
|
|
391
|
+
-------
|
|
392
|
+
HttpResponse[RecommendationDetailResponse]
|
|
393
|
+
Successful Response
|
|
394
|
+
"""
|
|
395
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
396
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/details",
|
|
397
|
+
method="GET",
|
|
398
|
+
request_options=request_options,
|
|
399
|
+
)
|
|
400
|
+
try:
|
|
401
|
+
if 200 <= _response.status_code < 300:
|
|
402
|
+
_data = typing.cast(
|
|
403
|
+
RecommendationDetailResponse,
|
|
404
|
+
parse_obj_as(
|
|
405
|
+
type_=RecommendationDetailResponse, # type: ignore
|
|
406
|
+
object_=_response.json(),
|
|
407
|
+
),
|
|
408
|
+
)
|
|
409
|
+
return HttpResponse(response=_response, data=_data)
|
|
410
|
+
if _response.status_code == 401:
|
|
411
|
+
raise UnauthorizedError(
|
|
412
|
+
headers=dict(_response.headers),
|
|
413
|
+
body=typing.cast(
|
|
414
|
+
AuthenticationError,
|
|
415
|
+
parse_obj_as(
|
|
416
|
+
type_=AuthenticationError, # type: ignore
|
|
417
|
+
object_=_response.json(),
|
|
418
|
+
),
|
|
419
|
+
),
|
|
420
|
+
)
|
|
421
|
+
if _response.status_code == 403:
|
|
422
|
+
raise ForbiddenError(
|
|
423
|
+
headers=dict(_response.headers),
|
|
424
|
+
body=typing.cast(
|
|
425
|
+
AuthorizationError,
|
|
426
|
+
parse_obj_as(
|
|
427
|
+
type_=AuthorizationError, # type: ignore
|
|
428
|
+
object_=_response.json(),
|
|
429
|
+
),
|
|
430
|
+
),
|
|
431
|
+
)
|
|
432
|
+
if _response.status_code == 422:
|
|
433
|
+
raise UnprocessableEntityError(
|
|
434
|
+
headers=dict(_response.headers),
|
|
435
|
+
body=typing.cast(
|
|
436
|
+
HttpValidationError,
|
|
437
|
+
parse_obj_as(
|
|
438
|
+
type_=HttpValidationError, # type: ignore
|
|
439
|
+
object_=_response.json(),
|
|
440
|
+
),
|
|
441
|
+
),
|
|
442
|
+
)
|
|
443
|
+
_response_json = _response.json()
|
|
444
|
+
except JSONDecodeError:
|
|
445
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
446
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
447
|
+
|
|
448
|
+
def get_wizard(
|
|
449
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
450
|
+
) -> HttpResponse[RecommendationWizardResponse]:
|
|
451
|
+
"""
|
|
452
|
+
Returns recommendation details for the Save Now wizard flow
|
|
453
|
+
|
|
454
|
+
Parameters
|
|
455
|
+
----------
|
|
456
|
+
recommendation_id : str
|
|
457
|
+
|
|
458
|
+
request_options : typing.Optional[RequestOptions]
|
|
459
|
+
Request-specific configuration.
|
|
460
|
+
|
|
461
|
+
Returns
|
|
462
|
+
-------
|
|
463
|
+
HttpResponse[RecommendationWizardResponse]
|
|
464
|
+
Successful Response
|
|
465
|
+
"""
|
|
466
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
467
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}",
|
|
468
|
+
method="GET",
|
|
469
|
+
request_options=request_options,
|
|
470
|
+
)
|
|
471
|
+
try:
|
|
472
|
+
if 200 <= _response.status_code < 300:
|
|
473
|
+
_data = typing.cast(
|
|
474
|
+
RecommendationWizardResponse,
|
|
475
|
+
parse_obj_as(
|
|
476
|
+
type_=RecommendationWizardResponse, # type: ignore
|
|
477
|
+
object_=_response.json(),
|
|
478
|
+
),
|
|
479
|
+
)
|
|
480
|
+
return HttpResponse(response=_response, data=_data)
|
|
481
|
+
if _response.status_code == 401:
|
|
482
|
+
raise UnauthorizedError(
|
|
483
|
+
headers=dict(_response.headers),
|
|
484
|
+
body=typing.cast(
|
|
485
|
+
AuthenticationError,
|
|
486
|
+
parse_obj_as(
|
|
487
|
+
type_=AuthenticationError, # type: ignore
|
|
488
|
+
object_=_response.json(),
|
|
489
|
+
),
|
|
490
|
+
),
|
|
491
|
+
)
|
|
492
|
+
if _response.status_code == 403:
|
|
493
|
+
raise ForbiddenError(
|
|
494
|
+
headers=dict(_response.headers),
|
|
495
|
+
body=typing.cast(
|
|
496
|
+
AuthorizationError,
|
|
497
|
+
parse_obj_as(
|
|
498
|
+
type_=AuthorizationError, # type: ignore
|
|
499
|
+
object_=_response.json(),
|
|
500
|
+
),
|
|
501
|
+
),
|
|
502
|
+
)
|
|
503
|
+
if _response.status_code == 422:
|
|
504
|
+
raise UnprocessableEntityError(
|
|
505
|
+
headers=dict(_response.headers),
|
|
506
|
+
body=typing.cast(
|
|
507
|
+
HttpValidationError,
|
|
508
|
+
parse_obj_as(
|
|
509
|
+
type_=HttpValidationError, # type: ignore
|
|
510
|
+
object_=_response.json(),
|
|
511
|
+
),
|
|
512
|
+
),
|
|
513
|
+
)
|
|
514
|
+
_response_json = _response.json()
|
|
515
|
+
except JSONDecodeError:
|
|
516
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
517
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
518
|
+
|
|
519
|
+
def accept_terms(
|
|
520
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
521
|
+
) -> HttpResponse[AcceptTermsResponse]:
|
|
522
|
+
"""
|
|
523
|
+
Records user acceptance of terms and conditions for a recommendation
|
|
524
|
+
|
|
525
|
+
Parameters
|
|
526
|
+
----------
|
|
527
|
+
recommendation_id : str
|
|
528
|
+
|
|
529
|
+
request_options : typing.Optional[RequestOptions]
|
|
530
|
+
Request-specific configuration.
|
|
531
|
+
|
|
532
|
+
Returns
|
|
533
|
+
-------
|
|
534
|
+
HttpResponse[AcceptTermsResponse]
|
|
535
|
+
Successful Response
|
|
536
|
+
"""
|
|
537
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
538
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/accept-terms",
|
|
539
|
+
method="POST",
|
|
540
|
+
request_options=request_options,
|
|
541
|
+
)
|
|
542
|
+
try:
|
|
543
|
+
if 200 <= _response.status_code < 300:
|
|
544
|
+
_data = typing.cast(
|
|
545
|
+
AcceptTermsResponse,
|
|
546
|
+
parse_obj_as(
|
|
547
|
+
type_=AcceptTermsResponse, # type: ignore
|
|
548
|
+
object_=_response.json(),
|
|
549
|
+
),
|
|
550
|
+
)
|
|
551
|
+
return HttpResponse(response=_response, data=_data)
|
|
552
|
+
if _response.status_code == 401:
|
|
553
|
+
raise UnauthorizedError(
|
|
554
|
+
headers=dict(_response.headers),
|
|
555
|
+
body=typing.cast(
|
|
556
|
+
AuthenticationError,
|
|
557
|
+
parse_obj_as(
|
|
558
|
+
type_=AuthenticationError, # type: ignore
|
|
559
|
+
object_=_response.json(),
|
|
560
|
+
),
|
|
561
|
+
),
|
|
562
|
+
)
|
|
563
|
+
if _response.status_code == 403:
|
|
564
|
+
raise ForbiddenError(
|
|
565
|
+
headers=dict(_response.headers),
|
|
566
|
+
body=typing.cast(
|
|
567
|
+
AuthorizationError,
|
|
568
|
+
parse_obj_as(
|
|
569
|
+
type_=AuthorizationError, # type: ignore
|
|
570
|
+
object_=_response.json(),
|
|
571
|
+
),
|
|
572
|
+
),
|
|
573
|
+
)
|
|
574
|
+
if _response.status_code == 422:
|
|
575
|
+
raise UnprocessableEntityError(
|
|
576
|
+
headers=dict(_response.headers),
|
|
577
|
+
body=typing.cast(
|
|
578
|
+
HttpValidationError,
|
|
579
|
+
parse_obj_as(
|
|
580
|
+
type_=HttpValidationError, # type: ignore
|
|
581
|
+
object_=_response.json(),
|
|
582
|
+
),
|
|
583
|
+
),
|
|
584
|
+
)
|
|
585
|
+
_response_json = _response.json()
|
|
586
|
+
except JSONDecodeError:
|
|
587
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
588
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
589
|
+
|
|
590
|
+
def update_tag(
|
|
591
|
+
self,
|
|
592
|
+
recommendation_id: str,
|
|
593
|
+
*,
|
|
594
|
+
tag: typing.Optional[str] = OMIT,
|
|
595
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
596
|
+
) -> HttpResponse[UpdateTagResponse]:
|
|
597
|
+
"""
|
|
598
|
+
Updates the tag value for a recommendation
|
|
599
|
+
|
|
600
|
+
Parameters
|
|
601
|
+
----------
|
|
602
|
+
recommendation_id : str
|
|
603
|
+
|
|
604
|
+
tag : typing.Optional[str]
|
|
605
|
+
New tag value. Send null to clear.
|
|
606
|
+
|
|
607
|
+
request_options : typing.Optional[RequestOptions]
|
|
608
|
+
Request-specific configuration.
|
|
609
|
+
|
|
610
|
+
Returns
|
|
611
|
+
-------
|
|
612
|
+
HttpResponse[UpdateTagResponse]
|
|
613
|
+
Successful Response
|
|
614
|
+
"""
|
|
615
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
616
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/tag",
|
|
617
|
+
method="POST",
|
|
618
|
+
json={
|
|
619
|
+
"tag": tag,
|
|
620
|
+
},
|
|
621
|
+
headers={
|
|
622
|
+
"content-type": "application/json",
|
|
623
|
+
},
|
|
624
|
+
request_options=request_options,
|
|
625
|
+
omit=OMIT,
|
|
626
|
+
)
|
|
627
|
+
try:
|
|
628
|
+
if 200 <= _response.status_code < 300:
|
|
629
|
+
_data = typing.cast(
|
|
630
|
+
UpdateTagResponse,
|
|
631
|
+
parse_obj_as(
|
|
632
|
+
type_=UpdateTagResponse, # type: ignore
|
|
633
|
+
object_=_response.json(),
|
|
634
|
+
),
|
|
635
|
+
)
|
|
636
|
+
return HttpResponse(response=_response, data=_data)
|
|
637
|
+
if _response.status_code == 401:
|
|
638
|
+
raise UnauthorizedError(
|
|
639
|
+
headers=dict(_response.headers),
|
|
640
|
+
body=typing.cast(
|
|
641
|
+
AuthenticationError,
|
|
642
|
+
parse_obj_as(
|
|
643
|
+
type_=AuthenticationError, # type: ignore
|
|
644
|
+
object_=_response.json(),
|
|
645
|
+
),
|
|
646
|
+
),
|
|
647
|
+
)
|
|
648
|
+
if _response.status_code == 403:
|
|
649
|
+
raise ForbiddenError(
|
|
650
|
+
headers=dict(_response.headers),
|
|
651
|
+
body=typing.cast(
|
|
652
|
+
AuthorizationError,
|
|
653
|
+
parse_obj_as(
|
|
654
|
+
type_=AuthorizationError, # type: ignore
|
|
655
|
+
object_=_response.json(),
|
|
656
|
+
),
|
|
657
|
+
),
|
|
658
|
+
)
|
|
659
|
+
if _response.status_code == 422:
|
|
660
|
+
raise UnprocessableEntityError(
|
|
661
|
+
headers=dict(_response.headers),
|
|
662
|
+
body=typing.cast(
|
|
663
|
+
HttpValidationError,
|
|
664
|
+
parse_obj_as(
|
|
665
|
+
type_=HttpValidationError, # type: ignore
|
|
666
|
+
object_=_response.json(),
|
|
667
|
+
),
|
|
668
|
+
),
|
|
669
|
+
)
|
|
670
|
+
_response_json = _response.json()
|
|
671
|
+
except JSONDecodeError:
|
|
672
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
673
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
674
|
+
|
|
675
|
+
def make_decision(
|
|
676
|
+
self,
|
|
677
|
+
recommendation_id: str,
|
|
678
|
+
*,
|
|
679
|
+
decision: str,
|
|
680
|
+
reason: typing.Optional[str] = OMIT,
|
|
681
|
+
explanation: typing.Optional[str] = OMIT,
|
|
682
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
683
|
+
) -> HttpResponse[SavingsDecisionResponse]:
|
|
684
|
+
"""
|
|
685
|
+
Records user decision to accept or reject a savings recommendation
|
|
686
|
+
|
|
687
|
+
Parameters
|
|
688
|
+
----------
|
|
689
|
+
recommendation_id : str
|
|
690
|
+
|
|
691
|
+
decision : str
|
|
692
|
+
Decision: 'accepted' or 'rejected'
|
|
693
|
+
|
|
694
|
+
reason : typing.Optional[str]
|
|
695
|
+
Rejection reason: operational, strategy, not_applicable, other (required if rejected)
|
|
696
|
+
|
|
697
|
+
explanation : typing.Optional[str]
|
|
698
|
+
Free text explanation (optional, used when reason is 'other')
|
|
699
|
+
|
|
700
|
+
request_options : typing.Optional[RequestOptions]
|
|
701
|
+
Request-specific configuration.
|
|
702
|
+
|
|
703
|
+
Returns
|
|
704
|
+
-------
|
|
705
|
+
HttpResponse[SavingsDecisionResponse]
|
|
706
|
+
Successful Response
|
|
707
|
+
"""
|
|
708
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
709
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/decision",
|
|
710
|
+
method="POST",
|
|
711
|
+
json={
|
|
712
|
+
"decision": decision,
|
|
713
|
+
"reason": reason,
|
|
714
|
+
"explanation": explanation,
|
|
715
|
+
},
|
|
716
|
+
headers={
|
|
717
|
+
"content-type": "application/json",
|
|
718
|
+
},
|
|
719
|
+
request_options=request_options,
|
|
720
|
+
omit=OMIT,
|
|
721
|
+
)
|
|
722
|
+
try:
|
|
723
|
+
if 200 <= _response.status_code < 300:
|
|
724
|
+
_data = typing.cast(
|
|
725
|
+
SavingsDecisionResponse,
|
|
726
|
+
parse_obj_as(
|
|
727
|
+
type_=SavingsDecisionResponse, # type: ignore
|
|
728
|
+
object_=_response.json(),
|
|
729
|
+
),
|
|
730
|
+
)
|
|
731
|
+
return HttpResponse(response=_response, data=_data)
|
|
732
|
+
if _response.status_code == 401:
|
|
733
|
+
raise UnauthorizedError(
|
|
734
|
+
headers=dict(_response.headers),
|
|
735
|
+
body=typing.cast(
|
|
736
|
+
AuthenticationError,
|
|
737
|
+
parse_obj_as(
|
|
738
|
+
type_=AuthenticationError, # type: ignore
|
|
739
|
+
object_=_response.json(),
|
|
740
|
+
),
|
|
741
|
+
),
|
|
742
|
+
)
|
|
743
|
+
if _response.status_code == 403:
|
|
744
|
+
raise ForbiddenError(
|
|
745
|
+
headers=dict(_response.headers),
|
|
746
|
+
body=typing.cast(
|
|
747
|
+
AuthorizationError,
|
|
748
|
+
parse_obj_as(
|
|
749
|
+
type_=AuthorizationError, # type: ignore
|
|
750
|
+
object_=_response.json(),
|
|
751
|
+
),
|
|
752
|
+
),
|
|
753
|
+
)
|
|
754
|
+
if _response.status_code == 422:
|
|
755
|
+
raise UnprocessableEntityError(
|
|
756
|
+
headers=dict(_response.headers),
|
|
757
|
+
body=typing.cast(
|
|
758
|
+
HttpValidationError,
|
|
759
|
+
parse_obj_as(
|
|
760
|
+
type_=HttpValidationError, # type: ignore
|
|
761
|
+
object_=_response.json(),
|
|
762
|
+
),
|
|
763
|
+
),
|
|
764
|
+
)
|
|
765
|
+
_response_json = _response.json()
|
|
766
|
+
except JSONDecodeError:
|
|
767
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
768
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
769
|
+
|
|
770
|
+
def set_implementation(
|
|
771
|
+
self, recommendation_id: str, *, method: str, request_options: typing.Optional[RequestOptions] = None
|
|
772
|
+
) -> HttpResponse[ImplementationMethodResponse]:
|
|
773
|
+
"""
|
|
774
|
+
Records the chosen implementation method for a recommendation
|
|
775
|
+
|
|
776
|
+
Parameters
|
|
777
|
+
----------
|
|
778
|
+
recommendation_id : str
|
|
779
|
+
|
|
780
|
+
method : str
|
|
781
|
+
Implementation method: 'one-click', 'iac', 'one-click-plus-iac', 'manual'
|
|
782
|
+
|
|
783
|
+
request_options : typing.Optional[RequestOptions]
|
|
784
|
+
Request-specific configuration.
|
|
785
|
+
|
|
786
|
+
Returns
|
|
787
|
+
-------
|
|
788
|
+
HttpResponse[ImplementationMethodResponse]
|
|
789
|
+
Successful Response
|
|
790
|
+
"""
|
|
791
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
792
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/implementation",
|
|
793
|
+
method="POST",
|
|
794
|
+
json={
|
|
795
|
+
"method": method,
|
|
796
|
+
},
|
|
797
|
+
headers={
|
|
798
|
+
"content-type": "application/json",
|
|
799
|
+
},
|
|
800
|
+
request_options=request_options,
|
|
801
|
+
omit=OMIT,
|
|
802
|
+
)
|
|
803
|
+
try:
|
|
804
|
+
if 200 <= _response.status_code < 300:
|
|
805
|
+
_data = typing.cast(
|
|
806
|
+
ImplementationMethodResponse,
|
|
807
|
+
parse_obj_as(
|
|
808
|
+
type_=ImplementationMethodResponse, # type: ignore
|
|
809
|
+
object_=_response.json(),
|
|
810
|
+
),
|
|
811
|
+
)
|
|
812
|
+
return HttpResponse(response=_response, data=_data)
|
|
813
|
+
if _response.status_code == 401:
|
|
814
|
+
raise UnauthorizedError(
|
|
815
|
+
headers=dict(_response.headers),
|
|
816
|
+
body=typing.cast(
|
|
817
|
+
AuthenticationError,
|
|
818
|
+
parse_obj_as(
|
|
819
|
+
type_=AuthenticationError, # type: ignore
|
|
820
|
+
object_=_response.json(),
|
|
821
|
+
),
|
|
822
|
+
),
|
|
823
|
+
)
|
|
824
|
+
if _response.status_code == 403:
|
|
825
|
+
raise ForbiddenError(
|
|
826
|
+
headers=dict(_response.headers),
|
|
827
|
+
body=typing.cast(
|
|
828
|
+
AuthorizationError,
|
|
829
|
+
parse_obj_as(
|
|
830
|
+
type_=AuthorizationError, # type: ignore
|
|
831
|
+
object_=_response.json(),
|
|
832
|
+
),
|
|
833
|
+
),
|
|
834
|
+
)
|
|
835
|
+
if _response.status_code == 422:
|
|
836
|
+
raise UnprocessableEntityError(
|
|
837
|
+
headers=dict(_response.headers),
|
|
838
|
+
body=typing.cast(
|
|
839
|
+
HttpValidationError,
|
|
840
|
+
parse_obj_as(
|
|
841
|
+
type_=HttpValidationError, # type: ignore
|
|
842
|
+
object_=_response.json(),
|
|
843
|
+
),
|
|
844
|
+
),
|
|
845
|
+
)
|
|
846
|
+
_response_json = _response.json()
|
|
847
|
+
except JSONDecodeError:
|
|
848
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
849
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
850
|
+
|
|
851
|
+
def complete_wizard(
|
|
852
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
853
|
+
) -> HttpResponse[CompleteWizardResponse]:
|
|
854
|
+
"""
|
|
855
|
+
Completes the wizard flow and triggers the appropriate workflow
|
|
856
|
+
|
|
857
|
+
Parameters
|
|
858
|
+
----------
|
|
859
|
+
recommendation_id : str
|
|
860
|
+
|
|
861
|
+
request_options : typing.Optional[RequestOptions]
|
|
862
|
+
Request-specific configuration.
|
|
863
|
+
|
|
864
|
+
Returns
|
|
865
|
+
-------
|
|
866
|
+
HttpResponse[CompleteWizardResponse]
|
|
867
|
+
Successful Response
|
|
868
|
+
"""
|
|
869
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
870
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/complete",
|
|
871
|
+
method="POST",
|
|
872
|
+
request_options=request_options,
|
|
873
|
+
)
|
|
874
|
+
try:
|
|
875
|
+
if 200 <= _response.status_code < 300:
|
|
876
|
+
_data = typing.cast(
|
|
877
|
+
CompleteWizardResponse,
|
|
878
|
+
parse_obj_as(
|
|
879
|
+
type_=CompleteWizardResponse, # type: ignore
|
|
880
|
+
object_=_response.json(),
|
|
881
|
+
),
|
|
882
|
+
)
|
|
883
|
+
return HttpResponse(response=_response, data=_data)
|
|
884
|
+
if _response.status_code == 401:
|
|
885
|
+
raise UnauthorizedError(
|
|
886
|
+
headers=dict(_response.headers),
|
|
887
|
+
body=typing.cast(
|
|
888
|
+
AuthenticationError,
|
|
889
|
+
parse_obj_as(
|
|
890
|
+
type_=AuthenticationError, # type: ignore
|
|
891
|
+
object_=_response.json(),
|
|
892
|
+
),
|
|
893
|
+
),
|
|
894
|
+
)
|
|
895
|
+
if _response.status_code == 403:
|
|
896
|
+
raise ForbiddenError(
|
|
897
|
+
headers=dict(_response.headers),
|
|
898
|
+
body=typing.cast(
|
|
899
|
+
AuthorizationError,
|
|
900
|
+
parse_obj_as(
|
|
901
|
+
type_=AuthorizationError, # type: ignore
|
|
902
|
+
object_=_response.json(),
|
|
903
|
+
),
|
|
904
|
+
),
|
|
905
|
+
)
|
|
906
|
+
if _response.status_code == 422:
|
|
907
|
+
raise UnprocessableEntityError(
|
|
908
|
+
headers=dict(_response.headers),
|
|
909
|
+
body=typing.cast(
|
|
910
|
+
HttpValidationError,
|
|
911
|
+
parse_obj_as(
|
|
912
|
+
type_=HttpValidationError, # type: ignore
|
|
913
|
+
object_=_response.json(),
|
|
914
|
+
),
|
|
915
|
+
),
|
|
916
|
+
)
|
|
917
|
+
_response_json = _response.json()
|
|
918
|
+
except JSONDecodeError:
|
|
919
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
920
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
class AsyncRawRecommendationsClient:
|
|
924
|
+
def __init__(self, *, client_wrapper: AsyncClientWrapper):
|
|
925
|
+
self._client_wrapper = client_wrapper
|
|
926
|
+
|
|
927
|
+
async def get_summary(
|
|
928
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
929
|
+
) -> AsyncHttpResponse[ProvidersSummaryResponse]:
|
|
930
|
+
"""
|
|
931
|
+
Returns provider-level aggregation for the carousel view (AWS, GCP, Azure, K8s)
|
|
932
|
+
|
|
933
|
+
Parameters
|
|
934
|
+
----------
|
|
935
|
+
request_options : typing.Optional[RequestOptions]
|
|
936
|
+
Request-specific configuration.
|
|
937
|
+
|
|
938
|
+
Returns
|
|
939
|
+
-------
|
|
940
|
+
AsyncHttpResponse[ProvidersSummaryResponse]
|
|
941
|
+
Successful Response
|
|
942
|
+
"""
|
|
943
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
944
|
+
"api/v1/recommendations/summary",
|
|
945
|
+
method="GET",
|
|
946
|
+
request_options=request_options,
|
|
947
|
+
)
|
|
948
|
+
try:
|
|
949
|
+
if 200 <= _response.status_code < 300:
|
|
950
|
+
_data = typing.cast(
|
|
951
|
+
ProvidersSummaryResponse,
|
|
952
|
+
parse_obj_as(
|
|
953
|
+
type_=ProvidersSummaryResponse, # type: ignore
|
|
954
|
+
object_=_response.json(),
|
|
955
|
+
),
|
|
956
|
+
)
|
|
957
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
958
|
+
if _response.status_code == 401:
|
|
959
|
+
raise UnauthorizedError(
|
|
960
|
+
headers=dict(_response.headers),
|
|
961
|
+
body=typing.cast(
|
|
962
|
+
AuthenticationError,
|
|
963
|
+
parse_obj_as(
|
|
964
|
+
type_=AuthenticationError, # type: ignore
|
|
965
|
+
object_=_response.json(),
|
|
966
|
+
),
|
|
967
|
+
),
|
|
968
|
+
)
|
|
969
|
+
if _response.status_code == 403:
|
|
970
|
+
raise ForbiddenError(
|
|
971
|
+
headers=dict(_response.headers),
|
|
972
|
+
body=typing.cast(
|
|
973
|
+
AuthorizationError,
|
|
974
|
+
parse_obj_as(
|
|
975
|
+
type_=AuthorizationError, # type: ignore
|
|
976
|
+
object_=_response.json(),
|
|
977
|
+
),
|
|
978
|
+
),
|
|
979
|
+
)
|
|
980
|
+
_response_json = _response.json()
|
|
981
|
+
except JSONDecodeError:
|
|
982
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
983
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
984
|
+
|
|
985
|
+
async def get_potential_savings_summary(
|
|
986
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
987
|
+
) -> AsyncHttpResponse[ProvidersSummaryResponse]:
|
|
988
|
+
"""
|
|
989
|
+
Returns potential savings summary grouped by provider (from dashboard_potential_savings)
|
|
990
|
+
|
|
991
|
+
Parameters
|
|
992
|
+
----------
|
|
993
|
+
request_options : typing.Optional[RequestOptions]
|
|
994
|
+
Request-specific configuration.
|
|
995
|
+
|
|
996
|
+
Returns
|
|
997
|
+
-------
|
|
998
|
+
AsyncHttpResponse[ProvidersSummaryResponse]
|
|
999
|
+
Successful Response
|
|
1000
|
+
"""
|
|
1001
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1002
|
+
"api/v1/recommendations/potential-savings/summary",
|
|
1003
|
+
method="GET",
|
|
1004
|
+
request_options=request_options,
|
|
1005
|
+
)
|
|
1006
|
+
try:
|
|
1007
|
+
if 200 <= _response.status_code < 300:
|
|
1008
|
+
_data = typing.cast(
|
|
1009
|
+
ProvidersSummaryResponse,
|
|
1010
|
+
parse_obj_as(
|
|
1011
|
+
type_=ProvidersSummaryResponse, # type: ignore
|
|
1012
|
+
object_=_response.json(),
|
|
1013
|
+
),
|
|
1014
|
+
)
|
|
1015
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1016
|
+
if _response.status_code == 401:
|
|
1017
|
+
raise UnauthorizedError(
|
|
1018
|
+
headers=dict(_response.headers),
|
|
1019
|
+
body=typing.cast(
|
|
1020
|
+
AuthenticationError,
|
|
1021
|
+
parse_obj_as(
|
|
1022
|
+
type_=AuthenticationError, # type: ignore
|
|
1023
|
+
object_=_response.json(),
|
|
1024
|
+
),
|
|
1025
|
+
),
|
|
1026
|
+
)
|
|
1027
|
+
if _response.status_code == 403:
|
|
1028
|
+
raise ForbiddenError(
|
|
1029
|
+
headers=dict(_response.headers),
|
|
1030
|
+
body=typing.cast(
|
|
1031
|
+
AuthorizationError,
|
|
1032
|
+
parse_obj_as(
|
|
1033
|
+
type_=AuthorizationError, # type: ignore
|
|
1034
|
+
object_=_response.json(),
|
|
1035
|
+
),
|
|
1036
|
+
),
|
|
1037
|
+
)
|
|
1038
|
+
_response_json = _response.json()
|
|
1039
|
+
except JSONDecodeError:
|
|
1040
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1041
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1042
|
+
|
|
1043
|
+
async def list(
|
|
1044
|
+
self,
|
|
1045
|
+
*,
|
|
1046
|
+
page: typing.Optional[int] = None,
|
|
1047
|
+
page_size: typing.Optional[int] = None,
|
|
1048
|
+
sort_by: typing.Optional[str] = None,
|
|
1049
|
+
sort_order: typing.Optional[str] = None,
|
|
1050
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
1051
|
+
) -> AsyncPager[RecommendationItem, RecommendationsBreakdownResponse]:
|
|
1052
|
+
"""
|
|
1053
|
+
Returns paginated list of all recommendations with actions
|
|
1054
|
+
|
|
1055
|
+
Parameters
|
|
1056
|
+
----------
|
|
1057
|
+
page : typing.Optional[int]
|
|
1058
|
+
Page number (1-indexed)
|
|
1059
|
+
|
|
1060
|
+
page_size : typing.Optional[int]
|
|
1061
|
+
Items per page (max 100)
|
|
1062
|
+
|
|
1063
|
+
sort_by : typing.Optional[str]
|
|
1064
|
+
Field to sort by (recommendation_id, service, environment, monthly_savings, annual_savings, savings_percentage, analysis_period, created_at)
|
|
1065
|
+
|
|
1066
|
+
sort_order : typing.Optional[str]
|
|
1067
|
+
Sort order (asc or desc)
|
|
1068
|
+
|
|
1069
|
+
request_options : typing.Optional[RequestOptions]
|
|
1070
|
+
Request-specific configuration.
|
|
1071
|
+
|
|
1072
|
+
Returns
|
|
1073
|
+
-------
|
|
1074
|
+
AsyncPager[RecommendationItem, RecommendationsBreakdownResponse]
|
|
1075
|
+
Successful Response
|
|
1076
|
+
"""
|
|
1077
|
+
page = page if page is not None else 1
|
|
1078
|
+
|
|
1079
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1080
|
+
"api/v1/recommendations",
|
|
1081
|
+
method="GET",
|
|
1082
|
+
params={
|
|
1083
|
+
"page": page,
|
|
1084
|
+
"page_size": page_size,
|
|
1085
|
+
"sort_by": sort_by,
|
|
1086
|
+
"sort_order": sort_order,
|
|
1087
|
+
},
|
|
1088
|
+
request_options=request_options,
|
|
1089
|
+
)
|
|
1090
|
+
try:
|
|
1091
|
+
if 200 <= _response.status_code < 300:
|
|
1092
|
+
_parsed_response = typing.cast(
|
|
1093
|
+
RecommendationsBreakdownResponse,
|
|
1094
|
+
parse_obj_as(
|
|
1095
|
+
type_=RecommendationsBreakdownResponse, # type: ignore
|
|
1096
|
+
object_=_response.json(),
|
|
1097
|
+
),
|
|
1098
|
+
)
|
|
1099
|
+
_items = _parsed_response.data.items if _parsed_response.data is not None else []
|
|
1100
|
+
|
|
1101
|
+
_has_next = True
|
|
1102
|
+
|
|
1103
|
+
async def _get_next():
|
|
1104
|
+
return await self.list(
|
|
1105
|
+
page=page + 1,
|
|
1106
|
+
page_size=page_size,
|
|
1107
|
+
sort_by=sort_by,
|
|
1108
|
+
sort_order=sort_order,
|
|
1109
|
+
request_options=request_options,
|
|
1110
|
+
)
|
|
1111
|
+
|
|
1112
|
+
return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
|
|
1113
|
+
if _response.status_code == 401:
|
|
1114
|
+
raise UnauthorizedError(
|
|
1115
|
+
headers=dict(_response.headers),
|
|
1116
|
+
body=typing.cast(
|
|
1117
|
+
AuthenticationError,
|
|
1118
|
+
parse_obj_as(
|
|
1119
|
+
type_=AuthenticationError, # type: ignore
|
|
1120
|
+
object_=_response.json(),
|
|
1121
|
+
),
|
|
1122
|
+
),
|
|
1123
|
+
)
|
|
1124
|
+
if _response.status_code == 403:
|
|
1125
|
+
raise ForbiddenError(
|
|
1126
|
+
headers=dict(_response.headers),
|
|
1127
|
+
body=typing.cast(
|
|
1128
|
+
AuthorizationError,
|
|
1129
|
+
parse_obj_as(
|
|
1130
|
+
type_=AuthorizationError, # type: ignore
|
|
1131
|
+
object_=_response.json(),
|
|
1132
|
+
),
|
|
1133
|
+
),
|
|
1134
|
+
)
|
|
1135
|
+
if _response.status_code == 422:
|
|
1136
|
+
raise UnprocessableEntityError(
|
|
1137
|
+
headers=dict(_response.headers),
|
|
1138
|
+
body=typing.cast(
|
|
1139
|
+
HttpValidationError,
|
|
1140
|
+
parse_obj_as(
|
|
1141
|
+
type_=HttpValidationError, # type: ignore
|
|
1142
|
+
object_=_response.json(),
|
|
1143
|
+
),
|
|
1144
|
+
),
|
|
1145
|
+
)
|
|
1146
|
+
_response_json = _response.json()
|
|
1147
|
+
except JSONDecodeError:
|
|
1148
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1149
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1150
|
+
|
|
1151
|
+
async def get_overview(
|
|
1152
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
1153
|
+
) -> AsyncHttpResponse[RecommendationsOverviewResponse]:
|
|
1154
|
+
"""
|
|
1155
|
+
Returns recommendations overview metrics across all providers (for dashboard)
|
|
1156
|
+
|
|
1157
|
+
Parameters
|
|
1158
|
+
----------
|
|
1159
|
+
request_options : typing.Optional[RequestOptions]
|
|
1160
|
+
Request-specific configuration.
|
|
1161
|
+
|
|
1162
|
+
Returns
|
|
1163
|
+
-------
|
|
1164
|
+
AsyncHttpResponse[RecommendationsOverviewResponse]
|
|
1165
|
+
Successful Response
|
|
1166
|
+
"""
|
|
1167
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1168
|
+
"api/v1/recommendations/overview",
|
|
1169
|
+
method="GET",
|
|
1170
|
+
request_options=request_options,
|
|
1171
|
+
)
|
|
1172
|
+
try:
|
|
1173
|
+
if 200 <= _response.status_code < 300:
|
|
1174
|
+
_data = typing.cast(
|
|
1175
|
+
RecommendationsOverviewResponse,
|
|
1176
|
+
parse_obj_as(
|
|
1177
|
+
type_=RecommendationsOverviewResponse, # type: ignore
|
|
1178
|
+
object_=_response.json(),
|
|
1179
|
+
),
|
|
1180
|
+
)
|
|
1181
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1182
|
+
if _response.status_code == 401:
|
|
1183
|
+
raise UnauthorizedError(
|
|
1184
|
+
headers=dict(_response.headers),
|
|
1185
|
+
body=typing.cast(
|
|
1186
|
+
AuthenticationError,
|
|
1187
|
+
parse_obj_as(
|
|
1188
|
+
type_=AuthenticationError, # type: ignore
|
|
1189
|
+
object_=_response.json(),
|
|
1190
|
+
),
|
|
1191
|
+
),
|
|
1192
|
+
)
|
|
1193
|
+
if _response.status_code == 403:
|
|
1194
|
+
raise ForbiddenError(
|
|
1195
|
+
headers=dict(_response.headers),
|
|
1196
|
+
body=typing.cast(
|
|
1197
|
+
AuthorizationError,
|
|
1198
|
+
parse_obj_as(
|
|
1199
|
+
type_=AuthorizationError, # type: ignore
|
|
1200
|
+
object_=_response.json(),
|
|
1201
|
+
),
|
|
1202
|
+
),
|
|
1203
|
+
)
|
|
1204
|
+
_response_json = _response.json()
|
|
1205
|
+
except JSONDecodeError:
|
|
1206
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1207
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1208
|
+
|
|
1209
|
+
async def get_processing(
|
|
1210
|
+
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
1211
|
+
) -> AsyncHttpResponse[ProcessingRecommendationsResponse]:
|
|
1212
|
+
"""
|
|
1213
|
+
Returns all recommendations currently in processing status
|
|
1214
|
+
|
|
1215
|
+
Parameters
|
|
1216
|
+
----------
|
|
1217
|
+
request_options : typing.Optional[RequestOptions]
|
|
1218
|
+
Request-specific configuration.
|
|
1219
|
+
|
|
1220
|
+
Returns
|
|
1221
|
+
-------
|
|
1222
|
+
AsyncHttpResponse[ProcessingRecommendationsResponse]
|
|
1223
|
+
Successful Response
|
|
1224
|
+
"""
|
|
1225
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1226
|
+
"api/v1/recommendations/processing",
|
|
1227
|
+
method="GET",
|
|
1228
|
+
request_options=request_options,
|
|
1229
|
+
)
|
|
1230
|
+
try:
|
|
1231
|
+
if 200 <= _response.status_code < 300:
|
|
1232
|
+
_data = typing.cast(
|
|
1233
|
+
ProcessingRecommendationsResponse,
|
|
1234
|
+
parse_obj_as(
|
|
1235
|
+
type_=ProcessingRecommendationsResponse, # type: ignore
|
|
1236
|
+
object_=_response.json(),
|
|
1237
|
+
),
|
|
1238
|
+
)
|
|
1239
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1240
|
+
if _response.status_code == 401:
|
|
1241
|
+
raise UnauthorizedError(
|
|
1242
|
+
headers=dict(_response.headers),
|
|
1243
|
+
body=typing.cast(
|
|
1244
|
+
AuthenticationError,
|
|
1245
|
+
parse_obj_as(
|
|
1246
|
+
type_=AuthenticationError, # type: ignore
|
|
1247
|
+
object_=_response.json(),
|
|
1248
|
+
),
|
|
1249
|
+
),
|
|
1250
|
+
)
|
|
1251
|
+
if _response.status_code == 403:
|
|
1252
|
+
raise ForbiddenError(
|
|
1253
|
+
headers=dict(_response.headers),
|
|
1254
|
+
body=typing.cast(
|
|
1255
|
+
AuthorizationError,
|
|
1256
|
+
parse_obj_as(
|
|
1257
|
+
type_=AuthorizationError, # type: ignore
|
|
1258
|
+
object_=_response.json(),
|
|
1259
|
+
),
|
|
1260
|
+
),
|
|
1261
|
+
)
|
|
1262
|
+
_response_json = _response.json()
|
|
1263
|
+
except JSONDecodeError:
|
|
1264
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1265
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1266
|
+
|
|
1267
|
+
async def get_details(
|
|
1268
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
1269
|
+
) -> AsyncHttpResponse[RecommendationDetailResponse]:
|
|
1270
|
+
"""
|
|
1271
|
+
Returns complete details for a specific recommendation
|
|
1272
|
+
|
|
1273
|
+
Parameters
|
|
1274
|
+
----------
|
|
1275
|
+
recommendation_id : str
|
|
1276
|
+
|
|
1277
|
+
request_options : typing.Optional[RequestOptions]
|
|
1278
|
+
Request-specific configuration.
|
|
1279
|
+
|
|
1280
|
+
Returns
|
|
1281
|
+
-------
|
|
1282
|
+
AsyncHttpResponse[RecommendationDetailResponse]
|
|
1283
|
+
Successful Response
|
|
1284
|
+
"""
|
|
1285
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1286
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/details",
|
|
1287
|
+
method="GET",
|
|
1288
|
+
request_options=request_options,
|
|
1289
|
+
)
|
|
1290
|
+
try:
|
|
1291
|
+
if 200 <= _response.status_code < 300:
|
|
1292
|
+
_data = typing.cast(
|
|
1293
|
+
RecommendationDetailResponse,
|
|
1294
|
+
parse_obj_as(
|
|
1295
|
+
type_=RecommendationDetailResponse, # type: ignore
|
|
1296
|
+
object_=_response.json(),
|
|
1297
|
+
),
|
|
1298
|
+
)
|
|
1299
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1300
|
+
if _response.status_code == 401:
|
|
1301
|
+
raise UnauthorizedError(
|
|
1302
|
+
headers=dict(_response.headers),
|
|
1303
|
+
body=typing.cast(
|
|
1304
|
+
AuthenticationError,
|
|
1305
|
+
parse_obj_as(
|
|
1306
|
+
type_=AuthenticationError, # type: ignore
|
|
1307
|
+
object_=_response.json(),
|
|
1308
|
+
),
|
|
1309
|
+
),
|
|
1310
|
+
)
|
|
1311
|
+
if _response.status_code == 403:
|
|
1312
|
+
raise ForbiddenError(
|
|
1313
|
+
headers=dict(_response.headers),
|
|
1314
|
+
body=typing.cast(
|
|
1315
|
+
AuthorizationError,
|
|
1316
|
+
parse_obj_as(
|
|
1317
|
+
type_=AuthorizationError, # type: ignore
|
|
1318
|
+
object_=_response.json(),
|
|
1319
|
+
),
|
|
1320
|
+
),
|
|
1321
|
+
)
|
|
1322
|
+
if _response.status_code == 422:
|
|
1323
|
+
raise UnprocessableEntityError(
|
|
1324
|
+
headers=dict(_response.headers),
|
|
1325
|
+
body=typing.cast(
|
|
1326
|
+
HttpValidationError,
|
|
1327
|
+
parse_obj_as(
|
|
1328
|
+
type_=HttpValidationError, # type: ignore
|
|
1329
|
+
object_=_response.json(),
|
|
1330
|
+
),
|
|
1331
|
+
),
|
|
1332
|
+
)
|
|
1333
|
+
_response_json = _response.json()
|
|
1334
|
+
except JSONDecodeError:
|
|
1335
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1336
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1337
|
+
|
|
1338
|
+
async def get_wizard(
|
|
1339
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
1340
|
+
) -> AsyncHttpResponse[RecommendationWizardResponse]:
|
|
1341
|
+
"""
|
|
1342
|
+
Returns recommendation details for the Save Now wizard flow
|
|
1343
|
+
|
|
1344
|
+
Parameters
|
|
1345
|
+
----------
|
|
1346
|
+
recommendation_id : str
|
|
1347
|
+
|
|
1348
|
+
request_options : typing.Optional[RequestOptions]
|
|
1349
|
+
Request-specific configuration.
|
|
1350
|
+
|
|
1351
|
+
Returns
|
|
1352
|
+
-------
|
|
1353
|
+
AsyncHttpResponse[RecommendationWizardResponse]
|
|
1354
|
+
Successful Response
|
|
1355
|
+
"""
|
|
1356
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1357
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}",
|
|
1358
|
+
method="GET",
|
|
1359
|
+
request_options=request_options,
|
|
1360
|
+
)
|
|
1361
|
+
try:
|
|
1362
|
+
if 200 <= _response.status_code < 300:
|
|
1363
|
+
_data = typing.cast(
|
|
1364
|
+
RecommendationWizardResponse,
|
|
1365
|
+
parse_obj_as(
|
|
1366
|
+
type_=RecommendationWizardResponse, # type: ignore
|
|
1367
|
+
object_=_response.json(),
|
|
1368
|
+
),
|
|
1369
|
+
)
|
|
1370
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1371
|
+
if _response.status_code == 401:
|
|
1372
|
+
raise UnauthorizedError(
|
|
1373
|
+
headers=dict(_response.headers),
|
|
1374
|
+
body=typing.cast(
|
|
1375
|
+
AuthenticationError,
|
|
1376
|
+
parse_obj_as(
|
|
1377
|
+
type_=AuthenticationError, # type: ignore
|
|
1378
|
+
object_=_response.json(),
|
|
1379
|
+
),
|
|
1380
|
+
),
|
|
1381
|
+
)
|
|
1382
|
+
if _response.status_code == 403:
|
|
1383
|
+
raise ForbiddenError(
|
|
1384
|
+
headers=dict(_response.headers),
|
|
1385
|
+
body=typing.cast(
|
|
1386
|
+
AuthorizationError,
|
|
1387
|
+
parse_obj_as(
|
|
1388
|
+
type_=AuthorizationError, # type: ignore
|
|
1389
|
+
object_=_response.json(),
|
|
1390
|
+
),
|
|
1391
|
+
),
|
|
1392
|
+
)
|
|
1393
|
+
if _response.status_code == 422:
|
|
1394
|
+
raise UnprocessableEntityError(
|
|
1395
|
+
headers=dict(_response.headers),
|
|
1396
|
+
body=typing.cast(
|
|
1397
|
+
HttpValidationError,
|
|
1398
|
+
parse_obj_as(
|
|
1399
|
+
type_=HttpValidationError, # type: ignore
|
|
1400
|
+
object_=_response.json(),
|
|
1401
|
+
),
|
|
1402
|
+
),
|
|
1403
|
+
)
|
|
1404
|
+
_response_json = _response.json()
|
|
1405
|
+
except JSONDecodeError:
|
|
1406
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1407
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1408
|
+
|
|
1409
|
+
async def accept_terms(
|
|
1410
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
1411
|
+
) -> AsyncHttpResponse[AcceptTermsResponse]:
|
|
1412
|
+
"""
|
|
1413
|
+
Records user acceptance of terms and conditions for a recommendation
|
|
1414
|
+
|
|
1415
|
+
Parameters
|
|
1416
|
+
----------
|
|
1417
|
+
recommendation_id : str
|
|
1418
|
+
|
|
1419
|
+
request_options : typing.Optional[RequestOptions]
|
|
1420
|
+
Request-specific configuration.
|
|
1421
|
+
|
|
1422
|
+
Returns
|
|
1423
|
+
-------
|
|
1424
|
+
AsyncHttpResponse[AcceptTermsResponse]
|
|
1425
|
+
Successful Response
|
|
1426
|
+
"""
|
|
1427
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1428
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/accept-terms",
|
|
1429
|
+
method="POST",
|
|
1430
|
+
request_options=request_options,
|
|
1431
|
+
)
|
|
1432
|
+
try:
|
|
1433
|
+
if 200 <= _response.status_code < 300:
|
|
1434
|
+
_data = typing.cast(
|
|
1435
|
+
AcceptTermsResponse,
|
|
1436
|
+
parse_obj_as(
|
|
1437
|
+
type_=AcceptTermsResponse, # type: ignore
|
|
1438
|
+
object_=_response.json(),
|
|
1439
|
+
),
|
|
1440
|
+
)
|
|
1441
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1442
|
+
if _response.status_code == 401:
|
|
1443
|
+
raise UnauthorizedError(
|
|
1444
|
+
headers=dict(_response.headers),
|
|
1445
|
+
body=typing.cast(
|
|
1446
|
+
AuthenticationError,
|
|
1447
|
+
parse_obj_as(
|
|
1448
|
+
type_=AuthenticationError, # type: ignore
|
|
1449
|
+
object_=_response.json(),
|
|
1450
|
+
),
|
|
1451
|
+
),
|
|
1452
|
+
)
|
|
1453
|
+
if _response.status_code == 403:
|
|
1454
|
+
raise ForbiddenError(
|
|
1455
|
+
headers=dict(_response.headers),
|
|
1456
|
+
body=typing.cast(
|
|
1457
|
+
AuthorizationError,
|
|
1458
|
+
parse_obj_as(
|
|
1459
|
+
type_=AuthorizationError, # type: ignore
|
|
1460
|
+
object_=_response.json(),
|
|
1461
|
+
),
|
|
1462
|
+
),
|
|
1463
|
+
)
|
|
1464
|
+
if _response.status_code == 422:
|
|
1465
|
+
raise UnprocessableEntityError(
|
|
1466
|
+
headers=dict(_response.headers),
|
|
1467
|
+
body=typing.cast(
|
|
1468
|
+
HttpValidationError,
|
|
1469
|
+
parse_obj_as(
|
|
1470
|
+
type_=HttpValidationError, # type: ignore
|
|
1471
|
+
object_=_response.json(),
|
|
1472
|
+
),
|
|
1473
|
+
),
|
|
1474
|
+
)
|
|
1475
|
+
_response_json = _response.json()
|
|
1476
|
+
except JSONDecodeError:
|
|
1477
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1478
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1479
|
+
|
|
1480
|
+
async def update_tag(
|
|
1481
|
+
self,
|
|
1482
|
+
recommendation_id: str,
|
|
1483
|
+
*,
|
|
1484
|
+
tag: typing.Optional[str] = OMIT,
|
|
1485
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
1486
|
+
) -> AsyncHttpResponse[UpdateTagResponse]:
|
|
1487
|
+
"""
|
|
1488
|
+
Updates the tag value for a recommendation
|
|
1489
|
+
|
|
1490
|
+
Parameters
|
|
1491
|
+
----------
|
|
1492
|
+
recommendation_id : str
|
|
1493
|
+
|
|
1494
|
+
tag : typing.Optional[str]
|
|
1495
|
+
New tag value. Send null to clear.
|
|
1496
|
+
|
|
1497
|
+
request_options : typing.Optional[RequestOptions]
|
|
1498
|
+
Request-specific configuration.
|
|
1499
|
+
|
|
1500
|
+
Returns
|
|
1501
|
+
-------
|
|
1502
|
+
AsyncHttpResponse[UpdateTagResponse]
|
|
1503
|
+
Successful Response
|
|
1504
|
+
"""
|
|
1505
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1506
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/tag",
|
|
1507
|
+
method="POST",
|
|
1508
|
+
json={
|
|
1509
|
+
"tag": tag,
|
|
1510
|
+
},
|
|
1511
|
+
headers={
|
|
1512
|
+
"content-type": "application/json",
|
|
1513
|
+
},
|
|
1514
|
+
request_options=request_options,
|
|
1515
|
+
omit=OMIT,
|
|
1516
|
+
)
|
|
1517
|
+
try:
|
|
1518
|
+
if 200 <= _response.status_code < 300:
|
|
1519
|
+
_data = typing.cast(
|
|
1520
|
+
UpdateTagResponse,
|
|
1521
|
+
parse_obj_as(
|
|
1522
|
+
type_=UpdateTagResponse, # type: ignore
|
|
1523
|
+
object_=_response.json(),
|
|
1524
|
+
),
|
|
1525
|
+
)
|
|
1526
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1527
|
+
if _response.status_code == 401:
|
|
1528
|
+
raise UnauthorizedError(
|
|
1529
|
+
headers=dict(_response.headers),
|
|
1530
|
+
body=typing.cast(
|
|
1531
|
+
AuthenticationError,
|
|
1532
|
+
parse_obj_as(
|
|
1533
|
+
type_=AuthenticationError, # type: ignore
|
|
1534
|
+
object_=_response.json(),
|
|
1535
|
+
),
|
|
1536
|
+
),
|
|
1537
|
+
)
|
|
1538
|
+
if _response.status_code == 403:
|
|
1539
|
+
raise ForbiddenError(
|
|
1540
|
+
headers=dict(_response.headers),
|
|
1541
|
+
body=typing.cast(
|
|
1542
|
+
AuthorizationError,
|
|
1543
|
+
parse_obj_as(
|
|
1544
|
+
type_=AuthorizationError, # type: ignore
|
|
1545
|
+
object_=_response.json(),
|
|
1546
|
+
),
|
|
1547
|
+
),
|
|
1548
|
+
)
|
|
1549
|
+
if _response.status_code == 422:
|
|
1550
|
+
raise UnprocessableEntityError(
|
|
1551
|
+
headers=dict(_response.headers),
|
|
1552
|
+
body=typing.cast(
|
|
1553
|
+
HttpValidationError,
|
|
1554
|
+
parse_obj_as(
|
|
1555
|
+
type_=HttpValidationError, # type: ignore
|
|
1556
|
+
object_=_response.json(),
|
|
1557
|
+
),
|
|
1558
|
+
),
|
|
1559
|
+
)
|
|
1560
|
+
_response_json = _response.json()
|
|
1561
|
+
except JSONDecodeError:
|
|
1562
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1563
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1564
|
+
|
|
1565
|
+
async def make_decision(
|
|
1566
|
+
self,
|
|
1567
|
+
recommendation_id: str,
|
|
1568
|
+
*,
|
|
1569
|
+
decision: str,
|
|
1570
|
+
reason: typing.Optional[str] = OMIT,
|
|
1571
|
+
explanation: typing.Optional[str] = OMIT,
|
|
1572
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
1573
|
+
) -> AsyncHttpResponse[SavingsDecisionResponse]:
|
|
1574
|
+
"""
|
|
1575
|
+
Records user decision to accept or reject a savings recommendation
|
|
1576
|
+
|
|
1577
|
+
Parameters
|
|
1578
|
+
----------
|
|
1579
|
+
recommendation_id : str
|
|
1580
|
+
|
|
1581
|
+
decision : str
|
|
1582
|
+
Decision: 'accepted' or 'rejected'
|
|
1583
|
+
|
|
1584
|
+
reason : typing.Optional[str]
|
|
1585
|
+
Rejection reason: operational, strategy, not_applicable, other (required if rejected)
|
|
1586
|
+
|
|
1587
|
+
explanation : typing.Optional[str]
|
|
1588
|
+
Free text explanation (optional, used when reason is 'other')
|
|
1589
|
+
|
|
1590
|
+
request_options : typing.Optional[RequestOptions]
|
|
1591
|
+
Request-specific configuration.
|
|
1592
|
+
|
|
1593
|
+
Returns
|
|
1594
|
+
-------
|
|
1595
|
+
AsyncHttpResponse[SavingsDecisionResponse]
|
|
1596
|
+
Successful Response
|
|
1597
|
+
"""
|
|
1598
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1599
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/decision",
|
|
1600
|
+
method="POST",
|
|
1601
|
+
json={
|
|
1602
|
+
"decision": decision,
|
|
1603
|
+
"reason": reason,
|
|
1604
|
+
"explanation": explanation,
|
|
1605
|
+
},
|
|
1606
|
+
headers={
|
|
1607
|
+
"content-type": "application/json",
|
|
1608
|
+
},
|
|
1609
|
+
request_options=request_options,
|
|
1610
|
+
omit=OMIT,
|
|
1611
|
+
)
|
|
1612
|
+
try:
|
|
1613
|
+
if 200 <= _response.status_code < 300:
|
|
1614
|
+
_data = typing.cast(
|
|
1615
|
+
SavingsDecisionResponse,
|
|
1616
|
+
parse_obj_as(
|
|
1617
|
+
type_=SavingsDecisionResponse, # type: ignore
|
|
1618
|
+
object_=_response.json(),
|
|
1619
|
+
),
|
|
1620
|
+
)
|
|
1621
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1622
|
+
if _response.status_code == 401:
|
|
1623
|
+
raise UnauthorizedError(
|
|
1624
|
+
headers=dict(_response.headers),
|
|
1625
|
+
body=typing.cast(
|
|
1626
|
+
AuthenticationError,
|
|
1627
|
+
parse_obj_as(
|
|
1628
|
+
type_=AuthenticationError, # type: ignore
|
|
1629
|
+
object_=_response.json(),
|
|
1630
|
+
),
|
|
1631
|
+
),
|
|
1632
|
+
)
|
|
1633
|
+
if _response.status_code == 403:
|
|
1634
|
+
raise ForbiddenError(
|
|
1635
|
+
headers=dict(_response.headers),
|
|
1636
|
+
body=typing.cast(
|
|
1637
|
+
AuthorizationError,
|
|
1638
|
+
parse_obj_as(
|
|
1639
|
+
type_=AuthorizationError, # type: ignore
|
|
1640
|
+
object_=_response.json(),
|
|
1641
|
+
),
|
|
1642
|
+
),
|
|
1643
|
+
)
|
|
1644
|
+
if _response.status_code == 422:
|
|
1645
|
+
raise UnprocessableEntityError(
|
|
1646
|
+
headers=dict(_response.headers),
|
|
1647
|
+
body=typing.cast(
|
|
1648
|
+
HttpValidationError,
|
|
1649
|
+
parse_obj_as(
|
|
1650
|
+
type_=HttpValidationError, # type: ignore
|
|
1651
|
+
object_=_response.json(),
|
|
1652
|
+
),
|
|
1653
|
+
),
|
|
1654
|
+
)
|
|
1655
|
+
_response_json = _response.json()
|
|
1656
|
+
except JSONDecodeError:
|
|
1657
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1658
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1659
|
+
|
|
1660
|
+
async def set_implementation(
|
|
1661
|
+
self, recommendation_id: str, *, method: str, request_options: typing.Optional[RequestOptions] = None
|
|
1662
|
+
) -> AsyncHttpResponse[ImplementationMethodResponse]:
|
|
1663
|
+
"""
|
|
1664
|
+
Records the chosen implementation method for a recommendation
|
|
1665
|
+
|
|
1666
|
+
Parameters
|
|
1667
|
+
----------
|
|
1668
|
+
recommendation_id : str
|
|
1669
|
+
|
|
1670
|
+
method : str
|
|
1671
|
+
Implementation method: 'one-click', 'iac', 'one-click-plus-iac', 'manual'
|
|
1672
|
+
|
|
1673
|
+
request_options : typing.Optional[RequestOptions]
|
|
1674
|
+
Request-specific configuration.
|
|
1675
|
+
|
|
1676
|
+
Returns
|
|
1677
|
+
-------
|
|
1678
|
+
AsyncHttpResponse[ImplementationMethodResponse]
|
|
1679
|
+
Successful Response
|
|
1680
|
+
"""
|
|
1681
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1682
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/implementation",
|
|
1683
|
+
method="POST",
|
|
1684
|
+
json={
|
|
1685
|
+
"method": method,
|
|
1686
|
+
},
|
|
1687
|
+
headers={
|
|
1688
|
+
"content-type": "application/json",
|
|
1689
|
+
},
|
|
1690
|
+
request_options=request_options,
|
|
1691
|
+
omit=OMIT,
|
|
1692
|
+
)
|
|
1693
|
+
try:
|
|
1694
|
+
if 200 <= _response.status_code < 300:
|
|
1695
|
+
_data = typing.cast(
|
|
1696
|
+
ImplementationMethodResponse,
|
|
1697
|
+
parse_obj_as(
|
|
1698
|
+
type_=ImplementationMethodResponse, # type: ignore
|
|
1699
|
+
object_=_response.json(),
|
|
1700
|
+
),
|
|
1701
|
+
)
|
|
1702
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1703
|
+
if _response.status_code == 401:
|
|
1704
|
+
raise UnauthorizedError(
|
|
1705
|
+
headers=dict(_response.headers),
|
|
1706
|
+
body=typing.cast(
|
|
1707
|
+
AuthenticationError,
|
|
1708
|
+
parse_obj_as(
|
|
1709
|
+
type_=AuthenticationError, # type: ignore
|
|
1710
|
+
object_=_response.json(),
|
|
1711
|
+
),
|
|
1712
|
+
),
|
|
1713
|
+
)
|
|
1714
|
+
if _response.status_code == 403:
|
|
1715
|
+
raise ForbiddenError(
|
|
1716
|
+
headers=dict(_response.headers),
|
|
1717
|
+
body=typing.cast(
|
|
1718
|
+
AuthorizationError,
|
|
1719
|
+
parse_obj_as(
|
|
1720
|
+
type_=AuthorizationError, # type: ignore
|
|
1721
|
+
object_=_response.json(),
|
|
1722
|
+
),
|
|
1723
|
+
),
|
|
1724
|
+
)
|
|
1725
|
+
if _response.status_code == 422:
|
|
1726
|
+
raise UnprocessableEntityError(
|
|
1727
|
+
headers=dict(_response.headers),
|
|
1728
|
+
body=typing.cast(
|
|
1729
|
+
HttpValidationError,
|
|
1730
|
+
parse_obj_as(
|
|
1731
|
+
type_=HttpValidationError, # type: ignore
|
|
1732
|
+
object_=_response.json(),
|
|
1733
|
+
),
|
|
1734
|
+
),
|
|
1735
|
+
)
|
|
1736
|
+
_response_json = _response.json()
|
|
1737
|
+
except JSONDecodeError:
|
|
1738
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1739
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1740
|
+
|
|
1741
|
+
async def complete_wizard(
|
|
1742
|
+
self, recommendation_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
1743
|
+
) -> AsyncHttpResponse[CompleteWizardResponse]:
|
|
1744
|
+
"""
|
|
1745
|
+
Completes the wizard flow and triggers the appropriate workflow
|
|
1746
|
+
|
|
1747
|
+
Parameters
|
|
1748
|
+
----------
|
|
1749
|
+
recommendation_id : str
|
|
1750
|
+
|
|
1751
|
+
request_options : typing.Optional[RequestOptions]
|
|
1752
|
+
Request-specific configuration.
|
|
1753
|
+
|
|
1754
|
+
Returns
|
|
1755
|
+
-------
|
|
1756
|
+
AsyncHttpResponse[CompleteWizardResponse]
|
|
1757
|
+
Successful Response
|
|
1758
|
+
"""
|
|
1759
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
1760
|
+
f"api/v1/recommendations/{jsonable_encoder(recommendation_id)}/complete",
|
|
1761
|
+
method="POST",
|
|
1762
|
+
request_options=request_options,
|
|
1763
|
+
)
|
|
1764
|
+
try:
|
|
1765
|
+
if 200 <= _response.status_code < 300:
|
|
1766
|
+
_data = typing.cast(
|
|
1767
|
+
CompleteWizardResponse,
|
|
1768
|
+
parse_obj_as(
|
|
1769
|
+
type_=CompleteWizardResponse, # type: ignore
|
|
1770
|
+
object_=_response.json(),
|
|
1771
|
+
),
|
|
1772
|
+
)
|
|
1773
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
1774
|
+
if _response.status_code == 401:
|
|
1775
|
+
raise UnauthorizedError(
|
|
1776
|
+
headers=dict(_response.headers),
|
|
1777
|
+
body=typing.cast(
|
|
1778
|
+
AuthenticationError,
|
|
1779
|
+
parse_obj_as(
|
|
1780
|
+
type_=AuthenticationError, # type: ignore
|
|
1781
|
+
object_=_response.json(),
|
|
1782
|
+
),
|
|
1783
|
+
),
|
|
1784
|
+
)
|
|
1785
|
+
if _response.status_code == 403:
|
|
1786
|
+
raise ForbiddenError(
|
|
1787
|
+
headers=dict(_response.headers),
|
|
1788
|
+
body=typing.cast(
|
|
1789
|
+
AuthorizationError,
|
|
1790
|
+
parse_obj_as(
|
|
1791
|
+
type_=AuthorizationError, # type: ignore
|
|
1792
|
+
object_=_response.json(),
|
|
1793
|
+
),
|
|
1794
|
+
),
|
|
1795
|
+
)
|
|
1796
|
+
if _response.status_code == 422:
|
|
1797
|
+
raise UnprocessableEntityError(
|
|
1798
|
+
headers=dict(_response.headers),
|
|
1799
|
+
body=typing.cast(
|
|
1800
|
+
HttpValidationError,
|
|
1801
|
+
parse_obj_as(
|
|
1802
|
+
type_=HttpValidationError, # type: ignore
|
|
1803
|
+
object_=_response.json(),
|
|
1804
|
+
),
|
|
1805
|
+
),
|
|
1806
|
+
)
|
|
1807
|
+
_response_json = _response.json()
|
|
1808
|
+
except JSONDecodeError:
|
|
1809
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1810
|
+
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|