From 021294ecc577e24f56839d852bc978b839feb7fe Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:13:51 +0000 Subject: [PATCH 01/39] feat(api): api update --- .stats.yml | 4 +-- src/whop_sdk/resources/companies.py | 30 +++++++++++++++++++ src/whop_sdk/types/affiliate.py | 23 ++++++++++---- src/whop_sdk/types/affiliate_list_response.py | 23 ++++++++++---- .../affiliates/override_create_response.py | 10 +++++-- .../affiliates/override_list_response.py | 10 +++++-- .../affiliates/override_retrieve_response.py | 10 +++++-- .../affiliates/override_update_response.py | 10 +++++-- src/whop_sdk/types/company_update_params.py | 18 +++++++++++ src/whop_sdk/types/shared/company.py | 27 ++++++++++++++++- tests/api_resources/test_companies.py | 6 ++++ 11 files changed, 148 insertions(+), 23 deletions(-) diff --git a/.stats.yml b/.stats.yml index c2e464bf..95e665f7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-97e920db587b07c064bef1bf31de5e110a3750ddfddc8fca26642e79e6b827f8.yml -openapi_spec_hash: 97ca16cc55271602443a4329d1e02895 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-e3735d7700813328ddb9c3da0127c03351e1e2102d6197b3a22f7a0627209488.yml +openapi_spec_hash: 6bd34ccbef8a342ba0f04737113b3529 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/companies.py b/src/whop_sdk/resources/companies.py index 37cb0775..6d3755a4 100644 --- a/src/whop_sdk/resources/companies.py +++ b/src/whop_sdk/resources/companies.py @@ -163,8 +163,11 @@ def update( self, id: str, *, + affiliate_application_required: Optional[bool] | Omit = omit, + affiliate_instructions: Optional[str] | Omit = omit, banner_image: Optional[company_update_params.BannerImage] | Omit = omit, description: Optional[str] | Omit = omit, + featured_affiliate_product_id: Optional[str] | Omit = omit, logo: Optional[company_update_params.Logo] | Omit = omit, route: Optional[str] | Omit = omit, send_customer_emails: Optional[bool] | Omit = omit, @@ -186,11 +189,20 @@ def update( - `company:basic:read` Args: + affiliate_application_required: Whether prospective affiliates must submit an application before they can + promote this company. + + affiliate_instructions: Guidelines and instructions shown to affiliates explaining how to promote this + company's products. + banner_image: The company's banner image. Accepts PNG or JPEG format. description: A promotional pitch displayed to potential customers on the company's store page. + featured_affiliate_product_id: The ID of the product to feature on this company's affiliate page. Pass null to + clear. + logo: The company's logo image. Accepts PNG, JPEG, or GIF format. route: The unique URL slug for the company's store page. Must be lowercase and can @@ -219,8 +231,11 @@ def update( f"/companies/{id}", body=maybe_transform( { + "affiliate_application_required": affiliate_application_required, + "affiliate_instructions": affiliate_instructions, "banner_image": banner_image, "description": description, + "featured_affiliate_product_id": featured_affiliate_product_id, "logo": logo, "route": route, "send_customer_emails": send_customer_emails, @@ -452,8 +467,11 @@ async def update( self, id: str, *, + affiliate_application_required: Optional[bool] | Omit = omit, + affiliate_instructions: Optional[str] | Omit = omit, banner_image: Optional[company_update_params.BannerImage] | Omit = omit, description: Optional[str] | Omit = omit, + featured_affiliate_product_id: Optional[str] | Omit = omit, logo: Optional[company_update_params.Logo] | Omit = omit, route: Optional[str] | Omit = omit, send_customer_emails: Optional[bool] | Omit = omit, @@ -475,11 +493,20 @@ async def update( - `company:basic:read` Args: + affiliate_application_required: Whether prospective affiliates must submit an application before they can + promote this company. + + affiliate_instructions: Guidelines and instructions shown to affiliates explaining how to promote this + company's products. + banner_image: The company's banner image. Accepts PNG or JPEG format. description: A promotional pitch displayed to potential customers on the company's store page. + featured_affiliate_product_id: The ID of the product to feature on this company's affiliate page. Pass null to + clear. + logo: The company's logo image. Accepts PNG, JPEG, or GIF format. route: The unique URL slug for the company's store page. Must be lowercase and can @@ -508,8 +535,11 @@ async def update( f"/companies/{id}", body=await async_maybe_transform( { + "affiliate_application_required": affiliate_application_required, + "affiliate_instructions": affiliate_instructions, "banner_image": banner_image, "description": description, + "featured_affiliate_product_id": featured_affiliate_product_id, "logo": logo, "route": route, "send_customer_emails": send_customer_emails, diff --git a/src/whop_sdk/types/affiliate.py b/src/whop_sdk/types/affiliate.py index 26de2b8b..e6809ff0 100644 --- a/src/whop_sdk/types/affiliate.py +++ b/src/whop_sdk/types/affiliate.py @@ -39,7 +39,9 @@ class User(BaseModel): class Affiliate(BaseModel): - """An affiliate of a company or a global affiliate""" + """ + An affiliate tracks a user's referral performance and commission earnings for a company, including retention rates, revenue metrics, and payout configurations. + """ id: str """The unique identifier for the affiliate.""" @@ -54,13 +56,16 @@ class Affiliate(BaseModel): """The datetime the affiliate was created.""" customer_retention_rate: str - """How many referrals have remained since they joined as members""" + """The percentage of referred customers who are still active members""" customer_retention_rate_ninety_days: str - """A rolling 90-day retention rate for this affiliate""" + """The percentage of referred customers who remained active over the last 90 days""" monthly_recurring_revenue_usd: str - """The total MRR of the affiliate""" + """ + The monthly recurring revenue generated by this affiliate's referrals, formatted + as a USD currency string + """ status: Optional[Status] = None """Statuses for resources""" @@ -69,13 +74,19 @@ class Affiliate(BaseModel): """The total count of all overrides for this affiliate""" total_referral_earnings_usd: str - """The total earnings of the affiliate from the users they referred""" + """ + The total commission earnings paid to this affiliate, formatted as a USD + currency string + """ total_referrals_count: int """The total referrals of the affiliate""" total_revenue_usd: str - """The total revenue of the affiliate from their referrals""" + """ + The total revenue generated from this affiliate's referrals, formatted as a USD + currency string + """ updated_at: datetime """The datetime the affiliate was last updated.""" diff --git a/src/whop_sdk/types/affiliate_list_response.py b/src/whop_sdk/types/affiliate_list_response.py index 9e24c352..64b57cab 100644 --- a/src/whop_sdk/types/affiliate_list_response.py +++ b/src/whop_sdk/types/affiliate_list_response.py @@ -39,7 +39,9 @@ class User(BaseModel): class AffiliateListResponse(BaseModel): - """An affiliate of a company or a global affiliate""" + """ + An affiliate tracks a user's referral performance and commission earnings for a company, including retention rates, revenue metrics, and payout configurations. + """ id: str """The unique identifier for the affiliate.""" @@ -54,13 +56,16 @@ class AffiliateListResponse(BaseModel): """The datetime the affiliate was created.""" customer_retention_rate: str - """How many referrals have remained since they joined as members""" + """The percentage of referred customers who are still active members""" customer_retention_rate_ninety_days: str - """A rolling 90-day retention rate for this affiliate""" + """The percentage of referred customers who remained active over the last 90 days""" monthly_recurring_revenue_usd: str - """The total MRR of the affiliate""" + """ + The monthly recurring revenue generated by this affiliate's referrals, formatted + as a USD currency string + """ status: Optional[Status] = None """Statuses for resources""" @@ -69,13 +74,19 @@ class AffiliateListResponse(BaseModel): """The total count of all overrides for this affiliate""" total_referral_earnings_usd: str - """The total earnings of the affiliate from the users they referred""" + """ + The total commission earnings paid to this affiliate, formatted as a USD + currency string + """ total_referrals_count: int """The total referrals of the affiliate""" total_revenue_usd: str - """The total revenue of the affiliate from their referrals""" + """ + The total revenue generated from this affiliate's referrals, formatted as a USD + currency string + """ updated_at: datetime """The datetime the affiliate was last updated.""" diff --git a/src/whop_sdk/types/affiliates/override_create_response.py b/src/whop_sdk/types/affiliates/override_create_response.py index b7c63d45..08a85c7c 100644 --- a/src/whop_sdk/types/affiliates/override_create_response.py +++ b/src/whop_sdk/types/affiliates/override_create_response.py @@ -13,7 +13,9 @@ class OverrideCreateResponse(BaseModel): - """An object storing information about the affiliate""" + """ + A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share + """ id: str """The unique identifier for the affiliate override.""" @@ -31,7 +33,11 @@ class OverrideCreateResponse(BaseModel): """The type of commission (percentage or flat_fee).""" commission_value: float - """The commission value (percentage 1-100 or flat fee in dollars).""" + """The commission amount. + + A percentage (1-100) when commission_type is percentage, or a dollar amount when + flat_fee. + """ override_type: AffiliateOverrideRoles """The type of override (standard or rev_share).""" diff --git a/src/whop_sdk/types/affiliates/override_list_response.py b/src/whop_sdk/types/affiliates/override_list_response.py index 09ce176d..f4704299 100644 --- a/src/whop_sdk/types/affiliates/override_list_response.py +++ b/src/whop_sdk/types/affiliates/override_list_response.py @@ -13,7 +13,9 @@ class OverrideListResponse(BaseModel): - """An object storing information about the affiliate""" + """ + A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share + """ id: str """The unique identifier for the affiliate override.""" @@ -31,7 +33,11 @@ class OverrideListResponse(BaseModel): """The type of commission (percentage or flat_fee).""" commission_value: float - """The commission value (percentage 1-100 or flat fee in dollars).""" + """The commission amount. + + A percentage (1-100) when commission_type is percentage, or a dollar amount when + flat_fee. + """ override_type: AffiliateOverrideRoles """The type of override (standard or rev_share).""" diff --git a/src/whop_sdk/types/affiliates/override_retrieve_response.py b/src/whop_sdk/types/affiliates/override_retrieve_response.py index 4e54c0fe..61b738f6 100644 --- a/src/whop_sdk/types/affiliates/override_retrieve_response.py +++ b/src/whop_sdk/types/affiliates/override_retrieve_response.py @@ -13,7 +13,9 @@ class OverrideRetrieveResponse(BaseModel): - """An object storing information about the affiliate""" + """ + A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share + """ id: str """The unique identifier for the affiliate override.""" @@ -31,7 +33,11 @@ class OverrideRetrieveResponse(BaseModel): """The type of commission (percentage or flat_fee).""" commission_value: float - """The commission value (percentage 1-100 or flat fee in dollars).""" + """The commission amount. + + A percentage (1-100) when commission_type is percentage, or a dollar amount when + flat_fee. + """ override_type: AffiliateOverrideRoles """The type of override (standard or rev_share).""" diff --git a/src/whop_sdk/types/affiliates/override_update_response.py b/src/whop_sdk/types/affiliates/override_update_response.py index b9ed5c9c..3b830e35 100644 --- a/src/whop_sdk/types/affiliates/override_update_response.py +++ b/src/whop_sdk/types/affiliates/override_update_response.py @@ -13,7 +13,9 @@ class OverrideUpdateResponse(BaseModel): - """An object storing information about the affiliate""" + """ + A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share + """ id: str """The unique identifier for the affiliate override.""" @@ -31,7 +33,11 @@ class OverrideUpdateResponse(BaseModel): """The type of commission (percentage or flat_fee).""" commission_value: float - """The commission value (percentage 1-100 or flat fee in dollars).""" + """The commission amount. + + A percentage (1-100) when commission_type is percentage, or a dollar amount when + flat_fee. + """ override_type: AffiliateOverrideRoles """The type of override (standard or rev_share).""" diff --git a/src/whop_sdk/types/company_update_params.py b/src/whop_sdk/types/company_update_params.py index c475d5fb..15aa74df 100644 --- a/src/whop_sdk/types/company_update_params.py +++ b/src/whop_sdk/types/company_update_params.py @@ -9,6 +9,18 @@ class CompanyUpdateParams(TypedDict, total=False): + affiliate_application_required: Optional[bool] + """ + Whether prospective affiliates must submit an application before they can + promote this company. + """ + + affiliate_instructions: Optional[str] + """ + Guidelines and instructions shown to affiliates explaining how to promote this + company's products. + """ + banner_image: Optional[BannerImage] """The company's banner image. Accepts PNG or JPEG format.""" @@ -18,6 +30,12 @@ class CompanyUpdateParams(TypedDict, total=False): page. """ + featured_affiliate_product_id: Optional[str] + """The ID of the product to feature on this company's affiliate page. + + Pass null to clear. + """ + logo: Optional[Logo] """The company's logo image. Accepts PNG, JPEG, or GIF format.""" diff --git a/src/whop_sdk/types/shared/company.py b/src/whop_sdk/types/shared/company.py index e30b8c1d..3a7b1c82 100644 --- a/src/whop_sdk/types/shared/company.py +++ b/src/whop_sdk/types/shared/company.py @@ -6,7 +6,20 @@ from ..._models import BaseModel -__all__ = ["Company", "Logo", "OwnerUser", "SocialLink"] +__all__ = ["Company", "FeaturedAffiliateProduct", "Logo", "OwnerUser", "SocialLink"] + + +class FeaturedAffiliateProduct(BaseModel): + """The product featured for affiliates to promote on this company's affiliate page. + + Null if none is configured. + """ + + id: str + """The unique identifier for the product.""" + + name: str + """The display name of the product shown to customers. Maximum 50 characters.""" class Logo(BaseModel): @@ -54,6 +67,12 @@ class Company(BaseModel): id: str """The unique identifier for the company.""" + affiliate_instructions: Optional[str] = None + """ + Guidelines and instructions provided to affiliates explaining how to promote + this company's products. + """ + created_at: datetime """The datetime the company was created.""" @@ -63,6 +82,12 @@ class Company(BaseModel): customers on the store page. """ + featured_affiliate_product: Optional[FeaturedAffiliateProduct] = None + """The product featured for affiliates to promote on this company's affiliate page. + + Null if none is configured. + """ + logo: Optional[Logo] = None """The company's logo.""" diff --git a/tests/api_resources/test_companies.py b/tests/api_resources/test_companies.py index 30eb5ebd..8b3e6f8e 100644 --- a/tests/api_resources/test_companies.py +++ b/tests/api_resources/test_companies.py @@ -125,8 +125,11 @@ def test_method_update(self, client: Whop) -> None: def test_method_update_with_all_params(self, client: Whop) -> None: company = client.companies.update( id="biz_xxxxxxxxxxxxxx", + affiliate_application_required=True, + affiliate_instructions="affiliate_instructions", banner_image={"id": "id"}, description="description", + featured_affiliate_product_id="featured_affiliate_product_id", logo={"id": "id"}, route="route", send_customer_emails=True, @@ -321,8 +324,11 @@ async def test_method_update(self, async_client: AsyncWhop) -> None: async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> None: company = await async_client.companies.update( id="biz_xxxxxxxxxxxxxx", + affiliate_application_required=True, + affiliate_instructions="affiliate_instructions", banner_image={"id": "id"}, description="description", + featured_affiliate_product_id="featured_affiliate_product_id", logo={"id": "id"}, route="route", send_customer_emails=True, From ca495f7081478f0056efbad9c75eea30af62f9fe Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 15:36:47 +0000 Subject: [PATCH 02/39] fix: sanitize endpoint path params --- src/whop_sdk/_utils/__init__.py | 1 + src/whop_sdk/_utils/_path.py | 127 ++++++++++++++++++ .../resources/affiliates/affiliates.py | 14 +- .../resources/affiliates/overrides.py | 22 +-- src/whop_sdk/resources/ai_chats.py | 14 +- src/whop_sdk/resources/app_builds.py | 10 +- src/whop_sdk/resources/apps.py | 10 +- src/whop_sdk/resources/authorized_users.py | 10 +- src/whop_sdk/resources/chat_channels.py | 10 +- .../resources/checkout_configurations.py | 6 +- src/whop_sdk/resources/companies.py | 10 +- .../resources/company_token_transactions.py | 6 +- src/whop_sdk/resources/course_chapters.py | 14 +- .../resources/course_lesson_interactions.py | 6 +- src/whop_sdk/resources/course_lessons.py | 26 ++-- src/whop_sdk/resources/course_students.py | 6 +- src/whop_sdk/resources/courses.py | 14 +- src/whop_sdk/resources/dispute_alerts.py | 6 +- src/whop_sdk/resources/disputes.py | 14 +- src/whop_sdk/resources/dm_channels.py | 14 +- src/whop_sdk/resources/dm_members.py | 14 +- src/whop_sdk/resources/entries.py | 14 +- src/whop_sdk/resources/experiences.py | 26 ++-- src/whop_sdk/resources/fee_markups.py | 6 +- src/whop_sdk/resources/files.py | 6 +- src/whop_sdk/resources/forum_posts.py | 10 +- src/whop_sdk/resources/forums.py | 10 +- src/whop_sdk/resources/invoices.py | 10 +- src/whop_sdk/resources/leads.py | 10 +- src/whop_sdk/resources/ledger_accounts.py | 5 +- src/whop_sdk/resources/members.py | 6 +- src/whop_sdk/resources/memberships.py | 118 ++++++++++++++-- src/whop_sdk/resources/messages.py | 14 +- src/whop_sdk/resources/payment_methods.py | 6 +- src/whop_sdk/resources/payments.py | 22 +-- src/whop_sdk/resources/payout_accounts.py | 5 +- src/whop_sdk/resources/payout_methods.py | 6 +- src/whop_sdk/resources/plans.py | 14 +- src/whop_sdk/resources/products.py | 14 +- src/whop_sdk/resources/promo_codes.py | 10 +- src/whop_sdk/resources/reactions.py | 10 +- src/whop_sdk/resources/refunds.py | 6 +- .../resources/resolution_center_cases.py | 6 +- src/whop_sdk/resources/reviews.py | 6 +- src/whop_sdk/resources/setup_intents.py | 6 +- src/whop_sdk/resources/shipments.py | 6 +- src/whop_sdk/resources/support_channels.py | 6 +- src/whop_sdk/resources/transfers.py | 6 +- src/whop_sdk/resources/users.py | 10 +- src/whop_sdk/resources/verifications.py | 6 +- src/whop_sdk/resources/webhooks.py | 14 +- src/whop_sdk/resources/withdrawals.py | 6 +- tests/test_utils/test_path.py | 89 ++++++++++++ 53 files changed, 577 insertions(+), 266 deletions(-) create mode 100644 src/whop_sdk/_utils/_path.py create mode 100644 tests/test_utils/test_path.py diff --git a/src/whop_sdk/_utils/__init__.py b/src/whop_sdk/_utils/__init__.py index dc64e29a..10cb66d2 100644 --- a/src/whop_sdk/_utils/__init__.py +++ b/src/whop_sdk/_utils/__init__.py @@ -1,3 +1,4 @@ +from ._path import path_template as path_template from ._sync import asyncify as asyncify from ._proxy import LazyProxy as LazyProxy from ._utils import ( diff --git a/src/whop_sdk/_utils/_path.py b/src/whop_sdk/_utils/_path.py new file mode 100644 index 00000000..4d6e1e4c --- /dev/null +++ b/src/whop_sdk/_utils/_path.py @@ -0,0 +1,127 @@ +from __future__ import annotations + +import re +from typing import ( + Any, + Mapping, + Callable, +) +from urllib.parse import quote + +# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E). +_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$") + +_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}") + + +def _quote_path_segment_part(value: str) -> str: + """Percent-encode `value` for use in a URI path segment. + + Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe. + https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 + """ + # quote() already treats unreserved characters (letters, digits, and -._~) + # as safe, so we only need to add sub-delims, ':', and '@'. + # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted. + return quote(value, safe="!$&'()*+,;=:@") + + +def _quote_query_part(value: str) -> str: + """Percent-encode `value` for use in a URI query string. + + Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe. + https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 + """ + return quote(value, safe="!$'()*+,;:@/?") + + +def _quote_fragment_part(value: str) -> str: + """Percent-encode `value` for use in a URI fragment. + + Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe. + https://datatracker.ietf.org/doc/html/rfc3986#section-3.5 + """ + return quote(value, safe="!$&'()*+,;=:@/?") + + +def _interpolate( + template: str, + values: Mapping[str, Any], + quoter: Callable[[str], str], +) -> str: + """Replace {name} placeholders in `template`, quoting each value with `quoter`. + + Placeholder names are looked up in `values`. + + Raises: + KeyError: If a placeholder is not found in `values`. + """ + # re.split with a capturing group returns alternating + # [text, name, text, name, ..., text] elements. + parts = _PLACEHOLDER_RE.split(template) + + for i in range(1, len(parts), 2): + name = parts[i] + if name not in values: + raise KeyError(f"a value for placeholder {{{name}}} was not provided") + val = values[name] + if val is None: + parts[i] = "null" + elif isinstance(val, bool): + parts[i] = "true" if val else "false" + else: + parts[i] = quoter(str(values[name])) + + return "".join(parts) + + +def path_template(template: str, /, **kwargs: Any) -> str: + """Interpolate {name} placeholders in `template` from keyword arguments. + + Args: + template: The template string containing {name} placeholders. + **kwargs: Keyword arguments to interpolate into the template. + + Returns: + The template with placeholders interpolated and percent-encoded. + + Safe characters for percent-encoding are dependent on the URI component. + Placeholders in path and fragment portions are percent-encoded where the `segment` + and `fragment` sets from RFC 3986 respectively are considered safe. + Placeholders in the query portion are percent-encoded where the `query` set from + RFC 3986 §3.3 is considered safe except for = and & characters. + + Raises: + KeyError: If a placeholder is not found in `kwargs`. + ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments). + """ + # Split the template into path, query, and fragment portions. + fragment_template: str | None = None + query_template: str | None = None + + rest = template + if "#" in rest: + rest, fragment_template = rest.split("#", 1) + if "?" in rest: + rest, query_template = rest.split("?", 1) + path_template = rest + + # Interpolate each portion with the appropriate quoting rules. + path_result = _interpolate(path_template, kwargs, _quote_path_segment_part) + + # Reject dot-segments (. and ..) in the final assembled path. The check + # runs after interpolation so that adjacent placeholders or a mix of static + # text and placeholders that together form a dot-segment are caught. + # Also reject percent-encoded dot-segments to protect against incorrectly + # implemented normalization in servers/proxies. + for segment in path_result.split("/"): + if _DOT_SEGMENT_RE.match(segment): + raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed") + + result = path_result + if query_template is not None: + result += "?" + _interpolate(query_template, kwargs, _quote_query_part) + if fragment_template is not None: + result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part) + + return result diff --git a/src/whop_sdk/resources/affiliates/affiliates.py b/src/whop_sdk/resources/affiliates/affiliates.py index 2c184ded..75b951ec 100644 --- a/src/whop_sdk/resources/affiliates/affiliates.py +++ b/src/whop_sdk/resources/affiliates/affiliates.py @@ -9,7 +9,7 @@ from ...types import Status, affiliate_list_params, affiliate_create_params from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform, async_maybe_transform +from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property from .overrides import ( OverridesResource, @@ -142,7 +142,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/affiliates/{id}", + path_template("/affiliates/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -259,7 +259,7 @@ def archive( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/affiliates/{id}/archive", + path_template("/affiliates/{id}/archive", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -296,7 +296,7 @@ def unarchive( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/affiliates/{id}/unarchive", + path_template("/affiliates/{id}/unarchive", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -408,7 +408,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/affiliates/{id}", + path_template("/affiliates/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -525,7 +525,7 @@ async def archive( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/affiliates/{id}/archive", + path_template("/affiliates/{id}/archive", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -562,7 +562,7 @@ async def unarchive( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/affiliates/{id}/unarchive", + path_template("/affiliates/{id}/unarchive", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/affiliates/overrides.py b/src/whop_sdk/resources/affiliates/overrides.py index a3158a16..351eab61 100644 --- a/src/whop_sdk/resources/affiliates/overrides.py +++ b/src/whop_sdk/resources/affiliates/overrides.py @@ -8,7 +8,7 @@ import httpx from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import required_args, maybe_transform, async_maybe_transform +from ..._utils import path_template, required_args, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -180,7 +180,7 @@ def create( if not path_id: raise ValueError(f"Expected a non-empty value for `path_id` but received {path_id!r}") return self._post( - f"/affiliates/{path_id}/overrides", + path_template("/affiliates/{path_id}/overrides", path_id=path_id), body=maybe_transform( { "body_id": body_id, @@ -233,7 +233,7 @@ def retrieve( if not override_id: raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}") return self._get( - f"/affiliates/{id}/overrides/{override_id}", + path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -285,7 +285,7 @@ def update( if not override_id: raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}") return self._patch( - f"/affiliates/{id}/overrides/{override_id}", + path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id), body=maybe_transform( { "applies_to_payments": applies_to_payments, @@ -346,7 +346,7 @@ def list( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( - f"/affiliates/{id}/overrides", + path_template("/affiliates/{id}/overrides", id=id), page=SyncCursorPage[OverrideListResponse], options=make_request_options( extra_headers=extra_headers, @@ -400,7 +400,7 @@ def delete( if not override_id: raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}") return self._delete( - f"/affiliates/{id}/overrides/{override_id}", + path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -547,7 +547,7 @@ async def create( if not path_id: raise ValueError(f"Expected a non-empty value for `path_id` but received {path_id!r}") return await self._post( - f"/affiliates/{path_id}/overrides", + path_template("/affiliates/{path_id}/overrides", path_id=path_id), body=await async_maybe_transform( { "body_id": body_id, @@ -600,7 +600,7 @@ async def retrieve( if not override_id: raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}") return await self._get( - f"/affiliates/{id}/overrides/{override_id}", + path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -652,7 +652,7 @@ async def update( if not override_id: raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}") return await self._patch( - f"/affiliates/{id}/overrides/{override_id}", + path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id), body=await async_maybe_transform( { "applies_to_payments": applies_to_payments, @@ -713,7 +713,7 @@ def list( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( - f"/affiliates/{id}/overrides", + path_template("/affiliates/{id}/overrides", id=id), page=AsyncCursorPage[OverrideListResponse], options=make_request_options( extra_headers=extra_headers, @@ -767,7 +767,7 @@ async def delete( if not override_id: raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}") return await self._delete( - f"/affiliates/{id}/overrides/{override_id}", + path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/ai_chats.py b/src/whop_sdk/resources/ai_chats.py index 6c9f4a1d..16d60eb9 100644 --- a/src/whop_sdk/resources/ai_chats.py +++ b/src/whop_sdk/resources/ai_chats.py @@ -9,7 +9,7 @@ from ..types import NotificationPreferences, ai_chat_list_params, ai_chat_create_params, ai_chat_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -135,7 +135,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/ai_chats/{id}", + path_template("/ai_chats/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -183,7 +183,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/ai_chats/{id}", + path_template("/ai_chats/{id}", id=id), body=maybe_transform( { "current_company_id": current_company_id, @@ -287,7 +287,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/ai_chats/{id}", + path_template("/ai_chats/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -402,7 +402,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/ai_chats/{id}", + path_template("/ai_chats/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -450,7 +450,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/ai_chats/{id}", + path_template("/ai_chats/{id}", id=id), body=await async_maybe_transform( { "current_company_id": current_company_id, @@ -554,7 +554,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/ai_chats/{id}", + path_template("/ai_chats/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/app_builds.py b/src/whop_sdk/resources/app_builds.py index e4e0f855..80465b2a 100644 --- a/src/whop_sdk/resources/app_builds.py +++ b/src/whop_sdk/resources/app_builds.py @@ -9,7 +9,7 @@ from ..types import app_build_list_params, app_build_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -149,7 +149,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/app_builds/{id}", + path_template("/app_builds/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -267,7 +267,7 @@ def promote( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/app_builds/{id}/promote", + path_template("/app_builds/{id}/promote", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -395,7 +395,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/app_builds/{id}", + path_template("/app_builds/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -513,7 +513,7 @@ async def promote( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/app_builds/{id}/promote", + path_template("/app_builds/{id}/promote", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/apps.py b/src/whop_sdk/resources/apps.py index 46fd9b78..15b482da 100644 --- a/src/whop_sdk/resources/apps.py +++ b/src/whop_sdk/resources/apps.py @@ -9,7 +9,7 @@ from ..types import AppType, app_list_params, app_create_params, app_update_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -145,7 +145,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/apps/{id}", + path_template("/apps/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -226,7 +226,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/apps/{id}", + path_template("/apps/{id}", id=id), body=maybe_transform( { "app_store_description": app_store_description, @@ -468,7 +468,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/apps/{id}", + path_template("/apps/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -549,7 +549,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/apps/{id}", + path_template("/apps/{id}", id=id), body=await async_maybe_transform( { "app_store_description": app_store_description, diff --git a/src/whop_sdk/resources/authorized_users.py b/src/whop_sdk/resources/authorized_users.py index 8ccdca5f..0519e3e2 100644 --- a/src/whop_sdk/resources/authorized_users.py +++ b/src/whop_sdk/resources/authorized_users.py @@ -9,7 +9,7 @@ from ..types import authorized_user_list_params, authorized_user_create_params, authorized_user_delete_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -139,7 +139,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/authorized_users/{id}", + path_template("/authorized_users/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -262,7 +262,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/authorized_users/{id}", + path_template("/authorized_users/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -387,7 +387,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/authorized_users/{id}", + path_template("/authorized_users/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -510,7 +510,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/authorized_users/{id}", + path_template("/authorized_users/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/whop_sdk/resources/chat_channels.py b/src/whop_sdk/resources/chat_channels.py index 0ed7bd7f..ef5da1a1 100644 --- a/src/whop_sdk/resources/chat_channels.py +++ b/src/whop_sdk/resources/chat_channels.py @@ -8,7 +8,7 @@ from ..types import chat_channel_list_params, chat_channel_update_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -77,7 +77,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/chat_channels/{id}", + path_template("/chat_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -135,7 +135,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/chat_channels/{id}", + path_template("/chat_channels/{id}", id=id), body=maybe_transform( { "ban_media": ban_media, @@ -273,7 +273,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/chat_channels/{id}", + path_template("/chat_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -331,7 +331,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/chat_channels/{id}", + path_template("/chat_channels/{id}", id=id), body=await async_maybe_transform( { "ban_media": ban_media, diff --git a/src/whop_sdk/resources/checkout_configurations.py b/src/whop_sdk/resources/checkout_configurations.py index 01606287..ca43a5f8 100644 --- a/src/whop_sdk/resources/checkout_configurations.py +++ b/src/whop_sdk/resources/checkout_configurations.py @@ -10,7 +10,7 @@ from ..types import checkout_configuration_list_params, checkout_configuration_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import required_args, maybe_transform, async_maybe_transform +from .._utils import path_template, required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -306,7 +306,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/checkout_configurations/{id}", + path_template("/checkout_configurations/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -672,7 +672,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/checkout_configurations/{id}", + path_template("/checkout_configurations/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/companies.py b/src/whop_sdk/resources/companies.py index 6d3755a4..38507758 100644 --- a/src/whop_sdk/resources/companies.py +++ b/src/whop_sdk/resources/companies.py @@ -9,7 +9,7 @@ from ..types import company_list_params, company_create_params, company_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -152,7 +152,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/companies/{id}", + path_template("/companies/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -228,7 +228,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/companies/{id}", + path_template("/companies/{id}", id=id), body=maybe_transform( { "affiliate_application_required": affiliate_application_required, @@ -456,7 +456,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/companies/{id}", + path_template("/companies/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -532,7 +532,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/companies/{id}", + path_template("/companies/{id}", id=id), body=await async_maybe_transform( { "affiliate_application_required": affiliate_application_required, diff --git a/src/whop_sdk/resources/company_token_transactions.py b/src/whop_sdk/resources/company_token_transactions.py index aa7bf6ce..2b3cbddc 100644 --- a/src/whop_sdk/resources/company_token_transactions.py +++ b/src/whop_sdk/resources/company_token_transactions.py @@ -13,7 +13,7 @@ company_token_transaction_create_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import required_args, maybe_transform, async_maybe_transform +from .._utils import path_template, required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -281,7 +281,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/company_token_transactions/{id}", + path_template("/company_token_transactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -614,7 +614,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/company_token_transactions/{id}", + path_template("/company_token_transactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/course_chapters.py b/src/whop_sdk/resources/course_chapters.py index 9d8345bf..41c7ea17 100644 --- a/src/whop_sdk/resources/course_chapters.py +++ b/src/whop_sdk/resources/course_chapters.py @@ -8,7 +8,7 @@ from ..types import course_chapter_list_params, course_chapter_create_params, course_chapter_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -124,7 +124,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/course_chapters/{id}", + path_template("/course_chapters/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -164,7 +164,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/course_chapters/{id}", + path_template("/course_chapters/{id}", id=id), body=maybe_transform({"title": title}, course_chapter_update_params.CourseChapterUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -265,7 +265,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/course_chapters/{id}", + path_template("/course_chapters/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -371,7 +371,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/course_chapters/{id}", + path_template("/course_chapters/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -411,7 +411,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/course_chapters/{id}", + path_template("/course_chapters/{id}", id=id), body=await async_maybe_transform({"title": title}, course_chapter_update_params.CourseChapterUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -512,7 +512,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/course_chapters/{id}", + path_template("/course_chapters/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/course_lesson_interactions.py b/src/whop_sdk/resources/course_lesson_interactions.py index 19d49434..0b19bceb 100644 --- a/src/whop_sdk/resources/course_lesson_interactions.py +++ b/src/whop_sdk/resources/course_lesson_interactions.py @@ -8,7 +8,7 @@ from ..types import course_lesson_interaction_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -76,7 +76,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/course_lesson_interactions/{id}", + path_template("/course_lesson_interactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -212,7 +212,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/course_lesson_interactions/{id}", + path_template("/course_lesson_interactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/course_lessons.py b/src/whop_sdk/resources/course_lessons.py index ef47ad3e..443134be 100644 --- a/src/whop_sdk/resources/course_lessons.py +++ b/src/whop_sdk/resources/course_lessons.py @@ -16,7 +16,7 @@ course_lesson_submit_assessment_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -166,7 +166,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/course_lessons/{id}", + path_template("/course_lessons/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -254,7 +254,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/course_lessons/{id}", + path_template("/course_lessons/{id}", id=id), body=maybe_transform( { "assessment_completion_requirement": assessment_completion_requirement, @@ -378,7 +378,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/course_lessons/{id}", + path_template("/course_lessons/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -411,7 +411,7 @@ def mark_as_completed( if not lesson_id: raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}") return self._post( - f"/course_lessons/{lesson_id}/mark_as_completed", + path_template("/course_lessons/{lesson_id}/mark_as_completed", lesson_id=lesson_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -445,7 +445,7 @@ def start( if not lesson_id: raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}") return self._post( - f"/course_lessons/{lesson_id}/start", + path_template("/course_lessons/{lesson_id}/start", lesson_id=lesson_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -481,7 +481,7 @@ def submit_assessment( if not lesson_id: raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}") return self._post( - f"/course_lessons/{lesson_id}/submit_assessment", + path_template("/course_lessons/{lesson_id}/submit_assessment", lesson_id=lesson_id), body=maybe_transform( {"answers": answers}, course_lesson_submit_assessment_params.CourseLessonSubmitAssessmentParams ), @@ -618,7 +618,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/course_lessons/{id}", + path_template("/course_lessons/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -706,7 +706,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/course_lessons/{id}", + path_template("/course_lessons/{id}", id=id), body=await async_maybe_transform( { "assessment_completion_requirement": assessment_completion_requirement, @@ -830,7 +830,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/course_lessons/{id}", + path_template("/course_lessons/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -863,7 +863,7 @@ async def mark_as_completed( if not lesson_id: raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}") return await self._post( - f"/course_lessons/{lesson_id}/mark_as_completed", + path_template("/course_lessons/{lesson_id}/mark_as_completed", lesson_id=lesson_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -897,7 +897,7 @@ async def start( if not lesson_id: raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}") return await self._post( - f"/course_lessons/{lesson_id}/start", + path_template("/course_lessons/{lesson_id}/start", lesson_id=lesson_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -933,7 +933,7 @@ async def submit_assessment( if not lesson_id: raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}") return await self._post( - f"/course_lessons/{lesson_id}/submit_assessment", + path_template("/course_lessons/{lesson_id}/submit_assessment", lesson_id=lesson_id), body=await async_maybe_transform( {"answers": answers}, course_lesson_submit_assessment_params.CourseLessonSubmitAssessmentParams ), diff --git a/src/whop_sdk/resources/course_students.py b/src/whop_sdk/resources/course_students.py index 83c1656e..a7c111a0 100644 --- a/src/whop_sdk/resources/course_students.py +++ b/src/whop_sdk/resources/course_students.py @@ -8,7 +8,7 @@ from ..types import course_student_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -76,7 +76,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/course_students/{id}", + path_template("/course_students/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -204,7 +204,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/course_students/{id}", + path_template("/course_students/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/courses.py b/src/whop_sdk/resources/courses.py index a5c5b25e..f8957ca5 100644 --- a/src/whop_sdk/resources/courses.py +++ b/src/whop_sdk/resources/courses.py @@ -8,7 +8,7 @@ from ..types import Languages, CourseVisibilities, course_list_params, course_create_params, course_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -156,7 +156,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/courses/{id}", + path_template("/courses/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -229,7 +229,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/courses/{id}", + path_template("/courses/{id}", id=id), body=maybe_transform( { "certificate_after_completion_enabled": certificate_after_completion_enabled, @@ -350,7 +350,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/courses/{id}", + path_template("/courses/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -486,7 +486,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/courses/{id}", + path_template("/courses/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -559,7 +559,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/courses/{id}", + path_template("/courses/{id}", id=id), body=await async_maybe_transform( { "certificate_after_completion_enabled": certificate_after_completion_enabled, @@ -680,7 +680,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/courses/{id}", + path_template("/courses/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/dispute_alerts.py b/src/whop_sdk/resources/dispute_alerts.py index 03b47ef2..7bfc7a65 100644 --- a/src/whop_sdk/resources/dispute_alerts.py +++ b/src/whop_sdk/resources/dispute_alerts.py @@ -9,7 +9,7 @@ from ..types import dispute_alert_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -82,7 +82,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/dispute_alerts/{id}", + path_template("/dispute_alerts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -223,7 +223,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/dispute_alerts/{id}", + path_template("/dispute_alerts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/disputes.py b/src/whop_sdk/resources/disputes.py index 0baa88dc..81cfc21f 100644 --- a/src/whop_sdk/resources/disputes.py +++ b/src/whop_sdk/resources/disputes.py @@ -9,7 +9,7 @@ from ..types import dispute_list_params, dispute_update_evidence_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -84,7 +84,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/disputes/{id}", + path_template("/disputes/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -211,7 +211,7 @@ def submit_evidence( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/disputes/{id}/submit_evidence", + path_template("/disputes/{id}/submit_evidence", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -300,7 +300,7 @@ def update_evidence( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/disputes/{id}/update_evidence", + path_template("/disputes/{id}/update_evidence", id=id), body=maybe_transform( { "access_activity_log": access_activity_log, @@ -384,7 +384,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/disputes/{id}", + path_template("/disputes/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -511,7 +511,7 @@ async def submit_evidence( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/disputes/{id}/submit_evidence", + path_template("/disputes/{id}/submit_evidence", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -600,7 +600,7 @@ async def update_evidence( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/disputes/{id}/update_evidence", + path_template("/disputes/{id}/update_evidence", id=id), body=await async_maybe_transform( { "access_activity_log": access_activity_log, diff --git a/src/whop_sdk/resources/dm_channels.py b/src/whop_sdk/resources/dm_channels.py index 7e51c55e..1bae5de2 100644 --- a/src/whop_sdk/resources/dm_channels.py +++ b/src/whop_sdk/resources/dm_channels.py @@ -8,7 +8,7 @@ from ..types import dm_channel_list_params, dm_channel_create_params, dm_channel_update_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -126,7 +126,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/dm_channels/{id}", + path_template("/dm_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -168,7 +168,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/dm_channels/{id}", + path_template("/dm_channels/{id}", id=id), body=maybe_transform({"custom_name": custom_name}, dm_channel_update_params.DmChannelUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -273,7 +273,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/dm_channels/{id}", + path_template("/dm_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -381,7 +381,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/dm_channels/{id}", + path_template("/dm_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -423,7 +423,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/dm_channels/{id}", + path_template("/dm_channels/{id}", id=id), body=await async_maybe_transform( {"custom_name": custom_name}, dm_channel_update_params.DmChannelUpdateParams ), @@ -530,7 +530,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/dm_channels/{id}", + path_template("/dm_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/dm_members.py b/src/whop_sdk/resources/dm_members.py index f1a8ca12..be2de9bb 100644 --- a/src/whop_sdk/resources/dm_members.py +++ b/src/whop_sdk/resources/dm_members.py @@ -14,7 +14,7 @@ dm_member_update_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -134,7 +134,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/dm_members/{id}", + path_template("/dm_members/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -178,7 +178,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/dm_members/{id}", + path_template("/dm_members/{id}", id=id), body=maybe_transform( { "notification_preference": notification_preference, @@ -288,7 +288,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/dm_members/{id}", + path_template("/dm_members/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -396,7 +396,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/dm_members/{id}", + path_template("/dm_members/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -440,7 +440,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/dm_members/{id}", + path_template("/dm_members/{id}", id=id), body=await async_maybe_transform( { "notification_preference": notification_preference, @@ -550,7 +550,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/dm_members/{id}", + path_template("/dm_members/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/entries.py b/src/whop_sdk/resources/entries.py index 41d5d23c..68473548 100644 --- a/src/whop_sdk/resources/entries.py +++ b/src/whop_sdk/resources/entries.py @@ -10,7 +10,7 @@ from ..types import entry_list_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -81,7 +81,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/entries/{id}", + path_template("/entries/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -212,7 +212,7 @@ def approve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/entries/{id}/approve", + path_template("/entries/{id}/approve", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -252,7 +252,7 @@ def deny( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/entries/{id}/deny", + path_template("/entries/{id}/deny", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -311,7 +311,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/entries/{id}", + path_template("/entries/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -442,7 +442,7 @@ async def approve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/entries/{id}/approve", + path_template("/entries/{id}/approve", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -482,7 +482,7 @@ async def deny( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/entries/{id}/deny", + path_template("/entries/{id}/deny", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/experiences.py b/src/whop_sdk/resources/experiences.py index 50542d1d..b8444bde 100644 --- a/src/whop_sdk/resources/experiences.py +++ b/src/whop_sdk/resources/experiences.py @@ -17,7 +17,7 @@ experience_duplicate_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -142,7 +142,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/experiences/{id}", + path_template("/experiences/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -195,7 +195,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/experiences/{id}", + path_template("/experiences/{id}", id=id), body=maybe_transform( { "access_level": access_level, @@ -317,7 +317,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/experiences/{id}", + path_template("/experiences/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -358,7 +358,7 @@ def attach( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/experiences/{id}/attach", + path_template("/experiences/{id}/attach", id=id), body=maybe_transform({"product_id": product_id}, experience_attach_params.ExperienceAttachParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -400,7 +400,7 @@ def detach( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/experiences/{id}/detach", + path_template("/experiences/{id}/detach", id=id), body=maybe_transform({"product_id": product_id}, experience_detach_params.ExperienceDetachParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -448,7 +448,7 @@ def duplicate( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/experiences/{id}/duplicate", + path_template("/experiences/{id}/duplicate", id=id), body=maybe_transform({"name": name}, experience_duplicate_params.ExperienceDuplicateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -564,7 +564,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/experiences/{id}", + path_template("/experiences/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -617,7 +617,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/experiences/{id}", + path_template("/experiences/{id}", id=id), body=await async_maybe_transform( { "access_level": access_level, @@ -739,7 +739,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/experiences/{id}", + path_template("/experiences/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -780,7 +780,7 @@ async def attach( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/experiences/{id}/attach", + path_template("/experiences/{id}/attach", id=id), body=await async_maybe_transform( {"product_id": product_id}, experience_attach_params.ExperienceAttachParams ), @@ -824,7 +824,7 @@ async def detach( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/experiences/{id}/detach", + path_template("/experiences/{id}/detach", id=id), body=await async_maybe_transform( {"product_id": product_id}, experience_detach_params.ExperienceDetachParams ), @@ -874,7 +874,7 @@ async def duplicate( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/experiences/{id}/duplicate", + path_template("/experiences/{id}/duplicate", id=id), body=await async_maybe_transform({"name": name}, experience_duplicate_params.ExperienceDuplicateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout diff --git a/src/whop_sdk/resources/fee_markups.py b/src/whop_sdk/resources/fee_markups.py index 9944dd2b..63eb13e9 100644 --- a/src/whop_sdk/resources/fee_markups.py +++ b/src/whop_sdk/resources/fee_markups.py @@ -8,7 +8,7 @@ from ..types import FeeMarkupType, fee_markup_list_params, fee_markup_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -210,7 +210,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/fee_markups/{id}", + path_template("/fee_markups/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -401,7 +401,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/fee_markups/{id}", + path_template("/fee_markups/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/files.py b/src/whop_sdk/resources/files.py index 5729ec7c..5e1ad1bc 100644 --- a/src/whop_sdk/resources/files.py +++ b/src/whop_sdk/resources/files.py @@ -6,7 +6,7 @@ from ..types import file_create_params from .._types import Body, Query, Headers, NotGiven, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -104,7 +104,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/files/{id}", + path_template("/files/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -194,7 +194,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/files/{id}", + path_template("/files/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/forum_posts.py b/src/whop_sdk/resources/forum_posts.py index 0acb986e..eacff2da 100644 --- a/src/whop_sdk/resources/forum_posts.py +++ b/src/whop_sdk/resources/forum_posts.py @@ -13,7 +13,7 @@ forum_post_update_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -181,7 +181,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/forum_posts/{id}", + path_template("/forum_posts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -234,7 +234,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/forum_posts/{id}", + path_template("/forum_posts/{id}", id=id), body=maybe_transform( { "attachments": attachments, @@ -475,7 +475,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/forum_posts/{id}", + path_template("/forum_posts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -528,7 +528,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/forum_posts/{id}", + path_template("/forum_posts/{id}", id=id), body=await async_maybe_transform( { "attachments": attachments, diff --git a/src/whop_sdk/resources/forums.py b/src/whop_sdk/resources/forums.py index 3159079e..15e04320 100644 --- a/src/whop_sdk/resources/forums.py +++ b/src/whop_sdk/resources/forums.py @@ -8,7 +8,7 @@ from ..types import forum_list_params, forum_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -78,7 +78,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/forums/{id}", + path_template("/forums/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -125,7 +125,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/forums/{id}", + path_template("/forums/{id}", id=id), body=maybe_transform( { "email_notification_preference": email_notification_preference, @@ -260,7 +260,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/forums/{id}", + path_template("/forums/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -307,7 +307,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/forums/{id}", + path_template("/forums/{id}", id=id), body=await async_maybe_transform( { "email_notification_preference": email_notification_preference, diff --git a/src/whop_sdk/resources/invoices.py b/src/whop_sdk/resources/invoices.py index aec677fc..9043ccbd 100644 --- a/src/whop_sdk/resources/invoices.py +++ b/src/whop_sdk/resources/invoices.py @@ -10,7 +10,7 @@ from ..types import invoice_list_params, invoice_create_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import required_args, maybe_transform, async_maybe_transform +from .._utils import path_template, required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -436,7 +436,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/invoices/{id}", + path_template("/invoices/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -569,7 +569,7 @@ def void( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/invoices/{id}/void", + path_template("/invoices/{id}/void", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -982,7 +982,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/invoices/{id}", + path_template("/invoices/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1115,7 +1115,7 @@ async def void( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/invoices/{id}/void", + path_template("/invoices/{id}/void", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/leads.py b/src/whop_sdk/resources/leads.py index df6f9929..d4ad5904 100644 --- a/src/whop_sdk/resources/leads.py +++ b/src/whop_sdk/resources/leads.py @@ -9,7 +9,7 @@ from ..types import lead_list_params, lead_create_params, lead_update_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -146,7 +146,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/leads/{id}", + path_template("/leads/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -193,7 +193,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/leads/{id}", + path_template("/leads/{id}", id=id), body=maybe_transform( { "metadata": metadata, @@ -407,7 +407,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/leads/{id}", + path_template("/leads/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -454,7 +454,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/leads/{id}", + path_template("/leads/{id}", id=id), body=await async_maybe_transform( { "metadata": metadata, diff --git a/src/whop_sdk/resources/ledger_accounts.py b/src/whop_sdk/resources/ledger_accounts.py index d213b5ca..778e7023 100644 --- a/src/whop_sdk/resources/ledger_accounts.py +++ b/src/whop_sdk/resources/ledger_accounts.py @@ -5,6 +5,7 @@ import httpx from .._types import Body, Query, Headers, NotGiven, not_given +from .._utils import path_template from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -70,7 +71,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/ledger_accounts/{id}", + path_template("/ledger_accounts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -129,7 +130,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/ledger_accounts/{id}", + path_template("/ledger_accounts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/members.py b/src/whop_sdk/resources/members.py index 811f248f..5fa0c041 100644 --- a/src/whop_sdk/resources/members.py +++ b/src/whop_sdk/resources/members.py @@ -10,7 +10,7 @@ from ..types import member_list_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -83,7 +83,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/members/{id}", + path_template("/members/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -259,7 +259,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/members/{id}", + path_template("/members/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/memberships.py b/src/whop_sdk/resources/memberships.py index 22af0afb..4045d089 100644 --- a/src/whop_sdk/resources/memberships.py +++ b/src/whop_sdk/resources/memberships.py @@ -15,7 +15,7 @@ membership_update_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -86,7 +86,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/memberships/{id}", + path_template("/memberships/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -129,7 +129,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/memberships/{id}", + path_template("/memberships/{id}", id=id), body=maybe_transform({"metadata": metadata}, membership_update_params.MembershipUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -244,6 +244,51 @@ def list( model=MembershipListResponse, ) + def add_free_days( + self, + id: str, + *, + free_days: int, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Membership: + """ + Add free days to extend a membership's current billing period, expiration date, + or Stripe trial. + + Required permissions: + + - `member:manage` + - `member:email:read` + - `member:basic:read` + + Args: + free_days: The number of free days to add (1-1095). Extends the billing period, expiration + date, or Stripe trial depending on plan type. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + path_template("/memberships/{id}/add_free_days", id=id), + body=maybe_transform({"free_days": free_days}, membership_add_free_days_params.MembershipAddFreeDaysParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Membership, + ) + def cancel( self, id: str, @@ -280,7 +325,7 @@ def cancel( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/memberships/{id}/cancel", + path_template("/memberships/{id}/cancel", id=id), body=maybe_transform( {"cancellation_mode": cancellation_mode}, membership_cancel_params.MembershipCancelParams ), @@ -328,7 +373,7 @@ def pause( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/memberships/{id}/pause", + path_template("/memberships/{id}/pause", id=id), body=maybe_transform({"void_payments": void_payments}, membership_pause_params.MembershipPauseParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -370,7 +415,7 @@ def resume( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/memberships/{id}/resume", + path_template("/memberships/{id}/resume", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -410,7 +455,7 @@ def uncancel( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/memberships/{id}/uncancel", + path_template("/memberships/{id}/uncancel", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -469,7 +514,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/memberships/{id}", + path_template("/memberships/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -512,7 +557,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/memberships/{id}", + path_template("/memberships/{id}", id=id), body=await async_maybe_transform({"metadata": metadata}, membership_update_params.MembershipUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -627,6 +672,53 @@ def list( model=MembershipListResponse, ) + async def add_free_days( + self, + id: str, + *, + free_days: int, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Membership: + """ + Add free days to extend a membership's current billing period, expiration date, + or Stripe trial. + + Required permissions: + + - `member:manage` + - `member:email:read` + - `member:basic:read` + + Args: + free_days: The number of free days to add (1-1095). Extends the billing period, expiration + date, or Stripe trial depending on plan type. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + path_template("/memberships/{id}/add_free_days", id=id), + body=await async_maybe_transform( + {"free_days": free_days}, membership_add_free_days_params.MembershipAddFreeDaysParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Membership, + ) + async def cancel( self, id: str, @@ -663,7 +755,7 @@ async def cancel( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/memberships/{id}/cancel", + path_template("/memberships/{id}/cancel", id=id), body=await async_maybe_transform( {"cancellation_mode": cancellation_mode}, membership_cancel_params.MembershipCancelParams ), @@ -711,7 +803,7 @@ async def pause( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/memberships/{id}/pause", + path_template("/memberships/{id}/pause", id=id), body=await async_maybe_transform( {"void_payments": void_payments}, membership_pause_params.MembershipPauseParams ), @@ -755,7 +847,7 @@ async def resume( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/memberships/{id}/resume", + path_template("/memberships/{id}/resume", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -795,7 +887,7 @@ async def uncancel( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/memberships/{id}/uncancel", + path_template("/memberships/{id}/uncancel", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/messages.py b/src/whop_sdk/resources/messages.py index 73316027..51e664a2 100644 --- a/src/whop_sdk/resources/messages.py +++ b/src/whop_sdk/resources/messages.py @@ -8,7 +8,7 @@ from ..types import message_list_params, message_create_params, message_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -145,7 +145,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/messages/{id}", + path_template("/messages/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -190,7 +190,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/messages/{id}", + path_template("/messages/{id}", id=id), body=maybe_transform( { "attachments": attachments, @@ -304,7 +304,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/messages/{id}", + path_template("/messages/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -430,7 +430,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/messages/{id}", + path_template("/messages/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -475,7 +475,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/messages/{id}", + path_template("/messages/{id}", id=id), body=await async_maybe_transform( { "attachments": attachments, @@ -589,7 +589,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/messages/{id}", + path_template("/messages/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/payment_methods.py b/src/whop_sdk/resources/payment_methods.py index 9e993655..6c759457 100644 --- a/src/whop_sdk/resources/payment_methods.py +++ b/src/whop_sdk/resources/payment_methods.py @@ -9,7 +9,7 @@ from ..types import payment_method_list_params, payment_method_retrieve_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -87,7 +87,7 @@ def retrieve( return cast( PaymentMethodRetrieveResponse, self._get( - f"/payment_methods/{id}", + path_template("/payment_methods/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -253,7 +253,7 @@ async def retrieve( return cast( PaymentMethodRetrieveResponse, await self._get( - f"/payment_methods/{id}", + path_template("/payment_methods/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/whop_sdk/resources/payments.py b/src/whop_sdk/resources/payments.py index d36041da..260f6e38 100644 --- a/src/whop_sdk/resources/payments.py +++ b/src/whop_sdk/resources/payments.py @@ -10,7 +10,7 @@ from ..types import payment_list_params, payment_create_params, payment_refund_params, payment_list_fees_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import required_args, maybe_transform, async_maybe_transform +from .._utils import path_template, required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -250,7 +250,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/payments/{id}", + path_template("/payments/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -420,7 +420,7 @@ def list_fees( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( - f"/payments/{id}/fees", + path_template("/payments/{id}/fees", id=id), page=SyncCursorPage[PaymentListFeesResponse], options=make_request_options( extra_headers=extra_headers, @@ -484,7 +484,7 @@ def refund( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/payments/{id}/refund", + path_template("/payments/{id}/refund", id=id), body=maybe_transform({"partial_amount": partial_amount}, payment_refund_params.PaymentRefundParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -532,7 +532,7 @@ def retry( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/payments/{id}/retry", + path_template("/payments/{id}/retry", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -579,7 +579,7 @@ def void( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( - f"/payments/{id}/void", + path_template("/payments/{id}/void", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -804,7 +804,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/payments/{id}", + path_template("/payments/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -974,7 +974,7 @@ def list_fees( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( - f"/payments/{id}/fees", + path_template("/payments/{id}/fees", id=id), page=AsyncCursorPage[PaymentListFeesResponse], options=make_request_options( extra_headers=extra_headers, @@ -1038,7 +1038,7 @@ async def refund( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/payments/{id}/refund", + path_template("/payments/{id}/refund", id=id), body=await async_maybe_transform( {"partial_amount": partial_amount}, payment_refund_params.PaymentRefundParams ), @@ -1088,7 +1088,7 @@ async def retry( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/payments/{id}/retry", + path_template("/payments/{id}/retry", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1135,7 +1135,7 @@ async def void( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( - f"/payments/{id}/void", + path_template("/payments/{id}/void", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/payout_accounts.py b/src/whop_sdk/resources/payout_accounts.py index c59b88b2..a6d57c30 100644 --- a/src/whop_sdk/resources/payout_accounts.py +++ b/src/whop_sdk/resources/payout_accounts.py @@ -5,6 +5,7 @@ import httpx from .._types import Body, Query, Headers, NotGiven, not_given +from .._utils import path_template from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -71,7 +72,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/payout_accounts/{id}", + path_template("/payout_accounts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -131,7 +132,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/payout_accounts/{id}", + path_template("/payout_accounts/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/payout_methods.py b/src/whop_sdk/resources/payout_methods.py index 0333f57e..c9fce4aa 100644 --- a/src/whop_sdk/resources/payout_methods.py +++ b/src/whop_sdk/resources/payout_methods.py @@ -8,7 +8,7 @@ from ..types import payout_method_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -75,7 +75,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/payout_methods/{id}", + path_template("/payout_methods/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -197,7 +197,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/payout_methods/{id}", + path_template("/payout_methods/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/plans.py b/src/whop_sdk/resources/plans.py index 413c3f89..542bf59a 100644 --- a/src/whop_sdk/resources/plans.py +++ b/src/whop_sdk/resources/plans.py @@ -10,7 +10,7 @@ from ..types import plan_list_params, plan_create_params, plan_update_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -225,7 +225,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/plans/{id}", + path_template("/plans/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -334,7 +334,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/plans/{id}", + path_template("/plans/{id}", id=id), body=maybe_transform( { "billing_period": billing_period, @@ -495,7 +495,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/plans/{id}", + path_template("/plans/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -693,7 +693,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/plans/{id}", + path_template("/plans/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -802,7 +802,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/plans/{id}", + path_template("/plans/{id}", id=id), body=await async_maybe_transform( { "billing_period": billing_period, @@ -963,7 +963,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/plans/{id}", + path_template("/plans/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/products.py b/src/whop_sdk/resources/products.py index 6909de05..0eac47eb 100644 --- a/src/whop_sdk/resources/products.py +++ b/src/whop_sdk/resources/products.py @@ -10,7 +10,7 @@ from ..types import product_list_params, product_create_params, product_update_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -208,7 +208,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/products/{id}", + path_template("/products/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -306,7 +306,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/products/{id}", + path_template("/products/{id}", id=id), body=maybe_transform( { "collect_shipping_address": collect_shipping_address, @@ -454,7 +454,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/products/{id}", + path_template("/products/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -636,7 +636,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/products/{id}", + path_template("/products/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -734,7 +734,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/products/{id}", + path_template("/products/{id}", id=id), body=await async_maybe_transform( { "collect_shipping_address": collect_shipping_address, @@ -882,7 +882,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/products/{id}", + path_template("/products/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/promo_codes.py b/src/whop_sdk/resources/promo_codes.py index 4d8deb2f..7d893047 100644 --- a/src/whop_sdk/resources/promo_codes.py +++ b/src/whop_sdk/resources/promo_codes.py @@ -9,7 +9,7 @@ from ..types import PromoCodeStatus, promo_code_list_params, promo_code_create_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -193,7 +193,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/promo_codes/{id}", + path_template("/promo_codes/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -316,7 +316,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/promo_codes/{id}", + path_template("/promo_codes/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -487,7 +487,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/promo_codes/{id}", + path_template("/promo_codes/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -610,7 +610,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/promo_codes/{id}", + path_template("/promo_codes/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/reactions.py b/src/whop_sdk/resources/reactions.py index 46882546..243ceafe 100644 --- a/src/whop_sdk/resources/reactions.py +++ b/src/whop_sdk/resources/reactions.py @@ -8,7 +8,7 @@ from ..types import reaction_list_params, reaction_create_params, reaction_delete_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -131,7 +131,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/reactions/{id}", + path_template("/reactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -239,7 +239,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/reactions/{id}", + path_template("/reactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -356,7 +356,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/reactions/{id}", + path_template("/reactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -464,7 +464,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/reactions/{id}", + path_template("/reactions/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/whop_sdk/resources/refunds.py b/src/whop_sdk/resources/refunds.py index ff24a705..d845816d 100644 --- a/src/whop_sdk/resources/refunds.py +++ b/src/whop_sdk/resources/refunds.py @@ -9,7 +9,7 @@ from ..types import refund_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -80,7 +80,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/refunds/{id}", + path_template("/refunds/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -225,7 +225,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/refunds/{id}", + path_template("/refunds/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/resolution_center_cases.py b/src/whop_sdk/resources/resolution_center_cases.py index 3563f157..90eb6a47 100644 --- a/src/whop_sdk/resources/resolution_center_cases.py +++ b/src/whop_sdk/resources/resolution_center_cases.py @@ -9,7 +9,7 @@ from ..types import resolution_center_case_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -80,7 +80,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/resolution_center_cases/{id}", + path_template("/resolution_center_cases/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -220,7 +220,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/resolution_center_cases/{id}", + path_template("/resolution_center_cases/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/reviews.py b/src/whop_sdk/resources/reviews.py index 3ce2c4d7..0ac1ea34 100644 --- a/src/whop_sdk/resources/reviews.py +++ b/src/whop_sdk/resources/reviews.py @@ -9,7 +9,7 @@ from ..types import review_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -72,7 +72,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/reviews/{id}", + path_template("/reviews/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -202,7 +202,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/reviews/{id}", + path_template("/reviews/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/setup_intents.py b/src/whop_sdk/resources/setup_intents.py index e85baf44..4c3b154b 100644 --- a/src/whop_sdk/resources/setup_intents.py +++ b/src/whop_sdk/resources/setup_intents.py @@ -9,7 +9,7 @@ from ..types import setup_intent_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -79,7 +79,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/setup_intents/{id}", + path_template("/setup_intents/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -218,7 +218,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/setup_intents/{id}", + path_template("/setup_intents/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/shipments.py b/src/whop_sdk/resources/shipments.py index 1b46c631..5a4eda54 100644 --- a/src/whop_sdk/resources/shipments.py +++ b/src/whop_sdk/resources/shipments.py @@ -8,7 +8,7 @@ from ..types import shipment_list_params, shipment_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -131,7 +131,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/shipments/{id}", + path_template("/shipments/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -318,7 +318,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/shipments/{id}", + path_template("/shipments/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/support_channels.py b/src/whop_sdk/resources/support_channels.py index 7b5146ae..7d919e49 100644 --- a/src/whop_sdk/resources/support_channels.py +++ b/src/whop_sdk/resources/support_channels.py @@ -9,7 +9,7 @@ from ..types import support_channel_list_params, support_channel_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -131,7 +131,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/support_channels/{id}", + path_template("/support_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -320,7 +320,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/support_channels/{id}", + path_template("/support_channels/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/transfers.py b/src/whop_sdk/resources/transfers.py index 6252141a..7ff65c6b 100644 --- a/src/whop_sdk/resources/transfers.py +++ b/src/whop_sdk/resources/transfers.py @@ -10,7 +10,7 @@ from ..types import transfer_list_params, transfer_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -152,7 +152,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/transfers/{id}", + path_template("/transfers/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -369,7 +369,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/transfers/{id}", + path_template("/transfers/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/users.py b/src/whop_sdk/resources/users.py index 70910724..6414c8e9 100644 --- a/src/whop_sdk/resources/users.py +++ b/src/whop_sdk/resources/users.py @@ -8,7 +8,7 @@ from ..types import user_list_params, user_update_profile_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -72,7 +72,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/users/{id}", + path_template("/users/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -169,7 +169,7 @@ def check_access( if not resource_id: raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}") return self._get( - f"/users/{id}/access/{resource_id}", + path_template("/users/{id}/access/{resource_id}", id=id, resource_id=resource_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -279,7 +279,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/users/{id}", + path_template("/users/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -376,7 +376,7 @@ async def check_access( if not resource_id: raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}") return await self._get( - f"/users/{id}/access/{resource_id}", + path_template("/users/{id}/access/{resource_id}", id=id, resource_id=resource_id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/verifications.py b/src/whop_sdk/resources/verifications.py index 54364d22..9ee917e2 100644 --- a/src/whop_sdk/resources/verifications.py +++ b/src/whop_sdk/resources/verifications.py @@ -8,7 +8,7 @@ from ..types import verification_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -75,7 +75,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/verifications/{id}", + path_template("/verifications/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -197,7 +197,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/verifications/{id}", + path_template("/verifications/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/webhooks.py b/src/whop_sdk/resources/webhooks.py index 340e6a65..30041448 100644 --- a/src/whop_sdk/resources/webhooks.py +++ b/src/whop_sdk/resources/webhooks.py @@ -9,7 +9,7 @@ from ..types import APIVersion, webhook_list_params, webhook_create_params, webhook_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._models import construct_type from .._resource import SyncAPIResource, AsyncAPIResource @@ -148,7 +148,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/webhooks/{id}", + path_template("/webhooks/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -200,7 +200,7 @@ def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._patch( - f"/webhooks/{id}", + path_template("/webhooks/{id}", id=id), body=maybe_transform( { "api_version": api_version, @@ -311,7 +311,7 @@ def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( - f"/webhooks/{id}", + path_template("/webhooks/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -460,7 +460,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/webhooks/{id}", + path_template("/webhooks/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -512,7 +512,7 @@ async def update( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._patch( - f"/webhooks/{id}", + path_template("/webhooks/{id}", id=id), body=await async_maybe_transform( { "api_version": api_version, @@ -623,7 +623,7 @@ async def delete( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( - f"/webhooks/{id}", + path_template("/webhooks/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/whop_sdk/resources/withdrawals.py b/src/whop_sdk/resources/withdrawals.py index 51b74257..5d76900a 100644 --- a/src/whop_sdk/resources/withdrawals.py +++ b/src/whop_sdk/resources/withdrawals.py @@ -9,7 +9,7 @@ from ..types import withdrawal_list_params, withdrawal_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -144,7 +144,7 @@ def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( - f"/withdrawals/{id}", + path_template("/withdrawals/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -344,7 +344,7 @@ async def retrieve( if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( - f"/withdrawals/{id}", + path_template("/withdrawals/{id}", id=id), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/tests/test_utils/test_path.py b/tests/test_utils/test_path.py new file mode 100644 index 00000000..bb4a49a0 --- /dev/null +++ b/tests/test_utils/test_path.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from typing import Any + +import pytest + +from whop_sdk._utils._path import path_template + + +@pytest.mark.parametrize( + "template, kwargs, expected", + [ + ("/v1/{id}", dict(id="abc"), "/v1/abc"), + ("/v1/{a}/{b}", dict(a="x", b="y"), "/v1/x/y"), + ("/v1/{a}{b}/path/{c}?val={d}#{e}", dict(a="x", b="y", c="z", d="u", e="v"), "/v1/xy/path/z?val=u#v"), + ("/{w}/{w}", dict(w="echo"), "/echo/echo"), + ("/v1/static", {}, "/v1/static"), + ("", {}, ""), + ("/v1/?q={n}&count=10", dict(n=42), "/v1/?q=42&count=10"), + ("/v1/{v}", dict(v=None), "/v1/null"), + ("/v1/{v}", dict(v=True), "/v1/true"), + ("/v1/{v}", dict(v=False), "/v1/false"), + ("/v1/{v}", dict(v=".hidden"), "/v1/.hidden"), # dot prefix ok + ("/v1/{v}", dict(v="file.txt"), "/v1/file.txt"), # dot in middle ok + ("/v1/{v}", dict(v="..."), "/v1/..."), # triple dot ok + ("/v1/{a}{b}", dict(a=".", b="txt"), "/v1/.txt"), # dot var combining with adjacent to be ok + ("/items?q={v}#{f}", dict(v=".", f=".."), "/items?q=.#.."), # dots in query/fragment are fine + ( + "/v1/{a}?query={b}", + dict(a="../../other/endpoint", b="a&bad=true"), + "/v1/..%2F..%2Fother%2Fendpoint?query=a%26bad%3Dtrue", + ), + ("/v1/{val}", dict(val="a/b/c"), "/v1/a%2Fb%2Fc"), + ("/v1/{val}", dict(val="a/b/c?query=value"), "/v1/a%2Fb%2Fc%3Fquery=value"), + ("/v1/{val}", dict(val="a/b/c?query=value&bad=true"), "/v1/a%2Fb%2Fc%3Fquery=value&bad=true"), + ("/v1/{val}", dict(val="%20"), "/v1/%2520"), # escapes escape sequences in input + # Query: slash and ? are safe, # is not + ("/items?q={v}", dict(v="a/b"), "/items?q=a/b"), + ("/items?q={v}", dict(v="a?b"), "/items?q=a?b"), + ("/items?q={v}", dict(v="a#b"), "/items?q=a%23b"), + ("/items?q={v}", dict(v="a b"), "/items?q=a%20b"), + # Fragment: slash and ? are safe + ("/docs#{v}", dict(v="a/b"), "/docs#a/b"), + ("/docs#{v}", dict(v="a?b"), "/docs#a?b"), + # Path: slash, ? and # are all encoded + ("/v1/{v}", dict(v="a/b"), "/v1/a%2Fb"), + ("/v1/{v}", dict(v="a?b"), "/v1/a%3Fb"), + ("/v1/{v}", dict(v="a#b"), "/v1/a%23b"), + # same var encoded differently by component + ( + "/v1/{v}?q={v}#{v}", + dict(v="a/b?c#d"), + "/v1/a%2Fb%3Fc%23d?q=a/b?c%23d#a/b?c%23d", + ), + ("/v1/{val}", dict(val="x?admin=true"), "/v1/x%3Fadmin=true"), # query injection + ("/v1/{val}", dict(val="x#admin"), "/v1/x%23admin"), # fragment injection + ], +) +def test_interpolation(template: str, kwargs: dict[str, Any], expected: str) -> None: + assert path_template(template, **kwargs) == expected + + +def test_missing_kwarg_raises_key_error() -> None: + with pytest.raises(KeyError, match="org_id"): + path_template("/v1/{org_id}") + + +@pytest.mark.parametrize( + "template, kwargs", + [ + ("{a}/path", dict(a=".")), + ("{a}/path", dict(a="..")), + ("/v1/{a}", dict(a=".")), + ("/v1/{a}", dict(a="..")), + ("/v1/{a}/path", dict(a=".")), + ("/v1/{a}/path", dict(a="..")), + ("/v1/{a}{b}", dict(a=".", b=".")), # adjacent vars → ".." + ("/v1/{a}.", dict(a=".")), # var + static → ".." + ("/v1/{a}{b}", dict(a="", b=".")), # empty + dot → "." + ("/v1/%2e/{x}", dict(x="ok")), # encoded dot in static text + ("/v1/%2e./{x}", dict(x="ok")), # mixed encoded ".." in static + ("/v1/.%2E/{x}", dict(x="ok")), # mixed encoded ".." in static + ("/v1/{v}?q=1", dict(v="..")), + ("/v1/{v}#frag", dict(v="..")), + ], +) +def test_dot_segment_rejected(template: str, kwargs: dict[str, Any]) -> None: + with pytest.raises(ValueError, match="dot-segment"): + path_template(template, **kwargs) From a391cfca3a11e21d4ac80518369b44f8f6f9ee2f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 15:13:37 +0000 Subject: [PATCH 03/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/company_list_response.py | 3 +++ src/whop_sdk/types/shared/company.py | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 95e665f7..0a792ebd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-e3735d7700813328ddb9c3da0127c03351e1e2102d6197b3a22f7a0627209488.yml -openapi_spec_hash: 6bd34ccbef8a342ba0f04737113b3529 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-e11bef0288245dae9a5f8118e178318824c2a2ba33fd9f7e49d2dee0c5c66b6b.yml +openapi_spec_hash: 780de21830cb6079c38c8a1e8e836b14 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/company_list_response.py b/src/whop_sdk/types/company_list_response.py index 197728d1..52d0916e 100644 --- a/src/whop_sdk/types/company_list_response.py +++ b/src/whop_sdk/types/company_list_response.py @@ -84,6 +84,9 @@ class CompanyListResponse(BaseModel): behalf of this company. """ + target_audience: Optional[str] = None + """The target audience for the company. Null if not set.""" + title: str """The display name of the company shown to customers.""" diff --git a/src/whop_sdk/types/shared/company.py b/src/whop_sdk/types/shared/company.py index 3a7b1c82..5155b677 100644 --- a/src/whop_sdk/types/shared/company.py +++ b/src/whop_sdk/types/shared/company.py @@ -129,6 +129,9 @@ class Company(BaseModel): company. """ + target_audience: Optional[str] = None + """The target audience for the company. Null if not set.""" + title: str """The display name of the company shown to customers.""" From e409b46665a918b487c9e10c25dd48819398f2bc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 12:38:44 +0000 Subject: [PATCH 04/39] chore(internal): update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 95ceb189..3824f4c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .prism.log +.stdy.log _dev __pycache__ From f4459b0d9fa3d7e4e01db71c29611d98099dfadf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 18:13:51 +0000 Subject: [PATCH 05/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/resources/apps.py | 18 +++++++++++++++++ src/whop_sdk/types/app_list_response.py | 20 +++++++++++++++++++ src/whop_sdk/types/app_update_params.py | 9 +++++++++ src/whop_sdk/types/shared/app.py | 20 +++++++++++++++++++ src/whop_sdk/types/shared/app_view_type.py | 2 +- .../types/shared_params/app_view_type.py | 2 +- tests/api_resources/test_apps.py | 4 ++++ 8 files changed, 75 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0a792ebd..e45843d7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-e11bef0288245dae9a5f8118e178318824c2a2ba33fd9f7e49d2dee0c5c66b6b.yml -openapi_spec_hash: 780de21830cb6079c38c8a1e8e836b14 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-47d955d6b9631b4ad43668426ff3867e9d7566926680ea2b4c4bd16869ccaff5.yml +openapi_spec_hash: d8f3bb32c233225f85b20b69318dada9 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/apps.py b/src/whop_sdk/resources/apps.py index 15b482da..c04a53dc 100644 --- a/src/whop_sdk/resources/apps.py +++ b/src/whop_sdk/resources/apps.py @@ -166,8 +166,10 @@ def update( icon: Optional[app_update_params.Icon] | Omit = omit, name: Optional[str] | Omit = omit, oauth_client_type: Optional[Literal["public", "confidential"]] | Omit = omit, + openapi_path: Optional[str] | Omit = omit, redirect_uris: Optional[SequenceNotStr[str]] | Omit = omit, required_scopes: Optional[List[Literal["read_user"]]] | Omit = omit, + skills_path: Optional[str] | Omit = omit, status: Optional[AppStatuses] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -208,11 +210,16 @@ def update( oauth_client_type: How this app authenticates at the OAuth token endpoint. + openapi_path: The URL path to the OpenAPI spec file of the app, such as + '/assets/openapi.json'. + redirect_uris: The whitelisted OAuth callback URLs that users are redirected to after authorizing the app required_scopes: The permission scopes the app will request from users when they install it. + skills_path: The URL path to the skills directory of the app, such as '/assets/skills/'. + status: The status of an experience interface extra_headers: Send extra headers @@ -239,8 +246,10 @@ def update( "icon": icon, "name": name, "oauth_client_type": oauth_client_type, + "openapi_path": openapi_path, "redirect_uris": redirect_uris, "required_scopes": required_scopes, + "skills_path": skills_path, "status": status, }, app_update_params.AppUpdateParams, @@ -489,8 +498,10 @@ async def update( icon: Optional[app_update_params.Icon] | Omit = omit, name: Optional[str] | Omit = omit, oauth_client_type: Optional[Literal["public", "confidential"]] | Omit = omit, + openapi_path: Optional[str] | Omit = omit, redirect_uris: Optional[SequenceNotStr[str]] | Omit = omit, required_scopes: Optional[List[Literal["read_user"]]] | Omit = omit, + skills_path: Optional[str] | Omit = omit, status: Optional[AppStatuses] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -531,11 +542,16 @@ async def update( oauth_client_type: How this app authenticates at the OAuth token endpoint. + openapi_path: The URL path to the OpenAPI spec file of the app, such as + '/assets/openapi.json'. + redirect_uris: The whitelisted OAuth callback URLs that users are redirected to after authorizing the app required_scopes: The permission scopes the app will request from users when they install it. + skills_path: The URL path to the skills directory of the app, such as '/assets/skills/'. + status: The status of an experience interface extra_headers: Send extra headers @@ -562,8 +578,10 @@ async def update( "icon": icon, "name": name, "oauth_client_type": oauth_client_type, + "openapi_path": openapi_path, "redirect_uris": redirect_uris, "required_scopes": required_scopes, + "skills_path": skills_path, "status": status, }, app_update_params.AppUpdateParams, diff --git a/src/whop_sdk/types/app_list_response.py b/src/whop_sdk/types/app_list_response.py index 53563e2e..8a0da2ed 100644 --- a/src/whop_sdk/types/app_list_response.py +++ b/src/whop_sdk/types/app_list_response.py @@ -117,6 +117,26 @@ class AppListResponse(BaseModel): Maximum 30 characters. """ + openapi_path: Optional[str] = None + """ + The URL path template for a specific view of this app, appended to the base + domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is + not configured. + """ + + origin: Optional[str] = None + """ + The full origin URL for this app's proxied domain (e.g., + 'https://myapp.apps.whop.com'). Null if no proxy domain is configured. + """ + + skills_path: Optional[str] = None + """ + The URL path template for a specific view of this app, appended to the base + domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is + not configured. + """ + status: AppStatuses """The current visibility status of this app on the Whop app store. diff --git a/src/whop_sdk/types/app_update_params.py b/src/whop_sdk/types/app_update_params.py index 2d5e48bc..8320361c 100644 --- a/src/whop_sdk/types/app_update_params.py +++ b/src/whop_sdk/types/app_update_params.py @@ -51,6 +51,12 @@ class AppUpdateParams(TypedDict, total=False): oauth_client_type: Optional[Literal["public", "confidential"]] """How this app authenticates at the OAuth token endpoint.""" + openapi_path: Optional[str] + """ + The URL path to the OpenAPI spec file of the app, such as + '/assets/openapi.json'. + """ + redirect_uris: Optional[SequenceNotStr[str]] """ The whitelisted OAuth callback URLs that users are redirected to after @@ -60,6 +66,9 @@ class AppUpdateParams(TypedDict, total=False): required_scopes: Optional[List[Literal["read_user"]]] """The permission scopes the app will request from users when they install it.""" + skills_path: Optional[str] + """The URL path to the skills directory of the app, such as '/assets/skills/'.""" + status: Optional[AppStatuses] """The status of an experience interface""" diff --git a/src/whop_sdk/types/shared/app.py b/src/whop_sdk/types/shared/app.py index ad75be71..90828995 100644 --- a/src/whop_sdk/types/shared/app.py +++ b/src/whop_sdk/types/shared/app.py @@ -205,6 +205,19 @@ class App(BaseModel): Maximum 30 characters. """ + openapi_path: Optional[str] = None + """ + The URL path template for a specific view of this app, appended to the base + domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is + not configured. + """ + + origin: Optional[str] = None + """ + The full origin URL for this app's proxied domain (e.g., + 'https://myapp.apps.whop.com'). Null if no proxy domain is configured. + """ + redirect_uris: List[str] """ The whitelisted OAuth callback URLs that users are redirected to after @@ -217,6 +230,13 @@ class App(BaseModel): required and optional permissions with justifications. """ + skills_path: Optional[str] = None + """ + The URL path template for a specific view of this app, appended to the base + domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is + not configured. + """ + stats: Optional[Stats] = None """ Aggregate usage statistics for this app, including daily, weekly, and monthly diff --git a/src/whop_sdk/types/shared/app_view_type.py b/src/whop_sdk/types/shared/app_view_type.py index 6665d5bc..05a00863 100644 --- a/src/whop_sdk/types/shared/app_view_type.py +++ b/src/whop_sdk/types/shared/app_view_type.py @@ -4,4 +4,4 @@ __all__ = ["AppViewType"] -AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics"] +AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics", "skills", "openapi"] diff --git a/src/whop_sdk/types/shared_params/app_view_type.py b/src/whop_sdk/types/shared_params/app_view_type.py index 65c818f1..2b604548 100644 --- a/src/whop_sdk/types/shared_params/app_view_type.py +++ b/src/whop_sdk/types/shared_params/app_view_type.py @@ -6,4 +6,4 @@ __all__ = ["AppViewType"] -AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics"] +AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics", "skills", "openapi"] diff --git a/tests/api_resources/test_apps.py b/tests/api_resources/test_apps.py index 1eb7bcef..042e705a 100644 --- a/tests/api_resources/test_apps.py +++ b/tests/api_resources/test_apps.py @@ -133,8 +133,10 @@ def test_method_update_with_all_params(self, client: Whop) -> None: icon={"id": "id"}, name="name", oauth_client_type="public", + openapi_path="openapi_path", redirect_uris=["string"], required_scopes=["read_user"], + skills_path="skills_path", status="live", ) assert_matches_type(App, app, path=["response"]) @@ -339,8 +341,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N icon={"id": "id"}, name="name", oauth_client_type="public", + openapi_path="openapi_path", redirect_uris=["string"], required_scopes=["read_user"], + skills_path="skills_path", status="live", ) assert_matches_type(App, app, path=["response"]) From 542823145fee2ead9f920efd00278464d8601513 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 15:15:28 +0000 Subject: [PATCH 06/39] chore(ci): skip lint on metadata-only changes Note that we still want to run tests, as these depend on the metadata. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7234cce3..ba9deff1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: timeout-minutes: 10 name: lint runs-on: ${{ github.repository == 'stainless-sdks/whopsdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@v6 @@ -38,7 +38,7 @@ jobs: run: ./scripts/lint build: - if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') timeout-minutes: 10 name: build permissions: From 7842b8a7510b3a1978b379f8b5340c0892e25c92 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:13:21 +0000 Subject: [PATCH 07/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e45843d7..751a7074 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-47d955d6b9631b4ad43668426ff3867e9d7566926680ea2b4c4bd16869ccaff5.yml -openapi_spec_hash: d8f3bb32c233225f85b20b69318dada9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-4c00a8772808faa48c54662ff78e53fc84e5f7e1646d450394de47d77949a27c.yml +openapi_spec_hash: 312b2bd51a834282e7b2ab7301c9a848 config_hash: 1a836d20bb988f001cc66d1526f71306 From bd3dd9e3b42426f2744f5b173e8a6b27c9ca58a6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 02:13:44 +0000 Subject: [PATCH 08/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 751a7074..b0960a01 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-4c00a8772808faa48c54662ff78e53fc84e5f7e1646d450394de47d77949a27c.yml -openapi_spec_hash: 312b2bd51a834282e7b2ab7301c9a848 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-ad7932b7b6d7b8330a96e38dffb2a855202293dd3fff6faedf02c9e462eaefd9.yml +openapi_spec_hash: a5992eb21f48bf525b074d907a9f1b56 config_hash: 1a836d20bb988f001cc66d1526f71306 From 8f4b022372bee1a75d74e83334431e030ee02496 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 03:13:37 +0000 Subject: [PATCH 09/39] feat(api): api update --- .stats.yml | 4 +- src/whop_sdk/resources/invoices.py | 88 +++ src/whop_sdk/types/invoice_create_params.py | 656 ++++++++++++++++++++ tests/api_resources/test_invoices.py | 104 ++++ 4 files changed, 850 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index b0960a01..c76da31d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-ad7932b7b6d7b8330a96e38dffb2a855202293dd3fff6faedf02c9e462eaefd9.yml -openapi_spec_hash: a5992eb21f48bf525b074d907a9f1b56 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-f8571888366aab87729cc4b87836dddb5b708a942e4ef591c163c65ee330a65a.yml +openapi_spec_hash: cb786e6f7f67a83344bf5144855215f1 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/invoices.py b/src/whop_sdk/resources/invoices.py index 9043ccbd..7d5bb7dd 100644 --- a/src/whop_sdk/resources/invoices.py +++ b/src/whop_sdk/resources/invoices.py @@ -62,8 +62,11 @@ def create( plan: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDPlan, product: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDProduct, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -104,11 +107,17 @@ def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -136,8 +145,11 @@ def create( plan: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressPlan, product: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -178,11 +190,17 @@ def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -210,8 +228,11 @@ def create( plan: invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDPlan, product_id: str, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -251,11 +272,17 @@ def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -283,8 +310,11 @@ def create( plan: invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressPlan, product_id: str, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -324,11 +354,17 @@ def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -366,8 +402,14 @@ def create( | invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct | Omit = omit, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress] + | Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress] + | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress] + | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, email_address: str | Omit = omit, @@ -390,8 +432,10 @@ def create( "plan": plan, "product": product, "automatically_finalizes_at": automatically_finalizes_at, + "billing_address": billing_address, "charge_buyer_fee": charge_buyer_fee, "customer_name": customer_name, + "mailing_address_id": mailing_address_id, "payment_method_id": payment_method_id, "payment_token_id": payment_token_id, "email_address": email_address, @@ -608,8 +652,11 @@ async def create( plan: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDPlan, product: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDProduct, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -650,11 +697,17 @@ async def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -682,8 +735,11 @@ async def create( plan: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressPlan, product: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -724,11 +780,17 @@ async def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -756,8 +818,11 @@ async def create( plan: invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDPlan, product_id: str, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -797,11 +862,17 @@ async def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -829,8 +900,11 @@ async def create( plan: invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressPlan, product_id: str, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -870,11 +944,17 @@ async def create( Only valid when collection_method is charge_automatically. If not provided, the charge will be processed immediately. + billing_address: Inline billing address to create a new mailing address for this invoice. Cannot + be used together with mailing_address_id. + charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice. customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. + Cannot be used together with billing_address. + payment_method_id: The unique identifier of the payment method to charge. Required when collection_method is charge_automatically. @@ -912,8 +992,14 @@ async def create( | invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct | Omit = omit, automatically_finalizes_at: Union[str, datetime, None] | Omit = omit, + billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress] + | Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress] + | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress] + | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress] + | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, email_address: str | Omit = omit, @@ -936,8 +1022,10 @@ async def create( "plan": plan, "product": product, "automatically_finalizes_at": automatically_finalizes_at, + "billing_address": billing_address, "charge_buyer_fee": charge_buyer_fee, "customer_name": customer_name, + "mailing_address_id": mailing_address_id, "payment_method_id": payment_method_id, "payment_token_id": payment_token_id, "email_address": email_address, diff --git a/src/whop_sdk/types/invoice_create_params.py b/src/whop_sdk/types/invoice_create_params.py index a3c6104b..0043a32c 100644 --- a/src/whop_sdk/types/invoice_create_params.py +++ b/src/whop_sdk/types/invoice_create_params.py @@ -18,16 +18,20 @@ "CreateInvoiceInputWithProductAndMemberIDPlan", "CreateInvoiceInputWithProductAndMemberIDPlanCustomField", "CreateInvoiceInputWithProductAndMemberIDProduct", + "CreateInvoiceInputWithProductAndMemberIDBillingAddress", "CreateInvoiceInputWithProductAndEmailAddress", "CreateInvoiceInputWithProductAndEmailAddressPlan", "CreateInvoiceInputWithProductAndEmailAddressPlanCustomField", "CreateInvoiceInputWithProductAndEmailAddressProduct", + "CreateInvoiceInputWithProductAndEmailAddressBillingAddress", "CreateInvoiceInputWithProductIDAndMemberID", "CreateInvoiceInputWithProductIDAndMemberIDPlan", "CreateInvoiceInputWithProductIDAndMemberIDPlanCustomField", "CreateInvoiceInputWithProductIDAndEmailAddress", "CreateInvoiceInputWithProductIDAndEmailAddressPlan", "CreateInvoiceInputWithProductIDAndEmailAddressPlanCustomField", + "CreateInvoiceInputWithProductIDAndMemberIDBillingAddress", + "CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress", ] @@ -70,6 +74,12 @@ class CreateInvoiceInputWithProductAndMemberID(TypedDict, total=False): charge will be processed immediately. """ + billing_address: Optional[CreateInvoiceInputWithProductAndMemberIDBillingAddress] + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + charge_buyer_fee: Optional[bool] """Whether to charge the customer a buyer fee on this invoice.""" @@ -80,6 +90,12 @@ class CreateInvoiceInputWithProductAndMemberID(TypedDict, total=False): company. """ + mailing_address_id: Optional[str] + """The unique identifier of an existing mailing address to attach to this invoice. + + Cannot be used together with billing_address. + """ + payment_method_id: Optional[str] """The unique identifier of the payment method to charge. @@ -186,6 +202,157 @@ class CreateInvoiceInputWithProductAndMemberIDProduct(TypedDict, total=False): """The ID of the product tax code to apply to this product.""" +class CreateInvoiceInputWithProductAndMemberIDBillingAddress(TypedDict, total=False): + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + + city: Optional[str] + """The city of the address.""" + + country: Optional[str] + """The country of the address.""" + + line1: Optional[str] + """The line 1 of the address.""" + + line2: Optional[str] + """The line 2 of the address.""" + + name: Optional[str] + """The name of the customer.""" + + phone: Optional[str] + """The phone number of the customer.""" + + postal_code: Optional[str] + """The postal code of the address.""" + + state: Optional[str] + """The state of the address.""" + + tax_id_type: Optional[ + Literal[ + "ad_nrt", + "ao_tin", + "ar_cuit", + "am_tin", + "aw_tin", + "au_abn", + "au_arn", + "eu_vat", + "az_tin", + "bs_tin", + "bh_vat", + "bd_bin", + "bb_tin", + "by_tin", + "bj_ifu", + "bo_tin", + "ba_tin", + "br_cnpj", + "br_cpf", + "bg_uic", + "bf_ifu", + "kh_tin", + "cm_niu", + "ca_bn", + "ca_gst_hst", + "ca_pst_bc", + "ca_pst_mb", + "ca_pst_sk", + "ca_qst", + "cv_nif", + "cl_tin", + "cn_tin", + "co_nit", + "cd_nif", + "cr_tin", + "hr_oib", + "do_rcn", + "ec_ruc", + "eg_tin", + "sv_nit", + "et_tin", + "eu_oss_vat", + "ge_vat", + "de_stn", + "gb_vat", + "gn_nif", + "hk_br", + "hu_tin", + "is_vat", + "in_gst", + "id_npwp", + "il_vat", + "jp_cn", + "jp_rn", + "jp_trn", + "kz_bin", + "ke_pin", + "kg_tin", + "la_tin", + "li_uid", + "li_vat", + "my_frp", + "my_itn", + "my_sst", + "mr_nif", + "mx_rfc", + "md_vat", + "me_pib", + "ma_vat", + "np_pan", + "nz_gst", + "ng_tin", + "mk_vat", + "no_vat", + "no_voec", + "om_vat", + "pe_ruc", + "ph_tin", + "pl_nip", + "ro_tin", + "ru_inn", + "ru_kpp", + "sa_vat", + "sn_ninea", + "rs_pib", + "sg_gst", + "sg_uen", + "si_tin", + "za_vat", + "kr_brn", + "es_cif", + "ch_uid", + "ch_vat", + "tw_vat", + "tj_tin", + "tz_vat", + "th_vat", + "tr_tin", + "ug_tin", + "ua_vat", + "ae_trn", + "us_ein", + "uy_ruc", + "uz_tin", + "uz_vat", + "ve_rif", + "vn_tin", + "zm_tin", + "zw_tin", + "sr_fin", + "xi_vat", + ] + ] + """The type of tax identifier""" + + tax_id_value: Optional[str] + """The value of the tax identifier.""" + + class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False): collection_method: Required[CollectionMethod] """How the invoice should be collected. @@ -226,6 +393,12 @@ class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False): charge will be processed immediately. """ + billing_address: Optional[CreateInvoiceInputWithProductAndEmailAddressBillingAddress] + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + charge_buyer_fee: Optional[bool] """Whether to charge the customer a buyer fee on this invoice.""" @@ -236,6 +409,12 @@ class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False): company. """ + mailing_address_id: Optional[str] + """The unique identifier of an existing mailing address to attach to this invoice. + + Cannot be used together with billing_address. + """ + payment_method_id: Optional[str] """The unique identifier of the payment method to charge. @@ -342,6 +521,157 @@ class CreateInvoiceInputWithProductAndEmailAddressProduct(TypedDict, total=False """The ID of the product tax code to apply to this product.""" +class CreateInvoiceInputWithProductAndEmailAddressBillingAddress(TypedDict, total=False): + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + + city: Optional[str] + """The city of the address.""" + + country: Optional[str] + """The country of the address.""" + + line1: Optional[str] + """The line 1 of the address.""" + + line2: Optional[str] + """The line 2 of the address.""" + + name: Optional[str] + """The name of the customer.""" + + phone: Optional[str] + """The phone number of the customer.""" + + postal_code: Optional[str] + """The postal code of the address.""" + + state: Optional[str] + """The state of the address.""" + + tax_id_type: Optional[ + Literal[ + "ad_nrt", + "ao_tin", + "ar_cuit", + "am_tin", + "aw_tin", + "au_abn", + "au_arn", + "eu_vat", + "az_tin", + "bs_tin", + "bh_vat", + "bd_bin", + "bb_tin", + "by_tin", + "bj_ifu", + "bo_tin", + "ba_tin", + "br_cnpj", + "br_cpf", + "bg_uic", + "bf_ifu", + "kh_tin", + "cm_niu", + "ca_bn", + "ca_gst_hst", + "ca_pst_bc", + "ca_pst_mb", + "ca_pst_sk", + "ca_qst", + "cv_nif", + "cl_tin", + "cn_tin", + "co_nit", + "cd_nif", + "cr_tin", + "hr_oib", + "do_rcn", + "ec_ruc", + "eg_tin", + "sv_nit", + "et_tin", + "eu_oss_vat", + "ge_vat", + "de_stn", + "gb_vat", + "gn_nif", + "hk_br", + "hu_tin", + "is_vat", + "in_gst", + "id_npwp", + "il_vat", + "jp_cn", + "jp_rn", + "jp_trn", + "kz_bin", + "ke_pin", + "kg_tin", + "la_tin", + "li_uid", + "li_vat", + "my_frp", + "my_itn", + "my_sst", + "mr_nif", + "mx_rfc", + "md_vat", + "me_pib", + "ma_vat", + "np_pan", + "nz_gst", + "ng_tin", + "mk_vat", + "no_vat", + "no_voec", + "om_vat", + "pe_ruc", + "ph_tin", + "pl_nip", + "ro_tin", + "ru_inn", + "ru_kpp", + "sa_vat", + "sn_ninea", + "rs_pib", + "sg_gst", + "sg_uen", + "si_tin", + "za_vat", + "kr_brn", + "es_cif", + "ch_uid", + "ch_vat", + "tw_vat", + "tj_tin", + "tz_vat", + "th_vat", + "tr_tin", + "ug_tin", + "ua_vat", + "ae_trn", + "us_ein", + "uy_ruc", + "uz_tin", + "uz_vat", + "ve_rif", + "vn_tin", + "zm_tin", + "zw_tin", + "sr_fin", + "xi_vat", + ] + ] + """The type of tax identifier""" + + tax_id_value: Optional[str] + """The value of the tax identifier.""" + + class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False): collection_method: Required[CollectionMethod] """How the invoice should be collected. @@ -378,6 +708,12 @@ class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False): charge will be processed immediately. """ + billing_address: Optional[CreateInvoiceInputWithProductIDAndMemberIDBillingAddress] + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + charge_buyer_fee: Optional[bool] """Whether to charge the customer a buyer fee on this invoice.""" @@ -388,6 +724,12 @@ class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False): company. """ + mailing_address_id: Optional[str] + """The unique identifier of an existing mailing address to attach to this invoice. + + Cannot be used together with billing_address. + """ + payment_method_id: Optional[str] """The unique identifier of the payment method to charge. @@ -481,6 +823,157 @@ class CreateInvoiceInputWithProductIDAndMemberIDPlan(TypedDict, total=False): """Visibility of a resource""" +class CreateInvoiceInputWithProductIDAndMemberIDBillingAddress(TypedDict, total=False): + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + + city: Optional[str] + """The city of the address.""" + + country: Optional[str] + """The country of the address.""" + + line1: Optional[str] + """The line 1 of the address.""" + + line2: Optional[str] + """The line 2 of the address.""" + + name: Optional[str] + """The name of the customer.""" + + phone: Optional[str] + """The phone number of the customer.""" + + postal_code: Optional[str] + """The postal code of the address.""" + + state: Optional[str] + """The state of the address.""" + + tax_id_type: Optional[ + Literal[ + "ad_nrt", + "ao_tin", + "ar_cuit", + "am_tin", + "aw_tin", + "au_abn", + "au_arn", + "eu_vat", + "az_tin", + "bs_tin", + "bh_vat", + "bd_bin", + "bb_tin", + "by_tin", + "bj_ifu", + "bo_tin", + "ba_tin", + "br_cnpj", + "br_cpf", + "bg_uic", + "bf_ifu", + "kh_tin", + "cm_niu", + "ca_bn", + "ca_gst_hst", + "ca_pst_bc", + "ca_pst_mb", + "ca_pst_sk", + "ca_qst", + "cv_nif", + "cl_tin", + "cn_tin", + "co_nit", + "cd_nif", + "cr_tin", + "hr_oib", + "do_rcn", + "ec_ruc", + "eg_tin", + "sv_nit", + "et_tin", + "eu_oss_vat", + "ge_vat", + "de_stn", + "gb_vat", + "gn_nif", + "hk_br", + "hu_tin", + "is_vat", + "in_gst", + "id_npwp", + "il_vat", + "jp_cn", + "jp_rn", + "jp_trn", + "kz_bin", + "ke_pin", + "kg_tin", + "la_tin", + "li_uid", + "li_vat", + "my_frp", + "my_itn", + "my_sst", + "mr_nif", + "mx_rfc", + "md_vat", + "me_pib", + "ma_vat", + "np_pan", + "nz_gst", + "ng_tin", + "mk_vat", + "no_vat", + "no_voec", + "om_vat", + "pe_ruc", + "ph_tin", + "pl_nip", + "ro_tin", + "ru_inn", + "ru_kpp", + "sa_vat", + "sn_ninea", + "rs_pib", + "sg_gst", + "sg_uen", + "si_tin", + "za_vat", + "kr_brn", + "es_cif", + "ch_uid", + "ch_vat", + "tw_vat", + "tj_tin", + "tz_vat", + "th_vat", + "tr_tin", + "ug_tin", + "ua_vat", + "ae_trn", + "us_ein", + "uy_ruc", + "uz_tin", + "uz_vat", + "ve_rif", + "vn_tin", + "zm_tin", + "zw_tin", + "sr_fin", + "xi_vat", + ] + ] + """The type of tax identifier""" + + tax_id_value: Optional[str] + """The value of the tax identifier.""" + + class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False): collection_method: Required[CollectionMethod] """How the invoice should be collected. @@ -518,6 +1011,12 @@ class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False): charge will be processed immediately. """ + billing_address: Optional[CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress] + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + charge_buyer_fee: Optional[bool] """Whether to charge the customer a buyer fee on this invoice.""" @@ -528,6 +1027,12 @@ class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False): company. """ + mailing_address_id: Optional[str] + """The unique identifier of an existing mailing address to attach to this invoice. + + Cannot be used together with billing_address. + """ + payment_method_id: Optional[str] """The unique identifier of the payment method to charge. @@ -621,6 +1126,157 @@ class CreateInvoiceInputWithProductIDAndEmailAddressPlan(TypedDict, total=False) """Visibility of a resource""" +class CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress(TypedDict, total=False): + """Inline billing address to create a new mailing address for this invoice. + + Cannot be used together with mailing_address_id. + """ + + city: Optional[str] + """The city of the address.""" + + country: Optional[str] + """The country of the address.""" + + line1: Optional[str] + """The line 1 of the address.""" + + line2: Optional[str] + """The line 2 of the address.""" + + name: Optional[str] + """The name of the customer.""" + + phone: Optional[str] + """The phone number of the customer.""" + + postal_code: Optional[str] + """The postal code of the address.""" + + state: Optional[str] + """The state of the address.""" + + tax_id_type: Optional[ + Literal[ + "ad_nrt", + "ao_tin", + "ar_cuit", + "am_tin", + "aw_tin", + "au_abn", + "au_arn", + "eu_vat", + "az_tin", + "bs_tin", + "bh_vat", + "bd_bin", + "bb_tin", + "by_tin", + "bj_ifu", + "bo_tin", + "ba_tin", + "br_cnpj", + "br_cpf", + "bg_uic", + "bf_ifu", + "kh_tin", + "cm_niu", + "ca_bn", + "ca_gst_hst", + "ca_pst_bc", + "ca_pst_mb", + "ca_pst_sk", + "ca_qst", + "cv_nif", + "cl_tin", + "cn_tin", + "co_nit", + "cd_nif", + "cr_tin", + "hr_oib", + "do_rcn", + "ec_ruc", + "eg_tin", + "sv_nit", + "et_tin", + "eu_oss_vat", + "ge_vat", + "de_stn", + "gb_vat", + "gn_nif", + "hk_br", + "hu_tin", + "is_vat", + "in_gst", + "id_npwp", + "il_vat", + "jp_cn", + "jp_rn", + "jp_trn", + "kz_bin", + "ke_pin", + "kg_tin", + "la_tin", + "li_uid", + "li_vat", + "my_frp", + "my_itn", + "my_sst", + "mr_nif", + "mx_rfc", + "md_vat", + "me_pib", + "ma_vat", + "np_pan", + "nz_gst", + "ng_tin", + "mk_vat", + "no_vat", + "no_voec", + "om_vat", + "pe_ruc", + "ph_tin", + "pl_nip", + "ro_tin", + "ru_inn", + "ru_kpp", + "sa_vat", + "sn_ninea", + "rs_pib", + "sg_gst", + "sg_uen", + "si_tin", + "za_vat", + "kr_brn", + "es_cif", + "ch_uid", + "ch_vat", + "tw_vat", + "tj_tin", + "tz_vat", + "th_vat", + "tr_tin", + "ug_tin", + "ua_vat", + "ae_trn", + "us_ein", + "uy_ruc", + "uz_tin", + "uz_vat", + "ve_rif", + "vn_tin", + "zm_tin", + "zw_tin", + "sr_fin", + "xi_vat", + ] + ] + """The type of tax identifier""" + + tax_id_value: Optional[str] + """The value of the tax identifier.""" + + InvoiceCreateParams: TypeAlias = Union[ CreateInvoiceInputWithProductAndMemberID, CreateInvoiceInputWithProductAndEmailAddress, diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py index 7db7c125..6d7664ab 100644 --- a/tests/api_resources/test_invoices.py +++ b/tests/api_resources/test_invoices.py @@ -70,8 +70,21 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: "product_tax_code_id": "ptc_xxxxxxxxxxxxxx", }, automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -163,8 +176,21 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None: "product_tax_code_id": "ptc_xxxxxxxxxxxxxx", }, automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -253,8 +279,21 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None: }, product_id="prod_xxxxxxxxxxxxx", automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -343,8 +382,21 @@ def test_method_create_with_all_params_overload_4(self, client: Whop) -> None: }, product_id="prod_xxxxxxxxxxxxx", automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -579,8 +631,21 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "product_tax_code_id": "ptc_xxxxxxxxxxxxxx", }, automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -672,8 +737,21 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn "product_tax_code_id": "ptc_xxxxxxxxxxxxxx", }, automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -762,8 +840,21 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn }, product_id="prod_xxxxxxxxxxxxx", automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) @@ -852,8 +943,21 @@ async def test_method_create_with_all_params_overload_4(self, async_client: Asyn }, product_id="prod_xxxxxxxxxxxxx", automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"), + billing_address={ + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "phone": "phone", + "postal_code": "postal_code", + "state": "state", + "tax_id_type": "ad_nrt", + "tax_id_value": "tax_id_value", + }, charge_buyer_fee=True, customer_name="customer_name", + mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", ) From a594def1b1dbf18faf42b883e609dccc4be06396 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 04:13:21 +0000 Subject: [PATCH 10/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index c76da31d..f40d67ae 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-f8571888366aab87729cc4b87836dddb5b708a942e4ef591c163c65ee330a65a.yml -openapi_spec_hash: cb786e6f7f67a83344bf5144855215f1 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-90533b739b8bd28e49a7affcedf2f2996d5d0830ba744d677ba28363a3bd7eea.yml +openapi_spec_hash: ae49412196645e41f47aa5dafd3dda65 config_hash: 1a836d20bb988f001cc66d1526f71306 From f756c561dd961167c44b09ac61ef8ac5eb068b06 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:13:42 +0000 Subject: [PATCH 11/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f40d67ae..ea23bf59 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-90533b739b8bd28e49a7affcedf2f2996d5d0830ba744d677ba28363a3bd7eea.yml -openapi_spec_hash: ae49412196645e41f47aa5dafd3dda65 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-a11957927fafae5a22f4742b1a8d2024cf2861e726c1d835f4a09b9b4c05b599.yml +openapi_spec_hash: d98f6f8f787b9c25925c1b998887cefa config_hash: 1a836d20bb988f001cc66d1526f71306 From a34e3b1e7dd2229d3bcf84f8e23e75035d9d26cc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:13:23 +0000 Subject: [PATCH 12/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ea23bf59..5f334cee 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-a11957927fafae5a22f4742b1a8d2024cf2861e726c1d835f4a09b9b4c05b599.yml -openapi_spec_hash: d98f6f8f787b9c25925c1b998887cefa +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-ef13f2df2bc4eaac11572a8567197410d4614ee355d53aaf17d764c3f376a2fd.yml +openapi_spec_hash: 0c43fb747ff3d940a3838d22bd3bb7b4 config_hash: 1a836d20bb988f001cc66d1526f71306 From a6443ea4697c674dc80a9877fd9c531a6b688d73 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 20:07:56 +0000 Subject: [PATCH 13/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/payment_provider.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5f334cee..42e773c2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-ef13f2df2bc4eaac11572a8567197410d4614ee355d53aaf17d764c3f376a2fd.yml -openapi_spec_hash: 0c43fb747ff3d940a3838d22bd3bb7b4 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-17ef842b3ad41e6fdaab973459c40519473cf0bfe76960455ccea2646fa49aef.yml +openapi_spec_hash: 1585d8c9ef1aa0431bfd34aae7564d87 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/payment_provider.py b/src/whop_sdk/types/payment_provider.py index c2ba590b..6d8567f3 100644 --- a/src/whop_sdk/types/payment_provider.py +++ b/src/whop_sdk/types/payment_provider.py @@ -17,4 +17,6 @@ "claritypay", "checkout_dot_com", "airwallex", + "coinflow", + "sequra", ] From d2130a37999232e79546bab050193f6d1ed16af4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 08:13:42 +0000 Subject: [PATCH 14/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 42e773c2..389e8aac 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-17ef842b3ad41e6fdaab973459c40519473cf0bfe76960455ccea2646fa49aef.yml -openapi_spec_hash: 1585d8c9ef1aa0431bfd34aae7564d87 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-27d92f6053fa8cf8d9cdc905f4f4f559f712c5ce60d678a0c84f5f52b42e5463.yml +openapi_spec_hash: b4d9251e49b7944706c64d127622e266 config_hash: 1a836d20bb988f001cc66d1526f71306 From e8bc1d6948d253c722be8ea0802e8187165f4a0d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 19:24:33 +0000 Subject: [PATCH 15/39] feat(internal): implement indices array format for query and form serialization --- src/whop_sdk/_qs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/whop_sdk/_qs.py b/src/whop_sdk/_qs.py index ada6fd3f..de8c99bc 100644 --- a/src/whop_sdk/_qs.py +++ b/src/whop_sdk/_qs.py @@ -101,7 +101,10 @@ def _stringify_item( items.extend(self._stringify_item(key, item, opts)) return items elif array_format == "indices": - raise NotImplementedError("The array indices format is not supported yet") + items = [] + for i, item in enumerate(value): + items.extend(self._stringify_item(f"{key}[{i}]", item, opts)) + return items elif array_format == "brackets": items = [] key = key + "[]" From 349533cc0cdb665e00d6ca104292b8cf9ae4d0d0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 22:13:20 +0000 Subject: [PATCH 16/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/shared/payment.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 389e8aac..10eafe3b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-27d92f6053fa8cf8d9cdc905f4f4f559f712c5ce60d678a0c84f5f52b42e5463.yml -openapi_spec_hash: b4d9251e49b7944706c64d127622e266 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-35d4ccff6c50cd9b1af902884cdc0445f533836bf0775e278d0b8d5cc826e2a5.yml +openapi_spec_hash: c304b4e47ee6f9801083496e6e55c3a7 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/shared/payment.py b/src/whop_sdk/types/shared/payment.py index 009f0356..c704b553 100644 --- a/src/whop_sdk/types/shared/payment.py +++ b/src/whop_sdk/types/shared/payment.py @@ -163,7 +163,7 @@ class FinancingTransaction(BaseModel): "authorize", "capture", "refund", - "cancel", + "canceled", "verify", "chargeback", "pre_chargeback", From cea4dc2006ad8a1819e93fa2632edc511ab9731c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 02:13:33 +0000 Subject: [PATCH 17/39] feat(api): api update --- .stats.yml | 4 +- src/whop_sdk/resources/invoices.py | 48 ++++++++- src/whop_sdk/types/invoice_create_params.py | 104 ++++++++++++++++++++ tests/api_resources/test_invoices.py | 56 +++++++++++ 4 files changed, 209 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 10eafe3b..abc0d95e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-35d4ccff6c50cd9b1af902884cdc0445f533836bf0775e278d0b8d5cc826e2a5.yml -openapi_spec_hash: c304b4e47ee6f9801083496e6e55c3a7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-451a41faec4cfbe09e270b7b6a43779d1a5cbf325bac29efb7bd6713b57f9055.yml +openapi_spec_hash: 6d9c17ed9be2ec875739dfb717211f6a config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/invoices.py b/src/whop_sdk/resources/invoices.py index 7d5bb7dd..eccc33a3 100644 --- a/src/whop_sdk/resources/invoices.py +++ b/src/whop_sdk/resources/invoices.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Union, Optional +from typing import List, Union, Iterable, Optional from datetime import datetime from typing_extensions import Literal, overload @@ -66,6 +66,8 @@ def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -115,6 +117,9 @@ def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -149,6 +154,8 @@ def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -198,6 +205,9 @@ def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -232,6 +242,8 @@ def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -280,6 +292,9 @@ def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -314,6 +329,8 @@ def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -362,6 +379,9 @@ def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -409,6 +429,8 @@ def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -435,6 +457,7 @@ def create( "billing_address": billing_address, "charge_buyer_fee": charge_buyer_fee, "customer_name": customer_name, + "line_items": line_items, "mailing_address_id": mailing_address_id, "payment_method_id": payment_method_id, "payment_token_id": payment_token_id, @@ -656,6 +679,8 @@ async def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -705,6 +730,9 @@ async def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -739,6 +767,8 @@ async def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -788,6 +818,9 @@ async def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -822,6 +855,8 @@ async def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -870,6 +905,9 @@ async def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -904,6 +942,8 @@ async def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -952,6 +992,9 @@ async def create( customer_name: The name of the customer. Required when creating an invoice for a customer who is not yet a member of the company. + line_items: Optional line items that break down the invoice total. When provided, the sum of + (quantity \\** unit_price) for all items must equal the plan price. + mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice. Cannot be used together with billing_address. @@ -999,6 +1042,8 @@ async def create( | Omit = omit, charge_buyer_fee: Optional[bool] | Omit = omit, customer_name: Optional[str] | Omit = omit, + line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]] + | Omit = omit, mailing_address_id: Optional[str] | Omit = omit, payment_method_id: Optional[str] | Omit = omit, payment_token_id: Optional[str] | Omit = omit, @@ -1025,6 +1070,7 @@ async def create( "billing_address": billing_address, "charge_buyer_fee": charge_buyer_fee, "customer_name": customer_name, + "line_items": line_items, "mailing_address_id": mailing_address_id, "payment_method_id": payment_method_id, "payment_token_id": payment_token_id, diff --git a/src/whop_sdk/types/invoice_create_params.py b/src/whop_sdk/types/invoice_create_params.py index 0043a32c..637f4ce8 100644 --- a/src/whop_sdk/types/invoice_create_params.py +++ b/src/whop_sdk/types/invoice_create_params.py @@ -19,19 +19,23 @@ "CreateInvoiceInputWithProductAndMemberIDPlanCustomField", "CreateInvoiceInputWithProductAndMemberIDProduct", "CreateInvoiceInputWithProductAndMemberIDBillingAddress", + "CreateInvoiceInputWithProductAndMemberIDLineItem", "CreateInvoiceInputWithProductAndEmailAddress", "CreateInvoiceInputWithProductAndEmailAddressPlan", "CreateInvoiceInputWithProductAndEmailAddressPlanCustomField", "CreateInvoiceInputWithProductAndEmailAddressProduct", "CreateInvoiceInputWithProductAndEmailAddressBillingAddress", + "CreateInvoiceInputWithProductAndEmailAddressLineItem", "CreateInvoiceInputWithProductIDAndMemberID", "CreateInvoiceInputWithProductIDAndMemberIDPlan", "CreateInvoiceInputWithProductIDAndMemberIDPlanCustomField", + "CreateInvoiceInputWithProductIDAndMemberIDLineItem", "CreateInvoiceInputWithProductIDAndEmailAddress", "CreateInvoiceInputWithProductIDAndEmailAddressPlan", "CreateInvoiceInputWithProductIDAndEmailAddressPlanCustomField", "CreateInvoiceInputWithProductIDAndMemberIDBillingAddress", "CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress", + "CreateInvoiceInputWithProductIDAndEmailAddressLineItem", ] @@ -90,6 +94,13 @@ class CreateInvoiceInputWithProductAndMemberID(TypedDict, total=False): company. """ + line_items: Optional[Iterable[CreateInvoiceInputWithProductAndMemberIDLineItem]] + """Optional line items that break down the invoice total. + + When provided, the sum of (quantity \\** unit_price) for all items must equal the + plan price. + """ + mailing_address_id: Optional[str] """The unique identifier of an existing mailing address to attach to this invoice. @@ -353,6 +364,24 @@ class CreateInvoiceInputWithProductAndMemberIDBillingAddress(TypedDict, total=Fa """The value of the tax identifier.""" +class CreateInvoiceInputWithProductAndMemberIDLineItem(TypedDict, total=False): + """ + A single line item to include on the invoice, with a label, quantity, and unit price. + """ + + label: Required[str] + """The label or description for this line item.""" + + unit_price: Required[float] + """The unit price for this line item. + + Provided as a number in the specified currency. Eg: 10.43 for $10.43 + """ + + quantity: Optional[float] + """The quantity of this line item. Defaults to 1.""" + + class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False): collection_method: Required[CollectionMethod] """How the invoice should be collected. @@ -409,6 +438,13 @@ class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False): company. """ + line_items: Optional[Iterable[CreateInvoiceInputWithProductAndEmailAddressLineItem]] + """Optional line items that break down the invoice total. + + When provided, the sum of (quantity \\** unit_price) for all items must equal the + plan price. + """ + mailing_address_id: Optional[str] """The unique identifier of an existing mailing address to attach to this invoice. @@ -672,6 +708,24 @@ class CreateInvoiceInputWithProductAndEmailAddressBillingAddress(TypedDict, tota """The value of the tax identifier.""" +class CreateInvoiceInputWithProductAndEmailAddressLineItem(TypedDict, total=False): + """ + A single line item to include on the invoice, with a label, quantity, and unit price. + """ + + label: Required[str] + """The label or description for this line item.""" + + unit_price: Required[float] + """The unit price for this line item. + + Provided as a number in the specified currency. Eg: 10.43 for $10.43 + """ + + quantity: Optional[float] + """The quantity of this line item. Defaults to 1.""" + + class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False): collection_method: Required[CollectionMethod] """How the invoice should be collected. @@ -724,6 +778,13 @@ class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False): company. """ + line_items: Optional[Iterable[CreateInvoiceInputWithProductIDAndMemberIDLineItem]] + """Optional line items that break down the invoice total. + + When provided, the sum of (quantity \\** unit_price) for all items must equal the + plan price. + """ + mailing_address_id: Optional[str] """The unique identifier of an existing mailing address to attach to this invoice. @@ -974,6 +1035,24 @@ class CreateInvoiceInputWithProductIDAndMemberIDBillingAddress(TypedDict, total= """The value of the tax identifier.""" +class CreateInvoiceInputWithProductIDAndMemberIDLineItem(TypedDict, total=False): + """ + A single line item to include on the invoice, with a label, quantity, and unit price. + """ + + label: Required[str] + """The label or description for this line item.""" + + unit_price: Required[float] + """The unit price for this line item. + + Provided as a number in the specified currency. Eg: 10.43 for $10.43 + """ + + quantity: Optional[float] + """The quantity of this line item. Defaults to 1.""" + + class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False): collection_method: Required[CollectionMethod] """How the invoice should be collected. @@ -1027,6 +1106,13 @@ class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False): company. """ + line_items: Optional[Iterable[CreateInvoiceInputWithProductIDAndEmailAddressLineItem]] + """Optional line items that break down the invoice total. + + When provided, the sum of (quantity \\** unit_price) for all items must equal the + plan price. + """ + mailing_address_id: Optional[str] """The unique identifier of an existing mailing address to attach to this invoice. @@ -1277,6 +1363,24 @@ class CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress(TypedDict, to """The value of the tax identifier.""" +class CreateInvoiceInputWithProductIDAndEmailAddressLineItem(TypedDict, total=False): + """ + A single line item to include on the invoice, with a label, quantity, and unit price. + """ + + label: Required[str] + """The label or description for this line item.""" + + unit_price: Required[float] + """The unit price for this line item. + + Provided as a number in the specified currency. Eg: 10.43 for $10.43 + """ + + quantity: Optional[float] + """The quantity of this line item. Defaults to 1.""" + + InvoiceCreateParams: TypeAlias = Union[ CreateInvoiceInputWithProductAndMemberID, CreateInvoiceInputWithProductAndEmailAddress, diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py index 6d7664ab..a24e8d9c 100644 --- a/tests/api_resources/test_invoices.py +++ b/tests/api_resources/test_invoices.py @@ -84,6 +84,13 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -190,6 +197,13 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None: }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -293,6 +307,13 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None: }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -396,6 +417,13 @@ def test_method_create_with_all_params_overload_4(self, client: Whop) -> None: }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -645,6 +673,13 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -751,6 +786,13 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -854,6 +896,13 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", @@ -957,6 +1006,13 @@ async def test_method_create_with_all_params_overload_4(self, async_client: Asyn }, charge_buyer_fee=True, customer_name="customer_name", + line_items=[ + { + "label": "label", + "unit_price": 6.9, + "quantity": 6.9, + } + ], mailing_address_id="ma_xxxxxxxxxxxxxxx", payment_method_id="pmt_xxxxxxxxxxxxxx", payment_token_id="payt_xxxxxxxxxxxxx", From 881d399d3b01938fd43252b435935798bd3171f7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 04:13:22 +0000 Subject: [PATCH 18/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/shared/payment.py | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index abc0d95e..6b32e57f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-451a41faec4cfbe09e270b7b6a43779d1a5cbf325bac29efb7bd6713b57f9055.yml -openapi_spec_hash: 6d9c17ed9be2ec875739dfb717211f6a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-1dd698cd5bed0170f6ec79bf8a271fb2c1e3ddcd5c04d04bab52672bdbf47858.yml +openapi_spec_hash: b2c30dc2eb50aebfe5c651640114d814 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/shared/payment.py b/src/whop_sdk/types/shared/payment.py index c704b553..b38c6ecf 100644 --- a/src/whop_sdk/types/shared/payment.py +++ b/src/whop_sdk/types/shared/payment.py @@ -154,7 +154,17 @@ class FinancingTransaction(BaseModel): """The date and time the payment transaction was created.""" status: Literal[ - "succeeded", "declined", "error", "pending", "created", "expired", "won", "rejected", "lost", "prevented" + "succeeded", + "declined", + "error", + "pending", + "created", + "expired", + "won", + "rejected", + "lost", + "prevented", + "canceled", ] """The status of the payment transaction.""" From 91ad304ea92ca8916afd9e6abb17d463b1b81b58 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 18:13:31 +0000 Subject: [PATCH 19/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/payment_method_types.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6b32e57f..30c37743 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-1dd698cd5bed0170f6ec79bf8a271fb2c1e3ddcd5c04d04bab52672bdbf47858.yml -openapi_spec_hash: b2c30dc2eb50aebfe5c651640114d814 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-d4580465767383dcef8c62f95e62e999b11beb3e67e811f3eea63f549865af65.yml +openapi_spec_hash: 4393e657b75d88d858b11426f2650f82 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/payment_method_types.py b/src/whop_sdk/types/payment_method_types.py index c61cc63f..526c34f5 100644 --- a/src/whop_sdk/types/payment_method_types.py +++ b/src/whop_sdk/types/payment_method_types.py @@ -94,5 +94,6 @@ "vipps", "wechat_pay", "zip", + "coinflow", "unknown", ] From 94e743d29aa47e576e8b20e9971830fea5515358 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 21:13:21 +0000 Subject: [PATCH 20/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 30c37743..a429afbe 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-d4580465767383dcef8c62f95e62e999b11beb3e67e811f3eea63f549865af65.yml -openapi_spec_hash: 4393e657b75d88d858b11426f2650f82 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-f9859c65cf7c106dda9843e9fa3ce3ab96997bb419f3fb837160632c01af429d.yml +openapi_spec_hash: 6ca01fe47df1434c462d8c6fc82353a2 config_hash: 1a836d20bb988f001cc66d1526f71306 From fddd0a471d4c6e3f2ab902f3bdb06e103d57562c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 00:13:22 +0000 Subject: [PATCH 21/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a429afbe..6e5045cc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-f9859c65cf7c106dda9843e9fa3ce3ab96997bb419f3fb837160632c01af429d.yml -openapi_spec_hash: 6ca01fe47df1434c462d8c6fc82353a2 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-9d071a3dca3b32251a17181e3774d16f03941bbafd226da8e8c9f55b2d53921d.yml +openapi_spec_hash: af965d03f9f02828e0fe57ca3fc62595 config_hash: 1a836d20bb988f001cc66d1526f71306 From 5a8eec61fa674b099e5baaa9bf4d5f62b053b2cb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 22:13:40 +0000 Subject: [PATCH 22/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6e5045cc..6d238da0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-9d071a3dca3b32251a17181e3774d16f03941bbafd226da8e8c9f55b2d53921d.yml -openapi_spec_hash: af965d03f9f02828e0fe57ca3fc62595 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-ed61152a244301ddc31d2e306e1b55527cda7c05f01e5da24186de20f439282a.yml +openapi_spec_hash: b29c3fe72c8be1937cc181b877a0c4b4 config_hash: 1a836d20bb988f001cc66d1526f71306 From 10c00d9e1c45709469a36ea63c624b04fa312e58 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 23:13:46 +0000 Subject: [PATCH 23/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/resources/products.py | 8 ++++---- src/whop_sdk/types/product_create_params.py | 2 +- src/whop_sdk/types/product_update_params.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6d238da0..5e9f2f85 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-ed61152a244301ddc31d2e306e1b55527cda7c05f01e5da24186de20f439282a.yml -openapi_spec_hash: b29c3fe72c8be1937cc181b877a0c4b4 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-8acc348875c7872b10ddb90865e28e50a57519d0d88d7f32bd0f04212310e7fd.yml +openapi_spec_hash: eae04b61404c6e621ee68406e0bc2c44 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/products.py b/src/whop_sdk/resources/products.py index 0eac47eb..1ec5bdf5 100644 --- a/src/whop_sdk/resources/products.py +++ b/src/whop_sdk/resources/products.py @@ -96,7 +96,7 @@ def create( Args: company_id: The unique identifier of the company to create this product for. - title: The display name of the product. Maximum 40 characters. + title: The display name of the product. Maximum 150 characters. collect_shipping_address: Whether the checkout flow collects a shipping address from the customer. @@ -291,7 +291,7 @@ def update( store_page_config: Layout and display configuration for this product on the company's store page. - title: The display name of the product. Maximum 40 characters. + title: The display name of the product. Maximum 150 characters. visibility: Visibility of a resource @@ -524,7 +524,7 @@ async def create( Args: company_id: The unique identifier of the company to create this product for. - title: The display name of the product. Maximum 40 characters. + title: The display name of the product. Maximum 150 characters. collect_shipping_address: Whether the checkout flow collects a shipping address from the customer. @@ -719,7 +719,7 @@ async def update( store_page_config: Layout and display configuration for this product on the company's store page. - title: The display name of the product. Maximum 40 characters. + title: The display name of the product. Maximum 150 characters. visibility: Visibility of a resource diff --git a/src/whop_sdk/types/product_create_params.py b/src/whop_sdk/types/product_create_params.py index ea86cc0b..28832497 100644 --- a/src/whop_sdk/types/product_create_params.py +++ b/src/whop_sdk/types/product_create_params.py @@ -21,7 +21,7 @@ class ProductCreateParams(TypedDict, total=False): """The unique identifier of the company to create this product for.""" title: Required[str] - """The display name of the product. Maximum 40 characters.""" + """The display name of the product. Maximum 150 characters.""" collect_shipping_address: Optional[bool] """Whether the checkout flow collects a shipping address from the customer.""" diff --git a/src/whop_sdk/types/product_update_params.py b/src/whop_sdk/types/product_update_params.py index d7e9dcad..abfaebe6 100644 --- a/src/whop_sdk/types/product_update_params.py +++ b/src/whop_sdk/types/product_update_params.py @@ -78,7 +78,7 @@ class ProductUpdateParams(TypedDict, total=False): """Layout and display configuration for this product on the company's store page.""" title: Optional[str] - """The display name of the product. Maximum 40 characters.""" + """The display name of the product. Maximum 150 characters.""" visibility: Optional[Visibility] """Visibility of a resource""" From 82ba7a3c12417e18a6408a32eb2c4bf160e94768 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 00:13:35 +0000 Subject: [PATCH 24/39] feat(api): api update --- .stats.yml | 4 +- api.md | 3 + src/whop_sdk/types/__init__.py | 9 + ...ution_center_case_created_webhook_event.py | 221 ++++++++++++++++++ ...ution_center_case_decided_webhook_event.py | 221 ++++++++++++++++++ ...ution_center_case_updated_webhook_event.py | 221 ++++++++++++++++++ src/whop_sdk/types/unwrap_webhook_event.py | 6 + src/whop_sdk/types/webhook_event.py | 3 + 8 files changed, 686 insertions(+), 2 deletions(-) create mode 100644 src/whop_sdk/types/resolution_center_case_created_webhook_event.py create mode 100644 src/whop_sdk/types/resolution_center_case_decided_webhook_event.py create mode 100644 src/whop_sdk/types/resolution_center_case_updated_webhook_event.py diff --git a/.stats.yml b/.stats.yml index 5e9f2f85..5ad7997d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-8acc348875c7872b10ddb90865e28e50a57519d0d88d7f32bd0f04212310e7fd.yml -openapi_spec_hash: eae04b61404c6e621ee68406e0bc2c44 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-78790cad3e4f2c9deb66a493fba41d920adddf3bf333fa2ef187d1e16508dfd9.yml +openapi_spec_hash: 78d529588d618ee51b5c8b34ef6c4c35 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/api.md b/api.md index 60f21818..3ee925c2 100644 --- a/api.md +++ b/api.md @@ -162,6 +162,9 @@ from whop_sdk.types import ( PayoutMethodCreatedWebhookEvent, VerificationSucceededWebhookEvent, PayoutAccountStatusUpdatedWebhookEvent, + ResolutionCenterCaseCreatedWebhookEvent, + ResolutionCenterCaseUpdatedWebhookEvent, + ResolutionCenterCaseDecidedWebhookEvent, PaymentCreatedWebhookEvent, PaymentSucceededWebhookEvent, PaymentFailedWebhookEvent, diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py index c4684b39..9de43165 100644 --- a/src/whop_sdk/types/__init__.py +++ b/src/whop_sdk/types/__init__.py @@ -378,6 +378,15 @@ from .payout_account_status_updated_webhook_event import ( PayoutAccountStatusUpdatedWebhookEvent as PayoutAccountStatusUpdatedWebhookEvent, ) +from .resolution_center_case_created_webhook_event import ( + ResolutionCenterCaseCreatedWebhookEvent as ResolutionCenterCaseCreatedWebhookEvent, +) +from .resolution_center_case_decided_webhook_event import ( + ResolutionCenterCaseDecidedWebhookEvent as ResolutionCenterCaseDecidedWebhookEvent, +) +from .resolution_center_case_updated_webhook_event import ( + ResolutionCenterCaseUpdatedWebhookEvent as ResolutionCenterCaseUpdatedWebhookEvent, +) from .course_lesson_interaction_completed_webhook_event import ( CourseLessonInteractionCompletedWebhookEvent as CourseLessonInteractionCompletedWebhookEvent, ) diff --git a/src/whop_sdk/types/resolution_center_case_created_webhook_event.py b/src/whop_sdk/types/resolution_center_case_created_webhook_event.py new file mode 100644 index 00000000..ef326786 --- /dev/null +++ b/src/whop_sdk/types/resolution_center_case_created_webhook_event.py @@ -0,0 +1,221 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel +from .shared.currency import Currency +from .resolution_center_case_status import ResolutionCenterCaseStatus +from .resolution_center_case_issue_type import ResolutionCenterCaseIssueType +from .resolution_center_case_customer_response import ResolutionCenterCaseCustomerResponse +from .resolution_center_case_merchant_response import ResolutionCenterCaseMerchantResponse +from .resolution_center_case_platform_response import ResolutionCenterCasePlatformResponse + +__all__ = [ + "ResolutionCenterCaseCreatedWebhookEvent", + "Data", + "DataCompany", + "DataMember", + "DataPayment", + "DataResolutionEvent", + "DataUser", +] + + +class DataCompany(BaseModel): + """The company involved in this resolution case. + + Null if the company no longer exists. + """ + + id: str + """The unique identifier for the company.""" + + title: str + """The display name of the company shown to customers.""" + + +class DataMember(BaseModel): + """The membership record associated with the disputed payment. + + Null if the membership no longer exists. + """ + + id: str + """The unique identifier for the extra public member.""" + + +class DataPayment(BaseModel): + """The payment record that is the subject of this resolution case.""" + + id: str + """The unique identifier for the payment.""" + + created_at: datetime + """The datetime the payment was created.""" + + currency: Optional[Currency] = None + """The available currencies on the platform""" + + paid_at: Optional[datetime] = None + """The time at which this payment was successfully collected. + + Null if the payment has not yet succeeded. As a Unix timestamp. + """ + + subtotal: Optional[float] = None + """The payment amount before taxes and discounts are applied. + + In the currency specified by the currency field. + """ + + total: float + """ + The total amount charged to the customer for this payment, including taxes and + after any discounts. In the currency specified by the currency field. + """ + + +class DataResolutionEvent(BaseModel): + """ + A resolution event is a message or action within a resolution case, such as a response, escalation, or status change. + """ + + id: str + """The unique identifier for the resolution event.""" + + action: Literal[ + "created", + "responded", + "accepted", + "denied", + "appealed", + "withdrew", + "requested_more_info", + "escalated", + "dispute_opened", + "dispute_customer_won", + "dispute_merchant_won", + ] + """The type of action recorded in this event.""" + + created_at: datetime + """The datetime the resolution event was created.""" + + details: Optional[str] = None + """The message body or additional context provided with this resolution event. + + Null if no details were included. + """ + + reporter_type: Literal["merchant", "customer", "platform", "system"] + """The party who performed this action.""" + + +class DataUser(BaseModel): + """The customer (buyer) who filed this resolution case.""" + + id: str + """The unique identifier for the user.""" + + name: Optional[str] = None + """The user's display name shown on their public profile.""" + + username: str + """The user's unique username shown on their public profile.""" + + +class Data(BaseModel): + """ + A resolution center case is a dispute or support case between a user and a company, tracking the issue, status, and outcome. + """ + + id: str + """The unique identifier for the resolution.""" + + company: Optional[DataCompany] = None + """The company involved in this resolution case. + + Null if the company no longer exists. + """ + + created_at: datetime + """The datetime the resolution was created.""" + + customer_appealed: bool + """Whether the customer has filed an appeal after the initial resolution decision.""" + + customer_response_actions: List[ResolutionCenterCaseCustomerResponse] + """The list of actions currently available to the customer.""" + + due_date: Optional[datetime] = None + """The deadline by which the next response is required. + + Null if no deadline is currently active. As a Unix timestamp. + """ + + issue: ResolutionCenterCaseIssueType + """The category of the dispute.""" + + member: Optional[DataMember] = None + """The membership record associated with the disputed payment. + + Null if the membership no longer exists. + """ + + merchant_appealed: bool + """Whether the merchant has filed an appeal after the initial resolution decision.""" + + merchant_response_actions: List[ResolutionCenterCaseMerchantResponse] + """The list of actions currently available to the merchant.""" + + payment: DataPayment + """The payment record that is the subject of this resolution case.""" + + platform_response_actions: List[ResolutionCenterCasePlatformResponse] + """ + The list of actions currently available to the Whop platform for moderating this + resolution. + """ + + resolution_events: List[DataResolutionEvent] + """ + The most recent 50 messages, actions, and status changes that have occurred + during this resolution case. + """ + + status: ResolutionCenterCaseStatus + """ + The current status of the resolution case, indicating which party needs to + respond or if the case is closed. + """ + + updated_at: datetime + """The datetime the resolution was last updated.""" + + user: DataUser + """The customer (buyer) who filed this resolution case.""" + + +class ResolutionCenterCaseCreatedWebhookEvent(BaseModel): + id: str + """A unique ID for every single webhook request""" + + api_version: Literal["v1"] + """The API version for this webhook""" + + data: Data + """ + A resolution center case is a dispute or support case between a user and a + company, tracking the issue, status, and outcome. + """ + + timestamp: datetime + """The timestamp in ISO 8601 format that the webhook was sent at on the server""" + + type: Literal["resolution_center_case.created"] + """The webhook event type""" + + company_id: Optional[str] = None + """The company ID that this webhook event is associated with""" diff --git a/src/whop_sdk/types/resolution_center_case_decided_webhook_event.py b/src/whop_sdk/types/resolution_center_case_decided_webhook_event.py new file mode 100644 index 00000000..c4641db5 --- /dev/null +++ b/src/whop_sdk/types/resolution_center_case_decided_webhook_event.py @@ -0,0 +1,221 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel +from .shared.currency import Currency +from .resolution_center_case_status import ResolutionCenterCaseStatus +from .resolution_center_case_issue_type import ResolutionCenterCaseIssueType +from .resolution_center_case_customer_response import ResolutionCenterCaseCustomerResponse +from .resolution_center_case_merchant_response import ResolutionCenterCaseMerchantResponse +from .resolution_center_case_platform_response import ResolutionCenterCasePlatformResponse + +__all__ = [ + "ResolutionCenterCaseDecidedWebhookEvent", + "Data", + "DataCompany", + "DataMember", + "DataPayment", + "DataResolutionEvent", + "DataUser", +] + + +class DataCompany(BaseModel): + """The company involved in this resolution case. + + Null if the company no longer exists. + """ + + id: str + """The unique identifier for the company.""" + + title: str + """The display name of the company shown to customers.""" + + +class DataMember(BaseModel): + """The membership record associated with the disputed payment. + + Null if the membership no longer exists. + """ + + id: str + """The unique identifier for the extra public member.""" + + +class DataPayment(BaseModel): + """The payment record that is the subject of this resolution case.""" + + id: str + """The unique identifier for the payment.""" + + created_at: datetime + """The datetime the payment was created.""" + + currency: Optional[Currency] = None + """The available currencies on the platform""" + + paid_at: Optional[datetime] = None + """The time at which this payment was successfully collected. + + Null if the payment has not yet succeeded. As a Unix timestamp. + """ + + subtotal: Optional[float] = None + """The payment amount before taxes and discounts are applied. + + In the currency specified by the currency field. + """ + + total: float + """ + The total amount charged to the customer for this payment, including taxes and + after any discounts. In the currency specified by the currency field. + """ + + +class DataResolutionEvent(BaseModel): + """ + A resolution event is a message or action within a resolution case, such as a response, escalation, or status change. + """ + + id: str + """The unique identifier for the resolution event.""" + + action: Literal[ + "created", + "responded", + "accepted", + "denied", + "appealed", + "withdrew", + "requested_more_info", + "escalated", + "dispute_opened", + "dispute_customer_won", + "dispute_merchant_won", + ] + """The type of action recorded in this event.""" + + created_at: datetime + """The datetime the resolution event was created.""" + + details: Optional[str] = None + """The message body or additional context provided with this resolution event. + + Null if no details were included. + """ + + reporter_type: Literal["merchant", "customer", "platform", "system"] + """The party who performed this action.""" + + +class DataUser(BaseModel): + """The customer (buyer) who filed this resolution case.""" + + id: str + """The unique identifier for the user.""" + + name: Optional[str] = None + """The user's display name shown on their public profile.""" + + username: str + """The user's unique username shown on their public profile.""" + + +class Data(BaseModel): + """ + A resolution center case is a dispute or support case between a user and a company, tracking the issue, status, and outcome. + """ + + id: str + """The unique identifier for the resolution.""" + + company: Optional[DataCompany] = None + """The company involved in this resolution case. + + Null if the company no longer exists. + """ + + created_at: datetime + """The datetime the resolution was created.""" + + customer_appealed: bool + """Whether the customer has filed an appeal after the initial resolution decision.""" + + customer_response_actions: List[ResolutionCenterCaseCustomerResponse] + """The list of actions currently available to the customer.""" + + due_date: Optional[datetime] = None + """The deadline by which the next response is required. + + Null if no deadline is currently active. As a Unix timestamp. + """ + + issue: ResolutionCenterCaseIssueType + """The category of the dispute.""" + + member: Optional[DataMember] = None + """The membership record associated with the disputed payment. + + Null if the membership no longer exists. + """ + + merchant_appealed: bool + """Whether the merchant has filed an appeal after the initial resolution decision.""" + + merchant_response_actions: List[ResolutionCenterCaseMerchantResponse] + """The list of actions currently available to the merchant.""" + + payment: DataPayment + """The payment record that is the subject of this resolution case.""" + + platform_response_actions: List[ResolutionCenterCasePlatformResponse] + """ + The list of actions currently available to the Whop platform for moderating this + resolution. + """ + + resolution_events: List[DataResolutionEvent] + """ + The most recent 50 messages, actions, and status changes that have occurred + during this resolution case. + """ + + status: ResolutionCenterCaseStatus + """ + The current status of the resolution case, indicating which party needs to + respond or if the case is closed. + """ + + updated_at: datetime + """The datetime the resolution was last updated.""" + + user: DataUser + """The customer (buyer) who filed this resolution case.""" + + +class ResolutionCenterCaseDecidedWebhookEvent(BaseModel): + id: str + """A unique ID for every single webhook request""" + + api_version: Literal["v1"] + """The API version for this webhook""" + + data: Data + """ + A resolution center case is a dispute or support case between a user and a + company, tracking the issue, status, and outcome. + """ + + timestamp: datetime + """The timestamp in ISO 8601 format that the webhook was sent at on the server""" + + type: Literal["resolution_center_case.decided"] + """The webhook event type""" + + company_id: Optional[str] = None + """The company ID that this webhook event is associated with""" diff --git a/src/whop_sdk/types/resolution_center_case_updated_webhook_event.py b/src/whop_sdk/types/resolution_center_case_updated_webhook_event.py new file mode 100644 index 00000000..349256f3 --- /dev/null +++ b/src/whop_sdk/types/resolution_center_case_updated_webhook_event.py @@ -0,0 +1,221 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel +from .shared.currency import Currency +from .resolution_center_case_status import ResolutionCenterCaseStatus +from .resolution_center_case_issue_type import ResolutionCenterCaseIssueType +from .resolution_center_case_customer_response import ResolutionCenterCaseCustomerResponse +from .resolution_center_case_merchant_response import ResolutionCenterCaseMerchantResponse +from .resolution_center_case_platform_response import ResolutionCenterCasePlatformResponse + +__all__ = [ + "ResolutionCenterCaseUpdatedWebhookEvent", + "Data", + "DataCompany", + "DataMember", + "DataPayment", + "DataResolutionEvent", + "DataUser", +] + + +class DataCompany(BaseModel): + """The company involved in this resolution case. + + Null if the company no longer exists. + """ + + id: str + """The unique identifier for the company.""" + + title: str + """The display name of the company shown to customers.""" + + +class DataMember(BaseModel): + """The membership record associated with the disputed payment. + + Null if the membership no longer exists. + """ + + id: str + """The unique identifier for the extra public member.""" + + +class DataPayment(BaseModel): + """The payment record that is the subject of this resolution case.""" + + id: str + """The unique identifier for the payment.""" + + created_at: datetime + """The datetime the payment was created.""" + + currency: Optional[Currency] = None + """The available currencies on the platform""" + + paid_at: Optional[datetime] = None + """The time at which this payment was successfully collected. + + Null if the payment has not yet succeeded. As a Unix timestamp. + """ + + subtotal: Optional[float] = None + """The payment amount before taxes and discounts are applied. + + In the currency specified by the currency field. + """ + + total: float + """ + The total amount charged to the customer for this payment, including taxes and + after any discounts. In the currency specified by the currency field. + """ + + +class DataResolutionEvent(BaseModel): + """ + A resolution event is a message or action within a resolution case, such as a response, escalation, or status change. + """ + + id: str + """The unique identifier for the resolution event.""" + + action: Literal[ + "created", + "responded", + "accepted", + "denied", + "appealed", + "withdrew", + "requested_more_info", + "escalated", + "dispute_opened", + "dispute_customer_won", + "dispute_merchant_won", + ] + """The type of action recorded in this event.""" + + created_at: datetime + """The datetime the resolution event was created.""" + + details: Optional[str] = None + """The message body or additional context provided with this resolution event. + + Null if no details were included. + """ + + reporter_type: Literal["merchant", "customer", "platform", "system"] + """The party who performed this action.""" + + +class DataUser(BaseModel): + """The customer (buyer) who filed this resolution case.""" + + id: str + """The unique identifier for the user.""" + + name: Optional[str] = None + """The user's display name shown on their public profile.""" + + username: str + """The user's unique username shown on their public profile.""" + + +class Data(BaseModel): + """ + A resolution center case is a dispute or support case between a user and a company, tracking the issue, status, and outcome. + """ + + id: str + """The unique identifier for the resolution.""" + + company: Optional[DataCompany] = None + """The company involved in this resolution case. + + Null if the company no longer exists. + """ + + created_at: datetime + """The datetime the resolution was created.""" + + customer_appealed: bool + """Whether the customer has filed an appeal after the initial resolution decision.""" + + customer_response_actions: List[ResolutionCenterCaseCustomerResponse] + """The list of actions currently available to the customer.""" + + due_date: Optional[datetime] = None + """The deadline by which the next response is required. + + Null if no deadline is currently active. As a Unix timestamp. + """ + + issue: ResolutionCenterCaseIssueType + """The category of the dispute.""" + + member: Optional[DataMember] = None + """The membership record associated with the disputed payment. + + Null if the membership no longer exists. + """ + + merchant_appealed: bool + """Whether the merchant has filed an appeal after the initial resolution decision.""" + + merchant_response_actions: List[ResolutionCenterCaseMerchantResponse] + """The list of actions currently available to the merchant.""" + + payment: DataPayment + """The payment record that is the subject of this resolution case.""" + + platform_response_actions: List[ResolutionCenterCasePlatformResponse] + """ + The list of actions currently available to the Whop platform for moderating this + resolution. + """ + + resolution_events: List[DataResolutionEvent] + """ + The most recent 50 messages, actions, and status changes that have occurred + during this resolution case. + """ + + status: ResolutionCenterCaseStatus + """ + The current status of the resolution case, indicating which party needs to + respond or if the case is closed. + """ + + updated_at: datetime + """The datetime the resolution was last updated.""" + + user: DataUser + """The customer (buyer) who filed this resolution case.""" + + +class ResolutionCenterCaseUpdatedWebhookEvent(BaseModel): + id: str + """A unique ID for every single webhook request""" + + api_version: Literal["v1"] + """The API version for this webhook""" + + data: Data + """ + A resolution center case is a dispute or support case between a user and a + company, tracking the issue, status, and outcome. + """ + + timestamp: datetime + """The timestamp in ISO 8601 format that the webhook was sent at on the server""" + + type: Literal["resolution_center_case.updated"] + """The webhook event type""" + + company_id: Optional[str] = None + """The company ID that this webhook event is associated with""" diff --git a/src/whop_sdk/types/unwrap_webhook_event.py b/src/whop_sdk/types/unwrap_webhook_event.py index 78041be9..7461dd7c 100644 --- a/src/whop_sdk/types/unwrap_webhook_event.py +++ b/src/whop_sdk/types/unwrap_webhook_event.py @@ -31,6 +31,9 @@ from .verification_succeeded_webhook_event import VerificationSucceededWebhookEvent from .setup_intent_requires_action_webhook_event import SetupIntentRequiresActionWebhookEvent from .payout_account_status_updated_webhook_event import PayoutAccountStatusUpdatedWebhookEvent +from .resolution_center_case_created_webhook_event import ResolutionCenterCaseCreatedWebhookEvent +from .resolution_center_case_decided_webhook_event import ResolutionCenterCaseDecidedWebhookEvent +from .resolution_center_case_updated_webhook_event import ResolutionCenterCaseUpdatedWebhookEvent from .course_lesson_interaction_completed_webhook_event import CourseLessonInteractionCompletedWebhookEvent from .membership_cancel_at_period_end_changed_webhook_event import MembershipCancelAtPeriodEndChangedWebhookEvent @@ -57,6 +60,9 @@ PayoutMethodCreatedWebhookEvent, VerificationSucceededWebhookEvent, PayoutAccountStatusUpdatedWebhookEvent, + ResolutionCenterCaseCreatedWebhookEvent, + ResolutionCenterCaseUpdatedWebhookEvent, + ResolutionCenterCaseDecidedWebhookEvent, PaymentCreatedWebhookEvent, PaymentSucceededWebhookEvent, PaymentFailedWebhookEvent, diff --git a/src/whop_sdk/types/webhook_event.py b/src/whop_sdk/types/webhook_event.py index e2a54153..cac6f3d9 100644 --- a/src/whop_sdk/types/webhook_event.py +++ b/src/whop_sdk/types/webhook_event.py @@ -24,6 +24,9 @@ "payout_method.created", "verification.succeeded", "payout_account.status_updated", + "resolution_center_case.created", + "resolution_center_case.updated", + "resolution_center_case.decided", "payment.created", "payment.succeeded", "payment.failed", From e733ac94f3c0f71876b46145c325e597c9569541 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 03:13:40 +0000 Subject: [PATCH 25/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/resources/products.py | 8 ++++---- src/whop_sdk/types/product_create_params.py | 2 +- src/whop_sdk/types/product_update_params.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5ad7997d..a8d44264 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-78790cad3e4f2c9deb66a493fba41d920adddf3bf333fa2ef187d1e16508dfd9.yml -openapi_spec_hash: 78d529588d618ee51b5c8b34ef6c4c35 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-127cfec745838ff7571d81a1f298ca4fbcd4357671dd602b03d3201b9f9725f4.yml +openapi_spec_hash: 7b2ef06e48c4c03bbb3b180e0b70eb5f config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/products.py b/src/whop_sdk/resources/products.py index 1ec5bdf5..f2dce526 100644 --- a/src/whop_sdk/resources/products.py +++ b/src/whop_sdk/resources/products.py @@ -96,7 +96,7 @@ def create( Args: company_id: The unique identifier of the company to create this product for. - title: The display name of the product. Maximum 150 characters. + title: The display name of the product. Maximum 80 characters. collect_shipping_address: Whether the checkout flow collects a shipping address from the customer. @@ -291,7 +291,7 @@ def update( store_page_config: Layout and display configuration for this product on the company's store page. - title: The display name of the product. Maximum 150 characters. + title: The display name of the product. Maximum 80 characters. visibility: Visibility of a resource @@ -524,7 +524,7 @@ async def create( Args: company_id: The unique identifier of the company to create this product for. - title: The display name of the product. Maximum 150 characters. + title: The display name of the product. Maximum 80 characters. collect_shipping_address: Whether the checkout flow collects a shipping address from the customer. @@ -719,7 +719,7 @@ async def update( store_page_config: Layout and display configuration for this product on the company's store page. - title: The display name of the product. Maximum 150 characters. + title: The display name of the product. Maximum 80 characters. visibility: Visibility of a resource diff --git a/src/whop_sdk/types/product_create_params.py b/src/whop_sdk/types/product_create_params.py index 28832497..ed4c851c 100644 --- a/src/whop_sdk/types/product_create_params.py +++ b/src/whop_sdk/types/product_create_params.py @@ -21,7 +21,7 @@ class ProductCreateParams(TypedDict, total=False): """The unique identifier of the company to create this product for.""" title: Required[str] - """The display name of the product. Maximum 150 characters.""" + """The display name of the product. Maximum 80 characters.""" collect_shipping_address: Optional[bool] """Whether the checkout flow collects a shipping address from the customer.""" diff --git a/src/whop_sdk/types/product_update_params.py b/src/whop_sdk/types/product_update_params.py index abfaebe6..6082edf2 100644 --- a/src/whop_sdk/types/product_update_params.py +++ b/src/whop_sdk/types/product_update_params.py @@ -78,7 +78,7 @@ class ProductUpdateParams(TypedDict, total=False): """Layout and display configuration for this product on the company's store page.""" title: Optional[str] - """The display name of the product. Maximum 150 characters.""" + """The display name of the product. Maximum 80 characters.""" visibility: Optional[Visibility] """Visibility of a resource""" From 6ac4297d8b69e3f8209c69786f7017dd10913053 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 18:13:35 +0000 Subject: [PATCH 26/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/card_brands.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a8d44264..f12a576b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-127cfec745838ff7571d81a1f298ca4fbcd4357671dd602b03d3201b9f9725f4.yml -openapi_spec_hash: 7b2ef06e48c4c03bbb3b180e0b70eb5f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-5a529505f868cfa92974cc13725520be062f908def4bff4804ecc40947105666.yml +openapi_spec_hash: 0bbfd3bb4111e2ece7a1fb3ef4fd388b config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/card_brands.py b/src/whop_sdk/types/card_brands.py index 1243eead..bd4345a7 100644 --- a/src/whop_sdk/types/card_brands.py +++ b/src/whop_sdk/types/card_brands.py @@ -43,5 +43,6 @@ "cabal", "hipercard", "jcblankapay", + "cmi", "unknown", ] From c7b5425e8257162625fd6db79079953247a05d90 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 00:13:19 +0000 Subject: [PATCH 27/39] feat(api): api update --- .stats.yml | 4 +-- api.md | 1 + src/whop_sdk/types/__init__.py | 3 ++ ...oice_marked_uncollectible_webhook_event.py | 34 +++++++++++++++++++ src/whop_sdk/types/shared/invoice_status.py | 2 +- .../types/shared_params/invoice_status.py | 2 +- src/whop_sdk/types/unwrap_webhook_event.py | 2 ++ src/whop_sdk/types/webhook_event.py | 1 + 8 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py diff --git a/.stats.yml b/.stats.yml index f12a576b..61e50354 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-5a529505f868cfa92974cc13725520be062f908def4bff4804ecc40947105666.yml -openapi_spec_hash: 0bbfd3bb4111e2ece7a1fb3ef4fd388b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-bfa2056a2dbdd58977591483334cb96a84c9bd7f53545b9e801bf30c881534c3.yml +openapi_spec_hash: 56b8f7b171433d3ca81b0aea3f4da588 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/api.md b/api.md index 3ee925c2..11e37169 100644 --- a/api.md +++ b/api.md @@ -144,6 +144,7 @@ from whop_sdk.types import ( WebhookListResponse, WebhookDeleteResponse, InvoiceCreatedWebhookEvent, + InvoiceMarkedUncollectibleWebhookEvent, InvoicePaidWebhookEvent, InvoicePastDueWebhookEvent, InvoiceVoidedWebhookEvent, diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py index 9de43165..aa689be7 100644 --- a/src/whop_sdk/types/__init__.py +++ b/src/whop_sdk/types/__init__.py @@ -372,6 +372,9 @@ from .resolution_center_case_retrieve_response import ( ResolutionCenterCaseRetrieveResponse as ResolutionCenterCaseRetrieveResponse, ) +from .invoice_marked_uncollectible_webhook_event import ( + InvoiceMarkedUncollectibleWebhookEvent as InvoiceMarkedUncollectibleWebhookEvent, +) from .setup_intent_requires_action_webhook_event import ( SetupIntentRequiresActionWebhookEvent as SetupIntentRequiresActionWebhookEvent, ) diff --git a/src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py b/src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py new file mode 100644 index 00000000..3152d5d2 --- /dev/null +++ b/src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel +from .shared.invoice import Invoice + +__all__ = ["InvoiceMarkedUncollectibleWebhookEvent"] + + +class InvoiceMarkedUncollectibleWebhookEvent(BaseModel): + id: str + """A unique ID for every single webhook request""" + + api_version: Literal["v1"] + """The API version for this webhook""" + + data: Invoice + """ + An invoice represents an itemized bill sent by a company to a customer for a + specific product and plan, tracking the amount owed, due date, and payment + status. + """ + + timestamp: datetime + """The timestamp in ISO 8601 format that the webhook was sent at on the server""" + + type: Literal["invoice.marked_uncollectible"] + """The webhook event type""" + + company_id: Optional[str] = None + """The company ID that this webhook event is associated with""" diff --git a/src/whop_sdk/types/shared/invoice_status.py b/src/whop_sdk/types/shared/invoice_status.py index 255b6a79..7e48fb62 100644 --- a/src/whop_sdk/types/shared/invoice_status.py +++ b/src/whop_sdk/types/shared/invoice_status.py @@ -4,4 +4,4 @@ __all__ = ["InvoiceStatus"] -InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "void"] +InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "uncollectible", "void"] diff --git a/src/whop_sdk/types/shared_params/invoice_status.py b/src/whop_sdk/types/shared_params/invoice_status.py index 1006ba8b..906e0629 100644 --- a/src/whop_sdk/types/shared_params/invoice_status.py +++ b/src/whop_sdk/types/shared_params/invoice_status.py @@ -6,4 +6,4 @@ __all__ = ["InvoiceStatus"] -InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "void"] +InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "uncollectible", "void"] diff --git a/src/whop_sdk/types/unwrap_webhook_event.py b/src/whop_sdk/types/unwrap_webhook_event.py index 7461dd7c..96f1582f 100644 --- a/src/whop_sdk/types/unwrap_webhook_event.py +++ b/src/whop_sdk/types/unwrap_webhook_event.py @@ -29,6 +29,7 @@ from .membership_deactivated_webhook_event import MembershipDeactivatedWebhookEvent from .setup_intent_succeeded_webhook_event import SetupIntentSucceededWebhookEvent from .verification_succeeded_webhook_event import VerificationSucceededWebhookEvent +from .invoice_marked_uncollectible_webhook_event import InvoiceMarkedUncollectibleWebhookEvent from .setup_intent_requires_action_webhook_event import SetupIntentRequiresActionWebhookEvent from .payout_account_status_updated_webhook_event import PayoutAccountStatusUpdatedWebhookEvent from .resolution_center_case_created_webhook_event import ResolutionCenterCaseCreatedWebhookEvent @@ -42,6 +43,7 @@ UnwrapWebhookEvent: TypeAlias = Annotated[ Union[ InvoiceCreatedWebhookEvent, + InvoiceMarkedUncollectibleWebhookEvent, InvoicePaidWebhookEvent, InvoicePastDueWebhookEvent, InvoiceVoidedWebhookEvent, diff --git a/src/whop_sdk/types/webhook_event.py b/src/whop_sdk/types/webhook_event.py index cac6f3d9..174e660a 100644 --- a/src/whop_sdk/types/webhook_event.py +++ b/src/whop_sdk/types/webhook_event.py @@ -6,6 +6,7 @@ WebhookEvent: TypeAlias = Literal[ "invoice.created", + "invoice.marked_uncollectible", "invoice.paid", "invoice.past_due", "invoice.voided", From 719e1f0b5b1cd8169be833d10ebe6c49f0019f7a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 01:13:26 +0000 Subject: [PATCH 28/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 61e50354..4892e97c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-bfa2056a2dbdd58977591483334cb96a84c9bd7f53545b9e801bf30c881534c3.yml -openapi_spec_hash: 56b8f7b171433d3ca81b0aea3f4da588 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-c1ee1647754628400e2960d7d0dce7151de7d8c2566f2ae7f1c69427725dae46.yml +openapi_spec_hash: 981e00e87ccd324803f2fc518e52f155 config_hash: 1a836d20bb988f001cc66d1526f71306 From 6aa464e34ab3d27134a66157a4ca0ef4d20b810a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 16:13:45 +0000 Subject: [PATCH 29/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/resources/payments.py | 16 ++++++++++++++++ src/whop_sdk/types/payment_list_params.py | 6 ++++++ src/whop_sdk/types/payment_list_response.py | 3 +++ src/whop_sdk/types/shared/payment.py | 3 +++ tests/api_resources/test_payments.py | 4 ++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 4892e97c..aef46f32 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-c1ee1647754628400e2960d7d0dce7151de7d8c2566f2ae7f1c69427725dae46.yml -openapi_spec_hash: 981e00e87ccd324803f2fc518e52f155 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-9a2beb0528630f5fb8e39d0eb979a59637919c7736961d5b0271274f6b350eb5.yml +openapi_spec_hash: 82a8ddcaa9de7e49c6d934e4926b32a9 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/resources/payments.py b/src/whop_sdk/resources/payments.py index 260f6e38..db84e495 100644 --- a/src/whop_sdk/resources/payments.py +++ b/src/whop_sdk/resources/payments.py @@ -277,6 +277,8 @@ def list( query: Optional[str] | Omit = omit, statuses: Optional[List[ReceiptStatus]] | Omit = omit, substatuses: Optional[List[FriendlyReceiptStatus]] | Omit = omit, + updated_after: Union[str, datetime, None] | Omit = omit, + updated_before: Union[str, datetime, None] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -335,6 +337,10 @@ def list( substatuses: Filter payments by their current substatus for more granular filtering. + updated_after: Only return payments last updated after this timestamp. + + updated_before: Only return payments last updated before this timestamp. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -370,6 +376,8 @@ def list( "query": query, "statuses": statuses, "substatuses": substatuses, + "updated_after": updated_after, + "updated_before": updated_before, }, payment_list_params.PaymentListParams, ), @@ -831,6 +839,8 @@ def list( query: Optional[str] | Omit = omit, statuses: Optional[List[ReceiptStatus]] | Omit = omit, substatuses: Optional[List[FriendlyReceiptStatus]] | Omit = omit, + updated_after: Union[str, datetime, None] | Omit = omit, + updated_before: Union[str, datetime, None] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -889,6 +899,10 @@ def list( substatuses: Filter payments by their current substatus for more granular filtering. + updated_after: Only return payments last updated after this timestamp. + + updated_before: Only return payments last updated before this timestamp. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -924,6 +938,8 @@ def list( "query": query, "statuses": statuses, "substatuses": substatuses, + "updated_after": updated_after, + "updated_before": updated_before, }, payment_list_params.PaymentListParams, ), diff --git a/src/whop_sdk/types/payment_list_params.py b/src/whop_sdk/types/payment_list_params.py index 5af6fe5f..1fcc2a22 100644 --- a/src/whop_sdk/types/payment_list_params.py +++ b/src/whop_sdk/types/payment_list_params.py @@ -74,3 +74,9 @@ class PaymentListParams(TypedDict, total=False): substatuses: Optional[List[FriendlyReceiptStatus]] """Filter payments by their current substatus for more granular filtering.""" + + updated_after: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Only return payments last updated after this timestamp.""" + + updated_before: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Only return payments last updated before this timestamp.""" diff --git a/src/whop_sdk/types/payment_list_response.py b/src/whop_sdk/types/payment_list_response.py index 438f5ecd..e026626b 100644 --- a/src/whop_sdk/types/payment_list_response.py +++ b/src/whop_sdk/types/payment_list_response.py @@ -348,6 +348,9 @@ class PaymentListResponse(BaseModel): total: Optional[float] = None """The total to show to the creator (excluding buyer fees).""" + updated_at: datetime + """The datetime the payment was last updated.""" + usd_total: Optional[float] = None """The total in USD to show to the creator (excluding buyer fees).""" diff --git a/src/whop_sdk/types/shared/payment.py b/src/whop_sdk/types/shared/payment.py index b38c6ecf..4d92b9e7 100644 --- a/src/whop_sdk/types/shared/payment.py +++ b/src/whop_sdk/types/shared/payment.py @@ -511,6 +511,9 @@ class Payment(BaseModel): total: Optional[float] = None """The total to show to the creator (excluding buyer fees).""" + updated_at: datetime + """The datetime the payment was last updated.""" + usd_total: Optional[float] = None """The total in USD to show to the creator (excluding buyer fees).""" diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py index e16cc671..4dc6a096 100644 --- a/tests/api_resources/test_payments.py +++ b/tests/api_resources/test_payments.py @@ -230,6 +230,8 @@ def test_method_list_with_all_params(self, client: Whop) -> None: query="query", statuses=["draft"], substatuses=["succeeded"], + updated_after=parse_datetime("2023-12-01T05:00:00.401Z"), + updated_before=parse_datetime("2023-12-01T05:00:00.401Z"), ) assert_matches_type(SyncCursorPage[PaymentListResponse], payment, path=["response"]) @@ -657,6 +659,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncWhop) -> Non query="query", statuses=["draft"], substatuses=["succeeded"], + updated_after=parse_datetime("2023-12-01T05:00:00.401Z"), + updated_before=parse_datetime("2023-12-01T05:00:00.401Z"), ) assert_matches_type(AsyncCursorPage[PaymentListResponse], payment, path=["response"]) From 82f02347c686891b5ffaeacd7cd84b9bc0a314d8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 23:13:24 +0000 Subject: [PATCH 30/39] feat(api): api update --- .stats.yml | 4 ++-- src/whop_sdk/types/payment_create_params.py | 8 ++++++++ tests/api_resources/test_payments.py | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index aef46f32..beca1d95 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 191 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-9a2beb0528630f5fb8e39d0eb979a59637919c7736961d5b0271274f6b350eb5.yml -openapi_spec_hash: 82a8ddcaa9de7e49c6d934e4926b32a9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-dbc99b95f02e6b568750045987763dbdafa1edc5a7ac425e3831e61929d7ecec.yml +openapi_spec_hash: d2ec900df5b29b03d1d1786336d1daf5 config_hash: 1a836d20bb988f001cc66d1526f71306 diff --git a/src/whop_sdk/types/payment_create_params.py b/src/whop_sdk/types/payment_create_params.py index 2d03e3b1..3335e5f5 100644 --- a/src/whop_sdk/types/payment_create_params.py +++ b/src/whop_sdk/types/payment_create_params.py @@ -97,6 +97,14 @@ class CreatePaymentInputWithPlanPlan(TypedDict, total=False): currency: Required[Currency] """The respective currency identifier for the plan.""" + application_fee_amount: Optional[float] + """The application fee amount collected by the platform from this connected + account. + + Provided as a number in dollars (e.g., 5.00 for $5.00). Must be less than the + total payment amount. Only valid for connected accounts with a parent company. + """ + billing_period: Optional[int] """The interval in days at which the plan charges (renewal plans). diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py index 4dc6a096..628f7f75 100644 --- a/tests/api_resources/test_payments.py +++ b/tests/api_resources/test_payments.py @@ -43,6 +43,7 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: payment_method_id="pmt_xxxxxxxxxxxxxx", plan={ "currency": "usd", + "application_fee_amount": 6.9, "billing_period": 42, "description": "description", "expiration_days": 42, @@ -472,6 +473,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn payment_method_id="pmt_xxxxxxxxxxxxxx", plan={ "currency": "usd", + "application_fee_amount": 6.9, "billing_period": 42, "description": "description", "expiration_days": 42, From 014b6bba88788acb14ce8240388b8712209f66fa Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 14:40:05 +0000 Subject: [PATCH 31/39] feat(api): manual updates --- .stats.yml | 4 +- api.md | 9 +- src/whop_sdk/resources/invoices.py | 174 +++++++ src/whop_sdk/types/__init__.py | 3 + src/whop_sdk/types/invoice_create_params.py | 465 +----------------- .../types/invoice_mark_paid_response.py | 7 + .../invoice_mark_uncollectible_response.py | 7 + src/whop_sdk/types/tax_identifier_type.py | 119 +++++ tests/api_resources/test_invoices.py | 174 ++++++- 9 files changed, 498 insertions(+), 464 deletions(-) create mode 100644 src/whop_sdk/types/invoice_mark_paid_response.py create mode 100644 src/whop_sdk/types/invoice_mark_uncollectible_response.py create mode 100644 src/whop_sdk/types/tax_identifier_type.py diff --git a/.stats.yml b/.stats.yml index beca1d95..6681f367 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 191 +configured_endpoints: 193 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-dbc99b95f02e6b568750045987763dbdafa1edc5a7ac425e3831e61929d7ecec.yml openapi_spec_hash: d2ec900df5b29b03d1d1786336d1daf5 -config_hash: 1a836d20bb988f001cc66d1526f71306 +config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a diff --git a/api.md b/api.md index 11e37169..1d4b9390 100644 --- a/api.md +++ b/api.md @@ -83,7 +83,12 @@ Methods: Types: ```python -from whop_sdk.types import InvoiceVoidResponse +from whop_sdk.types import ( + TaxIdentifierType, + InvoiceMarkPaidResponse, + InvoiceMarkUncollectibleResponse, + InvoiceVoidResponse, +) ``` Methods: @@ -91,6 +96,8 @@ Methods: - client.invoices.create(\*\*params) -> Invoice - client.invoices.retrieve(id) -> Invoice - client.invoices.list(\*\*params) -> SyncCursorPage[InvoiceListItem] +- client.invoices.mark_paid(id) -> InvoiceMarkPaidResponse +- client.invoices.mark_uncollectible(id) -> InvoiceMarkUncollectibleResponse - client.invoices.void(id) -> InvoiceVoidResponse # CourseLessonInteractions diff --git a/src/whop_sdk/resources/invoices.py b/src/whop_sdk/resources/invoices.py index eccc33a3..b3ef3f2e 100644 --- a/src/whop_sdk/resources/invoices.py +++ b/src/whop_sdk/resources/invoices.py @@ -27,6 +27,8 @@ from ..types.shared.invoice_status import InvoiceStatus from ..types.shared.collection_method import CollectionMethod from ..types.shared.invoice_list_item import InvoiceListItem +from ..types.invoice_mark_paid_response import InvoiceMarkPaidResponse +from ..types.invoice_mark_uncollectible_response import InvoiceMarkUncollectibleResponse __all__ = ["InvoicesResource", "AsyncInvoicesResource"] @@ -604,6 +606,80 @@ def list( model=InvoiceListItem, ) + def mark_paid( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InvoiceMarkPaidResponse: + """ + Mark an open invoice as paid when payment was collected outside of Whop. + + Required permissions: + + - `invoice:update` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + path_template("/invoices/{id}/mark_paid", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InvoiceMarkPaidResponse, + ) + + def mark_uncollectible( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InvoiceMarkUncollectibleResponse: + """ + Mark an open invoice as uncollectible when payment is not expected. + + Required permissions: + + - `invoice:update` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + path_template("/invoices/{id}/mark_uncollectible", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InvoiceMarkUncollectibleResponse, + ) + def void( self, id: str, @@ -1217,6 +1293,80 @@ def list( model=InvoiceListItem, ) + async def mark_paid( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InvoiceMarkPaidResponse: + """ + Mark an open invoice as paid when payment was collected outside of Whop. + + Required permissions: + + - `invoice:update` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + path_template("/invoices/{id}/mark_paid", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InvoiceMarkPaidResponse, + ) + + async def mark_uncollectible( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> InvoiceMarkUncollectibleResponse: + """ + Mark an open invoice as uncollectible when payment is not expected. + + Required permissions: + + - `invoice:update` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + path_template("/invoices/{id}/mark_uncollectible", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=InvoiceMarkUncollectibleResponse, + ) + async def void( self, id: str, @@ -1270,6 +1420,12 @@ def __init__(self, invoices: InvoicesResource) -> None: self.list = to_raw_response_wrapper( invoices.list, ) + self.mark_paid = to_raw_response_wrapper( + invoices.mark_paid, + ) + self.mark_uncollectible = to_raw_response_wrapper( + invoices.mark_uncollectible, + ) self.void = to_raw_response_wrapper( invoices.void, ) @@ -1288,6 +1444,12 @@ def __init__(self, invoices: AsyncInvoicesResource) -> None: self.list = async_to_raw_response_wrapper( invoices.list, ) + self.mark_paid = async_to_raw_response_wrapper( + invoices.mark_paid, + ) + self.mark_uncollectible = async_to_raw_response_wrapper( + invoices.mark_uncollectible, + ) self.void = async_to_raw_response_wrapper( invoices.void, ) @@ -1306,6 +1468,12 @@ def __init__(self, invoices: InvoicesResource) -> None: self.list = to_streamed_response_wrapper( invoices.list, ) + self.mark_paid = to_streamed_response_wrapper( + invoices.mark_paid, + ) + self.mark_uncollectible = to_streamed_response_wrapper( + invoices.mark_uncollectible, + ) self.void = to_streamed_response_wrapper( invoices.void, ) @@ -1324,6 +1492,12 @@ def __init__(self, invoices: AsyncInvoicesResource) -> None: self.list = async_to_streamed_response_wrapper( invoices.list, ) + self.mark_paid = async_to_streamed_response_wrapper( + invoices.mark_paid, + ) + self.mark_uncollectible = async_to_streamed_response_wrapper( + invoices.mark_uncollectible, + ) self.void = async_to_streamed_response_wrapper( invoices.void, ) diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py index aa689be7..95e067c7 100644 --- a/src/whop_sdk/types/__init__.py +++ b/src/whop_sdk/types/__init__.py @@ -133,6 +133,7 @@ from .payment_list_params import PaymentListParams as PaymentListParams from .product_list_params import ProductListParams as ProductListParams from .setup_intent_status import SetupIntentStatus as SetupIntentStatus +from .tax_identifier_type import TaxIdentifierType as TaxIdentifierType from .topup_create_params import TopupCreateParams as TopupCreateParams from .verification_status import VerificationStatus as VerificationStatus from .webhook_list_params import WebhookListParams as WebhookListParams @@ -258,6 +259,7 @@ from .fee_markup_create_response import FeeMarkupCreateResponse as FeeMarkupCreateResponse from .fee_markup_delete_response import FeeMarkupDeleteResponse as FeeMarkupDeleteResponse from .forum_post_visibility_type import ForumPostVisibilityType as ForumPostVisibilityType +from .invoice_mark_paid_response import InvoiceMarkPaidResponse as InvoiceMarkPaidResponse from .invoice_paid_webhook_event import InvoicePaidWebhookEvent as InvoicePaidWebhookEvent from .notification_create_params import NotificationCreateParams as NotificationCreateParams from .payment_list_fees_response import PaymentListFeesResponse as PaymentListFeesResponse @@ -328,6 +330,7 @@ from .payout_account_calculated_statuses import PayoutAccountCalculatedStatuses as PayoutAccountCalculatedStatuses from .resolution_center_case_list_params import ResolutionCenterCaseListParams as ResolutionCenterCaseListParams from .dispute_alert_created_webhook_event import DisputeAlertCreatedWebhookEvent as DisputeAlertCreatedWebhookEvent +from .invoice_mark_uncollectible_response import InvoiceMarkUncollectibleResponse as InvoiceMarkUncollectibleResponse from .payout_method_created_webhook_event import PayoutMethodCreatedWebhookEvent as PayoutMethodCreatedWebhookEvent from .setup_intent_canceled_webhook_event import SetupIntentCanceledWebhookEvent as SetupIntentCanceledWebhookEvent from .checkout_configuration_create_params import CheckoutConfigurationCreateParams as CheckoutConfigurationCreateParams diff --git a/src/whop_sdk/types/invoice_create_params.py b/src/whop_sdk/types/invoice_create_params.py index 637f4ce8..a197501f 100644 --- a/src/whop_sdk/types/invoice_create_params.py +++ b/src/whop_sdk/types/invoice_create_params.py @@ -9,6 +9,7 @@ from .._utils import PropertyInfo from .shared.plan_type import PlanType from .shared.visibility import Visibility +from .tax_identifier_type import TaxIdentifierType from .shared.release_method import ReleaseMethod from .shared.collection_method import CollectionMethod @@ -243,121 +244,7 @@ class CreateInvoiceInputWithProductAndMemberIDBillingAddress(TypedDict, total=Fa state: Optional[str] """The state of the address.""" - tax_id_type: Optional[ - Literal[ - "ad_nrt", - "ao_tin", - "ar_cuit", - "am_tin", - "aw_tin", - "au_abn", - "au_arn", - "eu_vat", - "az_tin", - "bs_tin", - "bh_vat", - "bd_bin", - "bb_tin", - "by_tin", - "bj_ifu", - "bo_tin", - "ba_tin", - "br_cnpj", - "br_cpf", - "bg_uic", - "bf_ifu", - "kh_tin", - "cm_niu", - "ca_bn", - "ca_gst_hst", - "ca_pst_bc", - "ca_pst_mb", - "ca_pst_sk", - "ca_qst", - "cv_nif", - "cl_tin", - "cn_tin", - "co_nit", - "cd_nif", - "cr_tin", - "hr_oib", - "do_rcn", - "ec_ruc", - "eg_tin", - "sv_nit", - "et_tin", - "eu_oss_vat", - "ge_vat", - "de_stn", - "gb_vat", - "gn_nif", - "hk_br", - "hu_tin", - "is_vat", - "in_gst", - "id_npwp", - "il_vat", - "jp_cn", - "jp_rn", - "jp_trn", - "kz_bin", - "ke_pin", - "kg_tin", - "la_tin", - "li_uid", - "li_vat", - "my_frp", - "my_itn", - "my_sst", - "mr_nif", - "mx_rfc", - "md_vat", - "me_pib", - "ma_vat", - "np_pan", - "nz_gst", - "ng_tin", - "mk_vat", - "no_vat", - "no_voec", - "om_vat", - "pe_ruc", - "ph_tin", - "pl_nip", - "ro_tin", - "ru_inn", - "ru_kpp", - "sa_vat", - "sn_ninea", - "rs_pib", - "sg_gst", - "sg_uen", - "si_tin", - "za_vat", - "kr_brn", - "es_cif", - "ch_uid", - "ch_vat", - "tw_vat", - "tj_tin", - "tz_vat", - "th_vat", - "tr_tin", - "ug_tin", - "ua_vat", - "ae_trn", - "us_ein", - "uy_ruc", - "uz_tin", - "uz_vat", - "ve_rif", - "vn_tin", - "zm_tin", - "zw_tin", - "sr_fin", - "xi_vat", - ] - ] + tax_id_type: Optional[TaxIdentifierType] """The type of tax identifier""" tax_id_value: Optional[str] @@ -587,121 +474,7 @@ class CreateInvoiceInputWithProductAndEmailAddressBillingAddress(TypedDict, tota state: Optional[str] """The state of the address.""" - tax_id_type: Optional[ - Literal[ - "ad_nrt", - "ao_tin", - "ar_cuit", - "am_tin", - "aw_tin", - "au_abn", - "au_arn", - "eu_vat", - "az_tin", - "bs_tin", - "bh_vat", - "bd_bin", - "bb_tin", - "by_tin", - "bj_ifu", - "bo_tin", - "ba_tin", - "br_cnpj", - "br_cpf", - "bg_uic", - "bf_ifu", - "kh_tin", - "cm_niu", - "ca_bn", - "ca_gst_hst", - "ca_pst_bc", - "ca_pst_mb", - "ca_pst_sk", - "ca_qst", - "cv_nif", - "cl_tin", - "cn_tin", - "co_nit", - "cd_nif", - "cr_tin", - "hr_oib", - "do_rcn", - "ec_ruc", - "eg_tin", - "sv_nit", - "et_tin", - "eu_oss_vat", - "ge_vat", - "de_stn", - "gb_vat", - "gn_nif", - "hk_br", - "hu_tin", - "is_vat", - "in_gst", - "id_npwp", - "il_vat", - "jp_cn", - "jp_rn", - "jp_trn", - "kz_bin", - "ke_pin", - "kg_tin", - "la_tin", - "li_uid", - "li_vat", - "my_frp", - "my_itn", - "my_sst", - "mr_nif", - "mx_rfc", - "md_vat", - "me_pib", - "ma_vat", - "np_pan", - "nz_gst", - "ng_tin", - "mk_vat", - "no_vat", - "no_voec", - "om_vat", - "pe_ruc", - "ph_tin", - "pl_nip", - "ro_tin", - "ru_inn", - "ru_kpp", - "sa_vat", - "sn_ninea", - "rs_pib", - "sg_gst", - "sg_uen", - "si_tin", - "za_vat", - "kr_brn", - "es_cif", - "ch_uid", - "ch_vat", - "tw_vat", - "tj_tin", - "tz_vat", - "th_vat", - "tr_tin", - "ug_tin", - "ua_vat", - "ae_trn", - "us_ein", - "uy_ruc", - "uz_tin", - "uz_vat", - "ve_rif", - "vn_tin", - "zm_tin", - "zw_tin", - "sr_fin", - "xi_vat", - ] - ] + tax_id_type: Optional[TaxIdentifierType] """The type of tax identifier""" tax_id_value: Optional[str] @@ -914,121 +687,7 @@ class CreateInvoiceInputWithProductIDAndMemberIDBillingAddress(TypedDict, total= state: Optional[str] """The state of the address.""" - tax_id_type: Optional[ - Literal[ - "ad_nrt", - "ao_tin", - "ar_cuit", - "am_tin", - "aw_tin", - "au_abn", - "au_arn", - "eu_vat", - "az_tin", - "bs_tin", - "bh_vat", - "bd_bin", - "bb_tin", - "by_tin", - "bj_ifu", - "bo_tin", - "ba_tin", - "br_cnpj", - "br_cpf", - "bg_uic", - "bf_ifu", - "kh_tin", - "cm_niu", - "ca_bn", - "ca_gst_hst", - "ca_pst_bc", - "ca_pst_mb", - "ca_pst_sk", - "ca_qst", - "cv_nif", - "cl_tin", - "cn_tin", - "co_nit", - "cd_nif", - "cr_tin", - "hr_oib", - "do_rcn", - "ec_ruc", - "eg_tin", - "sv_nit", - "et_tin", - "eu_oss_vat", - "ge_vat", - "de_stn", - "gb_vat", - "gn_nif", - "hk_br", - "hu_tin", - "is_vat", - "in_gst", - "id_npwp", - "il_vat", - "jp_cn", - "jp_rn", - "jp_trn", - "kz_bin", - "ke_pin", - "kg_tin", - "la_tin", - "li_uid", - "li_vat", - "my_frp", - "my_itn", - "my_sst", - "mr_nif", - "mx_rfc", - "md_vat", - "me_pib", - "ma_vat", - "np_pan", - "nz_gst", - "ng_tin", - "mk_vat", - "no_vat", - "no_voec", - "om_vat", - "pe_ruc", - "ph_tin", - "pl_nip", - "ro_tin", - "ru_inn", - "ru_kpp", - "sa_vat", - "sn_ninea", - "rs_pib", - "sg_gst", - "sg_uen", - "si_tin", - "za_vat", - "kr_brn", - "es_cif", - "ch_uid", - "ch_vat", - "tw_vat", - "tj_tin", - "tz_vat", - "th_vat", - "tr_tin", - "ug_tin", - "ua_vat", - "ae_trn", - "us_ein", - "uy_ruc", - "uz_tin", - "uz_vat", - "ve_rif", - "vn_tin", - "zm_tin", - "zw_tin", - "sr_fin", - "xi_vat", - ] - ] + tax_id_type: Optional[TaxIdentifierType] """The type of tax identifier""" tax_id_value: Optional[str] @@ -1242,121 +901,7 @@ class CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress(TypedDict, to state: Optional[str] """The state of the address.""" - tax_id_type: Optional[ - Literal[ - "ad_nrt", - "ao_tin", - "ar_cuit", - "am_tin", - "aw_tin", - "au_abn", - "au_arn", - "eu_vat", - "az_tin", - "bs_tin", - "bh_vat", - "bd_bin", - "bb_tin", - "by_tin", - "bj_ifu", - "bo_tin", - "ba_tin", - "br_cnpj", - "br_cpf", - "bg_uic", - "bf_ifu", - "kh_tin", - "cm_niu", - "ca_bn", - "ca_gst_hst", - "ca_pst_bc", - "ca_pst_mb", - "ca_pst_sk", - "ca_qst", - "cv_nif", - "cl_tin", - "cn_tin", - "co_nit", - "cd_nif", - "cr_tin", - "hr_oib", - "do_rcn", - "ec_ruc", - "eg_tin", - "sv_nit", - "et_tin", - "eu_oss_vat", - "ge_vat", - "de_stn", - "gb_vat", - "gn_nif", - "hk_br", - "hu_tin", - "is_vat", - "in_gst", - "id_npwp", - "il_vat", - "jp_cn", - "jp_rn", - "jp_trn", - "kz_bin", - "ke_pin", - "kg_tin", - "la_tin", - "li_uid", - "li_vat", - "my_frp", - "my_itn", - "my_sst", - "mr_nif", - "mx_rfc", - "md_vat", - "me_pib", - "ma_vat", - "np_pan", - "nz_gst", - "ng_tin", - "mk_vat", - "no_vat", - "no_voec", - "om_vat", - "pe_ruc", - "ph_tin", - "pl_nip", - "ro_tin", - "ru_inn", - "ru_kpp", - "sa_vat", - "sn_ninea", - "rs_pib", - "sg_gst", - "sg_uen", - "si_tin", - "za_vat", - "kr_brn", - "es_cif", - "ch_uid", - "ch_vat", - "tw_vat", - "tj_tin", - "tz_vat", - "th_vat", - "tr_tin", - "ug_tin", - "ua_vat", - "ae_trn", - "us_ein", - "uy_ruc", - "uz_tin", - "uz_vat", - "ve_rif", - "vn_tin", - "zm_tin", - "zw_tin", - "sr_fin", - "xi_vat", - ] - ] + tax_id_type: Optional[TaxIdentifierType] """The type of tax identifier""" tax_id_value: Optional[str] diff --git a/src/whop_sdk/types/invoice_mark_paid_response.py b/src/whop_sdk/types/invoice_mark_paid_response.py new file mode 100644 index 00000000..4ea337e1 --- /dev/null +++ b/src/whop_sdk/types/invoice_mark_paid_response.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import TypeAlias + +__all__ = ["InvoiceMarkPaidResponse"] + +InvoiceMarkPaidResponse: TypeAlias = bool diff --git a/src/whop_sdk/types/invoice_mark_uncollectible_response.py b/src/whop_sdk/types/invoice_mark_uncollectible_response.py new file mode 100644 index 00000000..a34c66d8 --- /dev/null +++ b/src/whop_sdk/types/invoice_mark_uncollectible_response.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import TypeAlias + +__all__ = ["InvoiceMarkUncollectibleResponse"] + +InvoiceMarkUncollectibleResponse: TypeAlias = bool diff --git a/src/whop_sdk/types/tax_identifier_type.py b/src/whop_sdk/types/tax_identifier_type.py new file mode 100644 index 00000000..6b186a3c --- /dev/null +++ b/src/whop_sdk/types/tax_identifier_type.py @@ -0,0 +1,119 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["TaxIdentifierType"] + +TaxIdentifierType: TypeAlias = Literal[ + "ad_nrt", + "ao_tin", + "ar_cuit", + "am_tin", + "aw_tin", + "au_abn", + "au_arn", + "eu_vat", + "az_tin", + "bs_tin", + "bh_vat", + "bd_bin", + "bb_tin", + "by_tin", + "bj_ifu", + "bo_tin", + "ba_tin", + "br_cnpj", + "br_cpf", + "bg_uic", + "bf_ifu", + "kh_tin", + "cm_niu", + "ca_bn", + "ca_gst_hst", + "ca_pst_bc", + "ca_pst_mb", + "ca_pst_sk", + "ca_qst", + "cv_nif", + "cl_tin", + "cn_tin", + "co_nit", + "cd_nif", + "cr_tin", + "hr_oib", + "do_rcn", + "ec_ruc", + "eg_tin", + "sv_nit", + "et_tin", + "eu_oss_vat", + "ge_vat", + "de_stn", + "gb_vat", + "gn_nif", + "hk_br", + "hu_tin", + "is_vat", + "in_gst", + "id_npwp", + "il_vat", + "jp_cn", + "jp_rn", + "jp_trn", + "kz_bin", + "ke_pin", + "kg_tin", + "la_tin", + "li_uid", + "li_vat", + "my_frp", + "my_itn", + "my_sst", + "mr_nif", + "mx_rfc", + "md_vat", + "me_pib", + "ma_vat", + "np_pan", + "nz_gst", + "ng_tin", + "mk_vat", + "no_vat", + "no_voec", + "om_vat", + "pe_ruc", + "ph_tin", + "pl_nip", + "ro_tin", + "ru_inn", + "ru_kpp", + "sa_vat", + "sn_ninea", + "rs_pib", + "sg_gst", + "sg_uen", + "si_tin", + "za_vat", + "kr_brn", + "es_cif", + "ch_uid", + "ch_vat", + "tw_vat", + "tj_tin", + "tz_vat", + "th_vat", + "tr_tin", + "ug_tin", + "ua_vat", + "ae_trn", + "us_ein", + "uy_ruc", + "uz_tin", + "uz_vat", + "ve_rif", + "vn_tin", + "zm_tin", + "zw_tin", + "sr_fin", + "xi_vat", +] diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py index a24e8d9c..97377e33 100644 --- a/tests/api_resources/test_invoices.py +++ b/tests/api_resources/test_invoices.py @@ -9,7 +9,11 @@ from whop_sdk import Whop, AsyncWhop from tests.utils import assert_matches_type -from whop_sdk.types import InvoiceVoidResponse +from whop_sdk.types import ( + InvoiceVoidResponse, + InvoiceMarkPaidResponse, + InvoiceMarkUncollectibleResponse, +) from whop_sdk._utils import parse_datetime from whop_sdk.pagination import SyncCursorPage, AsyncCursorPage from whop_sdk.types.shared import Invoice, InvoiceListItem @@ -561,6 +565,90 @@ def test_streaming_response_list(self, client: Whop) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_mark_paid(self, client: Whop) -> None: + invoice = client.invoices.mark_paid( + "inv_xxxxxxxxxxxxxx", + ) + assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_mark_paid(self, client: Whop) -> None: + response = client.invoices.with_raw_response.mark_paid( + "inv_xxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + invoice = response.parse() + assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_mark_paid(self, client: Whop) -> None: + with client.invoices.with_streaming_response.mark_paid( + "inv_xxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + invoice = response.parse() + assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_mark_paid(self, client: Whop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.invoices.with_raw_response.mark_paid( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_mark_uncollectible(self, client: Whop) -> None: + invoice = client.invoices.mark_uncollectible( + "inv_xxxxxxxxxxxxxx", + ) + assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_mark_uncollectible(self, client: Whop) -> None: + response = client.invoices.with_raw_response.mark_uncollectible( + "inv_xxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + invoice = response.parse() + assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_mark_uncollectible(self, client: Whop) -> None: + with client.invoices.with_streaming_response.mark_uncollectible( + "inv_xxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + invoice = response.parse() + assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_mark_uncollectible(self, client: Whop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.invoices.with_raw_response.mark_uncollectible( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_void(self, client: Whop) -> None: @@ -1150,6 +1238,90 @@ async def test_streaming_response_list(self, async_client: AsyncWhop) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_mark_paid(self, async_client: AsyncWhop) -> None: + invoice = await async_client.invoices.mark_paid( + "inv_xxxxxxxxxxxxxx", + ) + assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_mark_paid(self, async_client: AsyncWhop) -> None: + response = await async_client.invoices.with_raw_response.mark_paid( + "inv_xxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + invoice = await response.parse() + assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_mark_paid(self, async_client: AsyncWhop) -> None: + async with async_client.invoices.with_streaming_response.mark_paid( + "inv_xxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + invoice = await response.parse() + assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_mark_paid(self, async_client: AsyncWhop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.invoices.with_raw_response.mark_paid( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_mark_uncollectible(self, async_client: AsyncWhop) -> None: + invoice = await async_client.invoices.mark_uncollectible( + "inv_xxxxxxxxxxxxxx", + ) + assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_mark_uncollectible(self, async_client: AsyncWhop) -> None: + response = await async_client.invoices.with_raw_response.mark_uncollectible( + "inv_xxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + invoice = await response.parse() + assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_mark_uncollectible(self, async_client: AsyncWhop) -> None: + async with async_client.invoices.with_streaming_response.mark_uncollectible( + "inv_xxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + invoice = await response.parse() + assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_mark_uncollectible(self, async_client: AsyncWhop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.invoices.with_raw_response.mark_uncollectible( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_void(self, async_client: AsyncWhop) -> None: From 6f857b22e4db5b371779e0759ddbd82752a0acc9 Mon Sep 17 00:00:00 2001 From: Jon Harrell <4829245+jharrell@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:39:37 -0500 Subject: [PATCH 32/39] fix: add missing import and response wrappers for add_free_days method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The membership_add_free_days_params import and raw/streaming response wrappers were dropped during a generated→next merge. --- src/whop_sdk/resources/memberships.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/whop_sdk/resources/memberships.py b/src/whop_sdk/resources/memberships.py index 4045d089..c984344c 100644 --- a/src/whop_sdk/resources/memberships.py +++ b/src/whop_sdk/resources/memberships.py @@ -13,6 +13,7 @@ membership_pause_params, membership_cancel_params, membership_update_params, + membership_add_free_days_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from .._utils import path_template, maybe_transform, async_maybe_transform @@ -908,6 +909,9 @@ def __init__(self, memberships: MembershipsResource) -> None: self.list = to_raw_response_wrapper( memberships.list, ) + self.add_free_days = to_raw_response_wrapper( + memberships.add_free_days, + ) self.cancel = to_raw_response_wrapper( memberships.cancel, ) @@ -935,6 +939,9 @@ def __init__(self, memberships: AsyncMembershipsResource) -> None: self.list = async_to_raw_response_wrapper( memberships.list, ) + self.add_free_days = async_to_raw_response_wrapper( + memberships.add_free_days, + ) self.cancel = async_to_raw_response_wrapper( memberships.cancel, ) @@ -962,6 +969,9 @@ def __init__(self, memberships: MembershipsResource) -> None: self.list = to_streamed_response_wrapper( memberships.list, ) + self.add_free_days = to_streamed_response_wrapper( + memberships.add_free_days, + ) self.cancel = to_streamed_response_wrapper( memberships.cancel, ) @@ -989,6 +999,9 @@ def __init__(self, memberships: AsyncMembershipsResource) -> None: self.list = async_to_streamed_response_wrapper( memberships.list, ) + self.add_free_days = async_to_streamed_response_wrapper( + memberships.add_free_days, + ) self.cancel = async_to_streamed_response_wrapper( memberships.cancel, ) From c2694e3e189f52f64006c5b2503b901f31fcfe71 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:13:43 +0000 Subject: [PATCH 33/39] feat(api): api update --- .stats.yml | 4 +- .../resources/checkout_configurations.py | 56 +++++++++++++++ src/whop_sdk/resources/plans.py | 20 ++++++ .../checkout_configuration_create_params.py | 69 +++++++++++++++++++ src/whop_sdk/types/plan_create_params.py | 24 ++++++- src/whop_sdk/types/plan_update_params.py | 24 ++++++- .../test_checkout_configurations.py | 30 ++++++++ tests/api_resources/test_plans.py | 20 ++++++ 8 files changed, 243 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6681f367..c696f3cd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-dbc99b95f02e6b568750045987763dbdafa1edc5a7ac425e3831e61929d7ecec.yml -openapi_spec_hash: d2ec900df5b29b03d1d1786336d1daf5 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-8b51c179bc893fda87f78c0fe9fb6129549814ca33712d56e5b09b114565f15c.yml +openapi_spec_hash: 9d7a0acc81ca74048cd72db27ff89fac config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a diff --git a/src/whop_sdk/resources/checkout_configurations.py b/src/whop_sdk/resources/checkout_configurations.py index ca43a5f8..91d5e5d7 100644 --- a/src/whop_sdk/resources/checkout_configurations.py +++ b/src/whop_sdk/resources/checkout_configurations.py @@ -55,6 +55,10 @@ def create( *, plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan, affiliate_code: Optional[str] | Omit = omit, + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling + ] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, mode: Literal["payment"] | Omit = omit, @@ -87,6 +91,9 @@ def create( affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate. + checkout_styling: Checkout styling overrides for this session. Overrides plan and company + defaults. + currency: The available currencies on the platform metadata: Custom key-value metadata to attach to the checkout configuration. @@ -114,6 +121,10 @@ def create( *, plan_id: str, affiliate_code: Optional[str] | Omit = omit, + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling + ] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, mode: Literal["payment"] | Omit = omit, @@ -147,6 +158,9 @@ def create( affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate. + checkout_styling: Checkout styling overrides for this session. Overrides plan and company + defaults. + currency: The available currencies on the platform metadata: Custom key-value metadata to attach to the checkout configuration. @@ -174,6 +188,10 @@ def create( *, company_id: str, mode: Literal["setup"], + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling + ] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, payment_method_configuration: Optional[ @@ -204,6 +222,9 @@ def create( company_id: The unique identifier of the company to create the checkout configuration for. Only required in setup mode. + checkout_styling: Checkout styling overrides for this session. Overrides plan and company + defaults. + currency: The available currencies on the platform metadata: Custom key-value metadata to attach to the checkout configuration. @@ -231,6 +252,12 @@ def create( *, plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan | Omit = omit, affiliate_code: Optional[str] | Omit = omit, + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling + ] + | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling] + | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, mode: Literal["payment"] | Literal["setup"] | Omit = omit, @@ -259,6 +286,7 @@ def create( { "plan": plan, "affiliate_code": affiliate_code, + "checkout_styling": checkout_styling, "currency": currency, "metadata": metadata, "mode": mode, @@ -421,6 +449,10 @@ async def create( *, plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan, affiliate_code: Optional[str] | Omit = omit, + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling + ] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, mode: Literal["payment"] | Omit = omit, @@ -453,6 +485,9 @@ async def create( affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate. + checkout_styling: Checkout styling overrides for this session. Overrides plan and company + defaults. + currency: The available currencies on the platform metadata: Custom key-value metadata to attach to the checkout configuration. @@ -480,6 +515,10 @@ async def create( *, plan_id: str, affiliate_code: Optional[str] | Omit = omit, + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling + ] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, mode: Literal["payment"] | Omit = omit, @@ -513,6 +552,9 @@ async def create( affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate. + checkout_styling: Checkout styling overrides for this session. Overrides plan and company + defaults. + currency: The available currencies on the platform metadata: Custom key-value metadata to attach to the checkout configuration. @@ -540,6 +582,10 @@ async def create( *, company_id: str, mode: Literal["setup"], + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling + ] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, payment_method_configuration: Optional[ @@ -570,6 +616,9 @@ async def create( company_id: The unique identifier of the company to create the checkout configuration for. Only required in setup mode. + checkout_styling: Checkout styling overrides for this session. Overrides plan and company + defaults. + currency: The available currencies on the platform metadata: Custom key-value metadata to attach to the checkout configuration. @@ -597,6 +646,12 @@ async def create( *, plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan | Omit = omit, affiliate_code: Optional[str] | Omit = omit, + checkout_styling: Optional[ + checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling + ] + | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling] + | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling] + | Omit = omit, currency: Optional[Currency] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, mode: Literal["payment"] | Literal["setup"] | Omit = omit, @@ -625,6 +680,7 @@ async def create( { "plan": plan, "affiliate_code": affiliate_code, + "checkout_styling": checkout_styling, "currency": currency, "metadata": metadata, "mode": mode, diff --git a/src/whop_sdk/resources/plans.py b/src/whop_sdk/resources/plans.py index 542bf59a..a0f6dac1 100644 --- a/src/whop_sdk/resources/plans.py +++ b/src/whop_sdk/resources/plans.py @@ -61,6 +61,7 @@ def create( company_id: str, product_id: str, billing_period: Optional[int] | Omit = omit, + checkout_styling: Optional[plan_create_params.CheckoutStyling] | Omit = omit, currency: Optional[Currency] | Omit = omit, custom_fields: Optional[Iterable[plan_create_params.CustomField]] | Omit = omit, description: Optional[str] | Omit = omit, @@ -106,6 +107,9 @@ def create( billing_period: The number of days between recurring charges. For example, 30 for monthly or 365 for yearly. + checkout_styling: Checkout styling overrides for this plan. Pass null to inherit from the company + default. + currency: The available currencies on the platform custom_fields: An array of custom field definitions to collect from customers at checkout. @@ -167,6 +171,7 @@ def create( "company_id": company_id, "product_id": product_id, "billing_period": billing_period, + "checkout_styling": checkout_styling, "currency": currency, "custom_fields": custom_fields, "description": description, @@ -237,6 +242,7 @@ def update( id: str, *, billing_period: Optional[int] | Omit = omit, + checkout_styling: Optional[plan_update_params.CheckoutStyling] | Omit = omit, currency: Optional[Currency] | Omit = omit, custom_fields: Optional[Iterable[plan_update_params.CustomField]] | Omit = omit, description: Optional[str] | Omit = omit, @@ -277,6 +283,9 @@ def update( billing_period: The number of days between recurring charges. For example, 30 for monthly or 365 for yearly. + checkout_styling: Checkout styling overrides for this plan. Pass null to remove all overrides and + inherit from the company default. + currency: The available currencies on the platform custom_fields: An array of custom field definitions to collect from customers at checkout. @@ -338,6 +347,7 @@ def update( body=maybe_transform( { "billing_period": billing_period, + "checkout_styling": checkout_styling, "currency": currency, "custom_fields": custom_fields, "description": description, @@ -529,6 +539,7 @@ async def create( company_id: str, product_id: str, billing_period: Optional[int] | Omit = omit, + checkout_styling: Optional[plan_create_params.CheckoutStyling] | Omit = omit, currency: Optional[Currency] | Omit = omit, custom_fields: Optional[Iterable[plan_create_params.CustomField]] | Omit = omit, description: Optional[str] | Omit = omit, @@ -574,6 +585,9 @@ async def create( billing_period: The number of days between recurring charges. For example, 30 for monthly or 365 for yearly. + checkout_styling: Checkout styling overrides for this plan. Pass null to inherit from the company + default. + currency: The available currencies on the platform custom_fields: An array of custom field definitions to collect from customers at checkout. @@ -635,6 +649,7 @@ async def create( "company_id": company_id, "product_id": product_id, "billing_period": billing_period, + "checkout_styling": checkout_styling, "currency": currency, "custom_fields": custom_fields, "description": description, @@ -705,6 +720,7 @@ async def update( id: str, *, billing_period: Optional[int] | Omit = omit, + checkout_styling: Optional[plan_update_params.CheckoutStyling] | Omit = omit, currency: Optional[Currency] | Omit = omit, custom_fields: Optional[Iterable[plan_update_params.CustomField]] | Omit = omit, description: Optional[str] | Omit = omit, @@ -745,6 +761,9 @@ async def update( billing_period: The number of days between recurring charges. For example, 30 for monthly or 365 for yearly. + checkout_styling: Checkout styling overrides for this plan. Pass null to remove all overrides and + inherit from the company default. + currency: The available currencies on the platform custom_fields: An array of custom field definitions to collect from customers at checkout. @@ -806,6 +825,7 @@ async def update( body=await async_maybe_transform( { "billing_period": billing_period, + "checkout_styling": checkout_styling, "currency": currency, "custom_fields": custom_fields, "description": description, diff --git a/src/whop_sdk/types/checkout_configuration_create_params.py b/src/whop_sdk/types/checkout_configuration_create_params.py index cf71c431..c7b46bbf 100644 --- a/src/whop_sdk/types/checkout_configuration_create_params.py +++ b/src/whop_sdk/types/checkout_configuration_create_params.py @@ -21,10 +21,13 @@ "CreateCheckoutSessionInputModePaymentWithPlanPlanImage", "CreateCheckoutSessionInputModePaymentWithPlanPlanPaymentMethodConfiguration", "CreateCheckoutSessionInputModePaymentWithPlanPlanProduct", + "CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling", "CreateCheckoutSessionInputModePaymentWithPlanPaymentMethodConfiguration", "CreateCheckoutSessionInputModePaymentWithPlanID", + "CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling", "CreateCheckoutSessionInputModePaymentWithPlanIDPaymentMethodConfiguration", "CreateCheckoutSessionInputModeSetup", + "CreateCheckoutSessionInputModeSetupCheckoutStyling", "CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration", ] @@ -38,6 +41,12 @@ class CreateCheckoutSessionInputModePaymentWithPlan(TypedDict, total=False): affiliate_code: Optional[str] """An affiliate tracking code to attribute the checkout to a specific affiliate.""" + checkout_styling: Optional[CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling] + """Checkout styling overrides for this session. + + Overrides plan and company defaults. + """ + currency: Optional[Currency] """The available currencies on the platform""" @@ -275,6 +284,22 @@ class CreateCheckoutSessionInputModePaymentWithPlanPlan(TypedDict, total=False): """Visibility of a resource""" +class CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling(TypedDict, total=False): + """Checkout styling overrides for this session. + + Overrides plan and company defaults. + """ + + accent_color: Optional[str] + """The hex color code for the accent color on checkout pages.""" + + font: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" + + shape: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" + + class CreateCheckoutSessionInputModePaymentWithPlanPaymentMethodConfiguration(TypedDict, total=False): """The explicit payment method configuration for the checkout session. @@ -313,6 +338,12 @@ class CreateCheckoutSessionInputModePaymentWithPlanID(TypedDict, total=False): affiliate_code: Optional[str] """An affiliate tracking code to attribute the checkout to a specific affiliate.""" + checkout_styling: Optional[CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling] + """Checkout styling overrides for this session. + + Overrides plan and company defaults. + """ + currency: Optional[Currency] """The available currencies on the platform""" @@ -335,6 +366,22 @@ class CreateCheckoutSessionInputModePaymentWithPlanID(TypedDict, total=False): """The URL of the page where the checkout is being initiated from.""" +class CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling(TypedDict, total=False): + """Checkout styling overrides for this session. + + Overrides plan and company defaults. + """ + + accent_color: Optional[str] + """The hex color code for the accent color on checkout pages.""" + + font: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" + + shape: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" + + class CreateCheckoutSessionInputModePaymentWithPlanIDPaymentMethodConfiguration(TypedDict, total=False): """The explicit payment method configuration for the checkout session. @@ -372,6 +419,12 @@ class CreateCheckoutSessionInputModeSetup(TypedDict, total=False): mode: Required[Literal["setup"]] + checkout_styling: Optional[CreateCheckoutSessionInputModeSetupCheckoutStyling] + """Checkout styling overrides for this session. + + Overrides plan and company defaults. + """ + currency: Optional[Currency] """The available currencies on the platform""" @@ -392,6 +445,22 @@ class CreateCheckoutSessionInputModeSetup(TypedDict, total=False): """The URL of the page where the checkout is being initiated from.""" +class CreateCheckoutSessionInputModeSetupCheckoutStyling(TypedDict, total=False): + """Checkout styling overrides for this session. + + Overrides plan and company defaults. + """ + + accent_color: Optional[str] + """The hex color code for the accent color on checkout pages.""" + + font: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" + + shape: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" + + class CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration(TypedDict, total=False): """The explicit payment method configuration for the checkout session. diff --git a/src/whop_sdk/types/plan_create_params.py b/src/whop_sdk/types/plan_create_params.py index 5fd63def..e5962021 100644 --- a/src/whop_sdk/types/plan_create_params.py +++ b/src/whop_sdk/types/plan_create_params.py @@ -12,7 +12,7 @@ from .payment_method_types import PaymentMethodTypes from .shared.release_method import ReleaseMethod -__all__ = ["PlanCreateParams", "CustomField", "Image", "PaymentMethodConfiguration"] +__all__ = ["PlanCreateParams", "CheckoutStyling", "CustomField", "Image", "PaymentMethodConfiguration"] class PlanCreateParams(TypedDict, total=False): @@ -28,6 +28,12 @@ class PlanCreateParams(TypedDict, total=False): For example, 30 for monthly or 365 for yearly. """ + checkout_styling: Optional[CheckoutStyling] + """Checkout styling overrides for this plan. + + Pass null to inherit from the company default. + """ + currency: Optional[Currency] """The available currencies on the platform""" @@ -109,6 +115,22 @@ class PlanCreateParams(TypedDict, total=False): """Visibility of a resource""" +class CheckoutStyling(TypedDict, total=False): + """Checkout styling overrides for this plan. + + Pass null to inherit from the company default. + """ + + accent_color: Optional[str] + """The hex color code for the accent color on checkout pages.""" + + font: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" + + shape: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" + + class CustomField(TypedDict, total=False): field_type: Required[Literal["text"]] """The type of the custom field.""" diff --git a/src/whop_sdk/types/plan_update_params.py b/src/whop_sdk/types/plan_update_params.py index 6750817a..67f28ab7 100644 --- a/src/whop_sdk/types/plan_update_params.py +++ b/src/whop_sdk/types/plan_update_params.py @@ -10,7 +10,7 @@ from .shared.visibility import Visibility from .payment_method_types import PaymentMethodTypes -__all__ = ["PlanUpdateParams", "CustomField", "Image", "PaymentMethodConfiguration"] +__all__ = ["PlanUpdateParams", "CheckoutStyling", "CustomField", "Image", "PaymentMethodConfiguration"] class PlanUpdateParams(TypedDict, total=False): @@ -20,6 +20,12 @@ class PlanUpdateParams(TypedDict, total=False): For example, 30 for monthly or 365 for yearly. """ + checkout_styling: Optional[CheckoutStyling] + """Checkout styling overrides for this plan. + + Pass null to remove all overrides and inherit from the company default. + """ + currency: Optional[Currency] """The available currencies on the platform""" @@ -102,6 +108,22 @@ class PlanUpdateParams(TypedDict, total=False): """Visibility of a resource""" +class CheckoutStyling(TypedDict, total=False): + """Checkout styling overrides for this plan. + + Pass null to remove all overrides and inherit from the company default. + """ + + accent_color: Optional[str] + """The hex color code for the accent color on checkout pages.""" + + font: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" + + shape: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" + + class CustomField(TypedDict, total=False): field_type: Required[Literal["text"]] """The type of the custom field.""" diff --git a/tests/api_resources/test_checkout_configurations.py b/tests/api_resources/test_checkout_configurations.py index 8345d28a..75747767 100644 --- a/tests/api_resources/test_checkout_configurations.py +++ b/tests/api_resources/test_checkout_configurations.py @@ -89,6 +89,11 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: "visibility": "visible", }, affiliate_code="affiliate_code", + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", metadata={"foo": "bar"}, mode="payment", @@ -148,6 +153,11 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None: checkout_configuration = client.checkout_configurations.create( plan_id="plan_xxxxxxxxxxxxx", affiliate_code="affiliate_code", + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", metadata={"foo": "bar"}, mode="payment", @@ -202,6 +212,11 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None: checkout_configuration = client.checkout_configurations.create( company_id="biz_xxxxxxxxxxxxxx", mode="setup", + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", metadata={"foo": "bar"}, payment_method_configuration={ @@ -415,6 +430,11 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "visibility": "visible", }, affiliate_code="affiliate_code", + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", metadata={"foo": "bar"}, mode="payment", @@ -474,6 +494,11 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn checkout_configuration = await async_client.checkout_configurations.create( plan_id="plan_xxxxxxxxxxxxx", affiliate_code="affiliate_code", + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", metadata={"foo": "bar"}, mode="payment", @@ -528,6 +553,11 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn checkout_configuration = await async_client.checkout_configurations.create( company_id="biz_xxxxxxxxxxxxxx", mode="setup", + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", metadata={"foo": "bar"}, payment_method_configuration={ diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py index 296e4311..2c4fc401 100644 --- a/tests/api_resources/test_plans.py +++ b/tests/api_resources/test_plans.py @@ -39,6 +39,11 @@ def test_method_create_with_all_params(self, client: Whop) -> None: company_id="biz_xxxxxxxxxxxxxx", product_id="prod_xxxxxxxxxxxxx", billing_period=42, + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", custom_fields=[ { @@ -158,6 +163,11 @@ def test_method_update_with_all_params(self, client: Whop) -> None: plan = client.plans.update( id="plan_xxxxxxxxxxxxx", billing_period=42, + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", custom_fields=[ { @@ -345,6 +355,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N company_id="biz_xxxxxxxxxxxxxx", product_id="prod_xxxxxxxxxxxxx", billing_period=42, + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", custom_fields=[ { @@ -464,6 +479,11 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N plan = await async_client.plans.update( id="plan_xxxxxxxxxxxxx", billing_period=42, + checkout_styling={ + "accent_color": "accent_color", + "font": "system", + "shape": "rounded", + }, currency="usd", custom_fields=[ { From dfd2e5b1fde74bf5d93fa8195e3aa7610c8349e6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 4 Apr 2026 03:13:23 +0000 Subject: [PATCH 34/39] feat(api): api update --- .stats.yml | 4 +-- .../checkout_configuration_create_params.py | 36 +++++++++---------- src/whop_sdk/types/plan_create_params.py | 12 +++---- src/whop_sdk/types/plan_update_params.py | 12 +++---- .../test_checkout_configurations.py | 36 +++++++++---------- tests/api_resources/test_plans.py | 24 ++++++------- 6 files changed, 62 insertions(+), 62 deletions(-) diff --git a/.stats.yml b/.stats.yml index c696f3cd..044c6e46 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-8b51c179bc893fda87f78c0fe9fb6129549814ca33712d56e5b09b114565f15c.yml -openapi_spec_hash: 9d7a0acc81ca74048cd72db27ff89fac +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-a5bc893a2ecec2a58a685d56f3424927011259deb43cc36bd9ed3dab688fd4aa.yml +openapi_spec_hash: 4edf352632cda1cd4b3a25cd335e4fa8 config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a diff --git a/src/whop_sdk/types/checkout_configuration_create_params.py b/src/whop_sdk/types/checkout_configuration_create_params.py index c7b46bbf..ba315598 100644 --- a/src/whop_sdk/types/checkout_configuration_create_params.py +++ b/src/whop_sdk/types/checkout_configuration_create_params.py @@ -290,14 +290,14 @@ class CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling(TypedDict, to Overrides plan and company defaults. """ - accent_color: Optional[str] - """The hex color code for the accent color on checkout pages.""" + border_style: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" - font: Optional[Literal["system", "roboto", "open_sans"]] - """The different font families available for checkout pages.""" + button_color: Optional[str] + """A hex color code for the button color (e.g. #FF5733).""" - shape: Optional[Literal["rounded", "pill", "rectangular"]] - """The different border-radius styles available for checkout pages.""" + font_family: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" class CreateCheckoutSessionInputModePaymentWithPlanPaymentMethodConfiguration(TypedDict, total=False): @@ -372,14 +372,14 @@ class CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling(TypedDict, Overrides plan and company defaults. """ - accent_color: Optional[str] - """The hex color code for the accent color on checkout pages.""" + border_style: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" - font: Optional[Literal["system", "roboto", "open_sans"]] - """The different font families available for checkout pages.""" + button_color: Optional[str] + """A hex color code for the button color (e.g. #FF5733).""" - shape: Optional[Literal["rounded", "pill", "rectangular"]] - """The different border-radius styles available for checkout pages.""" + font_family: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" class CreateCheckoutSessionInputModePaymentWithPlanIDPaymentMethodConfiguration(TypedDict, total=False): @@ -451,15 +451,15 @@ class CreateCheckoutSessionInputModeSetupCheckoutStyling(TypedDict, total=False) Overrides plan and company defaults. """ - accent_color: Optional[str] - """The hex color code for the accent color on checkout pages.""" + border_style: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" + + button_color: Optional[str] + """A hex color code for the button color (e.g. #FF5733).""" - font: Optional[Literal["system", "roboto", "open_sans"]] + font_family: Optional[Literal["system", "roboto", "open_sans"]] """The different font families available for checkout pages.""" - shape: Optional[Literal["rounded", "pill", "rectangular"]] - """The different border-radius styles available for checkout pages.""" - class CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration(TypedDict, total=False): """The explicit payment method configuration for the checkout session. diff --git a/src/whop_sdk/types/plan_create_params.py b/src/whop_sdk/types/plan_create_params.py index e5962021..aebe2136 100644 --- a/src/whop_sdk/types/plan_create_params.py +++ b/src/whop_sdk/types/plan_create_params.py @@ -121,14 +121,14 @@ class CheckoutStyling(TypedDict, total=False): Pass null to inherit from the company default. """ - accent_color: Optional[str] - """The hex color code for the accent color on checkout pages.""" + border_style: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" - font: Optional[Literal["system", "roboto", "open_sans"]] - """The different font families available for checkout pages.""" + button_color: Optional[str] + """A hex color code for the button color (e.g. #FF5733).""" - shape: Optional[Literal["rounded", "pill", "rectangular"]] - """The different border-radius styles available for checkout pages.""" + font_family: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" class CustomField(TypedDict, total=False): diff --git a/src/whop_sdk/types/plan_update_params.py b/src/whop_sdk/types/plan_update_params.py index 67f28ab7..d98f1002 100644 --- a/src/whop_sdk/types/plan_update_params.py +++ b/src/whop_sdk/types/plan_update_params.py @@ -114,14 +114,14 @@ class CheckoutStyling(TypedDict, total=False): Pass null to remove all overrides and inherit from the company default. """ - accent_color: Optional[str] - """The hex color code for the accent color on checkout pages.""" + border_style: Optional[Literal["rounded", "pill", "rectangular"]] + """The different border-radius styles available for checkout pages.""" - font: Optional[Literal["system", "roboto", "open_sans"]] - """The different font families available for checkout pages.""" + button_color: Optional[str] + """A hex color code for the button color (e.g. #FF5733).""" - shape: Optional[Literal["rounded", "pill", "rectangular"]] - """The different border-radius styles available for checkout pages.""" + font_family: Optional[Literal["system", "roboto", "open_sans"]] + """The different font families available for checkout pages.""" class CustomField(TypedDict, total=False): diff --git a/tests/api_resources/test_checkout_configurations.py b/tests/api_resources/test_checkout_configurations.py index 75747767..cb455429 100644 --- a/tests/api_resources/test_checkout_configurations.py +++ b/tests/api_resources/test_checkout_configurations.py @@ -90,9 +90,9 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: }, affiliate_code="affiliate_code", checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", metadata={"foo": "bar"}, @@ -154,9 +154,9 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None: plan_id="plan_xxxxxxxxxxxxx", affiliate_code="affiliate_code", checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", metadata={"foo": "bar"}, @@ -213,9 +213,9 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None: company_id="biz_xxxxxxxxxxxxxx", mode="setup", checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", metadata={"foo": "bar"}, @@ -431,9 +431,9 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn }, affiliate_code="affiliate_code", checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", metadata={"foo": "bar"}, @@ -495,9 +495,9 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn plan_id="plan_xxxxxxxxxxxxx", affiliate_code="affiliate_code", checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", metadata={"foo": "bar"}, @@ -554,9 +554,9 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn company_id="biz_xxxxxxxxxxxxxx", mode="setup", checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", metadata={"foo": "bar"}, diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py index 2c4fc401..33d2cfcd 100644 --- a/tests/api_resources/test_plans.py +++ b/tests/api_resources/test_plans.py @@ -40,9 +40,9 @@ def test_method_create_with_all_params(self, client: Whop) -> None: product_id="prod_xxxxxxxxxxxxx", billing_period=42, checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", custom_fields=[ @@ -164,9 +164,9 @@ def test_method_update_with_all_params(self, client: Whop) -> None: id="plan_xxxxxxxxxxxxx", billing_period=42, checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", custom_fields=[ @@ -356,9 +356,9 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N product_id="prod_xxxxxxxxxxxxx", billing_period=42, checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", custom_fields=[ @@ -480,9 +480,9 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N id="plan_xxxxxxxxxxxxx", billing_period=42, checkout_styling={ - "accent_color": "accent_color", - "font": "system", - "shape": "rounded", + "border_style": "rounded", + "button_color": "button_color", + "font_family": "system", }, currency="usd", custom_fields=[ From f31d7e84b5529842fdc5ec197b9acd6e483b2a5f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 02:13:26 +0000 Subject: [PATCH 35/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 044c6e46..0fa05dd1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-a5bc893a2ecec2a58a685d56f3424927011259deb43cc36bd9ed3dab688fd4aa.yml -openapi_spec_hash: 4edf352632cda1cd4b3a25cd335e4fa8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-e972fd41393b2edf6b6fddb7c52b14da652d4cff58399d5e7fc5b005081b85c1.yml +openapi_spec_hash: ca7941edec9fa06d9319dbb6fd0cc5c8 config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a From 08769f56dc7ee2324312879c85739f4b9c088bb9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 01:13:40 +0000 Subject: [PATCH 36/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0fa05dd1..0fcb1151 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-e972fd41393b2edf6b6fddb7c52b14da652d4cff58399d5e7fc5b005081b85c1.yml -openapi_spec_hash: ca7941edec9fa06d9319dbb6fd0cc5c8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-3280b11e473a6d0cccd842e7c4fa6d0d29124b282da5dd02865a1b1af4b857a8.yml +openapi_spec_hash: 03ab8bc4ccf3e65d4d9a590ac8674f91 config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a From b9154f0c48bb29a41184fa00953f678b9761a02f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 05:13:22 +0000 Subject: [PATCH 37/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0fcb1151..7035d532 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-3280b11e473a6d0cccd842e7c4fa6d0d29124b282da5dd02865a1b1af4b857a8.yml -openapi_spec_hash: 03ab8bc4ccf3e65d4d9a590ac8674f91 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-35a533979ae42f8ed43f11c862a4cfe22d129ca71d9c2ba3ce269aeb8254ae27.yml +openapi_spec_hash: 0dba85d984aab8d9998f81297e1c0ba2 config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a From b09a48baa96f1493d0ef939db9dcb5d826741418 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 06:13:40 +0000 Subject: [PATCH 38/39] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7035d532..32314d62 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-35a533979ae42f8ed43f11c862a4cfe22d129ca71d9c2ba3ce269aeb8254ae27.yml -openapi_spec_hash: 0dba85d984aab8d9998f81297e1c0ba2 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-876b65a7e83beed2ddf0d639f3df62f98d4da76d26724730d8ae49ba87855b0e.yml +openapi_spec_hash: 0512773c97cda918c1017f3b972bff0c config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a From 7a0c28ce5aaa6fe5dd5a709c74fe1e2e51860865 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 06:14:06 +0000 Subject: [PATCH 39/39] release: 0.0.36 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- src/whop_sdk/_version.py | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 9682ed86..cacb3a0e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.35" + ".": "0.0.36" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c027435..7cb411b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # Changelog +## 0.0.36 (2026-04-07) + +Full Changelog: [v0.0.35...v0.0.36](https://github.com/whopio/whopsdk-python/compare/v0.0.35...v0.0.36) + +### Features + +* **api:** api update ([dfd2e5b](https://github.com/whopio/whopsdk-python/commit/dfd2e5b1fde74bf5d93fa8195e3aa7610c8349e6)) +* **api:** api update ([c2694e3](https://github.com/whopio/whopsdk-python/commit/c2694e3e189f52f64006c5b2503b901f31fcfe71)) +* **api:** api update ([82f0234](https://github.com/whopio/whopsdk-python/commit/82f02347c686891b5ffaeacd7cd84b9bc0a314d8)) +* **api:** api update ([6aa464e](https://github.com/whopio/whopsdk-python/commit/6aa464e34ab3d27134a66157a4ca0ef4d20b810a)) +* **api:** api update ([c7b5425](https://github.com/whopio/whopsdk-python/commit/c7b5425e8257162625fd6db79079953247a05d90)) +* **api:** api update ([6ac4297](https://github.com/whopio/whopsdk-python/commit/6ac4297d8b69e3f8209c69786f7017dd10913053)) +* **api:** api update ([e733ac9](https://github.com/whopio/whopsdk-python/commit/e733ac94f3c0f71876b46145c325e597c9569541)) +* **api:** api update ([82ba7a3](https://github.com/whopio/whopsdk-python/commit/82ba7a3c12417e18a6408a32eb2c4bf160e94768)) +* **api:** api update ([10c00d9](https://github.com/whopio/whopsdk-python/commit/10c00d9e1c45709469a36ea63c624b04fa312e58)) +* **api:** api update ([91ad304](https://github.com/whopio/whopsdk-python/commit/91ad304ea92ca8916afd9e6abb17d463b1b81b58)) +* **api:** api update ([881d399](https://github.com/whopio/whopsdk-python/commit/881d399d3b01938fd43252b435935798bd3171f7)) +* **api:** api update ([cea4dc2](https://github.com/whopio/whopsdk-python/commit/cea4dc2006ad8a1819e93fa2632edc511ab9731c)) +* **api:** api update ([349533c](https://github.com/whopio/whopsdk-python/commit/349533cc0cdb665e00d6ca104292b8cf9ae4d0d0)) +* **api:** api update ([a6443ea](https://github.com/whopio/whopsdk-python/commit/a6443ea4697c674dc80a9877fd9c531a6b688d73)) +* **api:** api update ([8f4b022](https://github.com/whopio/whopsdk-python/commit/8f4b022372bee1a75d74e83334431e030ee02496)) +* **api:** api update ([f4459b0](https://github.com/whopio/whopsdk-python/commit/f4459b0d9fa3d7e4e01db71c29611d98099dfadf)) +* **api:** api update ([a391cfc](https://github.com/whopio/whopsdk-python/commit/a391cfca3a11e21d4ac80518369b44f8f6f9ee2f)) +* **api:** api update ([021294e](https://github.com/whopio/whopsdk-python/commit/021294ecc577e24f56839d852bc978b839feb7fe)) +* **api:** manual updates ([014b6bb](https://github.com/whopio/whopsdk-python/commit/014b6bba88788acb14ce8240388b8712209f66fa)) +* **internal:** implement indices array format for query and form serialization ([e8bc1d6](https://github.com/whopio/whopsdk-python/commit/e8bc1d6948d253c722be8ea0802e8187165f4a0d)) + + +### Bug Fixes + +* add missing import and response wrappers for add_free_days method ([6f857b2](https://github.com/whopio/whopsdk-python/commit/6f857b22e4db5b371779e0759ddbd82752a0acc9)) +* sanitize endpoint path params ([ca495f7](https://github.com/whopio/whopsdk-python/commit/ca495f7081478f0056efbad9c75eea30af62f9fe)) + + +### Chores + +* **ci:** skip lint on metadata-only changes ([5428231](https://github.com/whopio/whopsdk-python/commit/542823145fee2ead9f920efd00278464d8601513)) +* **internal:** update gitignore ([e409b46](https://github.com/whopio/whopsdk-python/commit/e409b46665a918b487c9e10c25dd48819398f2bc)) + ## 0.0.35 (2026-03-18) Full Changelog: [v0.0.34...v0.0.35](https://github.com/whopio/whopsdk-python/compare/v0.0.34...v0.0.35) diff --git a/pyproject.toml b/pyproject.toml index 062c3d4b..9056f9e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "whop-sdk" -version = "0.0.35" +version = "0.0.36" description = "The official Python library for the Whop API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/whop_sdk/_version.py b/src/whop_sdk/_version.py index 057036ed..75c47829 100644 --- a/src/whop_sdk/_version.py +++ b/src/whop_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "whop_sdk" -__version__ = "0.0.35" # x-release-please-version +__version__ = "0.0.36" # x-release-please-version