recharge-api 2.0.2__tar.gz → 2.0.4__tar.gz

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.
Files changed (101) hide show
  1. {recharge_api-2.0.2/recharge_api.egg-info → recharge_api-2.0.4}/PKG-INFO +2 -1
  2. {recharge_api-2.0.2 → recharge_api-2.0.4}/pyproject.toml +2 -2
  3. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/token.py +1 -3
  4. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/account.py +3 -1
  5. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/address.py +4 -4
  6. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/charge.py +8 -10
  7. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/collection.py +1 -1
  8. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/customer.py +3 -2
  9. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/discount.py +7 -7
  10. recharge_api-2.0.4/recharge/model/v2/event.py +29 -0
  11. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/onetime.py +1 -1
  12. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/order.py +24 -17
  13. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/payment_method.py +12 -4
  14. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/plan.py +3 -3
  15. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/retention_strategy.py +3 -3
  16. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/store.py +11 -1
  17. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/subscription.py +10 -2
  18. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/token.py +1 -3
  19. {recharge_api-2.0.2 → recharge_api-2.0.4/recharge_api.egg-info}/PKG-INFO +2 -1
  20. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge_api.egg-info/requires.txt +1 -0
  21. recharge_api-2.0.2/recharge/model/v2/event.py +0 -34
  22. {recharge_api-2.0.2 → recharge_api-2.0.4}/LICENSE +0 -0
  23. {recharge_api-2.0.2 → recharge_api-2.0.4}/README.md +0 -0
  24. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/__init__.py +0 -0
  25. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/__init__.py +0 -0
  26. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/__init__.py +0 -0
  27. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/addresses.py +0 -0
  28. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/async_batches.py +0 -0
  29. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/charges.py +0 -0
  30. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/checkouts.py +0 -0
  31. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/customers.py +0 -0
  32. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/discounts.py +0 -0
  33. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/metafields.py +0 -0
  34. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/notifications.py +0 -0
  35. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/onetimes.py +0 -0
  36. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/orders.py +0 -0
  37. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/products.py +0 -0
  38. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/shop.py +0 -0
  39. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/subscriptions.py +0 -0
  40. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/tokens.py +0 -0
  41. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v1/webhooks.py +0 -0
  42. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/__init__.py +0 -0
  43. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/accounts.py +0 -0
  44. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/addresses.py +0 -0
  45. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/async_batches.py +0 -0
  46. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/bundle_selections.py +0 -0
  47. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/charges.py +0 -0
  48. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/checkouts.py +0 -0
  49. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/collections.py +0 -0
  50. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/customers.py +0 -0
  51. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/discounts.py +0 -0
  52. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/events.py +0 -0
  53. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/metafields.py +0 -0
  54. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/notifications.py +0 -0
  55. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/onetimes.py +0 -0
  56. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/orders.py +0 -0
  57. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/payment_methods.py +0 -0
  58. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/plans.py +0 -0
  59. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/products.py +0 -0
  60. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/retention_strategies.py +0 -0
  61. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/store.py +0 -0
  62. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/subscriptions.py +0 -0
  63. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/tokens.py +0 -0
  64. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/api/v2/webhooks.py +0 -0
  65. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/client.py +0 -0
  66. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/exceptions.py +0 -0
  67. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/__init__.py +0 -0
  68. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/__init__.py +0 -0
  69. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/address.py +0 -0
  70. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/async_batch.py +0 -0
  71. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/charge.py +0 -0
  72. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/checkout.py +0 -0
  73. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/customer.py +0 -0
  74. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/discount.py +0 -0
  75. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/metafield.py +0 -0
  76. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/notification.py +0 -0
  77. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/onetime.py +0 -0
  78. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/order.py +0 -0
  79. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/product.py +0 -0
  80. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/shop.py +0 -0
  81. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/subscription.py +0 -0
  82. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v1/webhook.py +0 -0
  83. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/__init__.py +0 -0
  84. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/async_batch.py +0 -0
  85. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/bundle_selection.py +0 -0
  86. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/checkout.py +0 -0
  87. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/metafield.py +0 -0
  88. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/notification.py +0 -0
  89. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/product.py +0 -0
  90. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/model/v2/webhook.py +0 -0
  91. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/pagination.py +0 -0
  92. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/retry.py +0 -0
  93. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/transport.py +0 -0
  94. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge/types.py +0 -0
  95. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge_api.egg-info/SOURCES.txt +0 -0
  96. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge_api.egg-info/dependency_links.txt +0 -0
  97. {recharge_api-2.0.2 → recharge_api-2.0.4}/recharge_api.egg-info/top_level.txt +0 -0
  98. {recharge_api-2.0.2 → recharge_api-2.0.4}/setup.cfg +0 -0
  99. {recharge_api-2.0.2 → recharge_api-2.0.4}/tests/test_client.py +0 -0
  100. {recharge_api-2.0.2 → recharge_api-2.0.4}/tests/test_pagination.py +0 -0
  101. {recharge_api-2.0.2 → recharge_api-2.0.4}/tests/test_retry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recharge-api
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: Python API Client for Recharge
5
5
  Author-email: ChemicalLuck <j.tebbett@outlook.com>
