diff --git a/autogen.py b/autogen.py index 0c6a230..1df9368 100644 --- a/autogen.py +++ b/autogen.py @@ -20,6 +20,17 @@ OPENAPI_URL = "https://api.vantage.sh/v2/oas_v3.json" OUTPUT_DIR = Path(__file__).parent / "src" / "vantage" +# Maps a substring found in a response description to the internal client method +# that should handle it, and the Python return type to emit. +# Checked against each HTTP status code's description during endpoint parsing. +RESPONSE_HANDLERS: list[tuple[str, str, str]] = [ + ( + "will be available at the location specified in the Location header", + "_request_for_location", + "str", + ), +] + @dataclass class Parameter: @@ -48,6 +59,8 @@ class Endpoint: request_body_type: str | None = None response_type: str | None = None is_multipart: bool = False + response_handler: str | None = None # internal client method to call, if not the default + response_handler_return_type: str | None = None @dataclass @@ -292,13 +305,27 @@ def parse_endpoints(schema: dict[str, Any]) -> list[Endpoint]: response_type = extract_response_type(spec.get("responses", {}), schemas) + description = spec.get("description") + + response_handler = None + response_handler_return_type = None + for resp_desc in spec.get("responses", {}).values(): + text = resp_desc.get("description", "") + for phrase, handler, return_type in RESPONSE_HANDLERS: + if phrase in text: + response_handler = handler + response_handler_return_type = return_type + break + if response_handler: + break + endpoints.append( Endpoint( path=path, method=method.upper(), operation_id=operation_id, summary=spec.get("summary"), - description=spec.get("description"), + description=description, deprecated=spec.get("deprecated", False), parameters=parameters, request_body_required=request_body.get("required", False) @@ -307,6 +334,8 @@ def parse_endpoints(schema: dict[str, Any]) -> list[Endpoint]: request_body_type=body_type, response_type=response_type, is_multipart=is_multipart, + response_handler=response_handler, + response_handler_return_type=response_handler_return_type, ) ) @@ -523,6 +552,18 @@ def generate_pydantic_models(schema: dict[str, Any]) -> str: return "\n".join(lines) +def _collect_handler_routes(resources: dict[str, Resource]) -> dict[str, list[tuple[str, str]]]: + """Scan all endpoints and group (method, path) pairs by their response_handler.""" + handler_routes: dict[str, list[tuple[str, str]]] = {} + for resource in resources.values(): + for endpoint in resource.endpoints: + if endpoint.response_handler: + handler_routes.setdefault(endpoint.response_handler, []).append( + (endpoint.method, endpoint.path) + ) + return handler_routes + + def generate_sync_client(resources: dict[str, Resource]) -> str: """Generate synchronous client code.""" lines = [ @@ -618,6 +659,19 @@ def generate_sync_client(resources: dict[str, Resource]) -> str: " body=response.text,", " )", "", + ] + ) + + # Inject generated routing: one if-block per handler, checking (method, path) + handler_routes = _collect_handler_routes(resources) + for handler, routes in sorted(handler_routes.items()): + route_set = "{" + ", ".join(f'("{m}", "{p}")' for m, p in sorted(routes)) + "}" + lines.append(f" if (method, path) in {route_set}:") + lines.append(f" return self.{handler}(response)") + lines.append("") + + lines.extend( + [ " try:", " data = response.json()", " except Exception:", @@ -625,6 +679,10 @@ def generate_sync_client(resources: dict[str, Resource]) -> str: "", " return data", "", + " def _request_for_location(self, response: Any) -> str:", + ' """Extract the Location header from a response."""', + ' return response.headers["Location"]', + "", "", ] ) @@ -699,7 +757,10 @@ def generate_sync_method(endpoint: Endpoint, method_name: str) -> list[str]: # Method signature param_str = ", ".join(["self"] + params) if params else "self" - return_type = endpoint.response_type or "Any" + if endpoint.response_handler: + return_type = endpoint.response_handler_return_type or "Any" + else: + return_type = endpoint.response_type or "None" lines.append(f" def {method_name}({param_str}) -> {return_type}:") # Docstring @@ -740,11 +801,20 @@ def generate_sync_method(endpoint: Endpoint, method_name: str) -> list[str]: lines.append(" body_data = None") # Make request and coerce response payload into typed models where possible - lines.append( - f' data = self._client.request("{endpoint.method}", path, params=params, body=body_data)' - ) - _append_response_mapping(lines, return_type, "data") - lines.append(" return data") + if endpoint.response_handler: + lines.append( + f' return self._client.request("{endpoint.method}", path, params=params, body=body_data)' + ) + elif endpoint.response_type is None: + lines.append( + f' self._client.request("{endpoint.method}", path, params=params, body=body_data)' + ) + else: + lines.append( + f' data = self._client.request("{endpoint.method}", path, params=params, body=body_data)' + ) + _append_response_mapping(lines, return_type, "data") + lines.append(" return data") return lines @@ -844,6 +914,19 @@ def generate_async_client(resources: dict[str, Resource]) -> str: " body=response.text,", " )", "", + ] + ) + + # Inject generated routing: one if-block per handler, checking (method, path) + handler_routes = _collect_handler_routes(resources) + for handler, routes in sorted(handler_routes.items()): + route_set = "{" + ", ".join(f'("{m}", "{p}")' for m, p in sorted(routes)) + "}" + lines.append(f" if (method, path) in {route_set}:") + lines.append(f" return self.{handler}(response)") + lines.append("") + + lines.extend( + [ " try:", " data = response.json()", " except Exception:", @@ -851,6 +934,10 @@ def generate_async_client(resources: dict[str, Resource]) -> str: "", " return data", "", + " def _request_for_location(self, response: Any) -> str:", + ' """Extract the Location header from a response."""', + ' return response.headers["Location"]', + "", "", ] ) @@ -925,7 +1012,10 @@ def generate_async_method(endpoint: Endpoint, method_name: str) -> list[str]: # Method signature param_str = ", ".join(["self"] + params) if params else "self" - return_type = endpoint.response_type or "Any" + if endpoint.response_handler: + return_type = endpoint.response_handler_return_type or "Any" + else: + return_type = endpoint.response_type or "None" lines.append(f" async def {method_name}({param_str}) -> {return_type}:") # Docstring @@ -966,11 +1056,20 @@ def generate_async_method(endpoint: Endpoint, method_name: str) -> list[str]: lines.append(" body_data = None") # Make request and coerce response payload into typed models where possible - lines.append( - f' data = await self._client.request("{endpoint.method}", path, params=params, body=body_data)' - ) - _append_response_mapping(lines, return_type, "data") - lines.append(" return data") + if endpoint.response_handler: + lines.append( + f' return await self._client.request("{endpoint.method}", path, params=params, body=body_data)' + ) + elif endpoint.response_type is None: + lines.append( + f' await self._client.request("{endpoint.method}", path, params=params, body=body_data)' + ) + else: + lines.append( + f' data = await self._client.request("{endpoint.method}", path, params=params, body=body_data)' + ) + _append_response_mapping(lines, return_type, "data") + lines.append(" return data") return lines diff --git a/src/vantage/_async/client.py b/src/vantage/_async/client.py index b68c78e..151aac8 100644 --- a/src/vantage/_async/client.py +++ b/src/vantage/_async/client.py @@ -123,6 +123,9 @@ async def request( body=response.text, ) + if (method, path) in {("POST", "/costs/data_exports"), ("POST", "/kubernetes_efficiency_reports/data_exports"), ("POST", "/unit_costs/data_exports")}: + return self._request_for_location(response) + try: data = response.json() except Exception: @@ -130,6 +133,10 @@ async def request( return data + def _request_for_location(self, response: Any) -> str: + """Extract the Location header from a response.""" + return response.headers["Location"] + class AccessGrantsAsyncApi: """Async API methods for access_grants resource.""" @@ -196,7 +203,7 @@ async def update(self, access_grant_token: str, body: UpdateAccessGrant) -> Acce return AccessGrant.model_validate(data) return data - async def delete(self, access_grant_token: str) -> Any: + async def delete(self, access_grant_token: str) -> None: """ Delete access grant @@ -205,10 +212,7 @@ async def delete(self, access_grant_token: str) -> Any: path = f"/access_grants/{quote(str(access_grant_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class AnomalyAlertsAsyncApi: @@ -334,7 +338,7 @@ async def update(self, anomaly_notification_token: str, body: UpdateAnomalyNotif return AnomalyNotification.model_validate(data) return data - async def delete(self, anomaly_notification_token: str) -> Any: + async def delete(self, anomaly_notification_token: str) -> None: """ Delete anomaly notification @@ -343,10 +347,7 @@ async def delete(self, anomaly_notification_token: str) -> Any: path = f"/anomaly_notifications/{quote(str(anomaly_notification_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class AuditLogsAsyncApi: @@ -462,7 +463,7 @@ async def update(self, billing_profile_token: str, body: UpdateBillingProfile) - return BillingProfile.model_validate(data) return data - async def delete(self, billing_profile_token: str) -> Any: + async def delete(self, billing_profile_token: str) -> None: """ Delete billing profile @@ -471,10 +472,7 @@ async def delete(self, billing_profile_token: str) -> Any: path = f"/billing_profiles/{quote(str(billing_profile_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class BillingRulesAsyncApi: @@ -542,7 +540,7 @@ async def update(self, billing_rule_token: str, body: UpdateBillingRule) -> Bill return BillingRule.model_validate(data) return data - async def delete(self, billing_rule_token: str) -> Any: + async def delete(self, billing_rule_token: str) -> None: """ Delete billing rule @@ -551,10 +549,7 @@ async def delete(self, billing_rule_token: str) -> Any: path = f"/billing_rules/{quote(str(billing_rule_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class BudgetAlertsAsyncApi: @@ -622,7 +617,7 @@ async def update(self, budget_alert_token: str, body: UpdateBudgetAlert) -> Budg return BudgetAlert.model_validate(data) return data - async def delete(self, budget_alert_token: str) -> Any: + async def delete(self, budget_alert_token: str) -> None: """ Delete budget alert @@ -631,10 +626,7 @@ async def delete(self, budget_alert_token: str) -> Any: path = f"/budget_alerts/{quote(str(budget_alert_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class BudgetsAsyncApi: @@ -704,7 +696,7 @@ async def update(self, budget_token: str, body: UpdateBudget) -> Budget: return Budget.model_validate(data) return data - async def delete(self, budget_token: str) -> Any: + async def delete(self, budget_token: str) -> None: """ Delete budget @@ -713,10 +705,7 @@ async def delete(self, budget_token: str) -> Any: path = f"/budgets/{quote(str(budget_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class BusinessMetricsAsyncApi: @@ -784,7 +773,7 @@ async def update(self, business_metric_token: str, body: UpdateBusinessMetric) - return BusinessMetric.model_validate(data) return data - async def delete(self, business_metric_token: str) -> Any: + async def delete(self, business_metric_token: str) -> None: """ Delete business metric @@ -793,10 +782,7 @@ async def delete(self, business_metric_token: str) -> Any: path = f"/business_metrics/{quote(str(business_metric_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def get_values(self, business_metric_token: str, *, page: Optional[int] = None, limit: Optional[int] = None, start_date: Optional[str] = None) -> BusinessMetricValues: """ @@ -943,7 +929,7 @@ async def update(self, cost_alert_token: str, body: UpdateCostAlert) -> CostAler return CostAlert.model_validate(data) return data - async def delete(self, cost_alert_token: str) -> Any: + async def delete(self, cost_alert_token: str) -> None: """ Delete cost alert @@ -952,10 +938,7 @@ async def delete(self, cost_alert_token: str) -> Any: path = f"/cost_alerts/{quote(str(cost_alert_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class CostProviderAccountsAsyncApi: @@ -1073,7 +1056,7 @@ async def update(self, cost_report_token: str, body: UpdateCostReport) -> CostRe return CostReport.model_validate(data) return data - async def delete(self, cost_report_token: str) -> Any: + async def delete(self, cost_report_token: str) -> None: """ Delete cost report @@ -1082,10 +1065,7 @@ async def delete(self, cost_report_token: str) -> Any: path = f"/cost_reports/{quote(str(cost_report_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def get_forecasted_costs(self, cost_report_token: str, *, start_date: Optional[str] = None, end_date: Optional[str] = None, provider: Optional[str] = None, service: Optional[str] = None, page: Optional[int] = None, limit: Optional[int] = None) -> ForecastedCosts: """ @@ -1138,7 +1118,7 @@ class CostsAsyncApi: def __init__(self, client: AsyncClient) -> None: self._client = client - async def create_export(self, body: CreateCostExport, *, groupings: Optional[List[str]] = None) -> Any: + async def create_export(self, body: CreateCostExport, *, groupings: Optional[List[str]] = None) -> str: """ Generate cost data export @@ -1149,10 +1129,7 @@ async def create_export(self, body: CreateCostExport, *, groupings: Optional[Lis "groupings": groupings, } body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = await self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + return await self._client.request("POST", path, params=params, body=body_data) async def list(self, *, cost_report_token: Optional[str] = None, filter: Optional[str] = None, workspace_token: Optional[str] = None, start_date: Optional[str] = None, end_date: Optional[str] = None, groupings: Optional[List[str]] = None, order: Optional[str] = None, limit: Optional[int] = None, page: Optional[int] = None, date_bin: Optional[str] = None, settings_include_credits: Optional[bool] = None, settings_include_refunds: Optional[bool] = None, settings_include_discounts: Optional[bool] = None, settings_include_tax: Optional[bool] = None, settings_amortize: Optional[bool] = None, settings_unallocated: Optional[bool] = None, settings_aggregate_by: Optional[str] = None, settings_show_previous_period: Optional[bool] = None) -> Costs: """ @@ -1253,7 +1230,7 @@ async def update(self, dashboard_token: str, body: UpdateDashboard) -> Dashboard return Dashboard.model_validate(data) return data - async def delete(self, dashboard_token: str) -> Any: + async def delete(self, dashboard_token: str) -> None: """ Delete dashboard @@ -1262,10 +1239,7 @@ async def delete(self, dashboard_token: str) -> Any: path = f"/dashboards/{quote(str(dashboard_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class DataExportsAsyncApi: @@ -1312,7 +1286,7 @@ async def list(self, *, page: Optional[int] = None, limit: Optional[int] = None) return ExchangeRates.model_validate(data) return data - async def create_via_csv(self, body: dict[str, Any]) -> Any: + async def create_via_csv(self, body: dict[str, Any]) -> None: """ Upload exchange rates via CSV @@ -1321,10 +1295,7 @@ async def create_via_csv(self, body: dict[str, Any]) -> Any: path = "/exchange_rates/csv" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = await self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("POST", path, params=params, body=body_data) class FinancialCommitmentReportsAsyncApi: @@ -1392,7 +1363,7 @@ async def update(self, financial_commitment_report_token: str, body: UpdateFinan return FinancialCommitmentReport.model_validate(data) return data - async def delete(self, financial_commitment_report_token: str) -> Any: + async def delete(self, financial_commitment_report_token: str) -> None: """ Delete financial commitment report @@ -1401,10 +1372,7 @@ async def delete(self, financial_commitment_report_token: str) -> Any: path = f"/financial_commitment_reports/{quote(str(financial_commitment_report_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class FinancialCommitmentsAsyncApi: @@ -1496,7 +1464,7 @@ async def update(self, folder_token: str, body: UpdateFolder) -> Folder: return Folder.model_validate(data) return data - async def delete(self, folder_token: str) -> Any: + async def delete(self, folder_token: str) -> None: """ Delete folder @@ -1505,10 +1473,7 @@ async def delete(self, folder_token: str) -> Any: path = f"/folders/{quote(str(folder_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class IntegrationsAsyncApi: @@ -1564,7 +1529,7 @@ async def update(self, integration_token: str, body: UpdateIntegration) -> Integ return Integration.model_validate(data) return data - async def delete(self, integration_token: str) -> Any: + async def delete(self, integration_token: str) -> None: """ Delete integration @@ -1573,10 +1538,7 @@ async def delete(self, integration_token: str) -> Any: path = f"/integrations/{quote(str(integration_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def create_custom_provider(self, body: CreateCustomProviderIntegration) -> Integration: """ @@ -1606,7 +1568,7 @@ async def create_user_costs_upload_via_csv(self, integration_token: str, body: d return UserCostsUpload.model_validate(data) return data - async def delete_user_costs_upload(self, integration_token: str, user_costs_upload_token: int) -> Any: + async def delete_user_costs_upload(self, integration_token: str, user_costs_upload_token: int) -> None: """ Delete user costs upload @@ -1615,10 +1577,7 @@ async def delete_user_costs_upload(self, integration_token: str, user_costs_uplo path = f"/integrations/{quote(str(integration_token), safe='')}/costs/{quote(str(user_costs_upload_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def get_user_costs_uploads(self, integration_token: str) -> UserCostsUploads: """ @@ -1715,7 +1674,7 @@ async def get(self, invoice_token: str) -> Invoice: return Invoice.model_validate(data) return data - async def download(self, invoice_token: str, body: DownloadInvoice) -> Any: + async def download(self, invoice_token: str, body: DownloadInvoice) -> None: """ Get invoice file @@ -1724,10 +1683,7 @@ async def download(self, invoice_token: str, body: DownloadInvoice) -> Any: path = f"/invoices/{quote(str(invoice_token), safe='')}/download" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = await self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("POST", path, params=params, body=body_data) async def send(self, invoice_token: str) -> SendInvoice: """ @@ -1823,7 +1779,7 @@ async def create(self, body: CreateKubernetesEfficiencyReport) -> KubernetesEffi return KubernetesEfficiencyReport.model_validate(data) return data - async def create_export(self, body: CreateKubernetesEfficiencyReportExport, *, groupings: Optional[List[str]] = None) -> DataExport: + async def create_export(self, body: CreateKubernetesEfficiencyReportExport, *, groupings: Optional[List[str]] = None) -> str: """ Generate Kubernetes efficiency data export @@ -1834,10 +1790,7 @@ async def create_export(self, body: CreateKubernetesEfficiencyReportExport, *, g "groupings": groupings, } body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = await self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return DataExport.model_validate(data) - return data + return await self._client.request("POST", path, params=params, body=body_data) async def get(self, kubernetes_efficiency_report_token: str) -> KubernetesEfficiencyReport: """ @@ -1867,7 +1820,7 @@ async def update(self, kubernetes_efficiency_report_token: str, body: UpdateKube return KubernetesEfficiencyReport.model_validate(data) return data - async def delete(self, kubernetes_efficiency_report_token: str) -> Any: + async def delete(self, kubernetes_efficiency_report_token: str) -> None: """ Delete Kubernetes efficiency report @@ -1876,10 +1829,7 @@ async def delete(self, kubernetes_efficiency_report_token: str) -> Any: path = f"/kubernetes_efficiency_reports/{quote(str(kubernetes_efficiency_report_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class ManagedAccountsAsyncApi: @@ -1947,7 +1897,7 @@ async def update(self, managed_account_token: str, body: UpdateManagedAccount) - return ManagedAccount.model_validate(data) return data - async def delete(self, managed_account_token: str) -> Any: + async def delete(self, managed_account_token: str) -> None: """ Delete managed account @@ -1956,10 +1906,7 @@ async def delete(self, managed_account_token: str) -> Any: path = f"/managed_accounts/{quote(str(managed_account_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def update_sso_connection_for(self, managed_account_token: str, body: UpdateSsoConnectionForManagedAccount) -> ManagedAccount: """ @@ -2076,7 +2023,7 @@ async def update(self, network_flow_report_token: str, body: UpdateNetworkFlowRe return NetworkFlowReport.model_validate(data) return data - async def delete(self, network_flow_report_token: str) -> Any: + async def delete(self, network_flow_report_token: str) -> None: """ Delete network flow report @@ -2085,10 +2032,7 @@ async def delete(self, network_flow_report_token: str) -> Any: path = f"/network_flow_reports/{quote(str(network_flow_report_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class PingAsyncApi: @@ -2097,15 +2041,12 @@ class PingAsyncApi: def __init__(self, client: AsyncClient) -> None: self._client = client - async def ping(self) -> Any: + async def ping(self) -> None: """This is a health check endpoint that can be used to determine Vantage API healthiness. It will return 200 if everything is running smoothly.""" path = "/ping" params = None body_data = None - data = await self._client.request("GET", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("GET", path, params=params, body=body_data) class ProductsAsyncApi: @@ -2245,7 +2186,7 @@ async def update(self, recommendation_view_token: str, body: UpdateRecommendatio return RecommendationView.model_validate(data) return data - async def delete(self, recommendation_view_token: str) -> Any: + async def delete(self, recommendation_view_token: str) -> None: """ Delete recommendation view @@ -2254,10 +2195,7 @@ async def delete(self, recommendation_view_token: str) -> Any: path = f"/recommendation_views/{quote(str(recommendation_view_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class RecommendationsAsyncApi: @@ -2435,7 +2373,7 @@ async def update(self, report_notification_token: str, body: UpdateReportNotific return ReportNotification.model_validate(data) return data - async def delete(self, report_notification_token: str) -> Any: + async def delete(self, report_notification_token: str) -> None: """ Delete report notification @@ -2444,10 +2382,7 @@ async def delete(self, report_notification_token: str) -> Any: path = f"/report_notifications/{quote(str(report_notification_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class ResourceReportsAsyncApi: @@ -2531,7 +2466,7 @@ async def update(self, resource_report_token: str, body: UpdateResourceReport) - return ResourceReport.model_validate(data) return data - async def delete(self, resource_report_token: str) -> Any: + async def delete(self, resource_report_token: str) -> None: """ Delete resource report @@ -2540,10 +2475,7 @@ async def delete(self, resource_report_token: str) -> Any: path = f"/resource_reports/{quote(str(resource_report_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class ResourcesAsyncApi: @@ -2655,7 +2587,7 @@ async def update(self, saved_filter_token: str, body: UpdateSavedFilter) -> Save return SavedFilter.model_validate(data) return data - async def delete(self, saved_filter_token: str) -> Any: + async def delete(self, saved_filter_token: str) -> None: """ Delete saved filter @@ -2664,10 +2596,7 @@ async def delete(self, saved_filter_token: str) -> Any: path = f"/saved_filters/{quote(str(saved_filter_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class SegmentsAsyncApi: @@ -2735,7 +2664,7 @@ async def update(self, segment_token: str, body: UpdateSegment) -> Segment: return Segment.model_validate(data) return data - async def delete(self, segment_token: str) -> Any: + async def delete(self, segment_token: str) -> None: """ Delete segment @@ -2744,10 +2673,7 @@ async def delete(self, segment_token: str) -> Any: path = f"/segments/{quote(str(segment_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class TagsAsyncApi: @@ -2876,7 +2802,7 @@ async def update(self, team_token: str, body: UpdateTeam) -> Team: return Team.model_validate(data) return data - async def delete(self, team_token: str) -> Any: + async def delete(self, team_token: str) -> None: """ Delete team @@ -2885,10 +2811,7 @@ async def delete(self, team_token: str) -> Any: path = f"/teams/{quote(str(team_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def get_members(self, team_token: str, *, page: Optional[int] = None, limit: Optional[int] = None) -> TeamMembers: """ @@ -2921,7 +2844,7 @@ async def add_member(self, team_token: str, body: AddTeamMember) -> TeamMember: return TeamMember.model_validate(data) return data - async def remove_member(self, team_token: str, user_token: str) -> Any: + async def remove_member(self, team_token: str, user_token: str) -> None: """ Remove team member @@ -2930,10 +2853,7 @@ async def remove_member(self, team_token: str, user_token: str) -> Any: path = f"/teams/{quote(str(team_token), safe='')}/members/{quote(str(user_token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) class UnitCostsAsyncApi: @@ -2942,7 +2862,7 @@ class UnitCostsAsyncApi: def __init__(self, client: AsyncClient) -> None: self._client = client - async def create_export(self, body: CreateUnitCostsExport) -> DataExport: + async def create_export(self, body: CreateUnitCostsExport) -> str: """ Generate data export of unit costs @@ -2951,10 +2871,7 @@ async def create_export(self, body: CreateUnitCostsExport) -> DataExport: path = "/unit_costs/data_exports" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = await self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return DataExport.model_validate(data) - return data + return await self._client.request("POST", path, params=params, body=body_data) async def list(self, *, cost_report_token: str, start_date: Optional[str] = None, end_date: Optional[str] = None, date_bin: Optional[str] = None, order: Optional[str] = None, limit: Optional[int] = None, page: Optional[int] = None) -> UnitCosts: """ @@ -3100,7 +3017,7 @@ async def update(self, token: str, body: UpdateVirtualTagConfig) -> VirtualTagCo return VirtualTagConfig.model_validate(data) return data - async def delete(self, token: str) -> Any: + async def delete(self, token: str) -> None: """ Delete virtual tag config @@ -3109,10 +3026,7 @@ async def delete(self, token: str) -> Any: path = f"/virtual_tag_configs/{quote(str(token), safe='')}" params = None body_data = None - data = await self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("DELETE", path, params=params, body=body_data) async def get_status(self, token: str) -> VirtualTagConfigStatus: """ @@ -3128,7 +3042,7 @@ async def get_status(self, token: str) -> VirtualTagConfigStatus: return VirtualTagConfigStatus.model_validate(data) return data - async def update_async(self, token: str, body: UpdateAsyncVirtualTagConfig) -> Any: + async def update_async(self, token: str, body: UpdateAsyncVirtualTagConfig) -> None: """ Update virtual tag config asynchronously @@ -3137,12 +3051,9 @@ async def update_async(self, token: str, body: UpdateAsyncVirtualTagConfig) -> A path = f"/virtual_tag_configs/{quote(str(token), safe='')}/async" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = await self._client.request("PUT", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("PUT", path, params=params, body=body_data) - async def get_async_virtual_tag_config_status(self, request_id: str) -> Any: + async def get_async_virtual_tag_config_status(self, request_id: str) -> None: """ Get async virtual tag config update status @@ -3151,10 +3062,7 @@ async def get_async_virtual_tag_config_status(self, request_id: str) -> Any: path = f"/virtual_tag_configs/async/{quote(str(request_id), safe='')}" params = None body_data = None - data = await self._client.request("GET", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + await self._client.request("GET", path, params=params, body=body_data) class WorkspacesAsyncApi: diff --git a/src/vantage/_sync/client.py b/src/vantage/_sync/client.py index 8524992..b96b753 100644 --- a/src/vantage/_sync/client.py +++ b/src/vantage/_sync/client.py @@ -123,6 +123,9 @@ def request( body=response.text, ) + if (method, path) in {("POST", "/costs/data_exports"), ("POST", "/kubernetes_efficiency_reports/data_exports"), ("POST", "/unit_costs/data_exports")}: + return self._request_for_location(response) + try: data = response.json() except Exception: @@ -130,6 +133,10 @@ def request( return data + def _request_for_location(self, response: Any) -> str: + """Extract the Location header from a response.""" + return response.headers["Location"] + class AccessGrantsApi: """API methods for access_grants resource.""" @@ -196,7 +203,7 @@ def update(self, access_grant_token: str, body: UpdateAccessGrant) -> AccessGran return AccessGrant.model_validate(data) return data - def delete(self, access_grant_token: str) -> Any: + def delete(self, access_grant_token: str) -> None: """ Delete access grant @@ -205,10 +212,7 @@ def delete(self, access_grant_token: str) -> Any: path = f"/access_grants/{quote(str(access_grant_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class AnomalyAlertsApi: @@ -334,7 +338,7 @@ def update(self, anomaly_notification_token: str, body: UpdateAnomalyNotificatio return AnomalyNotification.model_validate(data) return data - def delete(self, anomaly_notification_token: str) -> Any: + def delete(self, anomaly_notification_token: str) -> None: """ Delete anomaly notification @@ -343,10 +347,7 @@ def delete(self, anomaly_notification_token: str) -> Any: path = f"/anomaly_notifications/{quote(str(anomaly_notification_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class AuditLogsApi: @@ -462,7 +463,7 @@ def update(self, billing_profile_token: str, body: UpdateBillingProfile) -> Bill return BillingProfile.model_validate(data) return data - def delete(self, billing_profile_token: str) -> Any: + def delete(self, billing_profile_token: str) -> None: """ Delete billing profile @@ -471,10 +472,7 @@ def delete(self, billing_profile_token: str) -> Any: path = f"/billing_profiles/{quote(str(billing_profile_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class BillingRulesApi: @@ -542,7 +540,7 @@ def update(self, billing_rule_token: str, body: UpdateBillingRule) -> BillingRul return BillingRule.model_validate(data) return data - def delete(self, billing_rule_token: str) -> Any: + def delete(self, billing_rule_token: str) -> None: """ Delete billing rule @@ -551,10 +549,7 @@ def delete(self, billing_rule_token: str) -> Any: path = f"/billing_rules/{quote(str(billing_rule_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class BudgetAlertsApi: @@ -622,7 +617,7 @@ def update(self, budget_alert_token: str, body: UpdateBudgetAlert) -> BudgetAler return BudgetAlert.model_validate(data) return data - def delete(self, budget_alert_token: str) -> Any: + def delete(self, budget_alert_token: str) -> None: """ Delete budget alert @@ -631,10 +626,7 @@ def delete(self, budget_alert_token: str) -> Any: path = f"/budget_alerts/{quote(str(budget_alert_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class BudgetsApi: @@ -704,7 +696,7 @@ def update(self, budget_token: str, body: UpdateBudget) -> Budget: return Budget.model_validate(data) return data - def delete(self, budget_token: str) -> Any: + def delete(self, budget_token: str) -> None: """ Delete budget @@ -713,10 +705,7 @@ def delete(self, budget_token: str) -> Any: path = f"/budgets/{quote(str(budget_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class BusinessMetricsApi: @@ -784,7 +773,7 @@ def update(self, business_metric_token: str, body: UpdateBusinessMetric) -> Busi return BusinessMetric.model_validate(data) return data - def delete(self, business_metric_token: str) -> Any: + def delete(self, business_metric_token: str) -> None: """ Delete business metric @@ -793,10 +782,7 @@ def delete(self, business_metric_token: str) -> Any: path = f"/business_metrics/{quote(str(business_metric_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def get_values(self, business_metric_token: str, *, page: Optional[int] = None, limit: Optional[int] = None, start_date: Optional[str] = None) -> BusinessMetricValues: """ @@ -943,7 +929,7 @@ def update(self, cost_alert_token: str, body: UpdateCostAlert) -> CostAlert: return CostAlert.model_validate(data) return data - def delete(self, cost_alert_token: str) -> Any: + def delete(self, cost_alert_token: str) -> None: """ Delete cost alert @@ -952,10 +938,7 @@ def delete(self, cost_alert_token: str) -> Any: path = f"/cost_alerts/{quote(str(cost_alert_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class CostProviderAccountsApi: @@ -1073,7 +1056,7 @@ def update(self, cost_report_token: str, body: UpdateCostReport) -> CostReport: return CostReport.model_validate(data) return data - def delete(self, cost_report_token: str) -> Any: + def delete(self, cost_report_token: str) -> None: """ Delete cost report @@ -1082,10 +1065,7 @@ def delete(self, cost_report_token: str) -> Any: path = f"/cost_reports/{quote(str(cost_report_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def get_forecasted_costs(self, cost_report_token: str, *, start_date: Optional[str] = None, end_date: Optional[str] = None, provider: Optional[str] = None, service: Optional[str] = None, page: Optional[int] = None, limit: Optional[int] = None) -> ForecastedCosts: """ @@ -1138,7 +1118,7 @@ class CostsApi: def __init__(self, client: SyncClient) -> None: self._client = client - def create_export(self, body: CreateCostExport, *, groupings: Optional[List[str]] = None) -> Any: + def create_export(self, body: CreateCostExport, *, groupings: Optional[List[str]] = None) -> str: """ Generate cost data export @@ -1149,10 +1129,7 @@ def create_export(self, body: CreateCostExport, *, groupings: Optional[List[str] "groupings": groupings, } body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + return self._client.request("POST", path, params=params, body=body_data) def list(self, *, cost_report_token: Optional[str] = None, filter: Optional[str] = None, workspace_token: Optional[str] = None, start_date: Optional[str] = None, end_date: Optional[str] = None, groupings: Optional[List[str]] = None, order: Optional[str] = None, limit: Optional[int] = None, page: Optional[int] = None, date_bin: Optional[str] = None, settings_include_credits: Optional[bool] = None, settings_include_refunds: Optional[bool] = None, settings_include_discounts: Optional[bool] = None, settings_include_tax: Optional[bool] = None, settings_amortize: Optional[bool] = None, settings_unallocated: Optional[bool] = None, settings_aggregate_by: Optional[str] = None, settings_show_previous_period: Optional[bool] = None) -> Costs: """ @@ -1253,7 +1230,7 @@ def update(self, dashboard_token: str, body: UpdateDashboard) -> Dashboard: return Dashboard.model_validate(data) return data - def delete(self, dashboard_token: str) -> Any: + def delete(self, dashboard_token: str) -> None: """ Delete dashboard @@ -1262,10 +1239,7 @@ def delete(self, dashboard_token: str) -> Any: path = f"/dashboards/{quote(str(dashboard_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class DataExportsApi: @@ -1312,7 +1286,7 @@ def list(self, *, page: Optional[int] = None, limit: Optional[int] = None) -> Ex return ExchangeRates.model_validate(data) return data - def create_via_csv(self, body: dict[str, Any]) -> Any: + def create_via_csv(self, body: dict[str, Any]) -> None: """ Upload exchange rates via CSV @@ -1321,10 +1295,7 @@ def create_via_csv(self, body: dict[str, Any]) -> Any: path = "/exchange_rates/csv" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("POST", path, params=params, body=body_data) class FinancialCommitmentReportsApi: @@ -1392,7 +1363,7 @@ def update(self, financial_commitment_report_token: str, body: UpdateFinancialCo return FinancialCommitmentReport.model_validate(data) return data - def delete(self, financial_commitment_report_token: str) -> Any: + def delete(self, financial_commitment_report_token: str) -> None: """ Delete financial commitment report @@ -1401,10 +1372,7 @@ def delete(self, financial_commitment_report_token: str) -> Any: path = f"/financial_commitment_reports/{quote(str(financial_commitment_report_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class FinancialCommitmentsApi: @@ -1496,7 +1464,7 @@ def update(self, folder_token: str, body: UpdateFolder) -> Folder: return Folder.model_validate(data) return data - def delete(self, folder_token: str) -> Any: + def delete(self, folder_token: str) -> None: """ Delete folder @@ -1505,10 +1473,7 @@ def delete(self, folder_token: str) -> Any: path = f"/folders/{quote(str(folder_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class IntegrationsApi: @@ -1564,7 +1529,7 @@ def update(self, integration_token: str, body: UpdateIntegration) -> Integration return Integration.model_validate(data) return data - def delete(self, integration_token: str) -> Any: + def delete(self, integration_token: str) -> None: """ Delete integration @@ -1573,10 +1538,7 @@ def delete(self, integration_token: str) -> Any: path = f"/integrations/{quote(str(integration_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def create_custom_provider(self, body: CreateCustomProviderIntegration) -> Integration: """ @@ -1606,7 +1568,7 @@ def create_user_costs_upload_via_csv(self, integration_token: str, body: dict[st return UserCostsUpload.model_validate(data) return data - def delete_user_costs_upload(self, integration_token: str, user_costs_upload_token: int) -> Any: + def delete_user_costs_upload(self, integration_token: str, user_costs_upload_token: int) -> None: """ Delete user costs upload @@ -1615,10 +1577,7 @@ def delete_user_costs_upload(self, integration_token: str, user_costs_upload_tok path = f"/integrations/{quote(str(integration_token), safe='')}/costs/{quote(str(user_costs_upload_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def get_user_costs_uploads(self, integration_token: str) -> UserCostsUploads: """ @@ -1715,7 +1674,7 @@ def get(self, invoice_token: str) -> Invoice: return Invoice.model_validate(data) return data - def download(self, invoice_token: str, body: DownloadInvoice) -> Any: + def download(self, invoice_token: str, body: DownloadInvoice) -> None: """ Get invoice file @@ -1724,10 +1683,7 @@ def download(self, invoice_token: str, body: DownloadInvoice) -> Any: path = f"/invoices/{quote(str(invoice_token), safe='')}/download" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("POST", path, params=params, body=body_data) def send(self, invoice_token: str) -> SendInvoice: """ @@ -1823,7 +1779,7 @@ def create(self, body: CreateKubernetesEfficiencyReport) -> KubernetesEfficiency return KubernetesEfficiencyReport.model_validate(data) return data - def create_export(self, body: CreateKubernetesEfficiencyReportExport, *, groupings: Optional[List[str]] = None) -> DataExport: + def create_export(self, body: CreateKubernetesEfficiencyReportExport, *, groupings: Optional[List[str]] = None) -> str: """ Generate Kubernetes efficiency data export @@ -1834,10 +1790,7 @@ def create_export(self, body: CreateKubernetesEfficiencyReportExport, *, groupin "groupings": groupings, } body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return DataExport.model_validate(data) - return data + return self._client.request("POST", path, params=params, body=body_data) def get(self, kubernetes_efficiency_report_token: str) -> KubernetesEfficiencyReport: """ @@ -1867,7 +1820,7 @@ def update(self, kubernetes_efficiency_report_token: str, body: UpdateKubernetes return KubernetesEfficiencyReport.model_validate(data) return data - def delete(self, kubernetes_efficiency_report_token: str) -> Any: + def delete(self, kubernetes_efficiency_report_token: str) -> None: """ Delete Kubernetes efficiency report @@ -1876,10 +1829,7 @@ def delete(self, kubernetes_efficiency_report_token: str) -> Any: path = f"/kubernetes_efficiency_reports/{quote(str(kubernetes_efficiency_report_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class ManagedAccountsApi: @@ -1947,7 +1897,7 @@ def update(self, managed_account_token: str, body: UpdateManagedAccount) -> Mana return ManagedAccount.model_validate(data) return data - def delete(self, managed_account_token: str) -> Any: + def delete(self, managed_account_token: str) -> None: """ Delete managed account @@ -1956,10 +1906,7 @@ def delete(self, managed_account_token: str) -> Any: path = f"/managed_accounts/{quote(str(managed_account_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def update_sso_connection_for(self, managed_account_token: str, body: UpdateSsoConnectionForManagedAccount) -> ManagedAccount: """ @@ -2076,7 +2023,7 @@ def update(self, network_flow_report_token: str, body: UpdateNetworkFlowReport) return NetworkFlowReport.model_validate(data) return data - def delete(self, network_flow_report_token: str) -> Any: + def delete(self, network_flow_report_token: str) -> None: """ Delete network flow report @@ -2085,10 +2032,7 @@ def delete(self, network_flow_report_token: str) -> Any: path = f"/network_flow_reports/{quote(str(network_flow_report_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class PingApi: @@ -2097,15 +2041,12 @@ class PingApi: def __init__(self, client: SyncClient) -> None: self._client = client - def ping(self) -> Any: + def ping(self) -> None: """This is a health check endpoint that can be used to determine Vantage API healthiness. It will return 200 if everything is running smoothly.""" path = "/ping" params = None body_data = None - data = self._client.request("GET", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("GET", path, params=params, body=body_data) class ProductsApi: @@ -2245,7 +2186,7 @@ def update(self, recommendation_view_token: str, body: UpdateRecommendationView) return RecommendationView.model_validate(data) return data - def delete(self, recommendation_view_token: str) -> Any: + def delete(self, recommendation_view_token: str) -> None: """ Delete recommendation view @@ -2254,10 +2195,7 @@ def delete(self, recommendation_view_token: str) -> Any: path = f"/recommendation_views/{quote(str(recommendation_view_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class RecommendationsApi: @@ -2435,7 +2373,7 @@ def update(self, report_notification_token: str, body: UpdateReportNotification) return ReportNotification.model_validate(data) return data - def delete(self, report_notification_token: str) -> Any: + def delete(self, report_notification_token: str) -> None: """ Delete report notification @@ -2444,10 +2382,7 @@ def delete(self, report_notification_token: str) -> Any: path = f"/report_notifications/{quote(str(report_notification_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class ResourceReportsApi: @@ -2531,7 +2466,7 @@ def update(self, resource_report_token: str, body: UpdateResourceReport) -> Reso return ResourceReport.model_validate(data) return data - def delete(self, resource_report_token: str) -> Any: + def delete(self, resource_report_token: str) -> None: """ Delete resource report @@ -2540,10 +2475,7 @@ def delete(self, resource_report_token: str) -> Any: path = f"/resource_reports/{quote(str(resource_report_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class ResourcesApi: @@ -2655,7 +2587,7 @@ def update(self, saved_filter_token: str, body: UpdateSavedFilter) -> SavedFilte return SavedFilter.model_validate(data) return data - def delete(self, saved_filter_token: str) -> Any: + def delete(self, saved_filter_token: str) -> None: """ Delete saved filter @@ -2664,10 +2596,7 @@ def delete(self, saved_filter_token: str) -> Any: path = f"/saved_filters/{quote(str(saved_filter_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class SegmentsApi: @@ -2735,7 +2664,7 @@ def update(self, segment_token: str, body: UpdateSegment) -> Segment: return Segment.model_validate(data) return data - def delete(self, segment_token: str) -> Any: + def delete(self, segment_token: str) -> None: """ Delete segment @@ -2744,10 +2673,7 @@ def delete(self, segment_token: str) -> Any: path = f"/segments/{quote(str(segment_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class TagsApi: @@ -2876,7 +2802,7 @@ def update(self, team_token: str, body: UpdateTeam) -> Team: return Team.model_validate(data) return data - def delete(self, team_token: str) -> Any: + def delete(self, team_token: str) -> None: """ Delete team @@ -2885,10 +2811,7 @@ def delete(self, team_token: str) -> Any: path = f"/teams/{quote(str(team_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def get_members(self, team_token: str, *, page: Optional[int] = None, limit: Optional[int] = None) -> TeamMembers: """ @@ -2921,7 +2844,7 @@ def add_member(self, team_token: str, body: AddTeamMember) -> TeamMember: return TeamMember.model_validate(data) return data - def remove_member(self, team_token: str, user_token: str) -> Any: + def remove_member(self, team_token: str, user_token: str) -> None: """ Remove team member @@ -2930,10 +2853,7 @@ def remove_member(self, team_token: str, user_token: str) -> Any: path = f"/teams/{quote(str(team_token), safe='')}/members/{quote(str(user_token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) class UnitCostsApi: @@ -2942,7 +2862,7 @@ class UnitCostsApi: def __init__(self, client: SyncClient) -> None: self._client = client - def create_export(self, body: CreateUnitCostsExport) -> DataExport: + def create_export(self, body: CreateUnitCostsExport) -> str: """ Generate data export of unit costs @@ -2951,10 +2871,7 @@ def create_export(self, body: CreateUnitCostsExport) -> DataExport: path = "/unit_costs/data_exports" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = self._client.request("POST", path, params=params, body=body_data) - if isinstance(data, dict): - return DataExport.model_validate(data) - return data + return self._client.request("POST", path, params=params, body=body_data) def list(self, *, cost_report_token: str, start_date: Optional[str] = None, end_date: Optional[str] = None, date_bin: Optional[str] = None, order: Optional[str] = None, limit: Optional[int] = None, page: Optional[int] = None) -> UnitCosts: """ @@ -3100,7 +3017,7 @@ def update(self, token: str, body: UpdateVirtualTagConfig) -> VirtualTagConfig: return VirtualTagConfig.model_validate(data) return data - def delete(self, token: str) -> Any: + def delete(self, token: str) -> None: """ Delete virtual tag config @@ -3109,10 +3026,7 @@ def delete(self, token: str) -> Any: path = f"/virtual_tag_configs/{quote(str(token), safe='')}" params = None body_data = None - data = self._client.request("DELETE", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("DELETE", path, params=params, body=body_data) def get_status(self, token: str) -> VirtualTagConfigStatus: """ @@ -3128,7 +3042,7 @@ def get_status(self, token: str) -> VirtualTagConfigStatus: return VirtualTagConfigStatus.model_validate(data) return data - def update_async(self, token: str, body: UpdateAsyncVirtualTagConfig) -> Any: + def update_async(self, token: str, body: UpdateAsyncVirtualTagConfig) -> None: """ Update virtual tag config asynchronously @@ -3137,12 +3051,9 @@ def update_async(self, token: str, body: UpdateAsyncVirtualTagConfig) -> Any: path = f"/virtual_tag_configs/{quote(str(token), safe='')}/async" params = None body_data = body.model_dump(by_alias=True, exclude_none=True) if hasattr(body, 'model_dump') else body - data = self._client.request("PUT", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("PUT", path, params=params, body=body_data) - def get_async_virtual_tag_config_status(self, request_id: str) -> Any: + def get_async_virtual_tag_config_status(self, request_id: str) -> None: """ Get async virtual tag config update status @@ -3151,10 +3062,7 @@ def get_async_virtual_tag_config_status(self, request_id: str) -> Any: path = f"/virtual_tag_configs/async/{quote(str(request_id), safe='')}" params = None body_data = None - data = self._client.request("GET", path, params=params, body=body_data) - if isinstance(data, dict): - return Any.model_validate(data) - return data + self._client.request("GET", path, params=params, body=body_data) class WorkspacesApi: