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.
Files changed (208) hide show
  1. levelfour/__init__.py +495 -0
  2. levelfour/api_keys/__init__.py +34 -0
  3. levelfour/api_keys/client.py +337 -0
  4. levelfour/api_keys/raw_client.py +621 -0
  5. levelfour/api_keys/types/__init__.py +34 -0
  6. levelfour/api_keys/types/create_api_key_request_scope.py +5 -0
  7. levelfour/async_levelfour_client.py +39 -0
  8. levelfour/base_client.py +346 -0
  9. levelfour/client.py +54 -0
  10. levelfour/core/__init__.py +127 -0
  11. levelfour/core/api_error.py +23 -0
  12. levelfour/core/client_wrapper.py +105 -0
  13. levelfour/core/datetime_utils.py +70 -0
  14. levelfour/core/file.py +67 -0
  15. levelfour/core/force_multipart.py +18 -0
  16. levelfour/core/http_client.py +776 -0
  17. levelfour/core/http_response.py +59 -0
  18. levelfour/core/http_sse/__init__.py +42 -0
  19. levelfour/core/http_sse/_api.py +112 -0
  20. levelfour/core/http_sse/_decoders.py +61 -0
  21. levelfour/core/http_sse/_exceptions.py +7 -0
  22. levelfour/core/http_sse/_models.py +17 -0
  23. levelfour/core/jsonable_encoder.py +108 -0
  24. levelfour/core/logging.py +107 -0
  25. levelfour/core/pagination.py +82 -0
  26. levelfour/core/pydantic_utilities.py +577 -0
  27. levelfour/core/query_encoder.py +58 -0
  28. levelfour/core/remove_none_from_dict.py +11 -0
  29. levelfour/core/request_options.py +35 -0
  30. levelfour/core/serialization.py +276 -0
  31. levelfour/errors/__init__.py +40 -0
  32. levelfour/errors/forbidden_error.py +11 -0
  33. levelfour/errors/unauthorized_error.py +11 -0
  34. levelfour/errors/unprocessable_entity_error.py +11 -0
  35. levelfour/evaluation/__init__.py +4 -0
  36. levelfour/evaluation/client.py +102 -0
  37. levelfour/evaluation/raw_client.py +141 -0
  38. levelfour/exceptions.py +63 -0
  39. levelfour/health/__init__.py +4 -0
  40. levelfour/health/client.py +163 -0
  41. levelfour/health/raw_client.py +164 -0
  42. levelfour/integrations/__init__.py +0 -0
  43. levelfour/integrations/django.py +26 -0
  44. levelfour/integrations/fastapi.py +39 -0
  45. levelfour/integrations/telemetry.py +66 -0
  46. levelfour/levelfour_client.py +47 -0
  47. levelfour/pagination.py +84 -0
  48. levelfour/pr_analysis/__init__.py +4 -0
  49. levelfour/pr_analysis/client.py +408 -0
  50. levelfour/pr_analysis/raw_client.py +620 -0
  51. levelfour/pr_analysis_actions/__init__.py +4 -0
  52. levelfour/pr_analysis_actions/client.py +588 -0
  53. levelfour/pr_analysis_actions/raw_client.py +939 -0
  54. levelfour/pr_analysis_installations/__init__.py +4 -0
  55. levelfour/pr_analysis_installations/client.py +470 -0
  56. levelfour/pr_analysis_installations/raw_client.py +868 -0
  57. levelfour/providers/__init__.py +34 -0
  58. levelfour/providers/client.py +1504 -0
  59. levelfour/providers/raw_client.py +2398 -0
  60. levelfour/providers/types/__init__.py +36 -0
  61. levelfour/providers/types/list_spending_breakdown_providers_response.py +11 -0
  62. levelfour/py.typed +0 -0
  63. levelfour/recommendations/__init__.py +4 -0
  64. levelfour/recommendations/client.py +1018 -0
  65. levelfour/recommendations/raw_client.py +1810 -0
  66. levelfour/savings/__init__.py +4 -0
  67. levelfour/savings/client.py +401 -0
  68. levelfour/savings/raw_client.py +624 -0
  69. levelfour/spending/__init__.py +34 -0
  70. levelfour/spending/client.py +437 -0
  71. levelfour/spending/raw_client.py +684 -0
  72. levelfour/spending/types/__init__.py +34 -0
  73. levelfour/spending/types/list_breakdown_spending_response.py +12 -0
  74. levelfour/types/__init__.py +413 -0
  75. levelfour/types/accept_terms_data.py +25 -0
  76. levelfour/types/accept_terms_response.py +27 -0
  77. levelfour/types/action_request.py +42 -0
  78. levelfour/types/api_key_created_data.py +28 -0
  79. levelfour/types/api_key_data.py +27 -0
  80. levelfour/types/authentication_error.py +5 -0
  81. levelfour/types/authorization_error.py +5 -0
  82. levelfour/types/bad_request_error.py +5 -0
  83. levelfour/types/comparison_item.py +32 -0
  84. levelfour/types/complete_wizard_data.py +27 -0
  85. levelfour/types/complete_wizard_response.py +27 -0
  86. levelfour/types/conflict_error.py +5 -0
  87. levelfour/types/cost_breakdown_data.py +35 -0
  88. levelfour/types/cost_breakdown_item.py +71 -0
  89. levelfour/types/cost_breakdown_raw_data.py +37 -0
  90. levelfour/types/cost_breakdown_raw_response.py +27 -0
  91. levelfour/types/cost_breakdown_response.py +27 -0
  92. levelfour/types/costs_breakdown_chart_data.py +48 -0
  93. levelfour/types/costs_breakdown_chart_response.py +27 -0
  94. levelfour/types/costs_breakdown_data_point.py +46 -0
  95. levelfour/types/costs_breakdown_grouped_chart_data.py +52 -0
  96. levelfour/types/costs_breakdown_grouped_chart_response.py +27 -0
  97. levelfour/types/costs_breakdown_grouped_data_point.py +36 -0
  98. levelfour/types/costs_breakdown_totals.py +41 -0
  99. levelfour/types/create_api_key_response.py +23 -0
  100. levelfour/types/daily_spending_breakdown_data.py +42 -0
  101. levelfour/types/daily_spending_breakdown_response.py +27 -0
  102. levelfour/types/daily_spending_data_point.py +31 -0
  103. levelfour/types/dashboard_summary_data.py +72 -0
  104. levelfour/types/dashboard_summary_response.py +27 -0
  105. levelfour/types/delete_endpoint_data.py +20 -0
  106. levelfour/types/delete_endpoint_response.py +23 -0
  107. levelfour/types/endpoint_data.py +23 -0
  108. levelfour/types/error_response.py +23 -0
  109. levelfour/types/error_response_error.py +21 -0
  110. levelfour/types/evaluation_status_data.py +71 -0
  111. levelfour/types/evaluation_status_response.py +27 -0
  112. levelfour/types/execution_log_command.py +21 -0
  113. levelfour/types/execution_log_entry.py +23 -0
  114. levelfour/types/execution_step_schema.py +23 -0
  115. levelfour/types/http_validation_error.py +20 -0
  116. levelfour/types/implementation_method_data.py +25 -0
  117. levelfour/types/implementation_method_response.py +27 -0
  118. levelfour/types/implementation_step.py +27 -0
  119. levelfour/types/internal_server_error.py +5 -0
  120. levelfour/types/list_api_keys_data.py +21 -0
  121. levelfour/types/list_api_keys_response.py +23 -0
  122. levelfour/types/list_endpoints_response.py +23 -0
  123. levelfour/types/metric_data_point.py +27 -0
  124. levelfour/types/metric_series.py +40 -0
  125. levelfour/types/metric_series_entry.py +25 -0
  126. levelfour/types/monthly_spending_data.py +27 -0
  127. levelfour/types/monthly_spending_data_point.py +31 -0
  128. levelfour/types/monthly_spending_response.py +27 -0
  129. levelfour/types/not_found_error.py +5 -0
  130. levelfour/types/pagination_meta.py +51 -0
  131. levelfour/types/processing_recommendation_item.py +61 -0
  132. levelfour/types/processing_recommendations_data.py +28 -0
  133. levelfour/types/processing_recommendations_response.py +27 -0
  134. levelfour/types/provider.py +46 -0
  135. levelfour/types/provider_breakdown_data.py +31 -0
  136. levelfour/types/provider_breakdown_item.py +77 -0
  137. levelfour/types/provider_breakdown_response.py +27 -0
  138. levelfour/types/provider_filter_options_data.py +51 -0
  139. levelfour/types/provider_filter_options_response.py +27 -0
  140. levelfour/types/provider_potential_savings_summary_data.py +46 -0
  141. levelfour/types/provider_potential_savings_summary_response.py +27 -0
  142. levelfour/types/provider_recommendations_summary_data.py +37 -0
  143. levelfour/types/provider_recommendations_summary_response.py +27 -0
  144. levelfour/types/provider_saved_summary_data.py +56 -0
  145. levelfour/types/provider_saved_summary_response.py +27 -0
  146. levelfour/types/provider_service_breakdown_data.py +65 -0
  147. levelfour/types/provider_service_breakdown_item.py +72 -0
  148. levelfour/types/provider_service_breakdown_raw_data.py +62 -0
  149. levelfour/types/provider_service_breakdown_raw_response.py +27 -0
  150. levelfour/types/provider_service_breakdown_response.py +27 -0
  151. levelfour/types/provider_service_costs_breakdown_data.py +62 -0
  152. levelfour/types/provider_service_costs_breakdown_response.py +27 -0
  153. levelfour/types/provider_service_costs_data_point.py +36 -0
  154. levelfour/types/provider_spending.py +61 -0
  155. levelfour/types/provider_spending_summary_data.py +67 -0
  156. levelfour/types/provider_spending_summary_response.py +27 -0
  157. levelfour/types/provider_timeline_data.py +57 -0
  158. levelfour/types/provider_timeline_response.py +27 -0
  159. levelfour/types/provider_top_service.py +36 -0
  160. levelfour/types/providers_summary_data.py +24 -0
  161. levelfour/types/providers_summary_response.py +27 -0
  162. levelfour/types/rate_limit_error.py +5 -0
  163. levelfour/types/recommendation_actions.py +60 -0
  164. levelfour/types/recommendation_detail.py +42 -0
  165. levelfour/types/recommendation_detail_response.py +27 -0
  166. levelfour/types/recommendation_filter_options_data.py +41 -0
  167. levelfour/types/recommendation_filter_options_response.py +27 -0
  168. levelfour/types/recommendation_item.py +36 -0
  169. levelfour/types/recommendation_wizard_data.py +173 -0
  170. levelfour/types/recommendation_wizard_data_metrics.py +7 -0
  171. levelfour/types/recommendation_wizard_response.py +27 -0
  172. levelfour/types/recommendations_breakdown_data.py +26 -0
  173. levelfour/types/recommendations_breakdown_response.py +27 -0
  174. levelfour/types/recommendations_overview_data.py +51 -0
  175. levelfour/types/recommendations_overview_response.py +27 -0
  176. levelfour/types/register_endpoint_response.py +23 -0
  177. levelfour/types/resource_change.py +42 -0
  178. levelfour/types/resource_snapshot.py +21 -0
  179. levelfour/types/revoke_api_key_data.py +20 -0
  180. levelfour/types/revoke_api_key_response.py +23 -0
  181. levelfour/types/risk_assessment.py +29 -0
  182. levelfour/types/risk_factor.py +27 -0
  183. levelfour/types/saved_breakdown_data.py +31 -0
  184. levelfour/types/saved_breakdown_response.py +27 -0
  185. levelfour/types/saved_by_provider_breakdown_data.py +31 -0
  186. levelfour/types/saved_by_provider_breakdown_response.py +27 -0
  187. levelfour/types/saved_by_provider_item.py +76 -0
  188. levelfour/types/saved_item.py +35 -0
  189. levelfour/types/saved_provider_summary.py +36 -0
  190. levelfour/types/saved_summary_data.py +57 -0
  191. levelfour/types/saved_summary_response.py +27 -0
  192. levelfour/types/savings_decision_data.py +28 -0
  193. levelfour/types/savings_decision_response.py +27 -0
  194. levelfour/types/spending_by_date_item.py +36 -0
  195. levelfour/types/top_recommendation.py +56 -0
  196. levelfour/types/trigger_info.py +22 -0
  197. levelfour/types/update_tag_data.py +20 -0
  198. levelfour/types/update_tag_response.py +23 -0
  199. levelfour/types/validation_error.py +24 -0
  200. levelfour/types/validation_error_loc_item.py +5 -0
  201. levelfour/webhooks/__init__.py +4 -0
  202. levelfour/webhooks/client.py +273 -0
  203. levelfour/webhooks/raw_client.py +483 -0
  204. levelfour/webhooks/verifier.py +61 -0
  205. levelfour-0.1.0.dist-info/METADATA +12 -0
  206. levelfour-0.1.0.dist-info/RECORD +208 -0
  207. levelfour-0.1.0.dist-info/WHEEL +5 -0
  208. levelfour-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .monthly_spending_data_point import MonthlySpendingDataPoint