6
6
  Project-URL: Homepage, http://github.com/ChemicalLuck/recharge-api
@@ -23,6 +23,7 @@ Requires-Dist: pre-commit; extra == "dev"
23
23
  Requires-Dist: pytest; extra == "dev"
24
24
  Requires-Dist: pytest-cov; extra == "dev"
25
25
  Requires-Dist: responses; extra == "dev"
26
+ Requires-Dist: python-dotenv; extra == "dev"
26
27
  Dynamic: license-file
27
28
 
28
29
  # Recharge API Wrapper
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "recharge-api"
3
- version = "2.0.2"
3
+ version = "2.0.4"
4
4
  authors = [
5
5
  { name="ChemicalLuck", email="j.tebbett@outlook.com" }
6
6
  ]
@@ -20,7 +20,7 @@ classifiers = [
20
20
  dependencies = ["requests", "pydantic>=2.0"]
21
21
 
22
22
  [project.optional-dependencies]
23
- dev = ["ruff", "pre-commit", "pytest", "pytest-cov", "responses"]
23
+ dev = ["ruff", "pre-commit", "pytest", "pytest-cov", "responses", "python-dotenv"]
24
24
 
25
25
  [project.urls]
26
26
  Homepage = "http://github.com/ChemicalLuck/recharge-api"
@@ -2,8 +2,6 @@ from typing import Optional
2
2
 
3
3
  from pydantic import BaseModel, ConfigDict
4
4
 
5
- from recharge.types import RechargeScope
6
-
7
5
 
8
6
  class TokenClient(BaseModel):
9
7
  model_config = ConfigDict(extra="allow", populate_by_name=True)
@@ -18,4 +16,4 @@ class TokenInformation(BaseModel):
18
16
  client: Optional[TokenClient] = None
19
17
  contact_email: Optional[str] = None
20
18
  name: Optional[str] = None
21
- scopes: list[RechargeScope] = []
19
+ scopes: list[str] = []
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from pydantic import BaseModel, ConfigDict
2
4
 
3
5
 
@@ -7,5 +9,5 @@ class Account(BaseModel):
7
9
  id: int
8
10
  user_id: int
9
11
  created_at: str
10
- invited_at: str
12
+ invited_at: Optional[str] = None
11
13
  is_owner: bool
@@ -2,7 +2,7 @@ from typing import Literal, Optional
2
2
 
3
3
  from pydantic import BaseModel, ConfigDict
4
4
 
5
- AddressDiscountType = Literal["percentage", "fixed_amount"]
5
+ AddressDiscountValueType = Literal["percentage", "fixed_amount"]
6
6
 
7
7
 
8
8
  class AddressOrderAttribute(BaseModel):
@@ -15,10 +15,10 @@ class AddressOrderAttribute(BaseModel):
15
15
  class AddressDiscount(BaseModel):
16
16
  model_config = ConfigDict(extra="allow", populate_by_name=True)
17
17
 
18
- id: Optional[str] = None
18
+ id: Optional[int] = None
19
19
  code: Optional[str] = None
20
- value: Optional[int] = None
21
- discount_type: Optional[AddressDiscountType] = None
20
+ value: Optional[float] = None
21
+ value_type: Optional[AddressDiscountValueType] = None
22
22
 
23
23
 
24
24
  class AddressNoteAttribute(BaseModel):
@@ -24,14 +24,7 @@ class ChargeAnalyticsDataUtmParams(BaseModel):
24
24
  class ChargeAnalyticsData(BaseModel):
25
25
  model_config = ConfigDict(extra="allow", populate_by_name=True)
26
26
 
27
- utm_params: Optional[ChargeAnalyticsDataUtmParams] = None
28
-
29
- @field_validator("utm_params", mode="before")
30
- @classmethod
31
- def coerce_utm_params(cls, v: Any) -> Any:
32
- if isinstance(v, list):
33
- return None
34
- return v
27
+ utm_params: Optional[list[ChargeAnalyticsDataUtmParams]] = None
35
28
 
36
29
 
37
30
  class ChargeBillingAddress(BaseModel):
@@ -92,7 +85,7 @@ class ChargeExternalOrderId(BaseModel):
92
85
  class ChargeExternalTransactionId(BaseModel):
93
86
  model_config = ConfigDict(extra="allow", populate_by_name=True)
94
87
 
95
- ecommerce: Optional[str] = None
88
+ payment_processor: Optional[str] = None
96
89
 
97
90
 
98
91
  class ChargeLineItemImages(BaseModel):
@@ -128,8 +121,12 @@ class ChargeTaxLine(BaseModel):
128
121
  model_config = ConfigDict(extra="allow", populate_by_name=True)
129
122
 
130
123
  price: Optional[str] = None
131
- rate: Optional[str] = None
124
+ rate: Optional[Union[str, float]] = None
132
125
  title: Optional[str] = None
126
+ unit_price: Optional[str] = None
127
+
128
+
129
+ ChargeLineItemPurchaseItemType = Literal["subscription", "onetime"]
133
130
 
134
131
 
135
132
  class ChargeLineItem(BaseModel):
@@ -143,6 +140,7 @@ class ChargeLineItem(BaseModel):
143
140
  images: Optional[ChargeLineItemImages] = None
144
141
  original_price: Optional[str] = None
145
142
  properties: list[ChargeLineItemProperty] = []
143
+ purchase_item_type: Optional[ChargeLineItemPurchaseItemType] = None
146
144
  quantity: Optional[int] = None
147
145
  sku: Optional[str] = None
148
146
  tax_due: Optional[str] = None
@@ -15,7 +15,7 @@ class Collection(BaseModel):
15
15
  description: Optional[str] = None
16
16
  sort_order: Optional[CollectionSortOrder] = None
17
17
  title: Optional[str] = None
18
- type: Optional[Literal["manual"]] = None
18
+ type: Optional[str] = None
19
19
  updated_at: Optional[str] = None
20
20
 
21
21
 
@@ -45,6 +45,7 @@ class Customer(BaseModel):
45
45
  hash: str
46
46
  last_name: str
47
47
  phone: Optional[str] = None
48
+ status: Optional[CustomerStatus] = None
48
49
  subscriptions_active_count: int
49
50
  subscriptions_total_count: int
50
51
  tax_exempt: bool
@@ -97,7 +98,7 @@ class CustomerDeliveryOrderLineItem(BaseModel):
97
98
  subscription_id: int
98
99
  external_product_id: CustomerDeliveryOrderLineItemExternalProductId
99
100
  external_variant_id: CustomerDeliveryOrderLineItemExternalVariantId
100
- images: list[CustomerDeliveryOrderLineItemImage]
101
+ images: Optional[CustomerDeliveryOrderLineItemImage] = None
101
102
  is_prepaid: bool
102
103
  is_skippable: bool
103
104
  is_skipped: bool
@@ -167,7 +168,7 @@ class CustomerDeliveryOrder(BaseModel):
167
168
 
168
169
  id: Optional[int] = None
169
170
  address_id: int
170
- charge_id: int
171
+ charge_id: Optional[int] = None
171
172
  line_items: list[CustomerDeliveryOrderLineItem]
172
173
  order_subtotal: str
173
174
  payment_method: CustomerDeliveryOrderPaymentMethod
@@ -1,4 +1,4 @@
1
- from typing import Literal, Optional
1
+ from typing import Any, Literal, Optional, Union
2
2
 
3
3
  from pydantic import BaseModel, ConfigDict
4
4
 
@@ -10,7 +10,7 @@ DiscountAppliesToResource = Literal["shopify_product", "shopify_collection_id"]
10
10
  class DiscountAppliesTo(BaseModel):
11
11
  model_config = ConfigDict(extra="allow", populate_by_name=True)
12
12
 
13
- ids: Optional[list[str]] = None
13
+ ids: Optional[list[Union[str, int]]] = None
14
14
  purchase_item_type: Optional[DiscountAppliesToPurchaseItemType] = None
15
15
  resource: Optional[DiscountAppliesToResource] = None
16
16
 
@@ -21,7 +21,7 @@ DiscountProductType = Literal["ALL", "ONETIME", "SUBSCRIPTION"]
21
21
  class DiscountChannelSettingsValue(BaseModel):
22
22
  model_config = ConfigDict(extra="allow", populate_by_name=True)
23
23
 
24
- can_apply: bool
24
+ can_apply: Optional[bool] = None
25
25
 
26
26
 
27
27
  class DiscountChannelSettings(BaseModel):
@@ -44,9 +44,9 @@ class DiscountUsageLimits(BaseModel):
44
44
  model_config = ConfigDict(extra="allow", populate_by_name=True)
45
45
 
46
46
  one_application_per_customer: bool
47
- first_time_customer_restriction: DiscountFirstTimeCustomerRestriction
48
- max_subsequent_redemptions: int
49
- redemptions: int
47
+ first_time_customer_restriction: Optional[Any] = None
48
+ max_subsequent_redemptions: Optional[int] = None
49
+ redemptions: Optional[int] = None
50
50
 
51
51
 
52
52
  DiscountStatus = Literal["enabled", "disabled", "fully_disabled"]
@@ -55,7 +55,7 @@ DiscountStatus = Literal["enabled", "disabled", "fully_disabled"]
55
55
  class DiscountExternalDiscountId(BaseModel):
56
56
  model_config = ConfigDict(extra="allow", populate_by_name=True)
57
57
 
58
- ecommerce: str
58
+ ecommerce: Optional[str] = None
59
59
 
60
60
 
61
61
  class Discount(BaseModel):
@@ -0,0 +1,29 @@
1
+ from typing import Any, Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict
4
+
5
+
6
+ class EventSource(BaseModel):
7
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
8
+
9
+ account_id: Optional[Any] = None
10
+ api_token_id: Optional[Any] = None
11
+ api_token_name: Optional[str] = None
12
+ account_email: Optional[str] = None
13
+ origin: Optional[str] = None
14
+ user_type: Optional[str] = None
15
+
16
+
17
+ class Event(BaseModel):
18
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
19
+
20
+ id: int
21
+ object_id: int
22
+ customer_id: int
23
+ created_at: str
24
+ object_type: str
25
+ verb: str
26
+ description: str
27
+ updated_attributes: Any = None
28
+ source: Optional[EventSource] = None
29
+ custom_attributes: Any = None
@@ -33,7 +33,7 @@ class Onetime(BaseModel):
33
33
  external_variant_id: Optional[OnetimeExternalVariantId] = None
34
34
  is_cancelled: Optional[bool] = None
35
35
  next_charge_scheduled_at: Optional[str] = None
36
- price: Optional[int] = None
36
+ price: Optional[str] = None
37
37
  product_title: Optional[str] = None
38
38
  properties: list[OnetimeProperty] = []
39
39
  quantity: Optional[int] = None
@@ -1,6 +1,6 @@
1
- from typing import Literal, Optional
1
+ from typing import Any, Literal, Optional, Union
2
2
 
3
- from pydantic import BaseModel, ConfigDict
3
+ from pydantic import BaseModel, ConfigDict, field_validator
4
4
 
5
5
 
6
6
  class OrderBillingAddress(BaseModel):
@@ -11,7 +11,7 @@ class OrderBillingAddress(BaseModel):
11
11
  address2: Optional[str] = None
12
12
  city: Optional[str] = None
13
13
  company: Optional[str] = None
14
- country: Optional[str] = None
14
+ country_code: Optional[str] = None
15
15
  first_name: Optional[str] = None
16
16
  last_name: Optional[str] = None
17
17
  phone: Optional[str] = None
@@ -26,7 +26,7 @@ class OrderShippingAddress(BaseModel):
26
26
  address2: Optional[str] = None
27
27
  city: Optional[str] = None
28
28
  company: Optional[str] = None
29
- country: Optional[str] = None
29
+ country_code: Optional[str] = None
30
30
  first_name: Optional[str] = None
31
31
  last_name: Optional[str] = None
32
32
  phone: Optional[str] = None
@@ -76,7 +76,7 @@ class OrderLineItemTaxLine(BaseModel):
76
76
  model_config = ConfigDict(extra="allow", populate_by_name=True)
77
77
 
78
78
  price: str
79
- rate: str
79
+ rate: Union[str, float]
80
80
  title: str
81
81
 
82
82
 
@@ -119,7 +119,7 @@ OrderType = Literal["checkout", "recurring"]
119
119
  class OrderExternalTransactionId(BaseModel):
120
120
  model_config = ConfigDict(extra="allow", populate_by_name=True)
121
121
 
122
- ecommerce: str
122
+ payment_processor: Optional[str] = None
123
123
 
124
124
 
125
125
  class OrderExternalOrderNumber(BaseModel):
@@ -138,11 +138,11 @@ class OrderCharge(BaseModel):
138
138
  class OrderClientDetails(BaseModel):
139
139
  model_config = ConfigDict(extra="allow", populate_by_name=True)
140
140
 
141
- browser_ip: str
142
- user_agent: str
141
+ browser_ip: Optional[str] = None
142
+ user_agent: Optional[str] = None
143
143
 
144
144
 
145
- OrderDiscountValueType = Literal["percentage", "fixed_amount"]
145
+ OrderDiscountValueType = Literal["percentage", "fixed_amount", "shipping"]
146
146
 
147
147
 
148
148
  class OrderDiscount(BaseModel):
@@ -158,31 +158,38 @@ class OrderAttribute(BaseModel):
158
158
  model_config = ConfigDict(extra="allow", populate_by_name=True)
159
159
 
160
160
  name: str
161
- value: str
161
+ value: Optional[str] = None
162
162
 
163
163
 
164
164
  class OrderTaxLine(BaseModel):
165
165
  model_config = ConfigDict(extra="allow", populate_by_name=True)
166
166
 
167
167
  price: str
168
- rate: str
168
+ rate: Union[str, float]
169
169
  title: str
170
170
 
171
171
 
172
172
  class OrderShippingLine(BaseModel):
173
173
  model_config = ConfigDict(extra="allow", populate_by_name=True)
174
174
 
175
- code: str
176
- price: str
177
- source: str
178
- title: str
179
- taxable: bool
175
+ code: Optional[str] = None
176
+ price: Optional[str] = None
177
+ source: Optional[str] = None
178
+ title: Optional[str] = None
179
+ taxable: Optional[Union[str, bool]] = None
180
180
  tax_lines: list[OrderTaxLine] = []
181
181
 
182
182
 
183
183
  class Order(BaseModel):
184
184
  model_config = ConfigDict(extra="allow", populate_by_name=True)
185
185
 
186
+ @field_validator("tags", mode="before")
187
+ @classmethod
188
+ def parse_tags(cls, v: Any) -> Any:
189
+ if isinstance(v, str):
190
+ return [t.strip() for t in v.split(",") if t.strip()]
191
+ return v
192
+
186
193
  id: int
187
194
  address_id: int
188
195
  billing_address: Optional[OrderBillingAddress] = None
@@ -209,7 +216,7 @@ class Order(BaseModel):
209
216
  taxable: bool
210
217
  total_discounts: str
211
218
  total_duties: Optional[str] = None
212
- total_line_items_price: Optional[int] = None
219
+ total_line_items_price: Optional[str] = None
213
220
  total_price: str
214
221
  total_tax: str
215
222
  total_weight_grams: int
@@ -1,6 +1,6 @@
1
- from typing import Literal, Optional
1
+ from typing import Any, Literal, Optional
2
2
 
3
- from pydantic import BaseModel, ConfigDict
3
+ from pydantic import BaseModel, ConfigDict, field_validator
4
4
 
5
5
  PaymentMethodType = Literal[
6
6
  "CREDIT_CARD", "PAYPAL", "APPLE_PAY", "GOOGLE_PAY", "SEPA_DEBIT"
@@ -30,8 +30,8 @@ class PaymentMethodDetails(BaseModel):
30
30
  model_config = ConfigDict(extra="allow", populate_by_name=True)
31
31
 
32
32
  brand: Optional[str] = None
33
- exp_month: Optional[str] = None
34
- exp_year: Optional[str] = None
33
+ exp_month: Optional[int] = None
34
+ exp_year: Optional[int] = None
35
35
  last4: Optional[str] = None
36
36
  paypal_email: Optional[str] = None
37
37
  paypal_payer_id: Optional[str] = None
@@ -45,8 +45,16 @@ PaymentMethodStatus = Literal["unvalidated", "valid", "invalid", "empty"]
45
45
  class PaymentMethod(BaseModel):
46
46
  model_config = ConfigDict(extra="allow", populate_by_name=True)
47
47
 
48
+ @field_validator("payment_type", mode="before")
49
+ @classmethod
50
+ def uppercase_payment_type(cls, v: Any) -> Any:
51
+ if isinstance(v, str):
52
+ return v.upper()
53
+ return v
54
+
48
55
  id: int
49
56
  customer_id: int
57
+ billing_address: Optional[PaymentMethodBillingAddress] = None
50
58
  created_at: str
51
59
  default: bool
52
60
  payment_details: Optional[PaymentMethodDetails] = None
@@ -40,14 +40,14 @@ class PlanSubscriptionPreferences(BaseModel):
40
40
  model_config = ConfigDict(extra="allow", populate_by_name=True)
41
41
 
42
42
  apply_cutoff_date_to_checkout: Optional[bool] = None
43
- charge_interval_frequency: int
43
+ charge_interval_frequency: Optional[int] = None
44
44
  cutoff_day_of_month: Optional[int] = None
45
45
  cutoff_day_of_week: Optional[int] = None
46
46
  expire_after_specific_number_of_charges: Optional[int] = None
47
47
  order_day_of_month: Optional[int] = None
48
48
  order_day_of_week: Optional[int] = None
49
- order_interval_frequency: int
50
- interval_unit: PlanIntervalUnit
49
+ order_interval_frequency: Optional[int] = None
50
+ interval_unit: Optional[PlanIntervalUnit] = None
51
51
 
52
52
 
53
53
  class PlanChannelSettings(BaseModel):
@@ -1,4 +1,4 @@
1
- from typing import Literal
1
+ from typing import Literal, Optional
2
2
 
3
3
  from pydantic import BaseModel, ConfigDict
4
4
 
@@ -15,8 +15,8 @@ class RetentionStrategy(BaseModel):
15
15
  id: int
16
16
  cancellation_flow_type: RetentionStrategyCancellationFlowType
17
17
  created_at: str
18
- discount_code: str
19
- incentive_type: RetentionStrategyIncentiveType
18
+ discount_code: Optional[str] = None
19
+ incentive_type: Optional[RetentionStrategyIncentiveType] = None
20
20
  prevention_text: str
21
21
  reason: str
22
22
  updated_at: str
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from pydantic import BaseModel, ConfigDict
2
4
 
3
5
 
@@ -8,6 +10,14 @@ class StoreTimezone(BaseModel):
8
10
  name: str
9
11
 
10
12
 
13
+ class StorePresentmentCurrencySymbol(BaseModel):
14
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
15
+
16
+ currency: Optional[str] = None
17
+ locale_name: Optional[str] = None
18
+ symbol: Optional[str] = None
19
+
20
+
11
21
  class Store(BaseModel):
12
22
  model_config = ConfigDict(extra="allow", populate_by_name=True)
13
23
 
@@ -20,7 +30,7 @@ class Store(BaseModel):
20
30
  default_api_version: str
21
31
  email: str
22
32
  enabled_presentment_currencies: list[str]
23
- enabled_presentment_currencies_symbols: list[str]
33
+ enabled_presentment_currencies_symbols: list[StorePresentmentCurrencySymbol]
24
34
  disabled_currencies_historical: list[str]
25
35
  external_platform: str
26
36
  identifier: str
@@ -1,6 +1,6 @@
1
- from typing import Literal, Optional
1
+ from typing import Any, Literal, Optional
2
2
 
3
- from pydantic import BaseModel, ConfigDict
3
+ from pydantic import BaseModel, ConfigDict, field_validator
4
4
 
5
5
  SubscriptionOrderIntervalUnit = Literal["day", "week", "month"]
6
6
 
@@ -48,10 +48,18 @@ class SubscriptionExternalVariantId(BaseModel):
48
48
  class Subscription(BaseModel):
49
49
  model_config = ConfigDict(extra="allow", populate_by_name=True)
50
50
 
51
+ @field_validator("status", mode="before")
52
+ @classmethod
53
+ def uppercase_status(cls, v: Any) -> Any:
54
+ if isinstance(v, str):
55
+ return v.upper()
56
+ return v
57
+
51
58
  id: int
52
59
  address_id: int
53
60
  customer_id: int
54
61
  analytics_data: Optional[SubscriptionAnalyticsData] = None
62
+ plan_id: Optional[int] = None
55
63
  cancellation_reason: Optional[str] = None
56
64
  cancellation_reason_comment: Optional[str] = None
57
65
  cancelled_at: Optional[str] = None
@@ -1,7 +1,5 @@
1
1
  from pydantic import BaseModel, ConfigDict
2
2
 
3
- from recharge.types import RechargeScope
4
-
5
3
 
6
4
  class TokenClient(BaseModel):
7
5
  model_config = ConfigDict(extra="allow", populate_by_name=True)
@@ -16,4 +14,4 @@ class TokenInformation(BaseModel):
16
14
  client: TokenClient
17
15
  contact_email: str
18
16
  name: str
19
- scopes: list[RechargeScope]
17
+ scopes: list[str]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recharge-api
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: Python API Client for Recharge
5
5
  Author-email: ChemicalLuck <j.tebbett@outlook.com>
6
6
  Project-URL: Homepage, http://github.com/ChemicalLuck/recharge-api
@@ -23,6 +23,7 @@ Requires-Dist: pre-commit; extra == "dev"
23
23
  Requires-Dist: pytest; extra == "dev"
24
24
  Requires-Dist: pytest-cov; extra == "dev"
25
25
  Requires-Dist: responses; extra == "dev"
26
+ Requires-Dist: python-dotenv; extra == "dev"
26
27
  Dynamic: license-file
27
28
 
28
29
  # Recharge API Wrapper
@@ -7,3 +7,4 @@ pre-commit
7
7
  pytest
8
8
  pytest-cov
9
9
  responses
10
+ python-dotenv
@@ -1,34 +0,0 @@
1
- from pydantic import BaseModel, ConfigDict
2
-
3
-
4
- class EventSource(BaseModel):
5
- model_config = ConfigDict(extra="allow", populate_by_name=True)
6
-
7
- account_id: str
8
- api_token_id: str
9
- api_token_name: str
10
- account_email: str
11
- origin: str
12
- user_type: str
13
-
14
-
15
- class EventCustomAttributes(BaseModel):
16
- model_config = ConfigDict(extra="allow", populate_by_name=True)
17
-
18
- key: str
19
- value: str
20
-
21
-
22
- class Event(BaseModel):
23
- model_config = ConfigDict(extra="allow", populate_by_name=True)
24
-
25
- id: int
26
- object_id: int
27
- customer_id: int
28
- created_at: str
29
- object_type: str
30
- verb: str
31
- description: str
32
- updated_attributes: dict
33
- source: EventSource
34
- custom_attributes: EventCustomAttributes
File without changes
File without changes
File without changes