dodopayments 1.32.0__py3-none-any.whl → 1.34.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dodopayments might be problematic. Click here for more details.
- dodopayments/__init__.py +2 -1
- dodopayments/_base_client.py +38 -2
- dodopayments/_version.py +1 -1
- dodopayments/resources/products/products.py +90 -0
- dodopayments/resources/subscriptions.py +2 -2
- dodopayments/types/__init__.py +2 -0
- dodopayments/types/payment.py +3 -0
- dodopayments/types/payment_list_response.py +2 -0
- dodopayments/types/product.py +22 -1
- dodopayments/types/product_create_params.py +11 -1
- dodopayments/types/product_update_files_params.py +11 -0
- dodopayments/types/product_update_files_response.py +11 -0
- dodopayments/types/product_update_params.py +14 -1
- dodopayments/types/subscription_change_plan_params.py +1 -1
- {dodopayments-1.32.0.dist-info → dodopayments-1.34.1.dist-info}/METADATA +55 -3
- {dodopayments-1.32.0.dist-info → dodopayments-1.34.1.dist-info}/RECORD +18 -16
- {dodopayments-1.32.0.dist-info → dodopayments-1.34.1.dist-info}/WHEEL +0 -0
- {dodopayments-1.32.0.dist-info → dodopayments-1.34.1.dist-info}/licenses/LICENSE +0 -0
dodopayments/__init__.py
CHANGED
|
@@ -37,7 +37,7 @@ from ._exceptions import (
|
|
|
37
37
|
UnprocessableEntityError,
|
|
38
38
|
APIResponseValidationError,
|
|
39
39
|
)
|
|
40
|
-
from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
|
|
40
|
+
from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
|
|
41
41
|
from ._utils._logs import setup_logging as _setup_logging
|
|
42
42
|
|
|
43
43
|
__all__ = [
|
|
@@ -80,6 +80,7 @@ __all__ = [
|
|
|
80
80
|
"DEFAULT_CONNECTION_LIMITS",
|
|
81
81
|
"DefaultHttpxClient",
|
|
82
82
|
"DefaultAsyncHttpxClient",
|
|
83
|
+
"DefaultAioHttpClient",
|
|
83
84
|
]
|
|
84
85
|
|
|
85
86
|
if not _t.TYPE_CHECKING:
|
dodopayments/_base_client.py
CHANGED
|
@@ -1071,7 +1071,14 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1071
1071
|
) -> ResponseT:
|
|
1072
1072
|
origin = get_origin(cast_to) or cast_to
|
|
1073
1073
|
|
|
1074
|
-
if
|
|
1074
|
+
if (
|
|
1075
|
+
inspect.isclass(origin)
|
|
1076
|
+
and issubclass(origin, BaseAPIResponse)
|
|
1077
|
+
# we only want to actually return the custom BaseAPIResponse class if we're
|
|
1078
|
+
# returning the raw response, or if we're not streaming SSE, as if we're streaming
|
|
1079
|
+
# SSE then `cast_to` doesn't actively reflect the type we need to parse into
|
|
1080
|
+
and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
|
|
1081
|
+
):
|
|
1075
1082
|
if not issubclass(origin, APIResponse):
|
|
1076
1083
|
raise TypeError(f"API Response types must subclass {APIResponse}; Received {origin}")
|
|
1077
1084
|
|
|
@@ -1282,6 +1289,24 @@ class _DefaultAsyncHttpxClient(httpx.AsyncClient):
|
|
|
1282
1289
|
super().__init__(**kwargs)
|
|
1283
1290
|
|
|
1284
1291
|
|
|
1292
|
+
try:
|
|
1293
|
+
import httpx_aiohttp
|
|
1294
|
+
except ImportError:
|
|
1295
|
+
|
|
1296
|
+
class _DefaultAioHttpClient(httpx.AsyncClient):
|
|
1297
|
+
def __init__(self, **_kwargs: Any) -> None:
|
|
1298
|
+
raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra")
|
|
1299
|
+
else:
|
|
1300
|
+
|
|
1301
|
+
class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
|
|
1302
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
1303
|
+
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
|
|
1304
|
+
kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
|
|
1305
|
+
kwargs.setdefault("follow_redirects", True)
|
|
1306
|
+
|
|
1307
|
+
super().__init__(**kwargs)
|
|
1308
|
+
|
|
1309
|
+
|
|
1285
1310
|
if TYPE_CHECKING:
|
|
1286
1311
|
DefaultAsyncHttpxClient = httpx.AsyncClient
|
|
1287
1312
|
"""An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
|
|
@@ -1290,8 +1315,12 @@ if TYPE_CHECKING:
|
|
|
1290
1315
|
This is useful because overriding the `http_client` with your own instance of
|
|
1291
1316
|
`httpx.AsyncClient` will result in httpx's defaults being used, not ours.
|
|
1292
1317
|
"""
|
|
1318
|
+
|
|
1319
|
+
DefaultAioHttpClient = httpx.AsyncClient
|
|
1320
|
+
"""An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`."""
|
|
1293
1321
|
else:
|
|
1294
1322
|
DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
|
|
1323
|
+
DefaultAioHttpClient = _DefaultAioHttpClient
|
|
1295
1324
|
|
|
1296
1325
|
|
|
1297
1326
|
class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
|
|
@@ -1574,7 +1603,14 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1574
1603
|
) -> ResponseT:
|
|
1575
1604
|
origin = get_origin(cast_to) or cast_to
|
|
1576
1605
|
|
|
1577
|
-
if
|
|
1606
|
+
if (
|
|
1607
|
+
inspect.isclass(origin)
|
|
1608
|
+
and issubclass(origin, BaseAPIResponse)
|
|
1609
|
+
# we only want to actually return the custom BaseAPIResponse class if we're
|
|
1610
|
+
# returning the raw response, or if we're not streaming SSE, as if we're streaming
|
|
1611
|
+
# SSE then `cast_to` doesn't actively reflect the type we need to parse into
|
|
1612
|
+
and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
|
|
1613
|
+
):
|
|
1578
1614
|
if not issubclass(origin, AsyncAPIResponse):
|
|
1579
1615
|
raise TypeError(f"API Response types must subclass {AsyncAPIResponse}; Received {origin}")
|
|
1580
1616
|
|
dodopayments/_version.py
CHANGED
|
@@ -19,6 +19,7 @@ from ...types import (
|
|
|
19
19
|
product_list_params,
|
|
20
20
|
product_create_params,
|
|
21
21
|
product_update_params,
|
|
22
|
+
product_update_files_params,
|
|
22
23
|
)
|
|
23
24
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
|
|
24
25
|
from ..._utils import maybe_transform, async_maybe_transform
|
|
@@ -37,6 +38,7 @@ from ...types.price_param import PriceParam
|
|
|
37
38
|
from ...types.tax_category import TaxCategory
|
|
38
39
|
from ...types.product_list_response import ProductListResponse
|
|
39
40
|
from ...types.license_key_duration_param import LicenseKeyDurationParam
|
|
41
|
+
from ...types.product_update_files_response import ProductUpdateFilesResponse
|
|
40
42
|
|
|
41
43
|
__all__ = ["ProductsResource", "AsyncProductsResource"]
|
|
42
44
|
|
|
@@ -73,6 +75,7 @@ class ProductsResource(SyncAPIResource):
|
|
|
73
75
|
addons: Optional[List[str]] | NotGiven = NOT_GIVEN,
|
|
74
76
|
brand_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
75
77
|
description: Optional[str] | NotGiven = NOT_GIVEN,
|
|
78
|
+
digital_product_delivery: Optional[product_create_params.DigitalProductDelivery] | NotGiven = NOT_GIVEN,
|
|
76
79
|
license_key_activation_message: Optional[str] | NotGiven = NOT_GIVEN,
|
|
77
80
|
license_key_activations_limit: Optional[int] | NotGiven = NOT_GIVEN,
|
|
78
81
|
license_key_duration: Optional[LicenseKeyDurationParam] | NotGiven = NOT_GIVEN,
|
|
@@ -121,6 +124,7 @@ class ProductsResource(SyncAPIResource):
|
|
|
121
124
|
"addons": addons,
|
|
122
125
|
"brand_id": brand_id,
|
|
123
126
|
"description": description,
|
|
127
|
+
"digital_product_delivery": digital_product_delivery,
|
|
124
128
|
"license_key_activation_message": license_key_activation_message,
|
|
125
129
|
"license_key_activations_limit": license_key_activations_limit,
|
|
126
130
|
"license_key_duration": license_key_duration,
|
|
@@ -173,6 +177,7 @@ class ProductsResource(SyncAPIResource):
|
|
|
173
177
|
addons: Optional[List[str]] | NotGiven = NOT_GIVEN,
|
|
174
178
|
brand_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
175
179
|
description: Optional[str] | NotGiven = NOT_GIVEN,
|
|
180
|
+
digital_product_delivery: Optional[product_update_params.DigitalProductDelivery] | NotGiven = NOT_GIVEN,
|
|
176
181
|
image_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
177
182
|
license_key_activation_message: Optional[str] | NotGiven = NOT_GIVEN,
|
|
178
183
|
license_key_activations_limit: Optional[int] | NotGiven = NOT_GIVEN,
|
|
@@ -234,6 +239,7 @@ class ProductsResource(SyncAPIResource):
|
|
|
234
239
|
"addons": addons,
|
|
235
240
|
"brand_id": brand_id,
|
|
236
241
|
"description": description,
|
|
242
|
+
"digital_product_delivery": digital_product_delivery,
|
|
237
243
|
"image_id": image_id,
|
|
238
244
|
"license_key_activation_message": license_key_activation_message,
|
|
239
245
|
"license_key_activations_limit": license_key_activations_limit,
|
|
@@ -377,6 +383,39 @@ class ProductsResource(SyncAPIResource):
|
|
|
377
383
|
cast_to=NoneType,
|
|
378
384
|
)
|
|
379
385
|
|
|
386
|
+
def update_files(
|
|
387
|
+
self,
|
|
388
|
+
id: str,
|
|
389
|
+
*,
|
|
390
|
+
file_name: str,
|
|
391
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
392
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
393
|
+
extra_headers: Headers | None = None,
|
|
394
|
+
extra_query: Query | None = None,
|
|
395
|
+
extra_body: Body | None = None,
|
|
396
|
+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
397
|
+
) -> ProductUpdateFilesResponse:
|
|
398
|
+
"""
|
|
399
|
+
Args:
|
|
400
|
+
extra_headers: Send extra headers
|
|
401
|
+
|
|
402
|
+
extra_query: Add additional query parameters to the request
|
|
403
|
+
|
|
404
|
+
extra_body: Add additional JSON properties to the request
|
|
405
|
+
|
|
406
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
407
|
+
"""
|
|
408
|
+
if not id:
|
|
409
|
+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
|
|
410
|
+
return self._put(
|
|
411
|
+
f"/products/{id}/files",
|
|
412
|
+
body=maybe_transform({"file_name": file_name}, product_update_files_params.ProductUpdateFilesParams),
|
|
413
|
+
options=make_request_options(
|
|
414
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
415
|
+
),
|
|
416
|
+
cast_to=ProductUpdateFilesResponse,
|
|
417
|
+
)
|
|
418
|
+
|
|
380
419
|
|
|
381
420
|
class AsyncProductsResource(AsyncAPIResource):
|
|
382
421
|
@cached_property
|
|
@@ -410,6 +449,7 @@ class AsyncProductsResource(AsyncAPIResource):
|
|
|
410
449
|
addons: Optional[List[str]] | NotGiven = NOT_GIVEN,
|
|
411
450
|
brand_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
412
451
|
description: Optional[str] | NotGiven = NOT_GIVEN,
|
|
452
|
+
digital_product_delivery: Optional[product_create_params.DigitalProductDelivery] | NotGiven = NOT_GIVEN,
|
|
413
453
|
license_key_activation_message: Optional[str] | NotGiven = NOT_GIVEN,
|
|
414
454
|
license_key_activations_limit: Optional[int] | NotGiven = NOT_GIVEN,
|
|
415
455
|
license_key_duration: Optional[LicenseKeyDurationParam] | NotGiven = NOT_GIVEN,
|
|
@@ -458,6 +498,7 @@ class AsyncProductsResource(AsyncAPIResource):
|
|
|
458
498
|
"addons": addons,
|
|
459
499
|
"brand_id": brand_id,
|
|
460
500
|
"description": description,
|
|
501
|
+
"digital_product_delivery": digital_product_delivery,
|
|
461
502
|
"license_key_activation_message": license_key_activation_message,
|
|
462
503
|
"license_key_activations_limit": license_key_activations_limit,
|
|
463
504
|
"license_key_duration": license_key_duration,
|
|
@@ -510,6 +551,7 @@ class AsyncProductsResource(AsyncAPIResource):
|
|
|
510
551
|
addons: Optional[List[str]] | NotGiven = NOT_GIVEN,
|
|
511
552
|
brand_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
512
553
|
description: Optional[str] | NotGiven = NOT_GIVEN,
|
|
554
|
+
digital_product_delivery: Optional[product_update_params.DigitalProductDelivery] | NotGiven = NOT_GIVEN,
|
|
513
555
|
image_id: Optional[str] | NotGiven = NOT_GIVEN,
|
|
514
556
|
license_key_activation_message: Optional[str] | NotGiven = NOT_GIVEN,
|
|
515
557
|
license_key_activations_limit: Optional[int] | NotGiven = NOT_GIVEN,
|
|
@@ -571,6 +613,7 @@ class AsyncProductsResource(AsyncAPIResource):
|
|
|
571
613
|
"addons": addons,
|
|
572
614
|
"brand_id": brand_id,
|
|
573
615
|
"description": description,
|
|
616
|
+
"digital_product_delivery": digital_product_delivery,
|
|
574
617
|
"image_id": image_id,
|
|
575
618
|
"license_key_activation_message": license_key_activation_message,
|
|
576
619
|
"license_key_activations_limit": license_key_activations_limit,
|
|
@@ -714,6 +757,41 @@ class AsyncProductsResource(AsyncAPIResource):
|
|
|
714
757
|
cast_to=NoneType,
|
|
715
758
|
)
|
|
716
759
|
|
|
760
|
+
async def update_files(
|
|
761
|
+
self,
|
|
762
|
+
id: str,
|
|
763
|
+
*,
|
|
764
|
+
file_name: str,
|
|
765
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
766
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
767
|
+
extra_headers: Headers | None = None,
|
|
768
|
+
extra_query: Query | None = None,
|
|
769
|
+
extra_body: Body | None = None,
|
|
770
|
+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
771
|
+
) -> ProductUpdateFilesResponse:
|
|
772
|
+
"""
|
|
773
|
+
Args:
|
|
774
|
+
extra_headers: Send extra headers
|
|
775
|
+
|
|
776
|
+
extra_query: Add additional query parameters to the request
|
|
777
|
+
|
|
778
|
+
extra_body: Add additional JSON properties to the request
|
|
779
|
+
|
|
780
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
781
|
+
"""
|
|
782
|
+
if not id:
|
|
783
|
+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
|
|
784
|
+
return await self._put(
|
|
785
|
+
f"/products/{id}/files",
|
|
786
|
+
body=await async_maybe_transform(
|
|
787
|
+
{"file_name": file_name}, product_update_files_params.ProductUpdateFilesParams
|
|
788
|
+
),
|
|
789
|
+
options=make_request_options(
|
|
790
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
791
|
+
),
|
|
792
|
+
cast_to=ProductUpdateFilesResponse,
|
|
793
|
+
)
|
|
794
|
+
|
|
717
795
|
|
|
718
796
|
class ProductsResourceWithRawResponse:
|
|
719
797
|
def __init__(self, products: ProductsResource) -> None:
|
|
@@ -737,6 +815,9 @@ class ProductsResourceWithRawResponse:
|
|
|
737
815
|
self.unarchive = to_raw_response_wrapper(
|
|
738
816
|
products.unarchive,
|
|
739
817
|
)
|
|
818
|
+
self.update_files = to_raw_response_wrapper(
|
|
819
|
+
products.update_files,
|
|
820
|
+
)
|
|
740
821
|
|
|
741
822
|
@cached_property
|
|
742
823
|
def images(self) -> ImagesResourceWithRawResponse:
|
|
@@ -765,6 +846,9 @@ class AsyncProductsResourceWithRawResponse:
|
|
|
765
846
|
self.unarchive = async_to_raw_response_wrapper(
|
|
766
847
|
products.unarchive,
|
|
767
848
|
)
|
|
849
|
+
self.update_files = async_to_raw_response_wrapper(
|
|
850
|
+
products.update_files,
|
|
851
|
+
)
|
|
768
852
|
|
|
769
853
|
@cached_property
|
|
770
854
|
def images(self) -> AsyncImagesResourceWithRawResponse:
|
|
@@ -793,6 +877,9 @@ class ProductsResourceWithStreamingResponse:
|
|
|
793
877
|
self.unarchive = to_streamed_response_wrapper(
|
|
794
878
|
products.unarchive,
|
|
795
879
|
)
|
|
880
|
+
self.update_files = to_streamed_response_wrapper(
|
|
881
|
+
products.update_files,
|
|
882
|
+
)
|
|
796
883
|
|
|
797
884
|
@cached_property
|
|
798
885
|
def images(self) -> ImagesResourceWithStreamingResponse:
|
|
@@ -821,6 +908,9 @@ class AsyncProductsResourceWithStreamingResponse:
|
|
|
821
908
|
self.unarchive = async_to_streamed_response_wrapper(
|
|
822
909
|
products.unarchive,
|
|
823
910
|
)
|
|
911
|
+
self.update_files = async_to_streamed_response_wrapper(
|
|
912
|
+
products.update_files,
|
|
913
|
+
)
|
|
824
914
|
|
|
825
915
|
@cached_property
|
|
826
916
|
def images(self) -> AsyncImagesResourceWithStreamingResponse:
|
|
@@ -324,7 +324,7 @@ class SubscriptionsResource(SyncAPIResource):
|
|
|
324
324
|
subscription_id: str,
|
|
325
325
|
*,
|
|
326
326
|
product_id: str,
|
|
327
|
-
proration_billing_mode: Literal["prorated_immediately"],
|
|
327
|
+
proration_billing_mode: Literal["prorated_immediately", "full_immediately"],
|
|
328
328
|
quantity: int,
|
|
329
329
|
addons: Optional[Iterable[subscription_change_plan_params.Addon]] | NotGiven = NOT_GIVEN,
|
|
330
330
|
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
@@ -699,7 +699,7 @@ class AsyncSubscriptionsResource(AsyncAPIResource):
|
|
|
699
699
|
subscription_id: str,
|
|
700
700
|
*,
|
|
701
701
|
product_id: str,
|
|
702
|
-
proration_billing_mode: Literal["prorated_immediately"],
|
|
702
|
+
proration_billing_mode: Literal["prorated_immediately", "full_immediately"],
|
|
703
703
|
quantity: int,
|
|
704
704
|
addons: Optional[Iterable[subscription_change_plan_params.Addon]] | NotGiven = NOT_GIVEN,
|
|
705
705
|
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
dodopayments/types/__init__.py
CHANGED
|
@@ -78,10 +78,12 @@ from .subscription_charge_params import SubscriptionChargeParams as Subscription
|
|
|
78
78
|
from .subscription_create_params import SubscriptionCreateParams as SubscriptionCreateParams
|
|
79
79
|
from .subscription_list_response import SubscriptionListResponse as SubscriptionListResponse
|
|
80
80
|
from .subscription_update_params import SubscriptionUpdateParams as SubscriptionUpdateParams
|
|
81
|
+
from .product_update_files_params import ProductUpdateFilesParams as ProductUpdateFilesParams
|
|
81
82
|
from .addon_update_images_response import AddonUpdateImagesResponse as AddonUpdateImagesResponse
|
|
82
83
|
from .brand_update_images_response import BrandUpdateImagesResponse as BrandUpdateImagesResponse
|
|
83
84
|
from .subscription_charge_response import SubscriptionChargeResponse as SubscriptionChargeResponse
|
|
84
85
|
from .subscription_create_response import SubscriptionCreateResponse as SubscriptionCreateResponse
|
|
86
|
+
from .product_update_files_response import ProductUpdateFilesResponse as ProductUpdateFilesResponse
|
|
85
87
|
from .attach_existing_customer_param import AttachExistingCustomerParam as AttachExistingCustomerParam
|
|
86
88
|
from .subscription_change_plan_params import SubscriptionChangePlanParams as SubscriptionChangePlanParams
|
|
87
89
|
from .license_key_instance_list_params import LicenseKeyInstanceListParams as LicenseKeyInstanceListParams
|
dodopayments/types/payment.py
CHANGED
dodopayments/types/product.py
CHANGED
|
@@ -8,7 +8,26 @@ from .._models import BaseModel
|
|
|
8
8
|
from .tax_category import TaxCategory
|
|
9
9
|
from .license_key_duration import LicenseKeyDuration
|
|
10
10
|
|
|
11
|
-
__all__ = ["Product"]
|
|
11
|
+
__all__ = ["Product", "DigitalProductDelivery", "DigitalProductDeliveryFile"]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DigitalProductDeliveryFile(BaseModel):
|
|
15
|
+
file_id: str
|
|
16
|
+
|
|
17
|
+
file_name: str
|
|
18
|
+
|
|
19
|
+
url: str
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DigitalProductDelivery(BaseModel):
|
|
23
|
+
external_url: Optional[str] = None
|
|
24
|
+
"""External URL to digital product"""
|
|
25
|
+
|
|
26
|
+
files: Optional[List[DigitalProductDeliveryFile]] = None
|
|
27
|
+
"""Uploaded files ids of digital product"""
|
|
28
|
+
|
|
29
|
+
instructions: Optional[str] = None
|
|
30
|
+
"""Instructions to download and use the digital product"""
|
|
12
31
|
|
|
13
32
|
|
|
14
33
|
class Product(BaseModel):
|
|
@@ -46,6 +65,8 @@ class Product(BaseModel):
|
|
|
46
65
|
description: Optional[str] = None
|
|
47
66
|
"""Description of the product, optional."""
|
|
48
67
|
|
|
68
|
+
digital_product_delivery: Optional[DigitalProductDelivery] = None
|
|
69
|
+
|
|
49
70
|
image: Optional[str] = None
|
|
50
71
|
"""URL of the product image, optional."""
|
|
51
72
|
|
|
@@ -9,7 +9,7 @@ from .price_param import PriceParam
|
|
|
9
9
|
from .tax_category import TaxCategory
|
|
10
10
|
from .license_key_duration_param import LicenseKeyDurationParam
|
|
11
11
|
|
|
12
|
-
__all__ = ["ProductCreateParams"]
|
|
12
|
+
__all__ = ["ProductCreateParams", "DigitalProductDelivery"]
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ProductCreateParams(TypedDict, total=False):
|
|
@@ -30,6 +30,8 @@ class ProductCreateParams(TypedDict, total=False):
|
|
|
30
30
|
description: Optional[str]
|
|
31
31
|
"""Optional description of the product"""
|
|
32
32
|
|
|
33
|
+
digital_product_delivery: Optional[DigitalProductDelivery]
|
|
34
|
+
|
|
33
35
|
license_key_activation_message: Optional[str]
|
|
34
36
|
"""Optional message displayed during license key activation"""
|
|
35
37
|
|
|
@@ -45,3 +47,11 @@ class ProductCreateParams(TypedDict, total=False):
|
|
|
45
47
|
|
|
46
48
|
name: Optional[str]
|
|
47
49
|
"""Optional name of the product"""
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class DigitalProductDelivery(TypedDict, total=False):
|
|
53
|
+
external_url: Optional[str]
|
|
54
|
+
"""External URL to digital product"""
|
|
55
|
+
|
|
56
|
+
instructions: Optional[str]
|
|
57
|
+
"""Instructions to download and use the digital product"""
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing_extensions import Required, TypedDict
|
|
6
|
+
|
|
7
|
+
__all__ = ["ProductUpdateFilesParams"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ProductUpdateFilesParams(TypedDict, total=False):
|
|
11
|
+
file_name: Required[str]
|
|
@@ -9,7 +9,7 @@ from .price_param import PriceParam
|
|
|
9
9
|
from .tax_category import TaxCategory
|
|
10
10
|
from .license_key_duration_param import LicenseKeyDurationParam
|
|
11
11
|
|
|
12
|
-
__all__ = ["ProductUpdateParams"]
|
|
12
|
+
__all__ = ["ProductUpdateParams", "DigitalProductDelivery"]
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ProductUpdateParams(TypedDict, total=False):
|
|
@@ -21,6 +21,8 @@ class ProductUpdateParams(TypedDict, total=False):
|
|
|
21
21
|
description: Optional[str]
|
|
22
22
|
"""Description of the product, optional and must be at most 1000 characters."""
|
|
23
23
|
|
|
24
|
+
digital_product_delivery: Optional[DigitalProductDelivery]
|
|
25
|
+
|
|
24
26
|
image_id: Optional[str]
|
|
25
27
|
"""Product image id after its uploaded to S3"""
|
|
26
28
|
|
|
@@ -57,3 +59,14 @@ class ProductUpdateParams(TypedDict, total=False):
|
|
|
57
59
|
Represents the different categories of taxation applicable to various products
|
|
58
60
|
and services.
|
|
59
61
|
"""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class DigitalProductDelivery(TypedDict, total=False):
|
|
65
|
+
external_url: Optional[str]
|
|
66
|
+
"""External URL to digital product"""
|
|
67
|
+
|
|
68
|
+
files: Optional[List[str]]
|
|
69
|
+
"""Uploaded files ids of digital product"""
|
|
70
|
+
|
|
71
|
+
instructions: Optional[str]
|
|
72
|
+
"""Instructions to download and use the digital product"""
|
|
@@ -12,7 +12,7 @@ class SubscriptionChangePlanParams(TypedDict, total=False):
|
|
|
12
12
|
product_id: Required[str]
|
|
13
13
|
"""Unique identifier of the product to subscribe to"""
|
|
14
14
|
|
|
15
|
-
proration_billing_mode: Required[Literal["prorated_immediately"]]
|
|
15
|
+
proration_billing_mode: Required[Literal["prorated_immediately", "full_immediately"]]
|
|
16
16
|
|
|
17
17
|
quantity: Required[int]
|
|
18
18
|
"""Number of units to subscribe for. Must be at least 1."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dodopayments
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.34.1
|
|
4
4
|
Summary: The official Python library for the Dodo Payments API
|
|
5
5
|
Project-URL: Homepage, https://github.com/dodopayments/dodopayments-python
|
|
6
6
|
Project-URL: Repository, https://github.com/dodopayments/dodopayments-python
|
|
@@ -27,11 +27,14 @@ Requires-Dist: httpx<1,>=0.23.0
|
|
|
27
27
|
Requires-Dist: pydantic<3,>=1.9.0
|
|
28
28
|
Requires-Dist: sniffio
|
|
29
29
|
Requires-Dist: typing-extensions<5,>=4.10
|
|
30
|
+
Provides-Extra: aiohttp
|
|
31
|
+
Requires-Dist: aiohttp; extra == 'aiohttp'
|
|
32
|
+
Requires-Dist: httpx-aiohttp>=0.1.6; extra == 'aiohttp'
|
|
30
33
|
Description-Content-Type: text/markdown
|
|
31
34
|
|
|
32
35
|
# Dodo Payments Python API library
|
|
33
36
|
|
|
34
|
-
[](https://pypi.org/project/dodopayments/)
|
|
37
|
+
[>)](https://pypi.org/project/dodopayments/)
|
|
35
38
|
|
|
36
39
|
The [Dodo Payments](https://dodopayments.com) Python library provides convenient access to the Dodo Payments REST API from any Python 3.8+
|
|
37
40
|
application. The library includes type definitions for all request params and response fields,
|
|
@@ -129,6 +132,55 @@ asyncio.run(main())
|
|
|
129
132
|
|
|
130
133
|
Functionality between the synchronous and asynchronous clients is otherwise identical.
|
|
131
134
|
|
|
135
|
+
### With aiohttp
|
|
136
|
+
|
|
137
|
+
By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.
|
|
138
|
+
|
|
139
|
+
You can enable this by installing `aiohttp`:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
# install from PyPI
|
|
143
|
+
pip install dodopayments[aiohttp]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
import os
|
|
150
|
+
import asyncio
|
|
151
|
+
from dodopayments import DefaultAioHttpClient
|
|
152
|
+
from dodopayments import AsyncDodoPayments
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
async def main() -> None:
|
|
156
|
+
async with AsyncDodoPayments(
|
|
157
|
+
bearer_token=os.environ.get(
|
|
158
|
+
"DODO_PAYMENTS_API_KEY"
|
|
159
|
+
), # This is the default and can be omitted
|
|
160
|
+
http_client=DefaultAioHttpClient(),
|
|
161
|
+
) as client:
|
|
162
|
+
payment = await client.payments.create(
|
|
163
|
+
billing={
|
|
164
|
+
"city": "city",
|
|
165
|
+
"country": "AF",
|
|
166
|
+
"state": "state",
|
|
167
|
+
"street": "street",
|
|
168
|
+
"zipcode": "zipcode",
|
|
169
|
+
},
|
|
170
|
+
customer={"customer_id": "customer_id"},
|
|
171
|
+
product_cart=[
|
|
172
|
+
{
|
|
173
|
+
"product_id": "product_id",
|
|
174
|
+
"quantity": 0,
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
)
|
|
178
|
+
print(payment.payment_id)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
asyncio.run(main())
|
|
182
|
+
```
|
|
183
|
+
|
|
132
184
|
## Using types
|
|
133
185
|
|
|
134
186
|
Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:
|
|
@@ -322,7 +374,7 @@ client.with_options(max_retries=5).payments.create(
|
|
|
322
374
|
### Timeouts
|
|
323
375
|
|
|
324
376
|
By default requests time out after 1 minute. You can configure this with a `timeout` option,
|
|
325
|
-
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
|
|
377
|
+
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
|
|
326
378
|
|
|
327
379
|
```python
|
|
328
380
|
from dodopayments import DodoPayments
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
dodopayments/__init__.py,sha256=
|
|
2
|
-
dodopayments/_base_client.py,sha256=
|
|
1
|
+
dodopayments/__init__.py,sha256=jLgJiqM7q7-wstUdqp2RuuWVjLPGor5q-vw3liQR5lw,2711
|
|
2
|
+
dodopayments/_base_client.py,sha256=uukLcGUZH6eVyITp9lKMxmEt4xPRWW4ydqSZqxXEetc,66721
|
|
3
3
|
dodopayments/_client.py,sha256=6gxmSa9iNmeNzmpy05mph0aAbrzFU8P0swS3oYc0dKY,27376
|
|
4
4
|
dodopayments/_compat.py,sha256=VWemUKbj6DDkQ-O4baSpHVLJafotzeXmCQGJugfVTIw,6580
|
|
5
5
|
dodopayments/_constants.py,sha256=S14PFzyN9-I31wiV7SmIlL5Ga0MLHxdvegInGdXH7tM,462
|
|
@@ -11,7 +11,7 @@ dodopayments/_resource.py,sha256=Jfh17Q3kKzAhO-dlfIwYlueN9t1edaaY_vmnC9vErpA,113
|
|
|
11
11
|
dodopayments/_response.py,sha256=PDvrSN3E3IkXVw2GvyOCTNB8ch0Xn9yaWQz4w1nHZEQ,28854
|
|
12
12
|
dodopayments/_streaming.py,sha256=U4D6MhotaUaGaHz32lBt0XM98IOPIpPbKHUfbb0HGCk,10124
|
|
13
13
|
dodopayments/_types.py,sha256=gP0yR7AIegimhmZ6rYIjSHFCr9YWzvh-jZabbVcgtio,6203
|
|
14
|
-
dodopayments/_version.py,sha256=
|
|
14
|
+
dodopayments/_version.py,sha256=89jhNpsrrRxFm_Ay1fFqnmCFYNHvwHnIB8gv31usGNE,165
|
|
15
15
|
dodopayments/pagination.py,sha256=WYDrAWHvGL58Fe6X2yYZyYTAFvzWOR63JAsKURk2ti4,1308
|
|
16
16
|
dodopayments/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
dodopayments/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
|
|
@@ -37,7 +37,7 @@ dodopayments/resources/misc.py,sha256=BRPUna3lLIrJ-gMGOOQL1-xYx_oMwVDzKL4d498C7p
|
|
|
37
37
|
dodopayments/resources/payments.py,sha256=-eNGFfIH1y6OwJhLgu7b6WMHr7UrkJC6EZzZA6roHDk,24362
|
|
38
38
|
dodopayments/resources/payouts.py,sha256=NjBQALlhMcbMDO5AdWLioSFrGdMvpqki_HydRl0XJyE,6995
|
|
39
39
|
dodopayments/resources/refunds.py,sha256=zHDxUmpS1zlFcbuMRDTN0P2EKO2CYtqyWYMWigflMms,15094
|
|
40
|
-
dodopayments/resources/subscriptions.py,sha256=
|
|
40
|
+
dodopayments/resources/subscriptions.py,sha256=myWNfR32bR9lJGOAa6oCkRuFhzufO3-0jgvht1QaKis,36450
|
|
41
41
|
dodopayments/resources/webhook_events.py,sha256=ucdz7uBUeUtkWNcp3na6nOUq-67eYIfxwQ3tguTyWBw,12048
|
|
42
42
|
dodopayments/resources/customers/__init__.py,sha256=RIP1WYqO_PIq9b57tDaJWf9zIRxG_iFeFkOVhe3apAo,1146
|
|
43
43
|
dodopayments/resources/customers/customer_portal.py,sha256=E967nei40PZfCRFDv5K0jxxVBEOFpmZsEIkseOGsUM0,7010
|
|
@@ -47,8 +47,8 @@ dodopayments/resources/invoices/invoices.py,sha256=-XZWHtZk92Wbbz5qO0DgiOCZGNKv4
|
|
|
47
47
|
dodopayments/resources/invoices/payments.py,sha256=Kq32Cpzca3YuPdk8XjmF6wkRi6_BQ2aegyLf2FZ7KG8,6346
|
|
48
48
|
dodopayments/resources/products/__init__.py,sha256=GKmDlI7Pw4UnnCRlnhb5WBh2Y3UYhqme7RqC35aztGo,1028
|
|
49
49
|
dodopayments/resources/products/images.py,sha256=Dl-hxas2F6C30yhBifxCMy5xdLIgPSENHOhS8J6klJs,6388
|
|
50
|
-
dodopayments/resources/products/products.py,sha256=
|
|
51
|
-
dodopayments/types/__init__.py,sha256=
|
|
50
|
+
dodopayments/resources/products/products.py,sha256=Lv0Td8u9nqggIaduteOA6l6ViRQ_WrGJ1ZoEZnRjgks,37236
|
|
51
|
+
dodopayments/types/__init__.py,sha256=AWw4xT5gR0hwA7L22Y-dlehQ_A-JmHDvTvpivGhefyw,6920
|
|
52
52
|
dodopayments/types/addon_cart_response_item.py,sha256=R-I8Zd2HJKn0DmXmv6Oyu4oo-oEC1-dud0Q6_yqDB7k,235
|
|
53
53
|
dodopayments/types/addon_create_params.py,sha256=TxMBkJG5ZJXdLiyAzJ8YJPzMg98nGn6stXYQ7I1sH-A,731
|
|
54
54
|
dodopayments/types/addon_list_params.py,sha256=M3CxvfBwcirkJeNAIaOF2c5JdRR3GpTBVAZUdlfctg0,412
|
|
@@ -103,27 +103,29 @@ dodopayments/types/license_validate_response.py,sha256=vlSrdtsVYmQcsJpPMI-ENCf_a
|
|
|
103
103
|
dodopayments/types/misc_list_supported_countries_response.py,sha256=Imr7f0CAjq04iikVbDSUvG1ZSYzB9Fopx8pVfVtt-zw,307
|
|
104
104
|
dodopayments/types/one_time_product_cart_item.py,sha256=3l7J3KEE-SCXgArN25qKIXbIIu44Q2kxqd7jf73AGto,544
|
|
105
105
|
dodopayments/types/one_time_product_cart_item_param.py,sha256=JydRYPBnLhON1pCQPRpQzKLaGJTSrDn1IRVCcMK8iAE,633
|
|
106
|
-
dodopayments/types/payment.py,sha256=
|
|
106
|
+
dodopayments/types/payment.py,sha256=_Z6vrDs1p6F7cV_IQvAFjRX3GkrkMHuMN33rRcZhuqQ,3350
|
|
107
107
|
dodopayments/types/payment_create_params.py,sha256=GlxEMIxXu7FzlMxltv2ZRyh70tnhsJdGXQIDWTKztwo,2395
|
|
108
108
|
dodopayments/types/payment_create_response.py,sha256=6Evr_32yYRrMUnSTxD9QOLAgF-qAd8t85UGcLXI4BhE,1034
|
|
109
109
|
dodopayments/types/payment_list_params.py,sha256=6HNPenBx7OPl_u-K5rNRH5Yf2iJxeNOBan80q3Fi8Os,1069
|
|
110
|
-
dodopayments/types/payment_list_response.py,sha256=
|
|
110
|
+
dodopayments/types/payment_list_response.py,sha256=I4X52FokitP_OzrR7qQSnIrswyIDOI8E1gu1h4vyDHA,784
|
|
111
111
|
dodopayments/types/payment_retrieve_line_items_response.py,sha256=pYGKPFZwJgR2WWJpB6EW8ZTZ8wTsxTts51lC2kQGGQI,485
|
|
112
112
|
dodopayments/types/payout_list_params.py,sha256=FNePC2d3PqtkgF7KX8JNokuhf7hVRcYtRN1LR_wYhr4,414
|
|
113
113
|
dodopayments/types/payout_list_response.py,sha256=X1MohXqnkhveBGhCEvVf81B1A0CrkQAnbtN6Bx_Gvq8,1537
|
|
114
114
|
dodopayments/types/price.py,sha256=H6iWBa08ZDXZOKkHppfLaY1bSXjU2TSGSNy4E61s1V8,3021
|
|
115
115
|
dodopayments/types/price_param.py,sha256=931KAoFCDfTpc90_tvJySSSjbtajOeNMOl1DIe1_lKk,3075
|
|
116
|
-
dodopayments/types/product.py,sha256=
|
|
117
|
-
dodopayments/types/product_create_params.py,sha256=
|
|
116
|
+
dodopayments/types/product.py,sha256=pbl9X8lEzKDmdzQhtocSgvdQo9R1rBilCY1QT8dt-Ro,2262
|
|
117
|
+
dodopayments/types/product_create_params.py,sha256=0JQ__B8ISNOrtz2AkPEQMr4dN5KHJgxwOBrLrqpgLGE,1734
|
|
118
118
|
dodopayments/types/product_list_params.py,sha256=5ggVIibipP3mwTi2m7GjRM0JpCAzfM643Py16mcdMjU,780
|
|
119
119
|
dodopayments/types/product_list_response.py,sha256=ZP5xA0GKzKSzewE5nouvyNVMIQuP-W8sdkwlLWzK9UI,1792
|
|
120
|
-
dodopayments/types/
|
|
120
|
+
dodopayments/types/product_update_files_params.py,sha256=7AkcQ3mWfc2WyUOnWabzst-gQaWTuS3KSvmM1KYnhT4,300
|
|
121
|
+
dodopayments/types/product_update_files_response.py,sha256=a6sNHOCHQxxA7l55M3zS8S26O3UEFo1vctngHIy5tJo,239
|
|
122
|
+
dodopayments/types/product_update_params.py,sha256=uudICilkw6Hc9CTrj4EoMuKwX5V_dTlXTot8uim0Ev4,2222
|
|
121
123
|
dodopayments/types/refund.py,sha256=SDypA3TI34Y1cUTycikA15juiOsjdeQSw9TT9gKWK2M,940
|
|
122
124
|
dodopayments/types/refund_create_params.py,sha256=hua-rUlW_5ZfKaPsh8O06yPgsj0gH7ru9Rw0Rb-3moQ,912
|
|
123
125
|
dodopayments/types/refund_list_params.py,sha256=oBgwuTJNhXpCOY0LKc-sItxPdOJUVYnS5KqcNqcXpgM,937
|
|
124
126
|
dodopayments/types/refund_status.py,sha256=ftnBnLvslfMYcUg8t7nEvb6-m5NWyVVnNcgyVu9eZto,243
|
|
125
127
|
dodopayments/types/subscription.py,sha256=EITV2TNuS9kuYOSWXibeHTRud5_PtQSQLZbMEGkt1zo,2354
|
|
126
|
-
dodopayments/types/subscription_change_plan_params.py,sha256=
|
|
128
|
+
dodopayments/types/subscription_change_plan_params.py,sha256=ssVp-w6Ql0JesLYLd3Ftg2EUG337W-JacGNLJ43lqzs,851
|
|
127
129
|
dodopayments/types/subscription_charge_params.py,sha256=pgniOwmevUGAMPZIlzdVZEPjSGZ8nDZuMzHLIhbEhaE,541
|
|
128
130
|
dodopayments/types/subscription_charge_response.py,sha256=aDFuOKqqQ-_v1szx9oUT89QaeM3nvwrlAExzZhF0O-Q,228
|
|
129
131
|
dodopayments/types/subscription_create_params.py,sha256=vzr2_alFQKsbt5dzBLA_WWhOZdPBrf7faf8vsXxpbNE,3259
|
|
@@ -142,7 +144,7 @@ dodopayments/types/invoices/__init__.py,sha256=OKfJYcKb4NObdiRObqJV_dOyDQ8feXekD
|
|
|
142
144
|
dodopayments/types/products/__init__.py,sha256=-W2ETtkni8cZpsC4Eg1aRwuLg1plV1U429JFOR1U4Rw,273
|
|
143
145
|
dodopayments/types/products/image_update_params.py,sha256=JmSZGjXI9uZgKdO9_7CINyIOmuphlmZr7-7P7kE-R5Q,308
|
|
144
146
|
dodopayments/types/products/image_update_response.py,sha256=TcJyXjoJlONpwwR6yZdIuBTu2VNyLRZFELfstD9_V-o,273
|
|
145
|
-
dodopayments-1.
|
|
146
|
-
dodopayments-1.
|
|
147
|
-
dodopayments-1.
|
|
148
|
-
dodopayments-1.
|
|
147
|
+
dodopayments-1.34.1.dist-info/METADATA,sha256=B4Xg_gkYASUGbPBtaQpBrFHC95eTpmNpsS6mvNUs3XU,18916
|
|
148
|
+
dodopayments-1.34.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
149
|
+
dodopayments-1.34.1.dist-info/licenses/LICENSE,sha256=3_sqrBb5J3AT3FsjMKEOBRZhweWVsl_s_RjFlclm1vQ,11343
|
|
150
|
+
dodopayments-1.34.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|