8
+
9
+
10
+ class MonthlySpendingData(UniversalBaseModel):
11
+ """
12
+ Monthly spending data
13
+ """
14
+
15
+ data_points: typing.List[MonthlySpendingDataPoint] = pydantic.Field()
16
+ """
17
+ Monthly spending data points
18
+ """
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class MonthlySpendingDataPoint(UniversalBaseModel):
10
+ """
11
+ Monthly spending data point
12
+ """
13
+
14
+ month: str = pydantic.Field()
15
+ """
16
+ Month in YYYY-MM format
17
+ """
18
+
19
+ amount: float = pydantic.Field()
20
+ """
21
+ Total cost for this month
22
+ """
23
+
24
+ if IS_PYDANTIC_V2:
25
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from .monthly_spending_data import MonthlySpendingData
9
+
10
+
11
+ class MonthlySpendingResponse(UniversalBaseModel):
12
+ """
13
+ Response for monthly spending
14
+ """
15
+
16
+ success: typing.Optional[bool] = None
17
+ timestamp: typing.Optional[dt.datetime] = None
18
+ data: MonthlySpendingData
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .error_response import ErrorResponse
4
+
5
+ NotFoundError = ErrorResponse
@@ -0,0 +1,51 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class PaginationMeta(UniversalBaseModel):
10
+ """
11
+ Pagination metadata
12
+ """
13
+
14
+ total_items: int = pydantic.Field()
15
+ """
16
+ Total number of items across all pages
17
+ """
18
+
19
+ total_pages: int = pydantic.Field()
20
+ """
21
+ Total number of pages
22
+ """
23
+
24
+ current_page: int = pydantic.Field()
25
+ """
26
+ Current page number (1-indexed)
27
+ """
28
+
29
+ page_size: int = pydantic.Field()
30
+ """
31
+ Number of items per page
32
+ """
33
+
34
+ has_next: bool = pydantic.Field()
35
+ """
36
+ Whether there is a next page
37
+ """
38
+
39
+ has_previous: bool = pydantic.Field()
40
+ """
41
+ Whether there is a previous page
42
+ """
43
+
44
+ if IS_PYDANTIC_V2:
45
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
46
+ else:
47
+
48
+ class Config:
49
+ frozen = True
50
+ smart_union = True
51
+ extra = pydantic.Extra.allow
@@ -0,0 +1,61 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class ProcessingRecommendationItem(UniversalBaseModel):
10
+ """
11
+ A recommendation currently in processing status
12
+ """
13
+
14
+ recommendation_id: str = pydantic.Field()
15
+ """
16
+ Unique business identifier
17
+ """
18
+
19
+ service: str = pydantic.Field()
20
+ """
21
+ Service name (e.g., EC2, EBS, RDS)
22
+ """
23
+
24
+ environment: typing.Optional[str] = pydantic.Field(default=None)
25
+ """
26
+ Environment (e.g., Production, Staging)
27
+ """
28
+
29
+ monthly_savings: float = pydantic.Field()
30
+ """
31
+ Monthly savings amount
32
+ """
33
+
34
+ annual_savings: float = pydantic.Field()
35
+ """
36
+ Annual savings amount
37
+ """
38
+
39
+ implementation_method: typing.Optional[str] = pydantic.Field(default=None)
40
+ """
41
+ one-click, iac, one-click-plus-iac, manual
42
+ """
43
+
44
+ status: str = pydantic.Field()
45
+ """
46
+ Status (should be 'processing')
47
+ """
48
+
49
+ completed_at: typing.Optional[str] = pydantic.Field(default=None)
50
+ """
51
+ When the wizard was completed
52
+ """
53
+
54
+ if IS_PYDANTIC_V2:
55
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
56
+ else:
57
+
58
+ class Config:
59
+ frozen = True
60
+ smart_union = True
61
+ extra = pydantic.Extra.allow
@@ -0,0 +1,28 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .processing_recommendation_item import ProcessingRecommendationItem
8
+
9
+
10
+ class ProcessingRecommendationsData(UniversalBaseModel):
11
+ """
12
+ Data for processing recommendations list
13
+ """
14
+
15
+ items: typing.List[ProcessingRecommendationItem]
16
+ count: int = pydantic.Field()
17
+ """
18
+ Number of processing recommendations
19
+ """
20
+
21
+ if IS_PYDANTIC_V2:
22
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
23
+ else:
24
+
25
+ class Config:
26
+ frozen = True
27
+ smart_union = True
28
+ extra = pydantic.Extra.allow
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from .processing_recommendations_data import ProcessingRecommendationsData
9
+
10
+
11
+ class ProcessingRecommendationsResponse(UniversalBaseModel):
12
+ """
13
+ Response for processing recommendations endpoint
14
+ """
15
+
16
+ success: typing.Optional[bool] = None
17
+ timestamp: typing.Optional[dt.datetime] = None
18
+ data: ProcessingRecommendationsData
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow
@@ -0,0 +1,46 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class Provider(UniversalBaseModel):
10
+ """
11
+ Provider-level savings summary
12
+ """
13
+
14
+ provider_id: str = pydantic.Field()
15
+ """
16
+ Provider identifier: aws, gcp, azure, k8s
17
+ """
18
+
19
+ provider_name: str = pydantic.Field()
20
+ """
21
+ Display name: AWS, GCP, etc.
22
+ """
23
+
24
+ monthly_spending: float = pydantic.Field()
25
+ """
26
+ Current monthly spending for this provider
27
+ """
28
+
29
+ potential_savings: float = pydantic.Field()
30
+ """
31
+ Total potential monthly savings
32
+ """
33
+
34
+ potential_savings_percentage: float = pydantic.Field()
35
+ """
36
+ Savings as percentage of spending
37
+ """
38
+
39
+ if IS_PYDANTIC_V2:
40
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
41
+ else:
42
+
43
+ class Config:
44
+ frozen = True
45
+ smart_union = True
46
+ extra = pydantic.Extra.allow
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .pagination_meta import PaginationMeta
8
+ from .provider_breakdown_item import ProviderBreakdownItem
9
+
10
+
11
+ class ProviderBreakdownData(UniversalBaseModel):
12
+ """
13
+ Provider-specific breakdown with pagination
14
+ """
15
+
16
+ total_savings: float = pydantic.Field()
17
+ """
18
+ Sum of monthly_savings for all recommendations (not just current page)
19
+ """
20
+
21
+ items: typing.List[ProviderBreakdownItem]
22
+ pagination: PaginationMeta
23
+
24
+ if IS_PYDANTIC_V2:
25
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -0,0 +1,77 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .recommendation_actions import RecommendationActions
8
+
9
+
10
+ class ProviderBreakdownItem(UniversalBaseModel):
11
+ """
12
+ Simplified breakdown item for provider-specific view
13
+ """
14
+
15
+ recommendation_id: str = pydantic.Field()
16
+ """
17
+ Unique identifier for the recommendation
18
+ """
19
+
20
+ service: str = pydantic.Field()
21
+ """
22
+ Service name (e.g., EC2, EBS, RDS)
23
+ """
24
+
25
+ environment: typing.Optional[str] = pydantic.Field(default=None)
26
+ """
27
+ Environment (e.g., Production, Staging)
28
+ """
29
+
30
+ account: typing.Optional[str] = pydantic.Field(default=None)
31
+ """
32
+ Cloud account identifier
33
+ """
34
+
35
+ tag: typing.Optional[str] = pydantic.Field(default=None)
36
+ """
37
+ Resource tag value
38
+ """
39
+
40
+ monthly_savings: float = pydantic.Field()
41
+ """
42
+ Monthly savings amount
43
+ """
44
+
45
+ savings_percentage: float = pydantic.Field()
46
+ """
47
+ Savings as percentage of current spending
48
+ """
49
+
50
+ status: str = pydantic.Field()
51
+ """
52
+ Status: pending, processing, optimized, rejected, unavailable
53
+ """
54
+
55
+ actions: typing.Optional[RecommendationActions] = pydantic.Field(default=None)
56
+ """
57
+ Action details for this recommendation
58
+ """
59
+
60
+ terms_accepted_at: typing.Optional[str] = pydantic.Field(default=None)
61
+ """
62
+ When terms were accepted, null if not yet accepted
63
+ """
64
+
65
+ saving_accepted_by: typing.Optional[str] = pydantic.Field(default=None)
66
+ """
67
+ User who authored/approved the savings decision
68
+ """
69
+
70
+ if IS_PYDANTIC_V2:
71
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
72
+ else:
73
+
74
+ class Config:
75
+ frozen = True
76
+ smart_union = True
77
+ extra = pydantic.Extra.allow
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from .provider_breakdown_data import ProviderBreakdownData
9
+
10
+
11
+ class ProviderBreakdownResponse(UniversalBaseModel):
12
+ """
13
+ Response for provider-specific breakdown
14
+ """
15
+
16
+ success: typing.Optional[bool] = None
17
+ timestamp: typing.Optional[dt.datetime] = None
18
+ data: ProviderBreakdownData
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow
@@ -0,0 +1,51 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class ProviderFilterOptionsData(UniversalBaseModel):
10
+ """
11
+ Filter options data for provider spending breakdown
12
+ """
13
+
14
+ provider_id: str = pydantic.Field()
15
+ """
16
+ Provider identifier
17
+ """
18
+
19
+ services: typing.List[str] = pydantic.Field()
20
+ """
21
+ Distinct service names available for filtering
22
+ """
23
+
24
+ regions: typing.List[str] = pydantic.Field()
25
+ """
26
+ Distinct regions available for filtering
27
+ """
28
+
29
+ accounts: typing.List[str] = pydantic.Field()
30
+ """
31
+ Distinct account IDs available for filtering
32
+ """
33
+
34
+ tag_keys: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
35
+ """
36
+ Distinct tag keys available for filtering
37
+ """
38
+
39
+ tag_values: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
40
+ """
41
+ Distinct tag values available for filtering
42
+ """
43
+
44
+ if IS_PYDANTIC_V2:
45
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
46
+ else:
47
+
48
+ class Config:
49
+ frozen = True
50
+ smart_union = True
51
+ extra = pydantic.Extra.allow
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from .provider_filter_options_data import ProviderFilterOptionsData
9
+
10
+
11
+ class ProviderFilterOptionsResponse(UniversalBaseModel):
12
+ """
13
+ Response for provider filter options
14
+ """
15
+
16
+ success: typing.Optional[bool] = None
17
+ timestamp: typing.Optional[dt.datetime] = None
18
+ data: ProviderFilterOptionsData
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow
@@ -0,0 +1,46 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class ProviderPotentialSavingsSummaryData(UniversalBaseModel):
10
+ """
11
+ Provider-specific potential savings summary
12
+ """
13
+
14
+ provider_id: str = pydantic.Field()
15
+ """
16
+ Provider identifier
17
+ """
18
+
19
+ total_monthly_savings: float = pydantic.Field()
20
+ """
21
+ Total potential monthly savings
22
+ """
23
+
24
+ total_current_spending: float = pydantic.Field()
25
+ """
26
+ Total current monthly spending
27
+ """
28
+
29
+ total_recommendations: int = pydantic.Field()
30
+ """
31
+ Number of pending recommendations
32
+ """
33
+
34
+ savings_percentage: float = pydantic.Field()
35
+ """
36
+ Savings as percentage of current spending
37
+ """
38
+
39
+ if IS_PYDANTIC_V2:
40
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
41
+ else:
42
+
43
+ class Config:
44
+ frozen = True
45
+ smart_union = True
46
+ extra = pydantic.Extra.allow
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from .provider_potential_savings_summary_data import ProviderPotentialSavingsSummaryData
9
+
10
+
11
+ class ProviderPotentialSavingsSummaryResponse(UniversalBaseModel):
12
+ """
13
+ Response for provider-specific potential savings summary
14
+ """
15
+
16
+ success: typing.Optional[bool] = None
17
+ timestamp: typing.Optional[dt.datetime] = None
18
+ data: ProviderPotentialSavingsSummaryData
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow
@@ -0,0 +1,37 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .top_recommendation import TopRecommendation
8
+
9
+
10
+ class ProviderRecommendationsSummaryData(UniversalBaseModel):
11
+ """
12
+ Provider-specific recommendations summary with top recommendations
13
+ """
14
+
15
+ provider_id: str = pydantic.Field()
16
+ """
17
+ Provider identifier
18
+ """
19
+
20
+ provider_name: str = pydantic.Field()
21
+ """
22
+ Provider display name
23
+ """
24
+
25
+ top_recommendations: typing.List[TopRecommendation] = pydantic.Field()
26
+ """
27
+ Top 3 recommendations by savings
28
+ """
29
+
30
+ if IS_PYDANTIC_V2:
31
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
32
+ else:
33
+
34
+ class Config:
35
+ frozen = True
36
+ smart_union = True
37
+ extra = pydantic.Extra.allow
@@ -0,0 +1,27 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from .provider_recommendations_summary_data import ProviderRecommendationsSummaryData
9
+
10
+
11
+ class ProviderRecommendationsSummaryResponse(UniversalBaseModel):
12
+ """
13
+ Response for provider-specific recommendations summary
14
+ """
15
+
16
+ success: typing.Optional[bool] = None
17
+ timestamp: typing.Optional[dt.datetime] = None
18
+ data: ProviderRecommendationsSummaryData
19
+
20
+ if IS_PYDANTIC_V2:
21
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
22
+ else:
23
+
24
+ class Config:
25
+ frozen = True
26
+ smart_union = True
27
+ extra = pydantic.Extra.allow