From 16c3a9363d92ecdfb2262e5e584b1762514c3413 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:04:31 -0700 Subject: [PATCH] release: 0.1.0-alpha.2 (#5) Automated Release PR --- ## 0.1.0-alpha.2 (2024-06-10) Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/Metronome-Industries/metronome-python/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) ### Features * **api:** update via SDK Studio ([#4](https://github.com/Metronome-Industries/metronome-python/issues/4)) ([17b7ce5](https://github.com/Metronome-Industries/metronome-python/commit/17b7ce57f0c3eb6310ccce51501c84b3e117c4c4)) --- This Pull Request has been generated automatically as part of [Stainless](https://stainlessapi.com/)'s release process. For a better experience, it is recommended to use either rebase-merge or squash-merge when merging this pull request ([see details](https://github.com/stainless-api/release-please/#linear-git-commit-history-use-squash-merge)). _More technical details can be found at [stainless-api/release-please](https://github.com/stainless-api/release-please)_. --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 +++ api.md | 36 +++++------ pyproject.toml | 2 +- src/metronome/_version.py | 2 +- src/metronome/pagination.py | 54 ++++++++++++++++ src/metronome/resources/audit_logs.py | 25 ++++---- src/metronome/resources/billable_metrics.py | 20 +++--- src/metronome/resources/credit_grants.py | 42 +++++++------ .../resources/customers/customers.py | 58 ++++++++++-------- src/metronome/resources/customers/invoices.py | 22 ++++--- src/metronome/resources/customers/plans.py | 38 +++++++----- src/metronome/resources/plans.py | 61 ++++++++++--------- src/metronome/resources/usage.py | 24 +++++--- src/metronome/types/__init__.py | 1 - .../types/audit_log_list_response.py | 25 ++------ .../types/billable_metric_list_response.py | 10 +-- ...credit_grant_list_credit_types_response.py | 12 +--- .../types/credit_grant_list_response.py | 26 +++----- ...customer_list_billable_metrics_response.py | 10 +-- .../types/customer_list_costs_response.py | 18 ++---- src/metronome/types/customer_list_response.py | 14 ----- src/metronome/types/customers/__init__.py | 1 - .../types/customers/invoice_list_response.py | 14 ----- .../plan_list_price_adjustments_response.py | 14 ++--- .../types/customers/plan_list_response.py | 18 ++---- .../types/plan_list_charges_response.py | 18 ++---- .../types/plan_list_customers_response.py | 16 ++--- src/metronome/types/plan_list_response.py | 12 +--- .../types/usage_list_with_groups_response.py | 12 +--- .../api_resources/customers/test_invoices.py | 19 +++--- tests/api_resources/customers/test_plans.py | 33 +++++----- tests/api_resources/test_audit_logs.py | 17 +++--- tests/api_resources/test_billable_metrics.py | 17 +++--- tests/api_resources/test_credit_grants.py | 33 +++++----- tests/api_resources/test_customers.py | 51 ++++++++-------- tests/api_resources/test_plans.py | 49 +++++++-------- tests/api_resources/test_usage.py | 17 +++--- 38 files changed, 423 insertions(+), 428 deletions(-) create mode 100644 src/metronome/pagination.py delete mode 100644 src/metronome/types/customer_list_response.py delete mode 100644 src/metronome/types/customers/invoice_list_response.py diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ba6c3483..f14b480a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.1" + ".": "0.1.0-alpha.2" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c025a607..bfb7e19e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.1.0-alpha.2 (2024-06-10) + +Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/Metronome-Industries/metronome-python/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) + +### Features + +* **api:** update via SDK Studio ([#4](https://github.com/Metronome-Industries/metronome-python/issues/4)) ([17b7ce5](https://github.com/Metronome-Industries/metronome-python/commit/17b7ce57f0c3eb6310ccce51501c84b3e117c4c4)) + ## 0.1.0-alpha.1 (2024-06-10) Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/Metronome-Industries/metronome-python/compare/v0.0.1-alpha.0...v0.1.0-alpha.1) diff --git a/api.md b/api.md index cbbe2af0..54ba8651 100644 --- a/api.md +++ b/api.md @@ -43,10 +43,10 @@ from metronome.types import ( Methods: -- client.plans.list(\*\*params) -> PlanListResponse +- client.plans.list(\*\*params) -> SyncCursorPage[PlanListResponse] - client.plans.get_details(plan_id) -> PlanGetDetailsResponse -- client.plans.list_charges(plan_id, \*\*params) -> PlanListChargesResponse -- client.plans.list_customers(plan_id, \*\*params) -> PlanListCustomersResponse +- client.plans.list_charges(plan_id, \*\*params) -> SyncCursorPage[PlanListChargesResponse] +- client.plans.list_customers(plan_id, \*\*params) -> SyncCursorPage[PlanListCustomersResponse] # CreditGrants @@ -69,9 +69,9 @@ from metronome.types import ( Methods: - client.credit_grants.create(\*\*params) -> CreditGrantCreateResponse -- client.credit_grants.list(\*\*params) -> CreditGrantListResponse +- client.credit_grants.list(\*\*params) -> SyncCursorPage[CreditGrantListResponse] - client.credit_grants.edit(\*\*params) -> CreditGrantEditResponse -- client.credit_grants.list_credit_types(\*\*params) -> CreditGrantListCreditTypesResponse +- client.credit_grants.list_credit_types(\*\*params) -> SyncCursorPage[CreditGrantListCreditTypesResponse] - client.credit_grants.list_entries(\*\*params) -> CreditGrantListEntriesResponse - client.credit_grants.void(\*\*params) -> CreditGrantVoidResponse @@ -85,7 +85,6 @@ from metronome.types import ( CustomerDetail, CustomerCreateResponse, CustomerRetrieveResponse, - CustomerListResponse, CustomerArchiveResponse, CustomerListBillableMetricsResponse, CustomerListCostsResponse, @@ -97,10 +96,10 @@ Methods: - client.customers.create(\*\*params) -> CustomerCreateResponse - client.customers.retrieve(customer_id) -> CustomerRetrieveResponse -- client.customers.list(\*\*params) -> CustomerListResponse +- client.customers.list(\*\*params) -> SyncCursorPage[CustomerDetail] - client.customers.archive(\*\*params) -> CustomerArchiveResponse -- client.customers.list_billable_metrics(customer_id, \*\*params) -> CustomerListBillableMetricsResponse -- client.customers.list_costs(customer_id, \*\*params) -> CustomerListCostsResponse +- client.customers.list_billable_metrics(customer_id, \*\*params) -> SyncCursorPage[CustomerListBillableMetricsResponse] +- client.customers.list_costs(customer_id, \*\*params) -> SyncCursorPage[CustomerListCostsResponse] - client.customers.set_ingest_aliases(customer_id, \*\*params) -> None - client.customers.set_name(customer_id, \*\*params) -> CustomerSetNameResponse - client.customers.update_config(customer_id, \*\*params) -> None @@ -134,28 +133,23 @@ from metronome.types.customers import ( Methods: -- client.customers.plans.list(customer_id, \*\*params) -> PlanListResponse +- client.customers.plans.list(customer_id, \*\*params) -> SyncCursorPage[PlanListResponse] - client.customers.plans.add(customer_id, \*\*params) -> PlanAddResponse - client.customers.plans.end(customer_plan_id, \*, customer_id, \*\*params) -> PlanEndResponse -- client.customers.plans.list_price_adjustments(customer_plan_id, \*, customer_id, \*\*params) -> PlanListPriceAdjustmentsResponse +- client.customers.plans.list_price_adjustments(customer_plan_id, \*, customer_id, \*\*params) -> SyncCursorPage[PlanListPriceAdjustmentsResponse] ## Invoices Types: ```python -from metronome.types.customers import ( - Invoice, - InvoiceRetrieveResponse, - InvoiceListResponse, - InvoiceAddChargeResponse, -) +from metronome.types.customers import Invoice, InvoiceRetrieveResponse, InvoiceAddChargeResponse ``` Methods: - client.customers.invoices.retrieve(invoice_id, \*, customer_id, \*\*params) -> InvoiceRetrieveResponse -- client.customers.invoices.list(customer_id, \*\*params) -> InvoiceListResponse +- client.customers.invoices.list(customer_id, \*\*params) -> SyncCursorPage[Invoice] - client.customers.invoices.add_charge(customer_id, \*\*params) -> InvoiceAddChargeResponse ## BillingConfig @@ -196,7 +190,7 @@ Methods: - client.usage.list(\*\*params) -> UsageListResponse - client.usage.ingest(\*\*params) -> None -- client.usage.list_with_groups(\*\*params) -> UsageListWithGroupsResponse +- client.usage.list_with_groups(\*\*params) -> SyncCursorPage[UsageListWithGroupsResponse] # AuditLogs @@ -208,7 +202,7 @@ from metronome.types import AuditLogListResponse Methods: -- client.audit_logs.list(\*\*params) -> AuditLogListResponse +- client.audit_logs.list(\*\*params) -> SyncCursorPage[AuditLogListResponse] # CustomFields @@ -243,7 +237,7 @@ Methods: - client.billable_metrics.create(\*\*params) -> BillableMetricCreateResponse - client.billable_metrics.retrieve(billable_metric_id) -> BillableMetricRetrieveResponse -- client.billable_metrics.list(customer_id, \*\*params) -> BillableMetricListResponse +- client.billable_metrics.list(customer_id, \*\*params) -> SyncCursorPage[BillableMetricListResponse] - client.billable_metrics.archive(\*\*params) -> BillableMetricArchiveResponse # Services diff --git a/pyproject.toml b/pyproject.toml index 5e790a6b..46ec5121 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "metronome-sdk" -version = "0.1.0-alpha.1" +version = "0.1.0-alpha.2" description = "The official Python library for the metronome API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/metronome/_version.py b/src/metronome/_version.py index 6d0c2b0f..8eae549a 100644 --- a/src/metronome/_version.py +++ b/src/metronome/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "metronome" -__version__ = "0.1.0-alpha.1" # x-release-please-version +__version__ = "0.1.0-alpha.2" # x-release-please-version diff --git a/src/metronome/pagination.py b/src/metronome/pagination.py new file mode 100644 index 00000000..4fc10818 --- /dev/null +++ b/src/metronome/pagination.py @@ -0,0 +1,54 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Generic, TypeVar, Optional +from typing_extensions import override + +from ._base_client import BasePage, PageInfo, BaseSyncPage, BaseAsyncPage + +__all__ = ["SyncCursorPage", "AsyncCursorPage"] + +_T = TypeVar("_T") + + +class SyncCursorPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + next_page: Optional[str] = None + """Cursor to fetch the next page""" + data: List[_T] + """Items of the page""" + + @override + def _get_page_items(self) -> List[_T]: + data = self.data + if not data: + return [] + return data + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_page = self.next_page + if not next_page: + return None + + return PageInfo(params={"next_page": next_page}) + + +class AsyncCursorPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + next_page: Optional[str] = None + """Cursor to fetch the next page""" + data: List[_T] + """Items of the page""" + + @override + def _get_page_items(self) -> List[_T]: + data = self.data + if not data: + return [] + return data + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_page = self.next_page + if not next_page: + return None + + return PageInfo(params={"next_page": next_page}) diff --git a/src/metronome/resources/audit_logs.py b/src/metronome/resources/audit_logs.py index a340d9f8..95b8c2ee 100644 --- a/src/metronome/resources/audit_logs.py +++ b/src/metronome/resources/audit_logs.py @@ -10,10 +10,7 @@ from ..types import audit_log_list_params from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from .._utils import ( - maybe_transform, - async_maybe_transform, -) +from .._utils import maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -22,7 +19,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ..pagination import SyncCursorPage, AsyncCursorPage from .._base_client import ( + AsyncPaginator, make_request_options, ) from ..types.audit_log_list_response import AuditLogListResponse @@ -55,7 +54,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> AuditLogListResponse: + ) -> SyncCursorPage[AuditLogListResponse]: """Retrieves a range of audit logs. If no further audit logs are currently @@ -89,8 +88,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/auditLogs", + page=SyncCursorPage[AuditLogListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -109,7 +109,7 @@ def list( audit_log_list_params.AuditLogListParams, ), ), - cast_to=AuditLogListResponse, + model=AuditLogListResponse, ) @@ -122,7 +122,7 @@ def with_raw_response(self) -> AsyncAuditLogsResourceWithRawResponse: def with_streaming_response(self) -> AsyncAuditLogsResourceWithStreamingResponse: return AsyncAuditLogsResourceWithStreamingResponse(self) - async def list( + def list( self, *, ending_before: Union[str, datetime] | NotGiven = NOT_GIVEN, @@ -138,7 +138,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> AuditLogListResponse: + ) -> AsyncPaginator[AuditLogListResponse, AsyncCursorPage[AuditLogListResponse]]: """Retrieves a range of audit logs. If no further audit logs are currently @@ -172,14 +172,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/auditLogs", + page=AsyncCursorPage[AuditLogListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "ending_before": ending_before, "limit": limit, @@ -192,7 +193,7 @@ async def list( audit_log_list_params.AuditLogListParams, ), ), - cast_to=AuditLogListResponse, + model=AuditLogListResponse, ) diff --git a/src/metronome/resources/billable_metrics.py b/src/metronome/resources/billable_metrics.py index 02d18f03..9d42d3fc 100644 --- a/src/metronome/resources/billable_metrics.py +++ b/src/metronome/resources/billable_metrics.py @@ -25,7 +25,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ..pagination import SyncCursorPage, AsyncCursorPage from .._base_client import ( + AsyncPaginator, make_request_options, ) from ..types.billable_metric_list_response import BillableMetricListResponse @@ -175,7 +177,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> BillableMetricListResponse: + ) -> SyncCursorPage[BillableMetricListResponse]: """ List all billable metrics. @@ -197,8 +199,9 @@ def list( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return self._get( + return self._get_api_list( f"/customers/{customer_id}/billable-metrics", + page=SyncCursorPage[BillableMetricListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -213,7 +216,7 @@ def list( billable_metric_list_params.BillableMetricListParams, ), ), - cast_to=BillableMetricListResponse, + model=BillableMetricListResponse, ) def archive( @@ -375,7 +378,7 @@ async def retrieve( cast_to=BillableMetricRetrieveResponse, ) - async def list( + def list( self, customer_id: str, *, @@ -388,7 +391,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> BillableMetricListResponse: + ) -> AsyncPaginator[BillableMetricListResponse, AsyncCursorPage[BillableMetricListResponse]]: """ List all billable metrics. @@ -410,14 +413,15 @@ async def list( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return await self._get( + return self._get_api_list( f"/customers/{customer_id}/billable-metrics", + page=AsyncCursorPage[BillableMetricListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -426,7 +430,7 @@ async def list( billable_metric_list_params.BillableMetricListParams, ), ), - cast_to=BillableMetricListResponse, + model=BillableMetricListResponse, ) async def archive( diff --git a/src/metronome/resources/credit_grants.py b/src/metronome/resources/credit_grants.py index 15738c1e..96fa83bd 100644 --- a/src/metronome/resources/credit_grants.py +++ b/src/metronome/resources/credit_grants.py @@ -28,7 +28,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ..pagination import SyncCursorPage, AsyncCursorPage from .._base_client import ( + AsyncPaginator, make_request_options, ) from ..types.credit_grant_edit_response import CreditGrantEditResponse @@ -160,7 +162,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CreditGrantListResponse: + ) -> SyncCursorPage[CreditGrantListResponse]: """List credit grants. This list does not included voided grants. @@ -191,8 +193,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._post( + return self._get_api_list( "/credits/listGrants", + page=SyncCursorPage[CreditGrantListResponse], body=maybe_transform( { "credit_grant_ids": credit_grant_ids, @@ -216,7 +219,8 @@ def list( credit_grant_list_params.CreditGrantListParams, ), ), - cast_to=CreditGrantListResponse, + model=CreditGrantListResponse, + method="post", ) def edit( @@ -277,7 +281,7 @@ def list_credit_types( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CreditGrantListCreditTypesResponse: + ) -> SyncCursorPage[CreditGrantListCreditTypesResponse]: """ List all pricing units (known in the API by the legacy term "credit types"). @@ -294,8 +298,9 @@ def list_credit_types( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/credit-types/list", + page=SyncCursorPage[CreditGrantListCreditTypesResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -309,7 +314,7 @@ def list_credit_types( credit_grant_list_credit_types_params.CreditGrantListCreditTypesParams, ), ), - cast_to=CreditGrantListCreditTypesResponse, + model=CreditGrantListCreditTypesResponse, ) def list_entries( @@ -526,7 +531,7 @@ async def create( cast_to=CreditGrantCreateResponse, ) - async def list( + def list( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -542,7 +547,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CreditGrantListResponse: + ) -> AsyncPaginator[CreditGrantListResponse, AsyncCursorPage[CreditGrantListResponse]]: """List credit grants. This list does not included voided grants. @@ -573,9 +578,10 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._post( + return self._get_api_list( "/credits/listGrants", - body=await async_maybe_transform( + page=AsyncCursorPage[CreditGrantListResponse], + body=maybe_transform( { "credit_grant_ids": credit_grant_ids, "credit_type_ids": credit_type_ids, @@ -590,7 +596,7 @@ async def list( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -598,7 +604,8 @@ async def list( credit_grant_list_params.CreditGrantListParams, ), ), - cast_to=CreditGrantListResponse, + model=CreditGrantListResponse, + method="post", ) async def edit( @@ -648,7 +655,7 @@ async def edit( cast_to=CreditGrantEditResponse, ) - async def list_credit_types( + def list_credit_types( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -659,7 +666,7 @@ async def list_credit_types( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CreditGrantListCreditTypesResponse: + ) -> AsyncPaginator[CreditGrantListCreditTypesResponse, AsyncCursorPage[CreditGrantListCreditTypesResponse]]: """ List all pricing units (known in the API by the legacy term "credit types"). @@ -676,14 +683,15 @@ async def list_credit_types( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/credit-types/list", + page=AsyncCursorPage[CreditGrantListCreditTypesResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -691,7 +699,7 @@ async def list_credit_types( credit_grant_list_credit_types_params.CreditGrantListCreditTypesParams, ), ), - cast_to=CreditGrantListCreditTypesResponse, + model=CreditGrantListCreditTypesResponse, ) async def list_entries( diff --git a/src/metronome/resources/customers/customers.py b/src/metronome/resources/customers/customers.py index a8f41476..e6adc498 100644 --- a/src/metronome/resources/customers/customers.py +++ b/src/metronome/resources/customers/customers.py @@ -54,7 +54,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ...pagination import SyncCursorPage, AsyncCursorPage from ..._base_client import ( + AsyncPaginator, make_request_options, ) from .billing_config import ( @@ -65,7 +67,7 @@ BillingConfigResourceWithStreamingResponse, AsyncBillingConfigResourceWithStreamingResponse, ) -from ...types.customer_list_response import CustomerListResponse +from ...types.customer_detail import CustomerDetail from ...types.customer_create_response import CustomerCreateResponse from ...types.customer_archive_response import CustomerArchiveResponse from ...types.customer_retrieve_response import CustomerRetrieveResponse @@ -199,7 +201,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CustomerListResponse: + ) -> SyncCursorPage[CustomerDetail]: """ List all customers. @@ -225,8 +227,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/customers", + page=SyncCursorPage[CustomerDetail], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -244,7 +247,7 @@ def list( customer_list_params.CustomerListParams, ), ), - cast_to=CustomerListResponse, + model=CustomerDetail, ) def archive( @@ -292,7 +295,7 @@ def list_billable_metrics( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CustomerListBillableMetricsResponse: + ) -> SyncCursorPage[CustomerListBillableMetricsResponse]: """ List all billable metrics. @@ -314,8 +317,9 @@ def list_billable_metrics( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return self._get( + return self._get_api_list( f"/customers/{customer_id}/billable-metrics", + page=SyncCursorPage[CustomerListBillableMetricsResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -330,7 +334,7 @@ def list_billable_metrics( customer_list_billable_metrics_params.CustomerListBillableMetricsParams, ), ), - cast_to=CustomerListBillableMetricsResponse, + model=CustomerListBillableMetricsResponse, ) def list_costs( @@ -347,7 +351,7 @@ def list_costs( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CustomerListCostsResponse: + ) -> SyncCursorPage[CustomerListCostsResponse]: """ Fetch daily pending costs for the specified customer, broken down by credit type and line items. Note: this is not supported for customers whose plan includes a @@ -372,8 +376,9 @@ def list_costs( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return self._get( + return self._get_api_list( f"/customers/{customer_id}/costs", + page=SyncCursorPage[CustomerListCostsResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -389,7 +394,7 @@ def list_costs( customer_list_costs_params.CustomerListCostsParams, ), ), - cast_to=CustomerListCostsResponse, + model=CustomerListCostsResponse, ) def set_ingest_aliases( @@ -627,7 +632,7 @@ async def retrieve( cast_to=CustomerRetrieveResponse, ) - async def list( + def list( self, *, customer_ids: List[str] | NotGiven = NOT_GIVEN, @@ -642,7 +647,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CustomerListResponse: + ) -> AsyncPaginator[CustomerDetail, AsyncCursorPage[CustomerDetail]]: """ List all customers. @@ -668,14 +673,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/customers", + page=AsyncCursorPage[CustomerDetail], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "customer_ids": customer_ids, "ingest_alias": ingest_alias, @@ -687,7 +693,7 @@ async def list( customer_list_params.CustomerListParams, ), ), - cast_to=CustomerListResponse, + model=CustomerDetail, ) async def archive( @@ -722,7 +728,7 @@ async def archive( cast_to=CustomerArchiveResponse, ) - async def list_billable_metrics( + def list_billable_metrics( self, customer_id: str, *, @@ -735,7 +741,7 @@ async def list_billable_metrics( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CustomerListBillableMetricsResponse: + ) -> AsyncPaginator[CustomerListBillableMetricsResponse, AsyncCursorPage[CustomerListBillableMetricsResponse]]: """ List all billable metrics. @@ -757,14 +763,15 @@ async def list_billable_metrics( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return await self._get( + return self._get_api_list( f"/customers/{customer_id}/billable-metrics", + page=AsyncCursorPage[CustomerListBillableMetricsResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -773,10 +780,10 @@ async def list_billable_metrics( customer_list_billable_metrics_params.CustomerListBillableMetricsParams, ), ), - cast_to=CustomerListBillableMetricsResponse, + model=CustomerListBillableMetricsResponse, ) - async def list_costs( + def list_costs( self, customer_id: str, *, @@ -790,7 +797,7 @@ async def list_costs( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> CustomerListCostsResponse: + ) -> AsyncPaginator[CustomerListCostsResponse, AsyncCursorPage[CustomerListCostsResponse]]: """ Fetch daily pending costs for the specified customer, broken down by credit type and line items. Note: this is not supported for customers whose plan includes a @@ -815,14 +822,15 @@ async def list_costs( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return await self._get( + return self._get_api_list( f"/customers/{customer_id}/costs", + page=AsyncCursorPage[CustomerListCostsResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "ending_before": ending_before, "starting_on": starting_on, @@ -832,7 +840,7 @@ async def list_costs( customer_list_costs_params.CustomerListCostsParams, ), ), - cast_to=CustomerListCostsResponse, + model=CustomerListCostsResponse, ) async def set_ingest_aliases( diff --git a/src/metronome/resources/customers/invoices.py b/src/metronome/resources/customers/invoices.py index 8761b66f..81af8412 100644 --- a/src/metronome/resources/customers/invoices.py +++ b/src/metronome/resources/customers/invoices.py @@ -21,11 +21,13 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ...pagination import SyncCursorPage, AsyncCursorPage from ..._base_client import ( + AsyncPaginator, make_request_options, ) from ...types.customers import invoice_list_params, invoice_retrieve_params, invoice_add_charge_params -from ...types.customers.invoice_list_response import InvoiceListResponse +from ...types.customers.invoice import Invoice from ...types.customers.invoice_retrieve_response import InvoiceRetrieveResponse from ...types.customers.invoice_add_charge_response import InvoiceAddChargeResponse @@ -105,7 +107,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> InvoiceListResponse: + ) -> SyncCursorPage[Invoice]: """ List all invoices for a given customer, optionally filtered by status, date range, and/or credit type. @@ -140,8 +142,9 @@ def list( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return self._get( + return self._get_api_list( f"/customers/{customer_id}/invoices", + page=SyncCursorPage[Invoice], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -161,7 +164,7 @@ def list( invoice_list_params.InvoiceListParams, ), ), - cast_to=InvoiceListResponse, + model=Invoice, ) def add_charge( @@ -281,7 +284,7 @@ async def retrieve( cast_to=InvoiceRetrieveResponse, ) - async def list( + def list( self, customer_id: str, *, @@ -299,7 +302,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> InvoiceListResponse: + ) -> AsyncPaginator[Invoice, AsyncCursorPage[Invoice]]: """ List all invoices for a given customer, optionally filtered by status, date range, and/or credit type. @@ -334,14 +337,15 @@ async def list( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return await self._get( + return self._get_api_list( f"/customers/{customer_id}/invoices", + page=AsyncCursorPage[Invoice], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "credit_type_id": credit_type_id, "ending_before": ending_before, @@ -355,7 +359,7 @@ async def list( invoice_list_params.InvoiceListParams, ), ), - cast_to=InvoiceListResponse, + model=Invoice, ) async def add_charge( diff --git a/src/metronome/resources/customers/plans.py b/src/metronome/resources/customers/plans.py index 820e3aee..aceb98d6 100644 --- a/src/metronome/resources/customers/plans.py +++ b/src/metronome/resources/customers/plans.py @@ -20,7 +20,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ...pagination import SyncCursorPage, AsyncCursorPage from ..._base_client import ( + AsyncPaginator, make_request_options, ) from ...types.customers import plan_add_params, plan_end_params, plan_list_params, plan_list_price_adjustments_params @@ -53,7 +55,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListResponse: + ) -> SyncCursorPage[PlanListResponse]: """ List the given customer's plans in reverse-chronological order. @@ -72,8 +74,9 @@ def list( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return self._get( + return self._get_api_list( f"/customers/{customer_id}/plans", + page=SyncCursorPage[PlanListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -87,7 +90,7 @@ def list( plan_list_params.PlanListParams, ), ), - cast_to=PlanListResponse, + model=PlanListResponse, ) def add( @@ -236,7 +239,7 @@ def list_price_adjustments( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListPriceAdjustmentsResponse: + ) -> SyncCursorPage[PlanListPriceAdjustmentsResponse]: """Lists a customer plans adjustments. See the @@ -260,8 +263,9 @@ def list_price_adjustments( raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") if not customer_plan_id: raise ValueError(f"Expected a non-empty value for `customer_plan_id` but received {customer_plan_id!r}") - return self._get( + return self._get_api_list( f"/customers/{customer_id}/plans/{customer_plan_id}/priceAdjustments", + page=SyncCursorPage[PlanListPriceAdjustmentsResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -275,7 +279,7 @@ def list_price_adjustments( plan_list_price_adjustments_params.PlanListPriceAdjustmentsParams, ), ), - cast_to=PlanListPriceAdjustmentsResponse, + model=PlanListPriceAdjustmentsResponse, ) @@ -288,7 +292,7 @@ def with_raw_response(self) -> AsyncPlansResourceWithRawResponse: def with_streaming_response(self) -> AsyncPlansResourceWithStreamingResponse: return AsyncPlansResourceWithStreamingResponse(self) - async def list( + def list( self, customer_id: str, *, @@ -300,7 +304,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListResponse: + ) -> AsyncPaginator[PlanListResponse, AsyncCursorPage[PlanListResponse]]: """ List the given customer's plans in reverse-chronological order. @@ -319,14 +323,15 @@ async def list( """ if not customer_id: raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") - return await self._get( + return self._get_api_list( f"/customers/{customer_id}/plans", + page=AsyncCursorPage[PlanListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -334,7 +339,7 @@ async def list( plan_list_params.PlanListParams, ), ), - cast_to=PlanListResponse, + model=PlanListResponse, ) async def add( @@ -470,7 +475,7 @@ async def end( cast_to=PlanEndResponse, ) - async def list_price_adjustments( + def list_price_adjustments( self, customer_plan_id: str, *, @@ -483,7 +488,7 @@ async def list_price_adjustments( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListPriceAdjustmentsResponse: + ) -> AsyncPaginator[PlanListPriceAdjustmentsResponse, AsyncCursorPage[PlanListPriceAdjustmentsResponse]]: """Lists a customer plans adjustments. See the @@ -507,14 +512,15 @@ async def list_price_adjustments( raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}") if not customer_plan_id: raise ValueError(f"Expected a non-empty value for `customer_plan_id` but received {customer_plan_id!r}") - return await self._get( + return self._get_api_list( f"/customers/{customer_id}/plans/{customer_plan_id}/priceAdjustments", + page=AsyncCursorPage[PlanListPriceAdjustmentsResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -522,7 +528,7 @@ async def list_price_adjustments( plan_list_price_adjustments_params.PlanListPriceAdjustmentsParams, ), ), - cast_to=PlanListPriceAdjustmentsResponse, + model=PlanListPriceAdjustmentsResponse, ) diff --git a/src/metronome/resources/plans.py b/src/metronome/resources/plans.py index d151f2fd..b1f00bfd 100644 --- a/src/metronome/resources/plans.py +++ b/src/metronome/resources/plans.py @@ -8,10 +8,7 @@ from ..types import plan_list_params, plan_list_charges_params, plan_list_customers_params from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from .._utils import ( - maybe_transform, - async_maybe_transform, -) +from .._utils import maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -20,7 +17,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ..pagination import SyncCursorPage, AsyncCursorPage from .._base_client import ( + AsyncPaginator, make_request_options, ) from ..types.plan_list_response import PlanListResponse @@ -51,7 +50,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListResponse: + ) -> SyncCursorPage[PlanListResponse]: """ List all available plans. @@ -68,8 +67,9 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get( + return self._get_api_list( "/plans", + page=SyncCursorPage[PlanListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -83,7 +83,7 @@ def list( plan_list_params.PlanListParams, ), ), - cast_to=PlanListResponse, + model=PlanListResponse, ) def get_details( @@ -131,7 +131,7 @@ def list_charges( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListChargesResponse: + ) -> SyncCursorPage[PlanListChargesResponse]: """ Fetches a list of charges of a specific plan. @@ -150,8 +150,9 @@ def list_charges( """ if not plan_id: raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}") - return self._get( + return self._get_api_list( f"/planDetails/{plan_id}/charges", + page=SyncCursorPage[PlanListChargesResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -165,7 +166,7 @@ def list_charges( plan_list_charges_params.PlanListChargesParams, ), ), - cast_to=PlanListChargesResponse, + model=PlanListChargesResponse, ) def list_customers( @@ -181,7 +182,7 @@ def list_customers( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListCustomersResponse: + ) -> SyncCursorPage[PlanListCustomersResponse]: """ Fetches a list of customers on a specific plan (by default, only currently active plans are included) @@ -211,8 +212,9 @@ def list_customers( """ if not plan_id: raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}") - return self._get( + return self._get_api_list( f"/planDetails/{plan_id}/customers", + page=SyncCursorPage[PlanListCustomersResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -227,7 +229,7 @@ def list_customers( plan_list_customers_params.PlanListCustomersParams, ), ), - cast_to=PlanListCustomersResponse, + model=PlanListCustomersResponse, ) @@ -240,7 +242,7 @@ def with_raw_response(self) -> AsyncPlansResourceWithRawResponse: def with_streaming_response(self) -> AsyncPlansResourceWithStreamingResponse: return AsyncPlansResourceWithStreamingResponse(self) - async def list( + def list( self, *, limit: int | NotGiven = NOT_GIVEN, @@ -251,7 +253,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListResponse: + ) -> AsyncPaginator[PlanListResponse, AsyncCursorPage[PlanListResponse]]: """ List all available plans. @@ -268,14 +270,15 @@ async def list( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._get( + return self._get_api_list( "/plans", + page=AsyncCursorPage[PlanListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -283,7 +286,7 @@ async def list( plan_list_params.PlanListParams, ), ), - cast_to=PlanListResponse, + model=PlanListResponse, ) async def get_details( @@ -319,7 +322,7 @@ async def get_details( cast_to=PlanGetDetailsResponse, ) - async def list_charges( + def list_charges( self, plan_id: str, *, @@ -331,7 +334,7 @@ async def list_charges( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListChargesResponse: + ) -> AsyncPaginator[PlanListChargesResponse, AsyncCursorPage[PlanListChargesResponse]]: """ Fetches a list of charges of a specific plan. @@ -350,14 +353,15 @@ async def list_charges( """ if not plan_id: raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}") - return await self._get( + return self._get_api_list( f"/planDetails/{plan_id}/charges", + page=AsyncCursorPage[PlanListChargesResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -365,10 +369,10 @@ async def list_charges( plan_list_charges_params.PlanListChargesParams, ), ), - cast_to=PlanListChargesResponse, + model=PlanListChargesResponse, ) - async def list_customers( + def list_customers( self, plan_id: str, *, @@ -381,7 +385,7 @@ async def list_customers( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> PlanListCustomersResponse: + ) -> AsyncPaginator[PlanListCustomersResponse, AsyncCursorPage[PlanListCustomersResponse]]: """ Fetches a list of customers on a specific plan (by default, only currently active plans are included) @@ -411,14 +415,15 @@ async def list_customers( """ if not plan_id: raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}") - return await self._get( + return self._get_api_list( f"/planDetails/{plan_id}/customers", + page=AsyncCursorPage[PlanListCustomersResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -427,7 +432,7 @@ async def list_customers( plan_list_customers_params.PlanListCustomersParams, ), ), - cast_to=PlanListCustomersResponse, + model=PlanListCustomersResponse, ) diff --git a/src/metronome/resources/usage.py b/src/metronome/resources/usage.py index 43b1df67..fef37e88 100644 --- a/src/metronome/resources/usage.py +++ b/src/metronome/resources/usage.py @@ -22,7 +22,9 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ..pagination import SyncCursorPage, AsyncCursorPage from .._base_client import ( + AsyncPaginator, make_request_options, ) from ..types.usage_list_response import UsageListResponse @@ -159,7 +161,7 @@ def list_with_groups( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> UsageListWithGroupsResponse: + ) -> SyncCursorPage[UsageListWithGroupsResponse]: """ Fetch aggregated usage data for the specified customer, billable-metric, and optional group, broken into intervals of the specified length. @@ -185,8 +187,9 @@ def list_with_groups( timeout: Override the client-level default timeout for this request, in seconds """ - return self._post( + return self._get_api_list( "/usage/groups", + page=SyncCursorPage[UsageListWithGroupsResponse], body=maybe_transform( { "billable_metric_id": billable_metric_id, @@ -212,7 +215,8 @@ def list_with_groups( usage_list_with_groups_params.UsageListWithGroupsParams, ), ), - cast_to=UsageListWithGroupsResponse, + model=UsageListWithGroupsResponse, + method="post", ) @@ -326,7 +330,7 @@ async def ingest( cast_to=NoneType, ) - async def list_with_groups( + def list_with_groups( self, *, billable_metric_id: str, @@ -344,7 +348,7 @@ async def list_with_groups( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> UsageListWithGroupsResponse: + ) -> AsyncPaginator[UsageListWithGroupsResponse, AsyncCursorPage[UsageListWithGroupsResponse]]: """ Fetch aggregated usage data for the specified customer, billable-metric, and optional group, broken into intervals of the specified length. @@ -370,9 +374,10 @@ async def list_with_groups( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._post( + return self._get_api_list( "/usage/groups", - body=await async_maybe_transform( + page=AsyncCursorPage[UsageListWithGroupsResponse], + body=maybe_transform( { "billable_metric_id": billable_metric_id, "customer_id": customer_id, @@ -389,7 +394,7 @@ async def list_with_groups( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "limit": limit, "next_page": next_page, @@ -397,7 +402,8 @@ async def list_with_groups( usage_list_with_groups_params.UsageListWithGroupsParams, ), ), - cast_to=UsageListWithGroupsResponse, + model=UsageListWithGroupsResponse, + method="post", ) diff --git a/src/metronome/types/__init__.py b/src/metronome/types/__init__.py index d29d10d2..696381db 100644 --- a/src/metronome/types/__init__.py +++ b/src/metronome/types/__init__.py @@ -30,7 +30,6 @@ from .service_list_response import ServiceListResponse as ServiceListResponse from .alert_archive_response import AlertArchiveResponse as AlertArchiveResponse from .customer_create_params import CustomerCreateParams as CustomerCreateParams -from .customer_list_response import CustomerListResponse as CustomerListResponse from .audit_log_list_response import AuditLogListResponse as AuditLogListResponse from .customer_archive_params import CustomerArchiveParams as CustomerArchiveParams from .credit_grant_edit_params import CreditGrantEditParams as CreditGrantEditParams diff --git a/src/metronome/types/audit_log_list_response.py b/src/metronome/types/audit_log_list_response.py index 59cc885e..45bfbb2e 100644 --- a/src/metronome/types/audit_log_list_response.py +++ b/src/metronome/types/audit_log_list_response.py @@ -1,15 +1,15 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from datetime import datetime from typing_extensions import Literal from .._models import BaseModel -__all__ = ["AuditLogListResponse", "Data", "DataActor"] +__all__ = ["AuditLogListResponse", "Actor"] -class DataActor(BaseModel): +class Actor(BaseModel): id: str name: str @@ -17,14 +17,14 @@ class DataActor(BaseModel): email: Optional[str] = None -class Data(BaseModel): +class AuditLogListResponse(BaseModel): id: str timestamp: datetime action: Optional[str] = None - actor: Optional[DataActor] = None + actor: Optional[Actor] = None description: Optional[str] = None @@ -33,18 +33,3 @@ class Data(BaseModel): resource_type: Optional[str] = None status: Optional[Literal["success", "failure", "pending"]] = None - - -class AuditLogListResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None - """The next_page parameter is always returned to support ongoing log retrieval. - - It enables continuous querying, even when some requests return no new data. Save - the next_page token from each response and use it for future requests to ensure - no logs are missed. This setup is ideal for regular updates via automated - processes, like cron jobs, to fetch logs continuously as they become available. - When you receive an empty data array, it indicates a temporary absence of new - logs, but subsequent requests might return new data. - """ diff --git a/src/metronome/types/billable_metric_list_response.py b/src/metronome/types/billable_metric_list_response.py index b46f2851..375740be 100644 --- a/src/metronome/types/billable_metric_list_response.py +++ b/src/metronome/types/billable_metric_list_response.py @@ -4,18 +4,12 @@ from .._models import BaseModel -__all__ = ["BillableMetricListResponse", "Data"] +__all__ = ["BillableMetricListResponse"] -class Data(BaseModel): +class BillableMetricListResponse(BaseModel): id: str name: str group_by: Optional[List[str]] = None - - -class BillableMetricListResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/credit_grant_list_credit_types_response.py b/src/metronome/types/credit_grant_list_credit_types_response.py index fa5dbf2e..8b8b3e5f 100644 --- a/src/metronome/types/credit_grant_list_credit_types_response.py +++ b/src/metronome/types/credit_grant_list_credit_types_response.py @@ -1,21 +1,15 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from .._models import BaseModel -__all__ = ["CreditGrantListCreditTypesResponse", "Data"] +__all__ = ["CreditGrantListCreditTypesResponse"] -class Data(BaseModel): +class CreditGrantListCreditTypesResponse(BaseModel): id: Optional[str] = None is_currency: Optional[bool] = None name: Optional[str] = None - - -class CreditGrantListCreditTypesResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/credit_grant_list_response.py b/src/metronome/types/credit_grant_list_response.py index c35b237a..497a88bb 100644 --- a/src/metronome/types/credit_grant_list_response.py +++ b/src/metronome/types/credit_grant_list_response.py @@ -7,10 +7,10 @@ from .shared.credit_type import CreditType from .credit_ledger_entry import CreditLedgerEntry -__all__ = ["CreditGrantListResponse", "Data", "DataBalance", "DataGrantAmount", "DataPaidAmount", "DataProduct"] +__all__ = ["CreditGrantListResponse", "Balance", "GrantAmount", "PaidAmount", "Product"] -class DataBalance(BaseModel): +class Balance(BaseModel): effective_at: datetime """The end_date of the customer's current billing period.""" @@ -28,31 +28,31 @@ class DataBalance(BaseModel): """ -class DataGrantAmount(BaseModel): +class GrantAmount(BaseModel): amount: float credit_type: CreditType """the credit type for the amount granted""" -class DataPaidAmount(BaseModel): +class PaidAmount(BaseModel): amount: float credit_type: CreditType """the credit type for the amount paid""" -class DataProduct(BaseModel): +class Product(BaseModel): id: str name: str -class Data(BaseModel): +class CreditGrantListResponse(BaseModel): id: str """the Metronome ID of the credit grant""" - balance: DataBalance + balance: Balance """ The effective balance of the grant as of the end of the customer's current billing period. Expiration deductions will be included only if the grant expires @@ -70,12 +70,12 @@ class Data(BaseModel): expires_at: datetime - grant_amount: DataGrantAmount + grant_amount: GrantAmount """the amount of credits initially granted""" name: str - paid_amount: DataPaidAmount + paid_amount: PaidAmount """the amount paid for this credit grant""" pending_deductions: List[CreditLedgerEntry] @@ -90,7 +90,7 @@ class Data(BaseModel): if applicable """ - products: Optional[List[DataProduct]] = None + products: Optional[List[Product]] = None """The products which these credits will be applied to. (If unspecified, the credits will be applied to charges for all products.) @@ -104,9 +104,3 @@ class Data(BaseModel): If a request to create a record is made with a previously used uniqueness key, a new record will not be created and the request will fail with a 409 error. """ - - -class CreditGrantListResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/customer_list_billable_metrics_response.py b/src/metronome/types/customer_list_billable_metrics_response.py index 1c98f0e5..6c5c46fe 100644 --- a/src/metronome/types/customer_list_billable_metrics_response.py +++ b/src/metronome/types/customer_list_billable_metrics_response.py @@ -4,18 +4,12 @@ from .._models import BaseModel -__all__ = ["CustomerListBillableMetricsResponse", "Data"] +__all__ = ["CustomerListBillableMetricsResponse"] -class Data(BaseModel): +class CustomerListBillableMetricsResponse(BaseModel): id: str name: str group_by: Optional[List[str]] = None - - -class CustomerListBillableMetricsResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/customer_list_costs_response.py b/src/metronome/types/customer_list_costs_response.py index c8925ec1..1347e660 100644 --- a/src/metronome/types/customer_list_costs_response.py +++ b/src/metronome/types/customer_list_costs_response.py @@ -5,10 +5,10 @@ from .._models import BaseModel -__all__ = ["CustomerListCostsResponse", "Data", "DataCreditTypes", "DataCreditTypesLineItemBreakdown"] +__all__ = ["CustomerListCostsResponse", "CreditTypes", "CreditTypesLineItemBreakdown"] -class DataCreditTypesLineItemBreakdown(BaseModel): +class CreditTypesLineItemBreakdown(BaseModel): cost: float name: str @@ -18,23 +18,17 @@ class DataCreditTypesLineItemBreakdown(BaseModel): group_value: Optional[str] = None -class DataCreditTypes(BaseModel): +class CreditTypes(BaseModel): cost: Optional[float] = None - line_item_breakdown: Optional[List[DataCreditTypesLineItemBreakdown]] = None + line_item_breakdown: Optional[List[CreditTypesLineItemBreakdown]] = None name: Optional[str] = None -class Data(BaseModel): - credit_types: Dict[str, DataCreditTypes] +class CustomerListCostsResponse(BaseModel): + credit_types: Dict[str, CreditTypes] end_timestamp: datetime start_timestamp: datetime - - -class CustomerListCostsResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/customer_list_response.py b/src/metronome/types/customer_list_response.py deleted file mode 100644 index 071b162f..00000000 --- a/src/metronome/types/customer_list_response.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional - -from .._models import BaseModel -from .customer_detail import CustomerDetail - -__all__ = ["CustomerListResponse"] - - -class CustomerListResponse(BaseModel): - data: List[CustomerDetail] - - next_page: Optional[str] = None diff --git a/src/metronome/types/customers/__init__.py b/src/metronome/types/customers/__init__.py index a0520f3d..7baad8c8 100644 --- a/src/metronome/types/customers/__init__.py +++ b/src/metronome/types/customers/__init__.py @@ -15,7 +15,6 @@ from .alert_list_response import AlertListResponse as AlertListResponse from .invoice_list_params import InvoiceListParams as InvoiceListParams from .alert_retrieve_params import AlertRetrieveParams as AlertRetrieveParams -from .invoice_list_response import InvoiceListResponse as InvoiceListResponse from .alert_retrieve_response import AlertRetrieveResponse as AlertRetrieveResponse from .invoice_retrieve_params import InvoiceRetrieveParams as InvoiceRetrieveParams from .invoice_add_charge_params import InvoiceAddChargeParams as InvoiceAddChargeParams diff --git a/src/metronome/types/customers/invoice_list_response.py b/src/metronome/types/customers/invoice_list_response.py deleted file mode 100644 index 0dd78f3e..00000000 --- a/src/metronome/types/customers/invoice_list_response.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional - -from .invoice import Invoice -from ..._models import BaseModel - -__all__ = ["InvoiceListResponse"] - - -class InvoiceListResponse(BaseModel): - data: List[Invoice] - - next_page: Optional[str] = None diff --git a/src/metronome/types/customers/plan_list_price_adjustments_response.py b/src/metronome/types/customers/plan_list_price_adjustments_response.py index d01b8baa..3fe52623 100644 --- a/src/metronome/types/customers/plan_list_price_adjustments_response.py +++ b/src/metronome/types/customers/plan_list_price_adjustments_response.py @@ -5,10 +5,10 @@ from ..._models import BaseModel -__all__ = ["PlanListPriceAdjustmentsResponse", "Data", "DataPrice"] +__all__ = ["PlanListPriceAdjustmentsResponse", "Price"] -class DataPrice(BaseModel): +class Price(BaseModel): adjustment_type: Literal["fixed", "quantity", "percentage", "override"] """Determines how the value will be applied.""" @@ -18,19 +18,13 @@ class DataPrice(BaseModel): value: Optional[float] = None -class Data(BaseModel): +class PlanListPriceAdjustmentsResponse(BaseModel): charge_id: str charge_type: Literal["usage", "fixed", "composite", "minimum", "seat"] - prices: List[DataPrice] + prices: List[Price] start_period: float quantity: Optional[float] = None - - -class PlanListPriceAdjustmentsResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/customers/plan_list_response.py b/src/metronome/types/customers/plan_list_response.py index 9f42ff00..8ff2c3ff 100644 --- a/src/metronome/types/customers/plan_list_response.py +++ b/src/metronome/types/customers/plan_list_response.py @@ -6,10 +6,10 @@ from ..._models import BaseModel from ..shared.credit_type import CreditType -__all__ = ["PlanListResponse", "Data", "DataTrialInfo", "DataTrialInfoSpendingCap"] +__all__ = ["PlanListResponse", "TrialInfo", "TrialInfoSpendingCap"] -class DataTrialInfoSpendingCap(BaseModel): +class TrialInfoSpendingCap(BaseModel): amount: float amount_remaining: float @@ -17,13 +17,13 @@ class DataTrialInfoSpendingCap(BaseModel): credit_type: CreditType -class DataTrialInfo(BaseModel): +class TrialInfo(BaseModel): ending_before: datetime - spending_caps: List[DataTrialInfoSpendingCap] + spending_caps: List[TrialInfoSpendingCap] -class Data(BaseModel): +class PlanListResponse(BaseModel): id: str """the ID of the customer plan""" @@ -42,10 +42,4 @@ class Data(BaseModel): net_payment_terms_days: Optional[float] = None - trial_info: Optional[DataTrialInfo] = None - - -class PlanListResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None + trial_info: Optional[TrialInfo] = None diff --git a/src/metronome/types/plan_list_charges_response.py b/src/metronome/types/plan_list_charges_response.py index 3f3d9826..7d07ec38 100644 --- a/src/metronome/types/plan_list_charges_response.py +++ b/src/metronome/types/plan_list_charges_response.py @@ -6,10 +6,10 @@ from .._models import BaseModel from .shared.credit_type import CreditType -__all__ = ["PlanListChargesResponse", "Data", "DataPrice", "DataUnitConversion"] +__all__ = ["PlanListChargesResponse", "Price", "UnitConversion"] -class DataPrice(BaseModel): +class Price(BaseModel): tier: float """Used in pricing tiers. Indicates at what metric value the price applies.""" @@ -22,7 +22,7 @@ class DataPrice(BaseModel): quantity: Optional[float] = None -class DataUnitConversion(BaseModel): +class UnitConversion(BaseModel): division_factor: float """The conversion factor""" @@ -33,7 +33,7 @@ class DataUnitConversion(BaseModel): """ -class Data(BaseModel): +class PlanListChargesResponse(BaseModel): id: str charge_type: Literal["usage", "fixed", "composite", "minimum", "seat"] @@ -44,7 +44,7 @@ class Data(BaseModel): name: str - prices: List[DataPrice] + prices: List[Price] product_id: str @@ -58,11 +58,5 @@ class Data(BaseModel): Indicates how many billing periods pass before the charge applies. """ - unit_conversion: Optional[DataUnitConversion] = None + unit_conversion: Optional[UnitConversion] = None """Specifies how quantities for usage based charges will be converted.""" - - -class PlanListChargesResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/plan_list_customers_response.py b/src/metronome/types/plan_list_customers_response.py index 9ab968ec..28103933 100644 --- a/src/metronome/types/plan_list_customers_response.py +++ b/src/metronome/types/plan_list_customers_response.py @@ -1,15 +1,15 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import Dict, Optional from datetime import datetime from .._models import BaseModel from .customer_detail import CustomerDetail -__all__ = ["PlanListCustomersResponse", "Data", "DataPlanDetails"] +__all__ = ["PlanListCustomersResponse", "PlanDetails"] -class DataPlanDetails(BaseModel): +class PlanDetails(BaseModel): id: str custom_fields: Dict[str, str] @@ -25,13 +25,7 @@ class DataPlanDetails(BaseModel): """The end date of the plan""" -class Data(BaseModel): - customer_details: CustomerDetail - - plan_details: DataPlanDetails - - class PlanListCustomersResponse(BaseModel): - data: List[Data] + customer_details: CustomerDetail - next_page: Optional[str] = None + plan_details: PlanDetails diff --git a/src/metronome/types/plan_list_response.py b/src/metronome/types/plan_list_response.py index 824e03a3..e199fa72 100644 --- a/src/metronome/types/plan_list_response.py +++ b/src/metronome/types/plan_list_response.py @@ -1,13 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import Dict, Optional from .._models import BaseModel -__all__ = ["PlanListResponse", "Data"] +__all__ = ["PlanListResponse"] -class Data(BaseModel): +class PlanListResponse(BaseModel): id: str description: str @@ -15,9 +15,3 @@ class Data(BaseModel): name: str custom_fields: Optional[Dict[str, str]] = None - - -class PlanListResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/src/metronome/types/usage_list_with_groups_response.py b/src/metronome/types/usage_list_with_groups_response.py index 9325134e..eb21e8dd 100644 --- a/src/metronome/types/usage_list_with_groups_response.py +++ b/src/metronome/types/usage_list_with_groups_response.py @@ -1,14 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from datetime import datetime from .._models import BaseModel -__all__ = ["UsageListWithGroupsResponse", "Data"] +__all__ = ["UsageListWithGroupsResponse"] -class Data(BaseModel): +class UsageListWithGroupsResponse(BaseModel): ending_before: datetime group_key: Optional[str] = None @@ -18,9 +18,3 @@ class Data(BaseModel): starting_on: datetime value: Optional[float] = None - - -class UsageListWithGroupsResponse(BaseModel): - data: List[Data] - - next_page: Optional[str] = None diff --git a/tests/api_resources/customers/test_invoices.py b/tests/api_resources/customers/test_invoices.py index 0d60188d..e76de026 100644 --- a/tests/api_resources/customers/test_invoices.py +++ b/tests/api_resources/customers/test_invoices.py @@ -10,8 +10,9 @@ from metronome import Metronome, AsyncMetronome from tests.utils import assert_matches_type from metronome._utils import parse_datetime +from metronome.pagination import SyncCursorPage, AsyncCursorPage from metronome.types.customers import ( - InvoiceListResponse, + Invoice, InvoiceRetrieveResponse, InvoiceAddChargeResponse, ) @@ -84,7 +85,7 @@ def test_method_list(self, client: Metronome) -> None: invoice = client.customers.invoices.list( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(SyncCursorPage[Invoice], invoice, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -99,7 +100,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: starting_on=parse_datetime("2019-12-27T18:11:19.117Z"), status="string", ) - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(SyncCursorPage[Invoice], invoice, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -110,7 +111,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" invoice = response.parse() - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(SyncCursorPage[Invoice], invoice, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -121,7 +122,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" invoice = response.parse() - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(SyncCursorPage[Invoice], invoice, path=["response"]) assert cast(Any, response.is_closed) is True @@ -260,7 +261,7 @@ async def test_method_list(self, async_client: AsyncMetronome) -> None: invoice = await async_client.customers.invoices.list( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(AsyncCursorPage[Invoice], invoice, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -275,7 +276,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - starting_on=parse_datetime("2019-12-27T18:11:19.117Z"), status="string", ) - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(AsyncCursorPage[Invoice], invoice, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -286,7 +287,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" invoice = await response.parse() - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(AsyncCursorPage[Invoice], invoice, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -297,7 +298,7 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" invoice = await response.parse() - assert_matches_type(InvoiceListResponse, invoice, path=["response"]) + assert_matches_type(AsyncCursorPage[Invoice], invoice, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/customers/test_plans.py b/tests/api_resources/customers/test_plans.py index a0c4054c..027466db 100644 --- a/tests/api_resources/customers/test_plans.py +++ b/tests/api_resources/customers/test_plans.py @@ -10,6 +10,7 @@ from metronome import Metronome, AsyncMetronome from tests.utils import assert_matches_type from metronome._utils import parse_datetime +from metronome.pagination import SyncCursorPage, AsyncCursorPage from metronome.types.customers import ( PlanAddResponse, PlanEndResponse, @@ -28,7 +29,7 @@ def test_method_list(self, client: Metronome) -> None: plan = client.customers.plans.list( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -37,7 +38,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: limit=1, next_page="string", ) - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -48,7 +49,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -59,7 +60,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -242,7 +243,7 @@ def test_method_list_price_adjustments(self, client: Metronome) -> None: "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", customer_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", ) - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) @parametrize def test_method_list_price_adjustments_with_all_params(self, client: Metronome) -> None: @@ -252,7 +253,7 @@ def test_method_list_price_adjustments_with_all_params(self, client: Metronome) limit=1, next_page="string", ) - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) @parametrize def test_raw_response_list_price_adjustments(self, client: Metronome) -> None: @@ -264,7 +265,7 @@ def test_raw_response_list_price_adjustments(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) @parametrize def test_streaming_response_list_price_adjustments(self, client: Metronome) -> None: @@ -276,7 +277,7 @@ def test_streaming_response_list_price_adjustments(self, client: Metronome) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -303,7 +304,7 @@ async def test_method_list(self, async_client: AsyncMetronome) -> None: plan = await async_client.customers.plans.list( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -312,7 +313,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - limit=1, next_page="string", ) - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -323,7 +324,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -334,7 +335,7 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -517,7 +518,7 @@ async def test_method_list_price_adjustments(self, async_client: AsyncMetronome) "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", customer_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", ) - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) @parametrize async def test_method_list_price_adjustments_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -527,7 +528,7 @@ async def test_method_list_price_adjustments_with_all_params(self, async_client: limit=1, next_page="string", ) - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) @parametrize async def test_raw_response_list_price_adjustments(self, async_client: AsyncMetronome) -> None: @@ -539,7 +540,7 @@ async def test_raw_response_list_price_adjustments(self, async_client: AsyncMetr assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) @parametrize async def test_streaming_response_list_price_adjustments(self, async_client: AsyncMetronome) -> None: @@ -551,7 +552,7 @@ async def test_streaming_response_list_price_adjustments(self, async_client: Asy assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListPriceAdjustmentsResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListPriceAdjustmentsResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_audit_logs.py b/tests/api_resources/test_audit_logs.py index 436fb684..338365b1 100644 --- a/tests/api_resources/test_audit_logs.py +++ b/tests/api_resources/test_audit_logs.py @@ -11,6 +11,7 @@ from tests.utils import assert_matches_type from metronome.types import AuditLogListResponse from metronome._utils import parse_datetime +from metronome.pagination import SyncCursorPage, AsyncCursorPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -21,7 +22,7 @@ class TestAuditLogs: @parametrize def test_method_list(self, client: Metronome) -> None: audit_log = client.audit_logs.list() - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(SyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -34,7 +35,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: sort="date_asc", starting_on=parse_datetime("2019-12-27T18:11:19.117Z"), ) - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(SyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -43,7 +44,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" audit_log = response.parse() - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(SyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -52,7 +53,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" audit_log = response.parse() - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(SyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) assert cast(Any, response.is_closed) is True @@ -63,7 +64,7 @@ class TestAsyncAuditLogs: @parametrize async def test_method_list(self, async_client: AsyncMetronome) -> None: audit_log = await async_client.audit_logs.list() - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(AsyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -76,7 +77,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - sort="date_asc", starting_on=parse_datetime("2019-12-27T18:11:19.117Z"), ) - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(AsyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -85,7 +86,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" audit_log = await response.parse() - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(AsyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -94,6 +95,6 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" audit_log = await response.parse() - assert_matches_type(AuditLogListResponse, audit_log, path=["response"]) + assert_matches_type(AsyncCursorPage[AuditLogListResponse], audit_log, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_billable_metrics.py b/tests/api_resources/test_billable_metrics.py index a292d03f..61ce4775 100644 --- a/tests/api_resources/test_billable_metrics.py +++ b/tests/api_resources/test_billable_metrics.py @@ -15,6 +15,7 @@ BillableMetricArchiveResponse, BillableMetricRetrieveResponse, ) +from metronome.pagination import SyncCursorPage, AsyncCursorPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -134,7 +135,7 @@ def test_method_list(self, client: Metronome) -> None: billable_metric = client.billable_metrics.list( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(SyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -144,7 +145,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: next_page="string", on_current_plan=True, ) - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(SyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -155,7 +156,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" billable_metric = response.parse() - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(SyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -166,7 +167,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" billable_metric = response.parse() - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(SyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) assert cast(Any, response.is_closed) is True @@ -324,7 +325,7 @@ async def test_method_list(self, async_client: AsyncMetronome) -> None: billable_metric = await async_client.billable_metrics.list( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(AsyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -334,7 +335,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - next_page="string", on_current_plan=True, ) - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(AsyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -345,7 +346,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" billable_metric = await response.parse() - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(AsyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -356,7 +357,7 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" billable_metric = await response.parse() - assert_matches_type(BillableMetricListResponse, billable_metric, path=["response"]) + assert_matches_type(AsyncCursorPage[BillableMetricListResponse], billable_metric, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_credit_grants.py b/tests/api_resources/test_credit_grants.py index 60be742b..22698eb1 100644 --- a/tests/api_resources/test_credit_grants.py +++ b/tests/api_resources/test_credit_grants.py @@ -18,6 +18,7 @@ CreditGrantListCreditTypesResponse, ) from metronome._utils import parse_datetime +from metronome.pagination import SyncCursorPage, AsyncCursorPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -129,7 +130,7 @@ def test_streaming_response_create(self, client: Metronome) -> None: @parametrize def test_method_list(self, client: Metronome) -> None: credit_grant = client.credit_grants.list() - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -146,7 +147,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: effective_before=parse_datetime("2022-02-01T00:00:00Z"), not_expiring_before=parse_datetime("2022-02-01T00:00:00Z"), ) - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -155,7 +156,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = response.parse() - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -164,7 +165,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = response.parse() - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) assert cast(Any, response.is_closed) is True @@ -211,7 +212,7 @@ def test_streaming_response_edit(self, client: Metronome) -> None: @parametrize def test_method_list_credit_types(self, client: Metronome) -> None: credit_grant = client.credit_grants.list_credit_types() - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) @parametrize def test_method_list_credit_types_with_all_params(self, client: Metronome) -> None: @@ -219,7 +220,7 @@ def test_method_list_credit_types_with_all_params(self, client: Metronome) -> No limit=1, next_page="string", ) - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) @parametrize def test_raw_response_list_credit_types(self, client: Metronome) -> None: @@ -228,7 +229,7 @@ def test_raw_response_list_credit_types(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = response.parse() - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) @parametrize def test_streaming_response_list_credit_types(self, client: Metronome) -> None: @@ -237,7 +238,7 @@ def test_streaming_response_list_credit_types(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = response.parse() - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(SyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) assert cast(Any, response.is_closed) is True @@ -424,7 +425,7 @@ async def test_streaming_response_create(self, async_client: AsyncMetronome) -> @parametrize async def test_method_list(self, async_client: AsyncMetronome) -> None: credit_grant = await async_client.credit_grants.list() - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -441,7 +442,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - effective_before=parse_datetime("2022-02-01T00:00:00Z"), not_expiring_before=parse_datetime("2022-02-01T00:00:00Z"), ) - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -450,7 +451,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = await response.parse() - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -459,7 +460,7 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = await response.parse() - assert_matches_type(CreditGrantListResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListResponse], credit_grant, path=["response"]) assert cast(Any, response.is_closed) is True @@ -506,7 +507,7 @@ async def test_streaming_response_edit(self, async_client: AsyncMetronome) -> No @parametrize async def test_method_list_credit_types(self, async_client: AsyncMetronome) -> None: credit_grant = await async_client.credit_grants.list_credit_types() - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) @parametrize async def test_method_list_credit_types_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -514,7 +515,7 @@ async def test_method_list_credit_types_with_all_params(self, async_client: Asyn limit=1, next_page="string", ) - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) @parametrize async def test_raw_response_list_credit_types(self, async_client: AsyncMetronome) -> None: @@ -523,7 +524,7 @@ async def test_raw_response_list_credit_types(self, async_client: AsyncMetronome assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = await response.parse() - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) @parametrize async def test_streaming_response_list_credit_types(self, async_client: AsyncMetronome) -> None: @@ -532,7 +533,7 @@ async def test_streaming_response_list_credit_types(self, async_client: AsyncMet assert response.http_request.headers.get("X-Stainless-Lang") == "python" credit_grant = await response.parse() - assert_matches_type(CreditGrantListCreditTypesResponse, credit_grant, path=["response"]) + assert_matches_type(AsyncCursorPage[CreditGrantListCreditTypesResponse], credit_grant, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_customers.py b/tests/api_resources/test_customers.py index ba6fa850..3b9a617d 100644 --- a/tests/api_resources/test_customers.py +++ b/tests/api_resources/test_customers.py @@ -10,7 +10,7 @@ from metronome import Metronome, AsyncMetronome from tests.utils import assert_matches_type from metronome.types import ( - CustomerListResponse, + CustomerDetail, CustomerCreateResponse, CustomerArchiveResponse, CustomerSetNameResponse, @@ -19,6 +19,7 @@ CustomerListBillableMetricsResponse, ) from metronome._utils import parse_datetime +from metronome.pagination import SyncCursorPage, AsyncCursorPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -115,7 +116,7 @@ def test_path_params_retrieve(self, client: Metronome) -> None: @parametrize def test_method_list(self, client: Metronome) -> None: customer = client.customers.list() - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerDetail], customer, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -127,7 +128,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: only_archived=True, salesforce_account_ids=["string", "string", "string"], ) - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerDetail], customer, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -136,7 +137,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = response.parse() - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerDetail], customer, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -145,7 +146,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = response.parse() - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerDetail], customer, path=["response"]) assert cast(Any, response.is_closed) is True @@ -185,7 +186,7 @@ def test_method_list_billable_metrics(self, client: Metronome) -> None: customer = client.customers.list_billable_metrics( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) @parametrize def test_method_list_billable_metrics_with_all_params(self, client: Metronome) -> None: @@ -195,7 +196,7 @@ def test_method_list_billable_metrics_with_all_params(self, client: Metronome) - next_page="string", on_current_plan=True, ) - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) @parametrize def test_raw_response_list_billable_metrics(self, client: Metronome) -> None: @@ -206,7 +207,7 @@ def test_raw_response_list_billable_metrics(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = response.parse() - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) @parametrize def test_streaming_response_list_billable_metrics(self, client: Metronome) -> None: @@ -217,7 +218,7 @@ def test_streaming_response_list_billable_metrics(self, client: Metronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = response.parse() - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) assert cast(Any, response.is_closed) is True @@ -235,7 +236,7 @@ def test_method_list_costs(self, client: Metronome) -> None: ending_before=parse_datetime("2019-12-27T18:11:19.117Z"), starting_on=parse_datetime("2019-12-27T18:11:19.117Z"), ) - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) @parametrize def test_method_list_costs_with_all_params(self, client: Metronome) -> None: @@ -246,7 +247,7 @@ def test_method_list_costs_with_all_params(self, client: Metronome) -> None: limit=1, next_page="string", ) - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) @parametrize def test_raw_response_list_costs(self, client: Metronome) -> None: @@ -259,7 +260,7 @@ def test_raw_response_list_costs(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = response.parse() - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) @parametrize def test_streaming_response_list_costs(self, client: Metronome) -> None: @@ -272,7 +273,7 @@ def test_streaming_response_list_costs(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = response.parse() - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(SyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) assert cast(Any, response.is_closed) is True @@ -509,7 +510,7 @@ async def test_path_params_retrieve(self, async_client: AsyncMetronome) -> None: @parametrize async def test_method_list(self, async_client: AsyncMetronome) -> None: customer = await async_client.customers.list() - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerDetail], customer, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -521,7 +522,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - only_archived=True, salesforce_account_ids=["string", "string", "string"], ) - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerDetail], customer, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -530,7 +531,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = await response.parse() - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerDetail], customer, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -539,7 +540,7 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = await response.parse() - assert_matches_type(CustomerListResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerDetail], customer, path=["response"]) assert cast(Any, response.is_closed) is True @@ -579,7 +580,7 @@ async def test_method_list_billable_metrics(self, async_client: AsyncMetronome) customer = await async_client.customers.list_billable_metrics( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) @parametrize async def test_method_list_billable_metrics_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -589,7 +590,7 @@ async def test_method_list_billable_metrics_with_all_params(self, async_client: next_page="string", on_current_plan=True, ) - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) @parametrize async def test_raw_response_list_billable_metrics(self, async_client: AsyncMetronome) -> None: @@ -600,7 +601,7 @@ async def test_raw_response_list_billable_metrics(self, async_client: AsyncMetro assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = await response.parse() - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) @parametrize async def test_streaming_response_list_billable_metrics(self, async_client: AsyncMetronome) -> None: @@ -611,7 +612,7 @@ async def test_streaming_response_list_billable_metrics(self, async_client: Asyn assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = await response.parse() - assert_matches_type(CustomerListBillableMetricsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListBillableMetricsResponse], customer, path=["response"]) assert cast(Any, response.is_closed) is True @@ -629,7 +630,7 @@ async def test_method_list_costs(self, async_client: AsyncMetronome) -> None: ending_before=parse_datetime("2019-12-27T18:11:19.117Z"), starting_on=parse_datetime("2019-12-27T18:11:19.117Z"), ) - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) @parametrize async def test_method_list_costs_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -640,7 +641,7 @@ async def test_method_list_costs_with_all_params(self, async_client: AsyncMetron limit=1, next_page="string", ) - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) @parametrize async def test_raw_response_list_costs(self, async_client: AsyncMetronome) -> None: @@ -653,7 +654,7 @@ async def test_raw_response_list_costs(self, async_client: AsyncMetronome) -> No assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = await response.parse() - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) @parametrize async def test_streaming_response_list_costs(self, async_client: AsyncMetronome) -> None: @@ -666,7 +667,7 @@ async def test_streaming_response_list_costs(self, async_client: AsyncMetronome) assert response.http_request.headers.get("X-Stainless-Lang") == "python" customer = await response.parse() - assert_matches_type(CustomerListCostsResponse, customer, path=["response"]) + assert_matches_type(AsyncCursorPage[CustomerListCostsResponse], customer, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py index 8607d4ae..63c60417 100644 --- a/tests/api_resources/test_plans.py +++ b/tests/api_resources/test_plans.py @@ -15,6 +15,7 @@ PlanListChargesResponse, PlanListCustomersResponse, ) +from metronome.pagination import SyncCursorPage, AsyncCursorPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -25,7 +26,7 @@ class TestPlans: @parametrize def test_method_list(self, client: Metronome) -> None: plan = client.plans.list() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Metronome) -> None: @@ -33,7 +34,7 @@ def test_method_list_with_all_params(self, client: Metronome) -> None: limit=1, next_page="string", ) - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize def test_raw_response_list(self, client: Metronome) -> None: @@ -42,7 +43,7 @@ def test_raw_response_list(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize def test_streaming_response_list(self, client: Metronome) -> None: @@ -51,7 +52,7 @@ def test_streaming_response_list(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -98,7 +99,7 @@ def test_method_list_charges(self, client: Metronome) -> None: plan = client.plans.list_charges( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListChargesResponse], plan, path=["response"]) @parametrize def test_method_list_charges_with_all_params(self, client: Metronome) -> None: @@ -107,7 +108,7 @@ def test_method_list_charges_with_all_params(self, client: Metronome) -> None: limit=1, next_page="string", ) - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListChargesResponse], plan, path=["response"]) @parametrize def test_raw_response_list_charges(self, client: Metronome) -> None: @@ -118,7 +119,7 @@ def test_raw_response_list_charges(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListChargesResponse], plan, path=["response"]) @parametrize def test_streaming_response_list_charges(self, client: Metronome) -> None: @@ -129,7 +130,7 @@ def test_streaming_response_list_charges(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListChargesResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -145,7 +146,7 @@ def test_method_list_customers(self, client: Metronome) -> None: plan = client.plans.list_customers( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) @parametrize def test_method_list_customers_with_all_params(self, client: Metronome) -> None: @@ -155,7 +156,7 @@ def test_method_list_customers_with_all_params(self, client: Metronome) -> None: next_page="string", status="all", ) - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) @parametrize def test_raw_response_list_customers(self, client: Metronome) -> None: @@ -166,7 +167,7 @@ def test_raw_response_list_customers(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) @parametrize def test_streaming_response_list_customers(self, client: Metronome) -> None: @@ -177,7 +178,7 @@ def test_streaming_response_list_customers(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = response.parse() - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(SyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -195,7 +196,7 @@ class TestAsyncPlans: @parametrize async def test_method_list(self, async_client: AsyncMetronome) -> None: plan = await async_client.plans.list() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -203,7 +204,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMetronome) - limit=1, next_page="string", ) - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: @@ -212,7 +213,7 @@ async def test_raw_response_list(self, async_client: AsyncMetronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None: @@ -221,7 +222,7 @@ async def test_streaming_response_list(self, async_client: AsyncMetronome) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -268,7 +269,7 @@ async def test_method_list_charges(self, async_client: AsyncMetronome) -> None: plan = await async_client.plans.list_charges( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListChargesResponse], plan, path=["response"]) @parametrize async def test_method_list_charges_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -277,7 +278,7 @@ async def test_method_list_charges_with_all_params(self, async_client: AsyncMetr limit=1, next_page="string", ) - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListChargesResponse], plan, path=["response"]) @parametrize async def test_raw_response_list_charges(self, async_client: AsyncMetronome) -> None: @@ -288,7 +289,7 @@ async def test_raw_response_list_charges(self, async_client: AsyncMetronome) -> assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListChargesResponse], plan, path=["response"]) @parametrize async def test_streaming_response_list_charges(self, async_client: AsyncMetronome) -> None: @@ -299,7 +300,7 @@ async def test_streaming_response_list_charges(self, async_client: AsyncMetronom assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListChargesResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListChargesResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True @@ -315,7 +316,7 @@ async def test_method_list_customers(self, async_client: AsyncMetronome) -> None plan = await async_client.plans.list_customers( "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) @parametrize async def test_method_list_customers_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -325,7 +326,7 @@ async def test_method_list_customers_with_all_params(self, async_client: AsyncMe next_page="string", status="all", ) - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) @parametrize async def test_raw_response_list_customers(self, async_client: AsyncMetronome) -> None: @@ -336,7 +337,7 @@ async def test_raw_response_list_customers(self, async_client: AsyncMetronome) - assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) @parametrize async def test_streaming_response_list_customers(self, async_client: AsyncMetronome) -> None: @@ -347,7 +348,7 @@ async def test_streaming_response_list_customers(self, async_client: AsyncMetron assert response.http_request.headers.get("X-Stainless-Lang") == "python" plan = await response.parse() - assert_matches_type(PlanListCustomersResponse, plan, path=["response"]) + assert_matches_type(AsyncCursorPage[PlanListCustomersResponse], plan, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_usage.py b/tests/api_resources/test_usage.py index 37d9e0ed..f209fbcf 100644 --- a/tests/api_resources/test_usage.py +++ b/tests/api_resources/test_usage.py @@ -14,6 +14,7 @@ UsageListWithGroupsResponse, ) from metronome._utils import parse_datetime +from metronome.pagination import SyncCursorPage, AsyncCursorPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -155,7 +156,7 @@ def test_method_list_with_groups(self, client: Metronome) -> None: customer_id="04ca7e72-4229-4a6e-ab11-9f7376fccbcb", window_size="day", ) - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(SyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) @parametrize def test_method_list_with_groups_with_all_params(self, client: Metronome) -> None: @@ -173,7 +174,7 @@ def test_method_list_with_groups_with_all_params(self, client: Metronome) -> Non }, starting_on=parse_datetime("2021-01-01T00:00:00Z"), ) - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(SyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) @parametrize def test_raw_response_list_with_groups(self, client: Metronome) -> None: @@ -186,7 +187,7 @@ def test_raw_response_list_with_groups(self, client: Metronome) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" usage = response.parse() - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(SyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) @parametrize def test_streaming_response_list_with_groups(self, client: Metronome) -> None: @@ -199,7 +200,7 @@ def test_streaming_response_list_with_groups(self, client: Metronome) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" usage = response.parse() - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(SyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) assert cast(Any, response.is_closed) is True @@ -341,7 +342,7 @@ async def test_method_list_with_groups(self, async_client: AsyncMetronome) -> No customer_id="04ca7e72-4229-4a6e-ab11-9f7376fccbcb", window_size="day", ) - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(AsyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) @parametrize async def test_method_list_with_groups_with_all_params(self, async_client: AsyncMetronome) -> None: @@ -359,7 +360,7 @@ async def test_method_list_with_groups_with_all_params(self, async_client: Async }, starting_on=parse_datetime("2021-01-01T00:00:00Z"), ) - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(AsyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) @parametrize async def test_raw_response_list_with_groups(self, async_client: AsyncMetronome) -> None: @@ -372,7 +373,7 @@ async def test_raw_response_list_with_groups(self, async_client: AsyncMetronome) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" usage = await response.parse() - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(AsyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) @parametrize async def test_streaming_response_list_with_groups(self, async_client: AsyncMetronome) -> None: @@ -385,6 +386,6 @@ async def test_streaming_response_list_with_groups(self, async_client: AsyncMetr assert response.http_request.headers.get("X-Stainless-Lang") == "python" usage = await response.parse() - assert_matches_type(UsageListWithGroupsResponse, usage, path=["response"]) + assert_matches_type(AsyncCursorPage[UsageListWithGroupsResponse], usage, path=["response"]) assert cast(Any, response.is_closed) is True