diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4013f3..91bcb5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: 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 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install Rye run: | @@ -44,7 +44,7 @@ jobs: id-token: write runs-on: ${{ github.repository == 'stainless-sdks/whopsdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install Rye run: | @@ -81,7 +81,7 @@ jobs: 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 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install Rye run: | diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 64a890e..37d8724 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install Rye run: | diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index b63c0b6..dde36c9 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'whopio/whopsdk-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Check release environment run: | diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5ece83e..3d2ac0b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.23" + ".": "0.1.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 2cc29f7..57e9493 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 149 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-54c90c246d009f9f497b45992768d2a85ad7213629fa4910f25acd54fe226559.yml -openapi_spec_hash: 4b8eac0f1a57239c285b065fa2397a51 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-1d004dea35f368de09ec81418bc6b5f000b9e4e50942898c29cb7bde43b06aa0.yml +openapi_spec_hash: 25b216c56432ee234e8028271fcd5026 config_hash: d4f8c855179a930e9297fbd41adfb4f1 diff --git a/CHANGELOG.md b/CHANGELOG.md index c2a1c41..75fb324 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## 0.1.0 (2026-01-21) + +Full Changelog: [v0.0.23...v0.1.0](https://github.com/whopio/whopsdk-python/compare/v0.0.23...v0.1.0) + +### Features + +* **api:** api update ([d4ad504](https://github.com/whopio/whopsdk-python/commit/d4ad50414615e424f6d8bb580a9424872d0d4c22)) +* **api:** api update ([d897270](https://github.com/whopio/whopsdk-python/commit/d897270c715c88e37b70973e7c01d0a5981dd351)) +* **api:** api update ([3443622](https://github.com/whopio/whopsdk-python/commit/3443622036fccaf7dcba2e34d401fb3a256cded2)) +* **api:** api update ([57de7ee](https://github.com/whopio/whopsdk-python/commit/57de7eed7757ebb9d61521381a9469c46504754c)) +* **api:** api update ([9f6735d](https://github.com/whopio/whopsdk-python/commit/9f6735d3062eac581f80211d48f2f34a14aece4e)) +* **api:** api update ([78da3f2](https://github.com/whopio/whopsdk-python/commit/78da3f26588c299da76dce5868511b9146f17607)) +* **api:** api update ([ec3efe2](https://github.com/whopio/whopsdk-python/commit/ec3efe25e4e43e19ce03399c67e4afea1efc0028)) +* **api:** api update ([66fdb3b](https://github.com/whopio/whopsdk-python/commit/66fdb3b57cd29227a0b70f85c4a9fd092f572aa2)) +* **api:** api update ([3228988](https://github.com/whopio/whopsdk-python/commit/3228988ccc9c47cfc2e643ec7d546b03ccb5f3d7)) +* **api:** api update ([3e1e44b](https://github.com/whopio/whopsdk-python/commit/3e1e44bd9dcd40765bd3dd429ba4c8905370f0e0)) +* **api:** api update ([10170f5](https://github.com/whopio/whopsdk-python/commit/10170f57379561b95f4d9500c1dbe485c3048abe)) +* **api:** api update ([49d5794](https://github.com/whopio/whopsdk-python/commit/49d57942ab4dec302afb89fed5f6fa77f2b40e5d)) +* **api:** api update ([2370069](https://github.com/whopio/whopsdk-python/commit/23700699801a68e1e364420003aa55163d2c7917)) +* **api:** api update ([26e9984](https://github.com/whopio/whopsdk-python/commit/26e9984a3bf8cb77b6ff98fd1a5718e7d0734f4a)) +* **api:** api update ([63c9d28](https://github.com/whopio/whopsdk-python/commit/63c9d284fcb841598a93d85c1561e6a0cba73361)) +* **api:** api update ([a52f4a5](https://github.com/whopio/whopsdk-python/commit/a52f4a5504b7175c3938102449204088b606fe38)) +* **api:** api update ([c8afe02](https://github.com/whopio/whopsdk-python/commit/c8afe023d41bead426a76a593b244ec8b19db2d0)) +* **client:** add support for binary request streaming ([0cf5376](https://github.com/whopio/whopsdk-python/commit/0cf53763bf59ab21991ed5b5ccf57b1296261fb0)) + + +### Chores + +* **internal:** update `actions/checkout` version ([66cabf4](https://github.com/whopio/whopsdk-python/commit/66cabf4a519d11d82c45d446fb0bc404d8f8dd1a)) + ## 0.0.23 (2026-01-09) Full Changelog: [v0.0.22...v0.0.23](https://github.com/whopio/whopsdk-python/compare/v0.0.22...v0.0.23) diff --git a/README.md b/README.md index 5fd1201..2263a74 100644 --- a/README.md +++ b/README.md @@ -192,8 +192,6 @@ for payment in first_page.data: # Remove `await` for non-async usage. ``` -from datetime import datetime - ## Nested params Nested parameters are dictionaries, typed using `TypedDict`, for example: @@ -203,15 +201,12 @@ from whop_sdk import Whop client = Whop() -invoice = client.invoices.create( - collection_method="send_invoice", +app = client.apps.create( company_id="biz_xxxxxxxxxxxxxx", - due_date=datetime.fromisoformat("2023-12-01T05:00:00.401"), - member_id="mber_xxxxxxxxxxxxx", - plan={}, - product={"title": "title"}, + name="name", + icon={"id": "id"}, ) -print(invoice.plan) +print(app.icon) ``` ## Handling errors diff --git a/api.md b/api.md index 8eb5038..ce2a11d 100644 --- a/api.md +++ b/api.md @@ -651,7 +651,6 @@ from whop_sdk.types import ( WithdrawalFeeTypes, WithdrawalSpeeds, WithdrawalStatus, - WithdrawalTypes, WithdrawalCreateResponse, WithdrawalRetrieveResponse, WithdrawalListResponse, diff --git a/pyproject.toml b/pyproject.toml index 49fa596..56574b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "whop-sdk" -version = "0.0.23" +version = "0.1.0" description = "The official Python library for the Whop API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/whop_sdk/_base_client.py b/src/whop_sdk/_base_client.py index c16a1d4..3a0c188 100644 --- a/src/whop_sdk/_base_client.py +++ b/src/whop_sdk/_base_client.py @@ -9,6 +9,7 @@ import inspect import logging import platform +import warnings import email.utils from types import TracebackType from random import random @@ -51,9 +52,11 @@ ResponseT, AnyMapping, PostParser, + BinaryTypes, RequestFiles, HttpxSendArgs, RequestOptions, + AsyncBinaryTypes, HttpxRequestFiles, ModelBuilderProtocol, not_given, @@ -477,8 +480,19 @@ def _build_request( retries_taken: int = 0, ) -> httpx.Request: if log.isEnabledFor(logging.DEBUG): - log.debug("Request options: %s", model_dump(options, exclude_unset=True)) - + log.debug( + "Request options: %s", + model_dump( + options, + exclude_unset=True, + # Pydantic v1 can't dump every type we support in content, so we exclude it for now. + exclude={ + "content", + } + if PYDANTIC_V1 + else {}, + ), + ) kwargs: dict[str, Any] = {} json_data = options.json_data @@ -532,7 +546,13 @@ def _build_request( is_body_allowed = options.method.lower() != "get" if is_body_allowed: - if isinstance(json_data, bytes): + if options.content is not None and json_data is not None: + raise TypeError("Passing both `content` and `json_data` is not supported") + if options.content is not None and files is not None: + raise TypeError("Passing both `content` and `files` is not supported") + if options.content is not None: + kwargs["content"] = options.content + elif isinstance(json_data, bytes): kwargs["content"] = json_data else: kwargs["json"] = json_data if is_given(json_data) else None @@ -1194,6 +1214,7 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: Literal[False] = False, @@ -1206,6 +1227,7 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: Literal[True], @@ -1219,6 +1241,7 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: bool, @@ -1231,13 +1254,25 @@ def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, files: RequestFiles | None = None, stream: bool = False, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="post", url=path, json_data=body, files=to_httpx_files(files), **options + method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options ) return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) @@ -1247,11 +1282,23 @@ def patch( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="patch", url=path, json_data=body, files=to_httpx_files(files), **options + method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options ) return self.request(cast_to, opts) @@ -1261,11 +1308,23 @@ def put( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="put", url=path, json_data=body, files=to_httpx_files(files), **options + method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options ) return self.request(cast_to, opts) @@ -1275,9 +1334,19 @@ def delete( *, cast_to: Type[ResponseT], body: Body | None = None, + content: BinaryTypes | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options) + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) + opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options) return self.request(cast_to, opts) def get_api_list( @@ -1717,6 +1786,7 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: Literal[False] = False, @@ -1729,6 +1799,7 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: Literal[True], @@ -1742,6 +1813,7 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: bool, @@ -1754,13 +1826,25 @@ async def post( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, stream: bool = False, stream_cls: type[_AsyncStreamT] | None = None, ) -> ResponseT | _AsyncStreamT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options + method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls) @@ -1770,11 +1854,28 @@ async def patch( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options + method="patch", + url=path, + json_data=body, + content=content, + files=await async_to_httpx_files(files), + **options, ) return await self.request(cast_to, opts) @@ -1784,11 +1885,23 @@ async def put( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, files: RequestFiles | None = None, options: RequestOptions = {}, ) -> ResponseT: + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if files is not None and content is not None: + raise TypeError("Passing both `files` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) opts = FinalRequestOptions.construct( - method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options + method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options ) return await self.request(cast_to, opts) @@ -1798,9 +1911,19 @@ async def delete( *, cast_to: Type[ResponseT], body: Body | None = None, + content: AsyncBinaryTypes | None = None, options: RequestOptions = {}, ) -> ResponseT: - opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options) + if body is not None and content is not None: + raise TypeError("Passing both `body` and `content` is not supported") + if isinstance(body, bytes): + warnings.warn( + "Passing raw bytes as `body` is deprecated and will be removed in a future version. " + "Please pass raw bytes via the `content` parameter instead.", + DeprecationWarning, + stacklevel=2, + ) + opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options) return await self.request(cast_to, opts) def get_api_list( diff --git a/src/whop_sdk/_models.py b/src/whop_sdk/_models.py index ca9500b..29070e0 100644 --- a/src/whop_sdk/_models.py +++ b/src/whop_sdk/_models.py @@ -3,7 +3,20 @@ import os import inspect import weakref -from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast +from typing import ( + IO, + TYPE_CHECKING, + Any, + Type, + Union, + Generic, + TypeVar, + Callable, + Iterable, + Optional, + AsyncIterable, + cast, +) from datetime import date, datetime from typing_extensions import ( List, @@ -787,6 +800,7 @@ class FinalRequestOptionsInput(TypedDict, total=False): timeout: float | Timeout | None files: HttpxRequestFiles | None idempotency_key: str + content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] json_data: Body extra_json: AnyMapping follow_redirects: bool @@ -805,6 +819,7 @@ class FinalRequestOptions(pydantic.BaseModel): post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven() follow_redirects: Union[bool, None] = None + content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None # It should be noted that we cannot use `json` here as that would override # a BaseModel method in an incompatible fashion. json_data: Union[Body, None] = None diff --git a/src/whop_sdk/_types.py b/src/whop_sdk/_types.py index 22e43ad..66da6e5 100644 --- a/src/whop_sdk/_types.py +++ b/src/whop_sdk/_types.py @@ -13,9 +13,11 @@ Mapping, TypeVar, Callable, + Iterable, Iterator, Optional, Sequence, + AsyncIterable, ) from typing_extensions import ( Set, @@ -56,6 +58,13 @@ else: Base64FileInput = Union[IO[bytes], PathLike] FileContent = Union[IO[bytes], bytes, PathLike] # PathLike is not subscriptable in Python 3.8. + + +# Used for sending raw binary data / streaming data in request bodies +# e.g. for file uploads without multipart encoding +BinaryTypes = Union[bytes, bytearray, IO[bytes], Iterable[bytes]] +AsyncBinaryTypes = Union[bytes, bytearray, IO[bytes], AsyncIterable[bytes]] + FileTypes = Union[ # file (or bytes) FileContent, diff --git a/src/whop_sdk/_version.py b/src/whop_sdk/_version.py index b93a8c6..162053b 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.23" # x-release-please-version +__version__ = "0.1.0" # x-release-please-version diff --git a/src/whop_sdk/resources/apps.py b/src/whop_sdk/resources/apps.py index 860a154..8dc0871 100644 --- a/src/whop_sdk/resources/apps.py +++ b/src/whop_sdk/resources/apps.py @@ -56,6 +56,7 @@ def create( company_id: str, name: str, base_url: Optional[str] | Omit = omit, + icon: Optional[app_create_params.Icon] | 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, @@ -78,6 +79,8 @@ def create( base_url: The base URL of the app to be created + icon: The icon for the app in png, jpeg, or gif format + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -93,6 +96,7 @@ def create( "company_id": company_id, "name": name, "base_url": base_url, + "icon": icon, }, app_create_params.AppCreateParams, ), @@ -244,6 +248,11 @@ def list( "time_spent", "time_spent_last_24_hours", "daily_active_users", + "ai_prompt_count", + "total_ai_cost_usd", + "total_ai_tokens", + "last_ai_prompt_at", + "ai_average_rating", ] ] | Omit = omit, @@ -347,6 +356,7 @@ async def create( company_id: str, name: str, base_url: Optional[str] | Omit = omit, + icon: Optional[app_create_params.Icon] | 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, @@ -369,6 +379,8 @@ async def create( base_url: The base URL of the app to be created + icon: The icon for the app in png, jpeg, or gif format + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -384,6 +396,7 @@ async def create( "company_id": company_id, "name": name, "base_url": base_url, + "icon": icon, }, app_create_params.AppCreateParams, ), @@ -535,6 +548,11 @@ def list( "time_spent", "time_spent_last_24_hours", "daily_active_users", + "ai_prompt_count", + "total_ai_cost_usd", + "total_ai_tokens", + "last_ai_prompt_at", + "ai_average_rating", ] ] | Omit = omit, diff --git a/src/whop_sdk/resources/checkout_configurations.py b/src/whop_sdk/resources/checkout_configurations.py index cc29993..471f9d6 100644 --- a/src/whop_sdk/resources/checkout_configurations.py +++ b/src/whop_sdk/resources/checkout_configurations.py @@ -63,6 +63,7 @@ def create( ] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | 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, @@ -96,6 +97,8 @@ def create( redirect_url: The URL to redirect the user to after the checkout configuration is created + source_url: The URL of the page where the checkout is being initiated from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -120,6 +123,7 @@ def create( ] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | 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, @@ -153,6 +157,8 @@ def create( redirect_url: The URL to redirect the user to after the checkout configuration is created + source_url: The URL of the page where the checkout is being initiated from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -176,6 +182,7 @@ def create( ] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | 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, @@ -208,6 +215,8 @@ def create( redirect_url: The URL to redirect the user to after the checkout configuration is created + source_url: The URL of the page where the checkout is being initiated from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -236,6 +245,7 @@ def create( | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | Omit = omit, plan_id: str | Omit = omit, company_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -256,6 +266,7 @@ def create( "mode": mode, "payment_method_configuration": payment_method_configuration, "redirect_url": redirect_url, + "source_url": source_url, "plan_id": plan_id, "company_id": company_id, }, @@ -418,6 +429,7 @@ async def create( ] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | 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, @@ -451,6 +463,8 @@ async def create( redirect_url: The URL to redirect the user to after the checkout configuration is created + source_url: The URL of the page where the checkout is being initiated from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -475,6 +489,7 @@ async def create( ] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | 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, @@ -508,6 +523,8 @@ async def create( redirect_url: The URL to redirect the user to after the checkout configuration is created + source_url: The URL of the page where the checkout is being initiated from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -531,6 +548,7 @@ async def create( ] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | 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, @@ -563,6 +581,8 @@ async def create( redirect_url: The URL to redirect the user to after the checkout configuration is created + source_url: The URL of the page where the checkout is being initiated from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -591,6 +611,7 @@ async def create( | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration] | Omit = omit, redirect_url: Optional[str] | Omit = omit, + source_url: Optional[str] | Omit = omit, plan_id: str | Omit = omit, company_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -611,6 +632,7 @@ async def create( "mode": mode, "payment_method_configuration": payment_method_configuration, "redirect_url": redirect_url, + "source_url": source_url, "plan_id": plan_id, "company_id": company_id, }, diff --git a/src/whop_sdk/resources/companies.py b/src/whop_sdk/resources/companies.py index 6db2342..daac561 100644 --- a/src/whop_sdk/resources/companies.py +++ b/src/whop_sdk/resources/companies.py @@ -57,6 +57,7 @@ def create( title: str, business_type: Optional[BusinessTypes] | Omit = omit, industry_type: Optional[IndustryTypes] | Omit = omit, + logo: Optional[company_create_params.Logo] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, send_customer_emails: Optional[bool] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -85,6 +86,8 @@ def create( industry_type: The different industry types a company can be in. + logo: The logo for the company in png, jpeg, or gif format + metadata: Additional metadata for the account send_customer_emails: Whether Whop sends transactional emails to customers on behalf of this company. @@ -109,6 +112,7 @@ def create( "title": title, "business_type": business_type, "industry_type": industry_type, + "logo": logo, "metadata": metadata, "send_customer_emails": send_customer_emails, }, @@ -333,6 +337,7 @@ async def create( title: str, business_type: Optional[BusinessTypes] | Omit = omit, industry_type: Optional[IndustryTypes] | Omit = omit, + logo: Optional[company_create_params.Logo] | Omit = omit, metadata: Optional[Dict[str, object]] | Omit = omit, send_customer_emails: Optional[bool] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -361,6 +366,8 @@ async def create( industry_type: The different industry types a company can be in. + logo: The logo for the company in png, jpeg, or gif format + metadata: Additional metadata for the account send_customer_emails: Whether Whop sends transactional emails to customers on behalf of this company. @@ -385,6 +392,7 @@ async def create( "title": title, "business_type": business_type, "industry_type": industry_type, + "logo": logo, "metadata": metadata, "send_customer_emails": send_customer_emails, }, diff --git a/src/whop_sdk/resources/courses.py b/src/whop_sdk/resources/courses.py index e1da3a9..49d3ebb 100644 --- a/src/whop_sdk/resources/courses.py +++ b/src/whop_sdk/resources/courses.py @@ -54,7 +54,6 @@ def create( experience_id: str, title: str, certificate_after_completion_enabled: Optional[bool] | Omit = omit, - cover_image: Optional[str] | Omit = omit, order: Optional[str] | Omit = omit, require_completing_lessons_in_order: Optional[bool] | Omit = omit, tagline: Optional[str] | Omit = omit, @@ -82,8 +81,6 @@ def create( certificate_after_completion_enabled: Whether the course will award its students a PDF certificate after completing all lessons - cover_image: The cover image URL of the course - order: The decimal order position of the course within its experience. If not provided, it will be set to the next sequential order. Use fractional values (e.g., 1.5) to place between existing courses. @@ -113,7 +110,6 @@ def create( "experience_id": experience_id, "title": title, "certificate_after_completion_enabled": certificate_after_completion_enabled, - "cover_image": cover_image, "order": order, "require_completing_lessons_in_order": require_completing_lessons_in_order, "tagline": tagline, @@ -171,7 +167,6 @@ def update( *, certificate_after_completion_enabled: Optional[bool] | Omit = omit, chapters: Optional[Iterable[course_update_params.Chapter]] | Omit = omit, - cover_image: Optional[str] | Omit = omit, description: Optional[str] | Omit = omit, language: Optional[Languages] | Omit = omit, order: Optional[str] | Omit = omit, @@ -200,8 +195,6 @@ def update( chapters: The chapters and lessons to update - cover_image: The cover image URL of the course - description: A short description of the course language: The available languages for a course @@ -237,7 +230,6 @@ def update( { "certificate_after_completion_enabled": certificate_after_completion_enabled, "chapters": chapters, - "cover_image": cover_image, "description": description, "language": language, "order": order, @@ -386,7 +378,6 @@ async def create( experience_id: str, title: str, certificate_after_completion_enabled: Optional[bool] | Omit = omit, - cover_image: Optional[str] | Omit = omit, order: Optional[str] | Omit = omit, require_completing_lessons_in_order: Optional[bool] | Omit = omit, tagline: Optional[str] | Omit = omit, @@ -414,8 +405,6 @@ async def create( certificate_after_completion_enabled: Whether the course will award its students a PDF certificate after completing all lessons - cover_image: The cover image URL of the course - order: The decimal order position of the course within its experience. If not provided, it will be set to the next sequential order. Use fractional values (e.g., 1.5) to place between existing courses. @@ -445,7 +434,6 @@ async def create( "experience_id": experience_id, "title": title, "certificate_after_completion_enabled": certificate_after_completion_enabled, - "cover_image": cover_image, "order": order, "require_completing_lessons_in_order": require_completing_lessons_in_order, "tagline": tagline, @@ -503,7 +491,6 @@ async def update( *, certificate_after_completion_enabled: Optional[bool] | Omit = omit, chapters: Optional[Iterable[course_update_params.Chapter]] | Omit = omit, - cover_image: Optional[str] | Omit = omit, description: Optional[str] | Omit = omit, language: Optional[Languages] | Omit = omit, order: Optional[str] | Omit = omit, @@ -532,8 +519,6 @@ async def update( chapters: The chapters and lessons to update - cover_image: The cover image URL of the course - description: A short description of the course language: The available languages for a course @@ -569,7 +554,6 @@ async def update( { "certificate_after_completion_enabled": certificate_after_completion_enabled, "chapters": chapters, - "cover_image": cover_image, "description": description, "language": language, "order": order, diff --git a/src/whop_sdk/resources/experiences.py b/src/whop_sdk/resources/experiences.py index cbff300..8f347fe 100644 --- a/src/whop_sdk/resources/experiences.py +++ b/src/whop_sdk/resources/experiences.py @@ -61,6 +61,7 @@ def create( app_id: str, company_id: str, is_public: Optional[bool] | Omit = omit, + logo: Optional[experience_create_params.Logo] | Omit = omit, name: Optional[str] | Omit = omit, section_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. @@ -82,6 +83,8 @@ def create( is_public: Whether the experience is publicly accessible + logo: The logo for the experience + name: The name of the experience section_id: The ID of the section to create the experience in @@ -101,6 +104,7 @@ def create( "app_id": app_id, "company_id": company_id, "is_public": is_public, + "logo": logo, "name": name, "section_id": section_id, }, @@ -481,6 +485,7 @@ async def create( app_id: str, company_id: str, is_public: Optional[bool] | Omit = omit, + logo: Optional[experience_create_params.Logo] | Omit = omit, name: Optional[str] | Omit = omit, section_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. @@ -502,6 +507,8 @@ async def create( is_public: Whether the experience is publicly accessible + logo: The logo for the experience + name: The name of the experience section_id: The ID of the section to create the experience in @@ -521,6 +528,7 @@ async def create( "app_id": app_id, "company_id": company_id, "is_public": is_public, + "logo": logo, "name": name, "section_id": section_id, }, diff --git a/src/whop_sdk/resources/memberships.py b/src/whop_sdk/resources/memberships.py index 65de7ca..268d5e5 100644 --- a/src/whop_sdk/resources/memberships.py +++ b/src/whop_sdk/resources/memberships.py @@ -71,6 +71,7 @@ def retrieve( Required permissions: - `member:basic:read` + - `member:email:read` Args: extra_headers: Send extra headers @@ -109,6 +110,7 @@ def update( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -178,6 +180,7 @@ def list( Required permissions: - `member:basic:read` + - `member:email:read` Args: after: Returns the elements in the list that come after the specified cursor. @@ -269,6 +272,7 @@ def cancel( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -313,6 +317,7 @@ def pause( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -355,6 +360,7 @@ def resume( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -414,6 +420,7 @@ async def retrieve( Required permissions: - `member:basic:read` + - `member:email:read` Args: extra_headers: Send extra headers @@ -452,6 +459,7 @@ async def update( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -521,6 +529,7 @@ def list( Required permissions: - `member:basic:read` + - `member:email:read` Args: after: Returns the elements in the list that come after the specified cursor. @@ -612,6 +621,7 @@ async def cancel( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -656,6 +666,7 @@ async def pause( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: @@ -700,6 +711,7 @@ async def resume( Required permissions: - `member:manage` + - `member:email:read` - `member:basic:read` Args: diff --git a/src/whop_sdk/resources/notifications.py b/src/whop_sdk/resources/notifications.py index 50498aa..1c26b09 100644 --- a/src/whop_sdk/resources/notifications.py +++ b/src/whop_sdk/resources/notifications.py @@ -65,6 +65,10 @@ def create( """ Queues a notification to be sent to users in an experience or company team + Required permissions: + + - `notification:create` + Args: company_id: The id of the company to target. Only team members of this company will receive the notification. When clicked will take the user to your dashboard app view. @@ -116,6 +120,10 @@ def create( """ Queues a notification to be sent to users in an experience or company team + Required permissions: + + - `notification:create` + Args: content: The content of the notification @@ -229,6 +237,10 @@ async def create( """ Queues a notification to be sent to users in an experience or company team + Required permissions: + + - `notification:create` + Args: company_id: The id of the company to target. Only team members of this company will receive the notification. When clicked will take the user to your dashboard app view. @@ -280,6 +292,10 @@ async def create( """ Queues a notification to be sent to users in an experience or company team + Required permissions: + + - `notification:create` + Args: content: The content of the notification diff --git a/src/whop_sdk/resources/withdrawals.py b/src/whop_sdk/resources/withdrawals.py index eff8f1b..ce89801 100644 --- a/src/whop_sdk/resources/withdrawals.py +++ b/src/whop_sdk/resources/withdrawals.py @@ -56,6 +56,8 @@ def create( company_id: str, currency: Currency, payout_method_id: Optional[str] | Omit = omit, + platform_covers_fees: Optional[bool] | Omit = omit, + statement_descriptor: Optional[str] | 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, @@ -80,6 +82,11 @@ def create( payout_method_id: The ID of the payout method to use for the withdrawal. + platform_covers_fees: Whether the platform covers the payout fees instead of the connected account. + + statement_descriptor: Custom statement descriptor for the withdrawal. Must be between 5 and 22 + characters and contain only alphanumeric characters. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -96,6 +103,8 @@ def create( "company_id": company_id, "currency": currency, "payout_method_id": payout_method_id, + "platform_covers_fees": platform_covers_fees, + "statement_descriptor": statement_descriptor, }, withdrawal_create_params.WithdrawalCreateParams, ), @@ -246,6 +255,8 @@ async def create( company_id: str, currency: Currency, payout_method_id: Optional[str] | Omit = omit, + platform_covers_fees: Optional[bool] | Omit = omit, + statement_descriptor: Optional[str] | 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, @@ -270,6 +281,11 @@ async def create( payout_method_id: The ID of the payout method to use for the withdrawal. + platform_covers_fees: Whether the platform covers the payout fees instead of the connected account. + + statement_descriptor: Custom statement descriptor for the withdrawal. Must be between 5 and 22 + characters and contain only alphanumeric characters. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -286,6 +302,8 @@ async def create( "company_id": company_id, "currency": currency, "payout_method_id": payout_method_id, + "platform_covers_fees": platform_covers_fees, + "statement_descriptor": statement_descriptor, }, withdrawal_create_params.WithdrawalCreateParams, ), diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py index d59bcae..6d7773e 100644 --- a/src/whop_sdk/types/__init__.py +++ b/src/whop_sdk/types/__init__.py @@ -86,7 +86,6 @@ from .lead_list_params import LeadListParams as LeadListParams from .payment_provider import PaymentProvider as PaymentProvider from .plan_list_params import PlanListParams as PlanListParams -from .withdrawal_types import WithdrawalTypes as WithdrawalTypes from .app_create_params import AppCreateParams as AppCreateParams from .app_list_response import AppListResponse as AppListResponse from .app_update_params import AppUpdateParams as AppUpdateParams diff --git a/src/whop_sdk/types/app_build_create_params.py b/src/whop_sdk/types/app_build_create_params.py index 5d4d905..8a178b3 100644 --- a/src/whop_sdk/types/app_build_create_params.py +++ b/src/whop_sdk/types/app_build_create_params.py @@ -2,18 +2,13 @@ from __future__ import annotations -from typing import List, Union, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import List, Optional +from typing_extensions import Required, TypedDict from .shared.app_view_type import AppViewType from .shared.app_build_platforms import AppBuildPlatforms -__all__ = [ - "AppBuildCreateParams", - "Attachment", - "AttachmentAttachmentInputWithDirectUploadID", - "AttachmentAttachmentInputWithID", -] +__all__ = ["AppBuildCreateParams", "Attachment"] class AppBuildCreateParams(TypedDict, total=False): @@ -51,26 +46,11 @@ class AppBuildCreateParams(TypedDict, total=False): """ -class AttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. +class Attachment(TypedDict, total=False): + """Attachment input for the app build file. - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. + This should be an upload in .zip format. The zip should contain at least one main_js_bundle.hbc file and optionally an assets folder next to it. """ - -class AttachmentAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" - id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Attachment: TypeAlias = Union[AttachmentAttachmentInputWithDirectUploadID, AttachmentAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/app_create_params.py b/src/whop_sdk/types/app_create_params.py index 4f4f999..238216a 100644 --- a/src/whop_sdk/types/app_create_params.py +++ b/src/whop_sdk/types/app_create_params.py @@ -5,7 +5,7 @@ from typing import Optional from typing_extensions import Required, TypedDict -__all__ = ["AppCreateParams"] +__all__ = ["AppCreateParams", "Icon"] class AppCreateParams(TypedDict, total=False): @@ -17,3 +17,13 @@ class AppCreateParams(TypedDict, total=False): base_url: Optional[str] """The base URL of the app to be created""" + + icon: Optional[Icon] + """The icon for the app in png, jpeg, or gif format""" + + +class Icon(TypedDict, total=False): + """The icon for the app in png, jpeg, or gif format""" + + id: Required[str] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/app_list_params.py b/src/whop_sdk/types/app_list_params.py index 19d2772..619b81e 100644 --- a/src/whop_sdk/types/app_list_params.py +++ b/src/whop_sdk/types/app_list_params.py @@ -42,6 +42,11 @@ class AppListParams(TypedDict, total=False): "time_spent", "time_spent_last_24_hours", "daily_active_users", + "ai_prompt_count", + "total_ai_cost_usd", + "total_ai_tokens", + "last_ai_prompt_at", + "ai_average_rating", ] ] """The order to fetch the apps in for discovery.""" diff --git a/src/whop_sdk/types/app_update_params.py b/src/whop_sdk/types/app_update_params.py index de09316..c56e8f3 100644 --- a/src/whop_sdk/types/app_update_params.py +++ b/src/whop_sdk/types/app_update_params.py @@ -2,13 +2,13 @@ from __future__ import annotations -from typing import List, Union, Optional -from typing_extensions import Literal, Required, TypeAlias, TypedDict +from typing import List, Optional +from typing_extensions import Literal, Required, TypedDict from .app_type import AppType from .shared.app_statuses import AppStatuses -__all__ = ["AppUpdateParams", "Icon", "IconAttachmentInputWithDirectUploadID", "IconAttachmentInputWithID"] +__all__ = ["AppUpdateParams", "Icon"] class AppUpdateParams(TypedDict, total=False): @@ -46,26 +46,8 @@ class AppUpdateParams(TypedDict, total=False): """The status of an experience interface""" -class IconAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class IconAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Icon(TypedDict, total=False): + """The icon for the app""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Icon: TypeAlias = Union[IconAttachmentInputWithDirectUploadID, IconAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/card_brands.py b/src/whop_sdk/types/card_brands.py index 9a0539b..f170d86 100644 --- a/src/whop_sdk/types/card_brands.py +++ b/src/whop_sdk/types/card_brands.py @@ -21,5 +21,21 @@ "jcbrupay", "elo", "maestro", + "tarjeta_naranja", + "cirrus", + "nspk_mir", + "verve", + "ebt", + "private_label", + "local_brand", + "uatp", + "wexcard", + "uzcard", + "meeza", + "hrg_store_card", + "girocard", + "fuel_card", + "dankort", + "carnet", "unknown", ] diff --git a/src/whop_sdk/types/checkout_configuration_create_params.py b/src/whop_sdk/types/checkout_configuration_create_params.py index bcfe6f0..1cff79a 100644 --- a/src/whop_sdk/types/checkout_configuration_create_params.py +++ b/src/whop_sdk/types/checkout_configuration_create_params.py @@ -21,8 +21,6 @@ "CreateCheckoutSessionInputModePaymentWithPlanPlan", "CreateCheckoutSessionInputModePaymentWithPlanPlanCustomField", "CreateCheckoutSessionInputModePaymentWithPlanPlanImage", - "CreateCheckoutSessionInputModePaymentWithPlanPlanImageAttachmentInputWithDirectUploadID", - "CreateCheckoutSessionInputModePaymentWithPlanPlanImageAttachmentInputWithID", "CreateCheckoutSessionInputModePaymentWithPlanPlanPaymentMethodConfiguration", "CreateCheckoutSessionInputModePaymentWithPlanPlanProduct", "CreateCheckoutSessionInputModePaymentWithPlanPaymentMethodConfiguration", @@ -58,6 +56,9 @@ class CreateCheckoutSessionInputModePaymentWithPlan(TypedDict, total=False): redirect_url: Optional[str] """The URL to redirect the user to after the checkout configuration is created""" + source_url: Optional[str] + """The URL of the page where the checkout is being initiated from.""" + class CreateCheckoutSessionInputModePaymentWithPlanPlanCustomField(TypedDict, total=False): field_type: Required[Literal["text"]] @@ -79,32 +80,11 @@ class CreateCheckoutSessionInputModePaymentWithPlanPlanCustomField(TypedDict, to """Whether or not the field is required.""" -class CreateCheckoutSessionInputModePaymentWithPlanPlanImageAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class CreateCheckoutSessionInputModePaymentWithPlanPlanImageAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class CreateCheckoutSessionInputModePaymentWithPlanPlanImage(TypedDict, total=False): + """An image for the plan. This will be visible on the product page to customers.""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -CreateCheckoutSessionInputModePaymentWithPlanPlanImage: TypeAlias = Union[ - CreateCheckoutSessionInputModePaymentWithPlanPlanImageAttachmentInputWithDirectUploadID, - CreateCheckoutSessionInputModePaymentWithPlanPlanImageAttachmentInputWithID, -] + """The ID of an existing file object.""" class CreateCheckoutSessionInputModePaymentWithPlanPlanPaymentMethodConfiguration(TypedDict, total=False): @@ -271,6 +251,12 @@ class CreateCheckoutSessionInputModePaymentWithPlanPlan(TypedDict, total=False): split_pay_required_payments: Optional[int] """The number of payments required before pausing the subscription.""" + stock: Optional[int] + """The number of units available for purchase. + + If not provided, stock is unlimited. + """ + title: Optional[str] """The title of the plan. This will be visible on the product page to customers.""" @@ -334,6 +320,9 @@ class CreateCheckoutSessionInputModePaymentWithPlanID(TypedDict, total=False): redirect_url: Optional[str] """The URL to redirect the user to after the checkout configuration is created""" + source_url: Optional[str] + """The URL of the page where the checkout is being initiated from.""" + class CreateCheckoutSessionInputModePaymentWithPlanIDPaymentMethodConfiguration(TypedDict, total=False): """This currently only works for configurations made in 'setup' mode. @@ -388,6 +377,9 @@ class CreateCheckoutSessionInputModeSetup(TypedDict, total=False): redirect_url: Optional[str] """The URL to redirect the user to after the checkout configuration is created""" + source_url: Optional[str] + """The URL of the page where the checkout is being initiated from.""" + class CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration(TypedDict, total=False): """This currently only works for configurations made in 'setup' mode. diff --git a/src/whop_sdk/types/company_create_params.py b/src/whop_sdk/types/company_create_params.py index 866a031..f2a9e14 100644 --- a/src/whop_sdk/types/company_create_params.py +++ b/src/whop_sdk/types/company_create_params.py @@ -8,7 +8,7 @@ from .shared.business_types import BusinessTypes from .shared.industry_types import IndustryTypes -__all__ = ["CompanyCreateParams"] +__all__ = ["CompanyCreateParams", "Logo"] class CompanyCreateParams(TypedDict, total=False): @@ -27,6 +27,9 @@ class CompanyCreateParams(TypedDict, total=False): industry_type: Optional[IndustryTypes] """The different industry types a company can be in.""" + logo: Optional[Logo] + """The logo for the company in png, jpeg, or gif format""" + metadata: Optional[Dict[str, object]] """Additional metadata for the account""" @@ -37,3 +40,10 @@ class CompanyCreateParams(TypedDict, total=False): renewals, and membership cancelations/expirations. When disabled, the platform is responsible for handling these communications. This is defaulted to true. """ + + +class Logo(TypedDict, total=False): + """The logo for the company in png, jpeg, or gif format""" + + id: Required[str] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/company_update_params.py b/src/whop_sdk/types/company_update_params.py index 723d263..ca5eac4 100644 --- a/src/whop_sdk/types/company_update_params.py +++ b/src/whop_sdk/types/company_update_params.py @@ -2,21 +2,13 @@ from __future__ import annotations -from typing import Union, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Optional +from typing_extensions import Required, TypedDict from .shared.business_types import BusinessTypes from .shared.industry_types import IndustryTypes -__all__ = [ - "CompanyUpdateParams", - "BannerImage", - "BannerImageAttachmentInputWithDirectUploadID", - "BannerImageAttachmentInputWithID", - "Logo", - "LogoAttachmentInputWithDirectUploadID", - "LogoAttachmentInputWithID", -] +__all__ = ["CompanyUpdateParams", "BannerImage", "Logo"] class CompanyUpdateParams(TypedDict, total=False): @@ -44,51 +36,15 @@ class CompanyUpdateParams(TypedDict, total=False): """The title of the company""" -class BannerImageAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class BannerImageAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class BannerImage(TypedDict, total=False): + """The banner image for the company in png or jpeg format""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -BannerImage: TypeAlias = Union[BannerImageAttachmentInputWithDirectUploadID, BannerImageAttachmentInputWithID] + """The ID of an existing file object.""" -class LogoAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class LogoAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Logo(TypedDict, total=False): + """The logo for the company in png, jpeg, or gif format""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Logo: TypeAlias = Union[LogoAttachmentInputWithDirectUploadID, LogoAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/course_create_params.py b/src/whop_sdk/types/course_create_params.py index 02db9ae..5540532 100644 --- a/src/whop_sdk/types/course_create_params.py +++ b/src/whop_sdk/types/course_create_params.py @@ -2,17 +2,12 @@ from __future__ import annotations -from typing import Union, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Optional +from typing_extensions import Required, TypedDict from .course_visibilities import CourseVisibilities -__all__ = [ - "CourseCreateParams", - "Thumbnail", - "ThumbnailAttachmentInputWithDirectUploadID", - "ThumbnailAttachmentInputWithID", -] +__all__ = ["CourseCreateParams", "Thumbnail"] class CourseCreateParams(TypedDict, total=False): @@ -28,9 +23,6 @@ class CourseCreateParams(TypedDict, total=False): all lessons """ - cover_image: Optional[str] - """The cover image URL of the course""" - order: Optional[str] """The decimal order position of the course within its experience. @@ -57,26 +49,8 @@ class CourseCreateParams(TypedDict, total=False): """ -class ThumbnailAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class ThumbnailAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Thumbnail(TypedDict, total=False): + """The thumbnail for the course in png, jpeg, or gif format""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Thumbnail: TypeAlias = Union[ThumbnailAttachmentInputWithDirectUploadID, ThumbnailAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/course_lesson_create_params.py b/src/whop_sdk/types/course_lesson_create_params.py index 1262979..2cbe6b6 100644 --- a/src/whop_sdk/types/course_lesson_create_params.py +++ b/src/whop_sdk/types/course_lesson_create_params.py @@ -2,18 +2,13 @@ from __future__ import annotations -from typing import Union, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Optional +from typing_extensions import Required, TypedDict from .embed_type import EmbedType from .lesson_types import LessonTypes -__all__ = [ - "CourseLessonCreateParams", - "Thumbnail", - "ThumbnailAttachmentInputWithDirectUploadID", - "ThumbnailAttachmentInputWithID", -] +__all__ = ["CourseLessonCreateParams", "Thumbnail"] class CourseLessonCreateParams(TypedDict, total=False): @@ -42,26 +37,8 @@ class CourseLessonCreateParams(TypedDict, total=False): """The title of the lesson""" -class ThumbnailAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class ThumbnailAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Thumbnail(TypedDict, total=False): + """The thumbnail for the lesson in png, jpeg, or gif format""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Thumbnail: TypeAlias = Union[ThumbnailAttachmentInputWithDirectUploadID, ThumbnailAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/course_lesson_update_params.py b/src/whop_sdk/types/course_lesson_update_params.py index 24a4063..ae05b9d 100644 --- a/src/whop_sdk/types/course_lesson_update_params.py +++ b/src/whop_sdk/types/course_lesson_update_params.py @@ -2,8 +2,8 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict from .embed_type import EmbedType from .lesson_types import LessonTypes @@ -15,18 +15,10 @@ "AssessmentCompletionRequirement", "AssessmentQuestion", "AssessmentQuestionImage", - "AssessmentQuestionImageAttachmentInputWithDirectUploadID", - "AssessmentQuestionImageAttachmentInputWithID", "AssessmentQuestionOption", "Attachment", - "AttachmentAttachmentInputWithDirectUploadID", - "AttachmentAttachmentInputWithID", "MainPdf", - "MainPdfAttachmentInputWithDirectUploadID", - "MainPdfAttachmentInputWithID", "Thumbnail", - "ThumbnailAttachmentInputWithDirectUploadID", - "ThumbnailAttachmentInputWithID", ] @@ -99,31 +91,11 @@ class AssessmentCompletionRequirement(TypedDict, total=False): """ -class AssessmentQuestionImageAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class AssessmentQuestionImageAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class AssessmentQuestionImage(TypedDict, total=False): + """Optional image attachment for the question""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -AssessmentQuestionImage: TypeAlias = Union[ - AssessmentQuestionImageAttachmentInputWithDirectUploadID, AssessmentQuestionImageAttachmentInputWithID -] + """The ID of an existing file object.""" class AssessmentQuestionOption(TypedDict, total=False): @@ -169,76 +141,22 @@ class AssessmentQuestion(TypedDict, total=False): """The answer options for multiple choice/select questions""" -class AttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class AttachmentAttachmentInputWithID(TypedDict, total=False): +class Attachment(TypedDict, total=False): """Input for an attachment""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ + """The ID of an existing file object.""" -Attachment: TypeAlias = Union[AttachmentAttachmentInputWithDirectUploadID, AttachmentAttachmentInputWithID] - - -class MainPdfAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class MainPdfAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class MainPdf(TypedDict, total=False): + """The main PDF file for this lesson""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ + """The ID of an existing file object.""" -MainPdf: TypeAlias = Union[MainPdfAttachmentInputWithDirectUploadID, MainPdfAttachmentInputWithID] - - -class ThumbnailAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class ThumbnailAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Thumbnail(TypedDict, total=False): + """The thumbnail for the lesson in png, jpeg, or gif format""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Thumbnail: TypeAlias = Union[ThumbnailAttachmentInputWithDirectUploadID, ThumbnailAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/course_update_params.py b/src/whop_sdk/types/course_update_params.py index e490a9a..cfb65e5 100644 --- a/src/whop_sdk/types/course_update_params.py +++ b/src/whop_sdk/types/course_update_params.py @@ -2,20 +2,13 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict from .languages import Languages from .course_visibilities import CourseVisibilities -__all__ = [ - "CourseUpdateParams", - "Chapter", - "ChapterLesson", - "Thumbnail", - "ThumbnailAttachmentInputWithDirectUploadID", - "ThumbnailAttachmentInputWithID", -] +__all__ = ["CourseUpdateParams", "Chapter", "ChapterLesson", "Thumbnail"] class CourseUpdateParams(TypedDict, total=False): @@ -28,9 +21,6 @@ class CourseUpdateParams(TypedDict, total=False): chapters: Optional[Iterable[Chapter]] """The chapters and lessons to update""" - cover_image: Optional[str] - """The cover image URL of the course""" - description: Optional[str] """A short description of the course""" @@ -97,26 +87,8 @@ class Chapter(TypedDict, total=False): """The lessons to update within this chapter""" -class ThumbnailAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class ThumbnailAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Thumbnail(TypedDict, total=False): + """The thumbnail for the course in png, jpeg, or gif format""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Thumbnail: TypeAlias = Union[ThumbnailAttachmentInputWithDirectUploadID, ThumbnailAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/dispute_update_evidence_params.py b/src/whop_sdk/types/dispute_update_evidence_params.py index 33c1ef9..437ca29 100644 --- a/src/whop_sdk/types/dispute_update_evidence_params.py +++ b/src/whop_sdk/types/dispute_update_evidence_params.py @@ -2,23 +2,15 @@ from __future__ import annotations -from typing import Union, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Optional +from typing_extensions import Required, TypedDict __all__ = [ "DisputeUpdateEvidenceParams", "CancellationPolicyAttachment", - "CancellationPolicyAttachmentAttachmentInputWithDirectUploadID", - "CancellationPolicyAttachmentAttachmentInputWithID", "CustomerCommunicationAttachment", - "CustomerCommunicationAttachmentAttachmentInputWithDirectUploadID", - "CustomerCommunicationAttachmentAttachmentInputWithID", "RefundPolicyAttachment", - "RefundPolicyAttachmentAttachmentInputWithDirectUploadID", - "RefundPolicyAttachmentAttachmentInputWithID", "UncategorizedAttachment", - "UncategorizedAttachmentAttachmentInputWithDirectUploadID", - "UncategorizedAttachmentAttachmentInputWithID", ] @@ -66,110 +58,29 @@ class DisputeUpdateEvidenceParams(TypedDict, total=False): """A file that does not fit in the other categories.""" -class CancellationPolicyAttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class CancellationPolicyAttachmentAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class CancellationPolicyAttachment(TypedDict, total=False): + """A file containing the cancellation policy from the company.""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -CancellationPolicyAttachment: TypeAlias = Union[ - CancellationPolicyAttachmentAttachmentInputWithDirectUploadID, CancellationPolicyAttachmentAttachmentInputWithID -] + """The ID of an existing file object.""" -class CustomerCommunicationAttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class CustomerCommunicationAttachmentAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class CustomerCommunicationAttachment(TypedDict, total=False): + """A file containing the customer communication from the company (An image).""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -CustomerCommunicationAttachment: TypeAlias = Union[ - CustomerCommunicationAttachmentAttachmentInputWithDirectUploadID, - CustomerCommunicationAttachmentAttachmentInputWithID, -] + """The ID of an existing file object.""" -class RefundPolicyAttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class RefundPolicyAttachmentAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class RefundPolicyAttachment(TypedDict, total=False): + """A file containing the refund policy from the company.""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -RefundPolicyAttachment: TypeAlias = Union[ - RefundPolicyAttachmentAttachmentInputWithDirectUploadID, RefundPolicyAttachmentAttachmentInputWithID -] + """The ID of an existing file object.""" -class UncategorizedAttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class UncategorizedAttachmentAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class UncategorizedAttachment(TypedDict, total=False): + """A file that does not fit in the other categories.""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -UncategorizedAttachment: TypeAlias = Union[ - UncategorizedAttachmentAttachmentInputWithDirectUploadID, UncategorizedAttachmentAttachmentInputWithID -] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/experience_create_params.py b/src/whop_sdk/types/experience_create_params.py index 151a48a..c9eb7cf 100644 --- a/src/whop_sdk/types/experience_create_params.py +++ b/src/whop_sdk/types/experience_create_params.py @@ -5,7 +5,7 @@ from typing import Optional from typing_extensions import Required, TypedDict -__all__ = ["ExperienceCreateParams"] +__all__ = ["ExperienceCreateParams", "Logo"] class ExperienceCreateParams(TypedDict, total=False): @@ -18,8 +18,18 @@ class ExperienceCreateParams(TypedDict, total=False): is_public: Optional[bool] """Whether the experience is publicly accessible""" + logo: Optional[Logo] + """The logo for the experience""" + name: Optional[str] """The name of the experience""" section_id: Optional[str] """The ID of the section to create the experience in""" + + +class Logo(TypedDict, total=False): + """The logo for the experience""" + + id: Required[str] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/experience_update_params.py b/src/whop_sdk/types/experience_update_params.py index 1eba8a2..aed51dc 100644 --- a/src/whop_sdk/types/experience_update_params.py +++ b/src/whop_sdk/types/experience_update_params.py @@ -2,10 +2,10 @@ from __future__ import annotations -from typing import Union, Optional -from typing_extensions import Literal, Required, TypeAlias, TypedDict +from typing import Optional +from typing_extensions import Literal, Required, TypedDict -__all__ = ["ExperienceUpdateParams", "Logo", "LogoAttachmentInputWithDirectUploadID", "LogoAttachmentInputWithID"] +__all__ = ["ExperienceUpdateParams", "Logo"] class ExperienceUpdateParams(TypedDict, total=False): @@ -28,26 +28,8 @@ class ExperienceUpdateParams(TypedDict, total=False): """The ID of the section to update.""" -class LogoAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class LogoAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Logo(TypedDict, total=False): + """The logo for the experience""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Logo: TypeAlias = Union[LogoAttachmentInputWithDirectUploadID, LogoAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/forum_post_create_params.py b/src/whop_sdk/types/forum_post_create_params.py index b3ea980..56bf516 100644 --- a/src/whop_sdk/types/forum_post_create_params.py +++ b/src/whop_sdk/types/forum_post_create_params.py @@ -2,20 +2,13 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict from .shared.currency import Currency from .forum_post_visibility_type import ForumPostVisibilityType -__all__ = [ - "ForumPostCreateParams", - "Attachment", - "AttachmentAttachmentInputWithDirectUploadID", - "AttachmentAttachmentInputWithID", - "Poll", - "PollOption", -] +__all__ = ["ForumPostCreateParams", "Attachment", "Poll", "PollOption"] class ForumPostCreateParams(TypedDict, total=False): @@ -67,29 +60,11 @@ class ForumPostCreateParams(TypedDict, total=False): """The visibility types for forum posts""" -class AttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class AttachmentAttachmentInputWithID(TypedDict, total=False): +class Attachment(TypedDict, total=False): """Input for an attachment""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Attachment: TypeAlias = Union[AttachmentAttachmentInputWithDirectUploadID, AttachmentAttachmentInputWithID] + """The ID of an existing file object.""" class PollOption(TypedDict, total=False): diff --git a/src/whop_sdk/types/forum_post_update_params.py b/src/whop_sdk/types/forum_post_update_params.py index 0ba1825..936f0b1 100644 --- a/src/whop_sdk/types/forum_post_update_params.py +++ b/src/whop_sdk/types/forum_post_update_params.py @@ -2,17 +2,12 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict from .forum_post_visibility_type import ForumPostVisibilityType -__all__ = [ - "ForumPostUpdateParams", - "Attachment", - "AttachmentAttachmentInputWithDirectUploadID", - "AttachmentAttachmentInputWithID", -] +__all__ = ["ForumPostUpdateParams", "Attachment"] class ForumPostUpdateParams(TypedDict, total=False): @@ -35,26 +30,8 @@ class ForumPostUpdateParams(TypedDict, total=False): """The visibility types for forum posts""" -class AttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class AttachmentAttachmentInputWithID(TypedDict, total=False): +class Attachment(TypedDict, total=False): """Input for an attachment""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Attachment: TypeAlias = Union[AttachmentAttachmentInputWithDirectUploadID, AttachmentAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/ledger_account_retrieve_response.py b/src/whop_sdk/types/ledger_account_retrieve_response.py index be0369d..6be4b5d 100644 --- a/src/whop_sdk/types/ledger_account_retrieve_response.py +++ b/src/whop_sdk/types/ledger_account_retrieve_response.py @@ -198,24 +198,6 @@ class LedgerAccountRetrieveResponse(BaseModel): balances: List[Balance] """The balances associated with the account.""" - ledger_account_audit_status: Optional[ - Literal[ - "pending", - "pending_ai_review", - "approved", - "reserves_imposed", - "suspended", - "ignored", - "rejected", - "requested_more_information", - "information_submitted", - "requested_tos_violation_correction", - "clawback_attempted", - "awaiting_sales_review", - ] - ] = None - """The different statuses a LedgerAccountAudit can be""" - ledger_type: Literal["primary", "pool"] """The type of ledger account.""" diff --git a/src/whop_sdk/types/membership_list_response.py b/src/whop_sdk/types/membership_list_response.py index 4a56dda..33edfd9 100644 --- a/src/whop_sdk/types/membership_list_response.py +++ b/src/whop_sdk/types/membership_list_response.py @@ -2,6 +2,7 @@ from typing import Dict, Optional from datetime import datetime +from typing_extensions import Literal from .._models import BaseModel from .shared.currency import Currency @@ -57,6 +58,9 @@ class User(BaseModel): id: str """The internal ID of the user.""" + email: Optional[str] = None + """The email of the user""" + name: Optional[str] = None """The name of the user from their Whop account.""" @@ -79,6 +83,16 @@ class MembershipListResponse(BaseModel): Only applies for memberships that have a renewal plan. """ + cancel_option: Optional[ + Literal[ + "too_expensive", "switching", "missing_features", "technical_issues", "bad_experience", "other", "testing" + ] + ] = None + """ + The different reasons a user can choose for why they are canceling their + membership. + """ + canceled_at: Optional[datetime] = None """The epoch timestamp of when the customer initiated a cancellation.""" diff --git a/src/whop_sdk/types/message_create_params.py b/src/whop_sdk/types/message_create_params.py index 430cec0..855c110 100644 --- a/src/whop_sdk/types/message_create_params.py +++ b/src/whop_sdk/types/message_create_params.py @@ -2,17 +2,10 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict -__all__ = [ - "MessageCreateParams", - "Attachment", - "AttachmentAttachmentInputWithDirectUploadID", - "AttachmentAttachmentInputWithID", - "Poll", - "PollOption", -] +__all__ = ["MessageCreateParams", "Attachment", "Poll", "PollOption"] class MessageCreateParams(TypedDict, total=False): @@ -29,29 +22,11 @@ class MessageCreateParams(TypedDict, total=False): """The poll for this message""" -class AttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class AttachmentAttachmentInputWithID(TypedDict, total=False): +class Attachment(TypedDict, total=False): """Input for an attachment""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Attachment: TypeAlias = Union[AttachmentAttachmentInputWithDirectUploadID, AttachmentAttachmentInputWithID] + """The ID of an existing file object.""" class PollOption(TypedDict, total=False): diff --git a/src/whop_sdk/types/message_update_params.py b/src/whop_sdk/types/message_update_params.py index 6c92aff..06f3e57 100644 --- a/src/whop_sdk/types/message_update_params.py +++ b/src/whop_sdk/types/message_update_params.py @@ -2,15 +2,10 @@ from __future__ import annotations -from typing import Union, Iterable, Optional -from typing_extensions import Required, TypeAlias, TypedDict +from typing import Iterable, Optional +from typing_extensions import Required, TypedDict -__all__ = [ - "MessageUpdateParams", - "Attachment", - "AttachmentAttachmentInputWithDirectUploadID", - "AttachmentAttachmentInputWithID", -] +__all__ = ["MessageUpdateParams", "Attachment"] class MessageUpdateParams(TypedDict, total=False): @@ -24,26 +19,8 @@ class MessageUpdateParams(TypedDict, total=False): """Whether this message is pinned""" -class AttachmentAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class AttachmentAttachmentInputWithID(TypedDict, total=False): +class Attachment(TypedDict, total=False): """Input for an attachment""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Attachment: TypeAlias = Union[AttachmentAttachmentInputWithDirectUploadID, AttachmentAttachmentInputWithID] + """The ID of an existing file object.""" diff --git a/src/whop_sdk/types/payment_list_response.py b/src/whop_sdk/types/payment_list_response.py index 2985357..bc9ccb2 100644 --- a/src/whop_sdk/types/payment_list_response.py +++ b/src/whop_sdk/types/payment_list_response.py @@ -235,6 +235,9 @@ class PaymentListResponse(BaseModel): was made """ + next_payment_attempt: Optional[datetime] = None + """The time of the next schedule payment retry.""" + paid_at: Optional[datetime] = None """The datetime the payment was paid""" @@ -244,6 +247,9 @@ class PaymentListResponse(BaseModel): payment_method_type: Optional[PaymentMethodTypes] = None """The different types of payment methods that can be used.""" + payments_failed: Optional[int] = None + """The number of failed payment attempts for the payment.""" + plan: Optional[Plan] = None """The plan attached to this payment.""" diff --git a/src/whop_sdk/types/payout_method_created_webhook_event.py b/src/whop_sdk/types/payout_method_created_webhook_event.py index 113df4b..9fe8bdf 100644 --- a/src/whop_sdk/types/payout_method_created_webhook_event.py +++ b/src/whop_sdk/types/payout_method_created_webhook_event.py @@ -38,6 +38,9 @@ class Data(BaseModel): company: Optional[DataCompany] = None """The company associated with the payout token""" + created_at: datetime + """The date and time the payout token was created""" + currency: str """The currency code of the payout destination. diff --git a/src/whop_sdk/types/payout_method_list_response.py b/src/whop_sdk/types/payout_method_list_response.py index d211cbf..8e72aab 100644 --- a/src/whop_sdk/types/payout_method_list_response.py +++ b/src/whop_sdk/types/payout_method_list_response.py @@ -1,6 +1,7 @@ # 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 @@ -37,6 +38,9 @@ class PayoutMethodListResponse(BaseModel): company: Optional[Company] = None """The company associated with the payout token""" + created_at: datetime + """The date and time the payout token was created""" + currency: str """The currency code of the payout destination. diff --git a/src/whop_sdk/types/payout_method_retrieve_response.py b/src/whop_sdk/types/payout_method_retrieve_response.py index e7869a4..10a9fea 100644 --- a/src/whop_sdk/types/payout_method_retrieve_response.py +++ b/src/whop_sdk/types/payout_method_retrieve_response.py @@ -1,6 +1,7 @@ # 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 @@ -37,6 +38,9 @@ class PayoutMethodRetrieveResponse(BaseModel): company: Optional[Company] = None """The company associated with the payout token""" + created_at: datetime + """The date and time the payout token was created""" + currency: str """The currency code of the payout destination. diff --git a/src/whop_sdk/types/plan_create_params.py b/src/whop_sdk/types/plan_create_params.py index d23b060..c898c58 100644 --- a/src/whop_sdk/types/plan_create_params.py +++ b/src/whop_sdk/types/plan_create_params.py @@ -2,8 +2,8 @@ from __future__ import annotations -from typing import List, Union, Iterable, Optional -from typing_extensions import Literal, Required, TypeAlias, TypedDict +from typing import List, Iterable, Optional +from typing_extensions import Literal, Required, TypedDict from .shared.currency import Currency from .shared.tax_type import TaxType @@ -12,14 +12,7 @@ from .payment_method_types import PaymentMethodTypes from .shared.release_method import ReleaseMethod -__all__ = [ - "PlanCreateParams", - "CustomField", - "Image", - "ImageAttachmentInputWithDirectUploadID", - "ImageAttachmentInputWithID", - "PaymentMethodConfiguration", -] +__all__ = ["PlanCreateParams", "CustomField", "Image", "PaymentMethodConfiguration"] class PlanCreateParams(TypedDict, total=False): @@ -124,29 +117,11 @@ class CustomField(TypedDict, total=False): """Whether or not the field is required.""" -class ImageAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class ImageAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Image(TypedDict, total=False): + """An image for the plan. This will be visible on the product page to customers.""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Image: TypeAlias = Union[ImageAttachmentInputWithDirectUploadID, ImageAttachmentInputWithID] + """The ID of an existing file object.""" class PaymentMethodConfiguration(TypedDict, total=False): diff --git a/src/whop_sdk/types/plan_update_params.py b/src/whop_sdk/types/plan_update_params.py index 8c1f4e9..7bf3922 100644 --- a/src/whop_sdk/types/plan_update_params.py +++ b/src/whop_sdk/types/plan_update_params.py @@ -2,22 +2,15 @@ from __future__ import annotations -from typing import List, Union, Iterable, Optional -from typing_extensions import Literal, Required, TypeAlias, TypedDict +from typing import List, Iterable, Optional +from typing_extensions import Literal, Required, TypedDict from .shared.currency import Currency from .shared.tax_type import TaxType from .shared.visibility import Visibility from .payment_method_types import PaymentMethodTypes -__all__ = [ - "PlanUpdateParams", - "CustomField", - "Image", - "ImageAttachmentInputWithDirectUploadID", - "ImageAttachmentInputWithID", - "PaymentMethodConfiguration", -] +__all__ = ["PlanUpdateParams", "CustomField", "Image", "PaymentMethodConfiguration"] class PlanUpdateParams(TypedDict, total=False): @@ -114,29 +107,11 @@ class CustomField(TypedDict, total=False): """Whether or not the field is required.""" -class ImageAttachmentInputWithDirectUploadID(TypedDict, total=False): - """Input for an attachment""" - - direct_upload_id: Required[str] - """This ID should be used the first time you upload an attachment. - - It is the ID of the direct upload that was created when uploading the file to S3 - via the mediaDirectUpload mutation. - """ - - -class ImageAttachmentInputWithID(TypedDict, total=False): - """Input for an attachment""" +class Image(TypedDict, total=False): + """An image for the plan. This will be visible on the product page to customers.""" id: Required[str] - """The ID of an existing attachment object. - - Use this when updating a resource and keeping a subset of the attachments. Don't - use this unless you know what you're doing. - """ - - -Image: TypeAlias = Union[ImageAttachmentInputWithDirectUploadID, ImageAttachmentInputWithID] + """The ID of an existing file object.""" class PaymentMethodConfiguration(TypedDict, total=False): diff --git a/src/whop_sdk/types/shared/friendly_receipt_status.py b/src/whop_sdk/types/shared/friendly_receipt_status.py index f953c13..bec414e 100644 --- a/src/whop_sdk/types/shared/friendly_receipt_status.py +++ b/src/whop_sdk/types/shared/friendly_receipt_status.py @@ -5,20 +5,32 @@ __all__ = ["FriendlyReceiptStatus"] FriendlyReceiptStatus: TypeAlias = Literal[ - "auto_refunded", + "succeeded", + "pending", + "failed", + "past_due", + "canceled", + "price_too_low", + "uncollectible", "refunded", + "auto_refunded", "partially_refunded", "dispute_warning", - "open_resolution", - "open_dispute", - "failed", - "price_too_low", - "succeeded", + "dispute_needs_response", + "dispute_warning_needs_response", + "resolution_needs_response", + "dispute_under_review", + "dispute_warning_under_review", + "resolution_under_review", + "dispute_won", + "dispute_warning_closed", + "resolution_won", + "dispute_lost", + "dispute_closed", + "resolution_lost", "drafted", - "uncollectible", - "unresolved", - "past_due", - "pending", "incomplete", - "canceled", + "unresolved", + "open_dispute", + "open_resolution", ] diff --git a/src/whop_sdk/types/shared/membership.py b/src/whop_sdk/types/shared/membership.py index e77a083..cb3f38c 100644 --- a/src/whop_sdk/types/shared/membership.py +++ b/src/whop_sdk/types/shared/membership.py @@ -1,13 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, Optional +from typing import Dict, List, Optional from datetime import datetime +from typing_extensions import Literal from .currency import Currency from ..._models import BaseModel from .membership_status import MembershipStatus -__all__ = ["Membership", "Company", "Member", "Plan", "Product", "PromoCode", "User"] +__all__ = ["Membership", "Company", "CustomFieldResponse", "Member", "Plan", "Product", "PromoCode", "User"] class Company(BaseModel): @@ -20,6 +21,19 @@ class Company(BaseModel): """The title of the company.""" +class CustomFieldResponse(BaseModel): + """The response from a custom field on checkout""" + + id: str + """The ID of the custom field item""" + + answer: str + """The response a user gave to the specific question or field.""" + + question: str + """The question asked by the custom field""" + + class Member(BaseModel): """The Member that this Membership belongs to.""" @@ -57,6 +71,9 @@ class User(BaseModel): id: str """The internal ID of the user.""" + email: Optional[str] = None + """The email of the user""" + name: Optional[str] = None """The name of the user from their Whop account.""" @@ -79,6 +96,16 @@ class Membership(BaseModel): Only applies for memberships that have a renewal plan. """ + cancel_option: Optional[ + Literal[ + "too_expensive", "switching", "missing_features", "technical_issues", "bad_experience", "other", "testing" + ] + ] = None + """ + The different reasons a user can choose for why they are canceling their + membership. + """ + canceled_at: Optional[datetime] = None """The epoch timestamp of when the customer initiated a cancellation.""" @@ -94,6 +121,9 @@ class Membership(BaseModel): currency: Optional[Currency] = None """The available currencies on the platform""" + custom_field_responses: List[CustomFieldResponse] + """The responses to custom checkout questions for this membership.""" + license_key: Optional[str] = None """The license key for this Membership. diff --git a/src/whop_sdk/types/shared/payment.py b/src/whop_sdk/types/shared/payment.py index ff952bd..477ec82 100644 --- a/src/whop_sdk/types/shared/payment.py +++ b/src/whop_sdk/types/shared/payment.py @@ -235,6 +235,9 @@ class Payment(BaseModel): was made """ + next_payment_attempt: Optional[datetime] = None + """The time of the next schedule payment retry.""" + paid_at: Optional[datetime] = None """The datetime the payment was paid""" @@ -244,6 +247,9 @@ class Payment(BaseModel): payment_method_type: Optional[PaymentMethodTypes] = None """The different types of payment methods that can be used.""" + payments_failed: Optional[int] = None + """The number of failed payment attempts for the payment.""" + plan: Optional[Plan] = None """The plan attached to this payment.""" diff --git a/src/whop_sdk/types/shared_params/friendly_receipt_status.py b/src/whop_sdk/types/shared_params/friendly_receipt_status.py index 36e05da..eba400b 100644 --- a/src/whop_sdk/types/shared_params/friendly_receipt_status.py +++ b/src/whop_sdk/types/shared_params/friendly_receipt_status.py @@ -7,20 +7,32 @@ __all__ = ["FriendlyReceiptStatus"] FriendlyReceiptStatus: TypeAlias = Literal[ - "auto_refunded", + "succeeded", + "pending", + "failed", + "past_due", + "canceled", + "price_too_low", + "uncollectible", "refunded", + "auto_refunded", "partially_refunded", "dispute_warning", - "open_resolution", - "open_dispute", - "failed", - "price_too_low", - "succeeded", + "dispute_needs_response", + "dispute_warning_needs_response", + "resolution_needs_response", + "dispute_under_review", + "dispute_warning_under_review", + "resolution_under_review", + "dispute_won", + "dispute_warning_closed", + "resolution_won", + "dispute_lost", + "dispute_closed", + "resolution_lost", "drafted", - "uncollectible", - "unresolved", - "past_due", - "pending", "incomplete", - "canceled", + "unresolved", + "open_dispute", + "open_resolution", ] diff --git a/src/whop_sdk/types/withdrawal_create_params.py b/src/whop_sdk/types/withdrawal_create_params.py index 4b7947f..46d134f 100644 --- a/src/whop_sdk/types/withdrawal_create_params.py +++ b/src/whop_sdk/types/withdrawal_create_params.py @@ -22,3 +22,12 @@ class WithdrawalCreateParams(TypedDict, total=False): payout_method_id: Optional[str] """The ID of the payout method to use for the withdrawal.""" + + platform_covers_fees: Optional[bool] + """Whether the platform covers the payout fees instead of the connected account.""" + + statement_descriptor: Optional[str] + """Custom statement descriptor for the withdrawal. + + Must be between 5 and 22 characters and contain only alphanumeric characters. + """ diff --git a/src/whop_sdk/types/withdrawal_create_response.py b/src/whop_sdk/types/withdrawal_create_response.py index a90e912..b0cf04f 100644 --- a/src/whop_sdk/types/withdrawal_create_response.py +++ b/src/whop_sdk/types/withdrawal_create_response.py @@ -6,7 +6,6 @@ from .._models import BaseModel from .shared.currency import Currency -from .withdrawal_types import WithdrawalTypes from .withdrawal_speeds import WithdrawalSpeeds from .withdrawal_status import WithdrawalStatus from .withdrawal_fee_types import WithdrawalFeeTypes @@ -91,6 +90,7 @@ class WithdrawalCreateResponse(BaseModel): "invalid_account_number", "invalid_bank_code", "invalid_beneficiary", + "invalid_mailing_address", "invalid_branch_number", "invalid_branch_code", "invalid_phone_number", @@ -154,6 +154,3 @@ class WithdrawalCreateResponse(BaseModel): Provided on ACH transactions when available. """ - - withdrawal_type: WithdrawalTypes - """The type of withdrawal.""" diff --git a/src/whop_sdk/types/withdrawal_created_webhook_event.py b/src/whop_sdk/types/withdrawal_created_webhook_event.py index 67404bb..db28aac 100644 --- a/src/whop_sdk/types/withdrawal_created_webhook_event.py +++ b/src/whop_sdk/types/withdrawal_created_webhook_event.py @@ -6,7 +6,6 @@ from .._models import BaseModel from .shared.currency import Currency -from .withdrawal_types import WithdrawalTypes from .withdrawal_speeds import WithdrawalSpeeds from .withdrawal_status import WithdrawalStatus from .withdrawal_fee_types import WithdrawalFeeTypes @@ -91,6 +90,7 @@ class Data(BaseModel): "invalid_account_number", "invalid_bank_code", "invalid_beneficiary", + "invalid_mailing_address", "invalid_branch_number", "invalid_branch_code", "invalid_phone_number", @@ -155,9 +155,6 @@ class Data(BaseModel): Provided on ACH transactions when available. """ - withdrawal_type: WithdrawalTypes - """The type of withdrawal.""" - class WithdrawalCreatedWebhookEvent(BaseModel): id: str diff --git a/src/whop_sdk/types/withdrawal_list_response.py b/src/whop_sdk/types/withdrawal_list_response.py index 085821f..987c43a 100644 --- a/src/whop_sdk/types/withdrawal_list_response.py +++ b/src/whop_sdk/types/withdrawal_list_response.py @@ -5,7 +5,6 @@ from .._models import BaseModel from .shared.currency import Currency -from .withdrawal_types import WithdrawalTypes from .withdrawal_speeds import WithdrawalSpeeds from .withdrawal_status import WithdrawalStatus from .withdrawal_fee_types import WithdrawalFeeTypes @@ -49,6 +48,3 @@ class WithdrawalListResponse(BaseModel): status: WithdrawalStatus """Status of the withdrawal.""" - - withdrawal_type: WithdrawalTypes - """The type of withdrawal.""" diff --git a/src/whop_sdk/types/withdrawal_retrieve_response.py b/src/whop_sdk/types/withdrawal_retrieve_response.py index 34efb5d..c723afb 100644 --- a/src/whop_sdk/types/withdrawal_retrieve_response.py +++ b/src/whop_sdk/types/withdrawal_retrieve_response.py @@ -6,7 +6,6 @@ from .._models import BaseModel from .shared.currency import Currency -from .withdrawal_types import WithdrawalTypes from .withdrawal_speeds import WithdrawalSpeeds from .withdrawal_status import WithdrawalStatus from .withdrawal_fee_types import WithdrawalFeeTypes @@ -91,6 +90,7 @@ class WithdrawalRetrieveResponse(BaseModel): "invalid_account_number", "invalid_bank_code", "invalid_beneficiary", + "invalid_mailing_address", "invalid_branch_number", "invalid_branch_code", "invalid_phone_number", @@ -154,6 +154,3 @@ class WithdrawalRetrieveResponse(BaseModel): Provided on ACH transactions when available. """ - - withdrawal_type: WithdrawalTypes - """The type of withdrawal.""" diff --git a/src/whop_sdk/types/withdrawal_types.py b/src/whop_sdk/types/withdrawal_types.py deleted file mode 100644 index b743fe1..0000000 --- a/src/whop_sdk/types/withdrawal_types.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal, TypeAlias - -__all__ = ["WithdrawalTypes"] - -WithdrawalTypes: TypeAlias = Literal["regular", "clawback"] diff --git a/src/whop_sdk/types/withdrawal_updated_webhook_event.py b/src/whop_sdk/types/withdrawal_updated_webhook_event.py index 6b06304..d1c8205 100644 --- a/src/whop_sdk/types/withdrawal_updated_webhook_event.py +++ b/src/whop_sdk/types/withdrawal_updated_webhook_event.py @@ -6,7 +6,6 @@ from .._models import BaseModel from .shared.currency import Currency -from .withdrawal_types import WithdrawalTypes from .withdrawal_speeds import WithdrawalSpeeds from .withdrawal_status import WithdrawalStatus from .withdrawal_fee_types import WithdrawalFeeTypes @@ -91,6 +90,7 @@ class Data(BaseModel): "invalid_account_number", "invalid_bank_code", "invalid_beneficiary", + "invalid_mailing_address", "invalid_branch_number", "invalid_branch_code", "invalid_phone_number", @@ -155,9 +155,6 @@ class Data(BaseModel): Provided on ACH transactions when available. """ - withdrawal_type: WithdrawalTypes - """The type of withdrawal.""" - class WithdrawalUpdatedWebhookEvent(BaseModel): id: str diff --git a/tests/api_resources/test_app_builds.py b/tests/api_resources/test_app_builds.py index ca89544..7fa79fb 100644 --- a/tests/api_resources/test_app_builds.py +++ b/tests/api_resources/test_app_builds.py @@ -24,7 +24,7 @@ class TestAppBuilds: @parametrize def test_method_create(self, client: Whop) -> None: app_build = client.app_builds.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ) @@ -34,7 +34,7 @@ def test_method_create(self, client: Whop) -> None: @parametrize def test_method_create_with_all_params(self, client: Whop) -> None: app_build = client.app_builds.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ai_prompt_id="prmt_xxxxxxxxxxxxx", @@ -47,7 +47,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: @parametrize def test_raw_response_create(self, client: Whop) -> None: response = client.app_builds.with_raw_response.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ) @@ -61,7 +61,7 @@ def test_raw_response_create(self, client: Whop) -> None: @parametrize def test_streaming_response_create(self, client: Whop) -> None: with client.app_builds.with_streaming_response.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ) as response: @@ -217,7 +217,7 @@ class TestAsyncAppBuilds: @parametrize async def test_method_create(self, async_client: AsyncWhop) -> None: app_build = await async_client.app_builds.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ) @@ -227,7 +227,7 @@ async def test_method_create(self, async_client: AsyncWhop) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> None: app_build = await async_client.app_builds.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ai_prompt_id="prmt_xxxxxxxxxxxxx", @@ -240,7 +240,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N @parametrize async def test_raw_response_create(self, async_client: AsyncWhop) -> None: response = await async_client.app_builds.with_raw_response.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ) @@ -254,7 +254,7 @@ async def test_raw_response_create(self, async_client: AsyncWhop) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncWhop) -> None: async with async_client.app_builds.with_streaming_response.create( - attachment={"direct_upload_id": "direct_upload_id"}, + attachment={"id": "id"}, checksum="checksum", platform="ios", ) as response: diff --git a/tests/api_resources/test_apps.py b/tests/api_resources/test_apps.py index 4689235..a85c711 100644 --- a/tests/api_resources/test_apps.py +++ b/tests/api_resources/test_apps.py @@ -35,6 +35,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: company_id="biz_xxxxxxxxxxxxxx", name="name", base_url="base_url", + icon={"id": "id"}, ) assert_matches_type(App, app, path=["response"]) @@ -128,7 +129,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None: description="description", discover_path="discover_path", experience_path="experience_path", - icon={"direct_upload_id": "direct_upload_id"}, + icon={"id": "id"}, name="name", required_scopes=["read_user"], status="live", @@ -237,6 +238,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N company_id="biz_xxxxxxxxxxxxxx", name="name", base_url="base_url", + icon={"id": "id"}, ) assert_matches_type(App, app, path=["response"]) @@ -330,7 +332,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N description="description", discover_path="discover_path", experience_path="experience_path", - icon={"direct_upload_id": "direct_upload_id"}, + icon={"id": "id"}, name="name", required_scopes=["read_user"], status="live", diff --git a/tests/api_resources/test_checkout_configurations.py b/tests/api_resources/test_checkout_configurations.py index fc38794..daef2a2 100644 --- a/tests/api_resources/test_checkout_configurations.py +++ b/tests/api_resources/test_checkout_configurations.py @@ -55,7 +55,7 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: "description": "description", "expiration_days": 42, "force_create_new_plan": True, - "image": {"direct_upload_id": "direct_upload_id"}, + "image": {"id": "id"}, "initial_price": 6.9, "internal_notes": "internal_notes", "override_tax_type": "inclusive", @@ -85,6 +85,7 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: "release_method": "buy_now", "renewal_price": 6.9, "split_pay_required_payments": 42, + "stock": 42, "title": "title", "trial_period_days": 42, "visibility": "visible", @@ -99,6 +100,7 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None: "include_platform_defaults": True, }, redirect_url="redirect_url", + source_url="source_url", ) assert_matches_type(CheckoutConfiguration, checkout_configuration, path=["response"]) @@ -157,6 +159,7 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None: "include_platform_defaults": True, }, redirect_url="redirect_url", + source_url="source_url", ) assert_matches_type(CheckoutConfiguration, checkout_configuration, path=["response"]) @@ -209,6 +212,7 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None: "include_platform_defaults": True, }, redirect_url="redirect_url", + source_url="source_url", ) assert_matches_type(CheckoutConfiguration, checkout_configuration, path=["response"]) @@ -379,7 +383,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "description": "description", "expiration_days": 42, "force_create_new_plan": True, - "image": {"direct_upload_id": "direct_upload_id"}, + "image": {"id": "id"}, "initial_price": 6.9, "internal_notes": "internal_notes", "override_tax_type": "inclusive", @@ -409,6 +413,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "release_method": "buy_now", "renewal_price": 6.9, "split_pay_required_payments": 42, + "stock": 42, "title": "title", "trial_period_days": 42, "visibility": "visible", @@ -423,6 +428,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "include_platform_defaults": True, }, redirect_url="redirect_url", + source_url="source_url", ) assert_matches_type(CheckoutConfiguration, checkout_configuration, path=["response"]) @@ -481,6 +487,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn "include_platform_defaults": True, }, redirect_url="redirect_url", + source_url="source_url", ) assert_matches_type(CheckoutConfiguration, checkout_configuration, path=["response"]) @@ -533,6 +540,7 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn "include_platform_defaults": True, }, redirect_url="redirect_url", + source_url="source_url", ) assert_matches_type(CheckoutConfiguration, checkout_configuration, path=["response"]) diff --git a/tests/api_resources/test_companies.py b/tests/api_resources/test_companies.py index 60ccee7..a99e02d 100644 --- a/tests/api_resources/test_companies.py +++ b/tests/api_resources/test_companies.py @@ -41,6 +41,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: title="title", business_type="education_program", industry_type="trading", + logo={"id": "id"}, metadata={"foo": "bar"}, send_customer_emails=True, ) @@ -131,10 +132,10 @@ 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", - banner_image={"direct_upload_id": "direct_upload_id"}, + banner_image={"id": "id"}, business_type="education_program", industry_type="trading", - logo={"direct_upload_id": "direct_upload_id"}, + logo={"id": "id"}, send_customer_emails=True, title="title", ) @@ -248,6 +249,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N title="title", business_type="education_program", industry_type="trading", + logo={"id": "id"}, metadata={"foo": "bar"}, send_customer_emails=True, ) @@ -338,10 +340,10 @@ 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", - banner_image={"direct_upload_id": "direct_upload_id"}, + banner_image={"id": "id"}, business_type="education_program", industry_type="trading", - logo={"direct_upload_id": "direct_upload_id"}, + logo={"id": "id"}, send_customer_emails=True, title="title", ) diff --git a/tests/api_resources/test_course_lessons.py b/tests/api_resources/test_course_lessons.py index 6906762..0e48b0b 100644 --- a/tests/api_resources/test_course_lessons.py +++ b/tests/api_resources/test_course_lessons.py @@ -44,7 +44,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: days_from_course_start_until_unlock=42, embed_id="embed_id", embed_type="youtube", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, title="title", ) assert_matches_type(Lesson, course_lesson, path=["response"]) @@ -142,7 +142,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None: "question_text": "question_text", "question_type": "short_answer", "id": "id", - "image": {"direct_upload_id": "direct_upload_id"}, + "image": {"id": "id"}, "options": [ { "is_correct": True, @@ -152,16 +152,16 @@ def test_method_update_with_all_params(self, client: Whop) -> None: ], } ], - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", days_from_course_start_until_unlock=42, embed_id="embed_id", embed_type="youtube", lesson_type="text", - main_pdf={"direct_upload_id": "direct_upload_id"}, + main_pdf={"id": "id"}, max_attempts=42, mux_asset_id="mux_xxxxxxxxxxxxxx", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, title="title", visibility="visible", ) @@ -439,7 +439,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N days_from_course_start_until_unlock=42, embed_id="embed_id", embed_type="youtube", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, title="title", ) assert_matches_type(Lesson, course_lesson, path=["response"]) @@ -537,7 +537,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N "question_text": "question_text", "question_type": "short_answer", "id": "id", - "image": {"direct_upload_id": "direct_upload_id"}, + "image": {"id": "id"}, "options": [ { "is_correct": True, @@ -547,16 +547,16 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N ], } ], - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", days_from_course_start_until_unlock=42, embed_id="embed_id", embed_type="youtube", lesson_type="text", - main_pdf={"direct_upload_id": "direct_upload_id"}, + main_pdf={"id": "id"}, max_attempts=42, mux_asset_id="mux_xxxxxxxxxxxxxx", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, title="title", visibility="visible", ) diff --git a/tests/api_resources/test_courses.py b/tests/api_resources/test_courses.py index 97bf2c1..5479a0a 100644 --- a/tests/api_resources/test_courses.py +++ b/tests/api_resources/test_courses.py @@ -38,11 +38,10 @@ def test_method_create_with_all_params(self, client: Whop) -> None: experience_id="exp_xxxxxxxxxxxxxx", title="title", certificate_after_completion_enabled=True, - cover_image="cover_image", order="123.45", require_completing_lessons_in_order=True, tagline="tagline", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, visibility="visible", ) assert_matches_type(Course, course, path=["response"]) @@ -146,13 +145,12 @@ def test_method_update_with_all_params(self, client: Whop) -> None: ], } ], - cover_image="cover_image", description="description", language="en", order="123.45", require_completing_lessons_in_order=True, tagline="tagline", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, title="title", visibility="visible", ) @@ -297,11 +295,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N experience_id="exp_xxxxxxxxxxxxxx", title="title", certificate_after_completion_enabled=True, - cover_image="cover_image", order="123.45", require_completing_lessons_in_order=True, tagline="tagline", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, visibility="visible", ) assert_matches_type(Course, course, path=["response"]) @@ -405,13 +402,12 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N ], } ], - cover_image="cover_image", description="description", language="en", order="123.45", require_completing_lessons_in_order=True, tagline="tagline", - thumbnail={"direct_upload_id": "direct_upload_id"}, + thumbnail={"id": "id"}, title="title", visibility="visible", ) diff --git a/tests/api_resources/test_disputes.py b/tests/api_resources/test_disputes.py index 3e2f313..b0b905e 100644 --- a/tests/api_resources/test_disputes.py +++ b/tests/api_resources/test_disputes.py @@ -167,18 +167,18 @@ def test_method_update_evidence_with_all_params(self, client: Whop) -> None: id="dspt_xxxxxxxxxxxxx", access_activity_log="access_activity_log", billing_address="billing_address", - cancellation_policy_attachment={"direct_upload_id": "direct_upload_id"}, + cancellation_policy_attachment={"id": "id"}, cancellation_policy_disclosure="cancellation_policy_disclosure", - customer_communication_attachment={"direct_upload_id": "direct_upload_id"}, + customer_communication_attachment={"id": "id"}, customer_email_address="customer_email_address", customer_name="customer_name", notes="notes", product_description="product_description", - refund_policy_attachment={"direct_upload_id": "direct_upload_id"}, + refund_policy_attachment={"id": "id"}, refund_policy_disclosure="refund_policy_disclosure", refund_refusal_explanation="refund_refusal_explanation", service_date="service_date", - uncategorized_attachment={"direct_upload_id": "direct_upload_id"}, + uncategorized_attachment={"id": "id"}, ) assert_matches_type(Dispute, dispute, path=["response"]) @@ -370,18 +370,18 @@ async def test_method_update_evidence_with_all_params(self, async_client: AsyncW id="dspt_xxxxxxxxxxxxx", access_activity_log="access_activity_log", billing_address="billing_address", - cancellation_policy_attachment={"direct_upload_id": "direct_upload_id"}, + cancellation_policy_attachment={"id": "id"}, cancellation_policy_disclosure="cancellation_policy_disclosure", - customer_communication_attachment={"direct_upload_id": "direct_upload_id"}, + customer_communication_attachment={"id": "id"}, customer_email_address="customer_email_address", customer_name="customer_name", notes="notes", product_description="product_description", - refund_policy_attachment={"direct_upload_id": "direct_upload_id"}, + refund_policy_attachment={"id": "id"}, refund_policy_disclosure="refund_policy_disclosure", refund_refusal_explanation="refund_refusal_explanation", service_date="service_date", - uncategorized_attachment={"direct_upload_id": "direct_upload_id"}, + uncategorized_attachment={"id": "id"}, ) assert_matches_type(Dispute, dispute, path=["response"]) diff --git a/tests/api_resources/test_experiences.py b/tests/api_resources/test_experiences.py index 899c4af..29f449c 100644 --- a/tests/api_resources/test_experiences.py +++ b/tests/api_resources/test_experiences.py @@ -39,6 +39,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: app_id="app_xxxxxxxxxxxxxx", company_id="biz_xxxxxxxxxxxxxx", is_public=True, + logo={"id": "id"}, name="name", section_id="section_id", ) @@ -129,7 +130,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None: id="exp_xxxxxxxxxxxxxx", access_level="public", is_public=True, - logo={"direct_upload_id": "direct_upload_id"}, + logo={"id": "id"}, name="name", order="123.45", section_id="section_id", @@ -427,6 +428,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N app_id="app_xxxxxxxxxxxxxx", company_id="biz_xxxxxxxxxxxxxx", is_public=True, + logo={"id": "id"}, name="name", section_id="section_id", ) @@ -517,7 +519,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N id="exp_xxxxxxxxxxxxxx", access_level="public", is_public=True, - logo={"direct_upload_id": "direct_upload_id"}, + logo={"id": "id"}, name="name", order="123.45", section_id="section_id", diff --git a/tests/api_resources/test_forum_posts.py b/tests/api_resources/test_forum_posts.py index ab8c9a3..edf9e7d 100644 --- a/tests/api_resources/test_forum_posts.py +++ b/tests/api_resources/test_forum_posts.py @@ -34,7 +34,7 @@ def test_method_create(self, client: Whop) -> None: def test_method_create_with_all_params(self, client: Whop) -> None: forum_post = client.forum_posts.create( experience_id="exp_xxxxxxxxxxxxxx", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", is_mention=True, parent_id="parent_id", @@ -135,7 +135,7 @@ def test_method_update(self, client: Whop) -> None: def test_method_update_with_all_params(self, client: Whop) -> None: forum_post = client.forum_posts.update( id="id", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", is_pinned=True, title="title", @@ -244,7 +244,7 @@ async def test_method_create(self, async_client: AsyncWhop) -> None: async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> None: forum_post = await async_client.forum_posts.create( experience_id="exp_xxxxxxxxxxxxxx", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", is_mention=True, parent_id="parent_id", @@ -345,7 +345,7 @@ async def test_method_update(self, async_client: AsyncWhop) -> None: async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> None: forum_post = await async_client.forum_posts.update( id="id", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", is_pinned=True, title="title", diff --git a/tests/api_resources/test_messages.py b/tests/api_resources/test_messages.py index 0fa3da9..38e1ae7 100644 --- a/tests/api_resources/test_messages.py +++ b/tests/api_resources/test_messages.py @@ -36,7 +36,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: message = client.messages.create( channel_id="channel_id", content="content", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], poll={ "options": [ { @@ -131,7 +131,7 @@ def test_method_update(self, client: Whop) -> None: def test_method_update_with_all_params(self, client: Whop) -> None: message = client.messages.update( id="id", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", is_pinned=True, ) @@ -239,7 +239,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N message = await async_client.messages.create( channel_id="channel_id", content="content", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], poll={ "options": [ { @@ -334,7 +334,7 @@ async def test_method_update(self, async_client: AsyncWhop) -> None: async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> None: message = await async_client.messages.update( id="id", - attachments=[{"direct_upload_id": "direct_upload_id"}], + attachments=[{"id": "id"}], content="content", is_pinned=True, ) diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py index 63bf95b..c652ce2 100644 --- a/tests/api_resources/test_payments.py +++ b/tests/api_resources/test_payments.py @@ -232,7 +232,7 @@ def test_method_list_with_all_params(self, client: Whop) -> None: plan_ids=["string"], product_ids=["string"], statuses=["draft"], - substatuses=["auto_refunded"], + substatuses=["succeeded"], ) assert_matches_type(SyncCursorPage[PaymentListResponse], payment, path=["response"]) @@ -666,7 +666,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncWhop) -> Non plan_ids=["string"], product_ids=["string"], statuses=["draft"], - substatuses=["auto_refunded"], + substatuses=["succeeded"], ) assert_matches_type(AsyncCursorPage[PaymentListResponse], payment, path=["response"]) diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py index 5be9c26..7ee37e4 100644 --- a/tests/api_resources/test_plans.py +++ b/tests/api_resources/test_plans.py @@ -52,7 +52,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None: ], description="description", expiration_days=42, - image={"direct_upload_id": "direct_upload_id"}, + image={"id": "id"}, initial_price=6.9, internal_notes="internal_notes", legacy_payment_method_controls=True, @@ -171,7 +171,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None: ], description="description", expiration_days=42, - image={"direct_upload_id": "direct_upload_id"}, + image={"id": "id"}, initial_price=6.9, internal_notes="internal_notes", legacy_payment_method_controls=True, @@ -358,7 +358,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N ], description="description", expiration_days=42, - image={"direct_upload_id": "direct_upload_id"}, + image={"id": "id"}, initial_price=6.9, internal_notes="internal_notes", legacy_payment_method_controls=True, @@ -477,7 +477,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N ], description="description", expiration_days=42, - image={"direct_upload_id": "direct_upload_id"}, + image={"id": "id"}, initial_price=6.9, internal_notes="internal_notes", legacy_payment_method_controls=True, diff --git a/tests/api_resources/test_withdrawals.py b/tests/api_resources/test_withdrawals.py index 2e8fd84..01b619d 100644 --- a/tests/api_resources/test_withdrawals.py +++ b/tests/api_resources/test_withdrawals.py @@ -41,6 +41,8 @@ def test_method_create_with_all_params(self, client: Whop) -> None: company_id="biz_xxxxxxxxxxxxxx", currency="usd", payout_method_id="payout_method_id", + platform_covers_fees=True, + statement_descriptor="statement_descriptor", ) assert_matches_type(WithdrawalCreateResponse, withdrawal, path=["response"]) @@ -189,6 +191,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N company_id="biz_xxxxxxxxxxxxxx", currency="usd", payout_method_id="payout_method_id", + platform_covers_fees=True, + statement_descriptor="statement_descriptor", ) assert_matches_type(WithdrawalCreateResponse, withdrawal, path=["response"]) diff --git a/tests/test_client.py b/tests/test_client.py index a7ad153..03ee724 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -8,10 +8,11 @@ import json import asyncio import inspect +import dataclasses import tracemalloc -from typing import Any, Union, cast +from typing import Any, Union, TypeVar, Callable, Iterable, Iterator, Optional, Coroutine, cast from unittest import mock -from typing_extensions import Literal +from typing_extensions import Literal, AsyncIterator, override import httpx import pytest @@ -36,6 +37,7 @@ from .utils import update_env +T = TypeVar("T") base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") api_key = "My API Key" @@ -50,6 +52,57 @@ def _low_retry_timeout(*_args: Any, **_kwargs: Any) -> float: return 0.1 +def mirror_request_content(request: httpx.Request) -> httpx.Response: + return httpx.Response(200, content=request.content) + + +# note: we can't use the httpx.MockTransport class as it consumes the request +# body itself, which means we can't test that the body is read lazily +class MockTransport(httpx.BaseTransport, httpx.AsyncBaseTransport): + def __init__( + self, + handler: Callable[[httpx.Request], httpx.Response] + | Callable[[httpx.Request], Coroutine[Any, Any, httpx.Response]], + ) -> None: + self.handler = handler + + @override + def handle_request( + self, + request: httpx.Request, + ) -> httpx.Response: + assert not inspect.iscoroutinefunction(self.handler), "handler must not be a coroutine function" + assert inspect.isfunction(self.handler), "handler must be a function" + return self.handler(request) + + @override + async def handle_async_request( + self, + request: httpx.Request, + ) -> httpx.Response: + assert inspect.iscoroutinefunction(self.handler), "handler must be a coroutine function" + return await self.handler(request) + + +@dataclasses.dataclass +class Counter: + value: int = 0 + + +def _make_sync_iterator(iterable: Iterable[T], counter: Optional[Counter] = None) -> Iterator[T]: + for item in iterable: + if counter: + counter.value += 1 + yield item + + +async def _make_async_iterator(iterable: Iterable[T], counter: Optional[Counter] = None) -> AsyncIterator[T]: + for item in iterable: + if counter: + counter.value += 1 + yield item + + class TestWhop: @pytest.mark.respx(base_url=base_url) def test_raw_response(self, respx_mock: MockRouter, client: Whop) -> None: @@ -486,6 +539,70 @@ def test_multipart_repeating_array(self, client: Whop) -> None: b"", ] + @pytest.mark.respx(base_url=base_url) + def test_binary_content_upload(self, respx_mock: MockRouter, client: Whop) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + response = client.post( + "/upload", + content=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + + def test_binary_content_upload_with_iterator(self) -> None: + file_content = b"Hello, this is a test file." + counter = Counter() + iterator = _make_sync_iterator([file_content], counter=counter) + + def mock_handler(request: httpx.Request) -> httpx.Response: + assert counter.value == 0, "the request body should not have been read" + return httpx.Response(200, content=request.read()) + + with Whop( + base_url=base_url, + api_key=api_key, + _strict_response_validation=True, + http_client=httpx.Client(transport=MockTransport(handler=mock_handler)), + ) as client: + response = client.post( + "/upload", + content=iterator, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + assert counter.value == 1 + + @pytest.mark.respx(base_url=base_url) + def test_binary_content_upload_with_body_is_deprecated(self, respx_mock: MockRouter, client: Whop) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + with pytest.deprecated_call( + match="Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead." + ): + response = client.post( + "/upload", + body=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + @pytest.mark.respx(base_url=base_url) def test_basic_union_response(self, respx_mock: MockRouter, client: Whop) -> None: class Model1(BaseModel): @@ -1288,6 +1405,72 @@ def test_multipart_repeating_array(self, async_client: AsyncWhop) -> None: b"", ] + @pytest.mark.respx(base_url=base_url) + async def test_binary_content_upload(self, respx_mock: MockRouter, async_client: AsyncWhop) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + response = await async_client.post( + "/upload", + content=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + + async def test_binary_content_upload_with_asynciterator(self) -> None: + file_content = b"Hello, this is a test file." + counter = Counter() + iterator = _make_async_iterator([file_content], counter=counter) + + async def mock_handler(request: httpx.Request) -> httpx.Response: + assert counter.value == 0, "the request body should not have been read" + return httpx.Response(200, content=await request.aread()) + + async with AsyncWhop( + base_url=base_url, + api_key=api_key, + _strict_response_validation=True, + http_client=httpx.AsyncClient(transport=MockTransport(handler=mock_handler)), + ) as client: + response = await client.post( + "/upload", + content=iterator, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + assert counter.value == 1 + + @pytest.mark.respx(base_url=base_url) + async def test_binary_content_upload_with_body_is_deprecated( + self, respx_mock: MockRouter, async_client: AsyncWhop + ) -> None: + respx_mock.post("/upload").mock(side_effect=mirror_request_content) + + file_content = b"Hello, this is a test file." + + with pytest.deprecated_call( + match="Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead." + ): + response = await async_client.post( + "/upload", + body=file_content, + cast_to=httpx.Response, + options={"headers": {"Content-Type": "application/octet-stream"}}, + ) + + assert response.status_code == 200 + assert response.request.headers["Content-Type"] == "application/octet-stream" + assert response.content == file_content + @pytest.mark.respx(base_url=base_url) async def test_basic_union_response(self, respx_mock: MockRouter, async_client: AsyncWhop) -> None: class Model1(BaseModel):