ordercloud-python 2026.4.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.
Files changed (114) hide show
  1. ordercloud/__init__.py +37 -0
  2. ordercloud/auth.py +136 -0
  3. ordercloud/client.py +211 -0
  4. ordercloud/config.py +42 -0
  5. ordercloud/errors.py +47 -0
  6. ordercloud/http.py +218 -0
  7. ordercloud/middleware.py +66 -0
  8. ordercloud/models/__init__.py +271 -0
  9. ordercloud/models/address.py +47 -0
  10. ordercloud/models/api_client.py +116 -0
  11. ordercloud/models/approval.py +73 -0
  12. ordercloud/models/assignments.py +402 -0
  13. ordercloud/models/auth_models.py +114 -0
  14. ordercloud/models/bundle.py +31 -0
  15. ordercloud/models/buyer.py +271 -0
  16. ordercloud/models/catalog.py +33 -0
  17. ordercloud/models/category.py +35 -0
  18. ordercloud/models/cost_center.py +27 -0
  19. ordercloud/models/credit_card.py +35 -0
  20. ordercloud/models/delivery.py +277 -0
  21. ordercloud/models/discount.py +63 -0
  22. ordercloud/models/integration.py +76 -0
  23. ordercloud/models/inventory_record.py +53 -0
  24. ordercloud/models/line_item.py +95 -0
  25. ordercloud/models/line_item_types.py +89 -0
  26. ordercloud/models/message_sender.py +80 -0
  27. ordercloud/models/misc.py +280 -0
  28. ordercloud/models/open_id_connect.py +47 -0
  29. ordercloud/models/order.py +477 -0
  30. ordercloud/models/order_return.py +92 -0
  31. ordercloud/models/payment.py +77 -0
  32. ordercloud/models/price_schedule.py +76 -0
  33. ordercloud/models/product.py +227 -0
  34. ordercloud/models/product_collection.py +186 -0
  35. ordercloud/models/promotion.py +297 -0
  36. ordercloud/models/security.py +89 -0
  37. ordercloud/models/shared.py +131 -0
  38. ordercloud/models/shipment.py +150 -0
  39. ordercloud/models/spec.py +67 -0
  40. ordercloud/models/spending_account.py +33 -0
  41. ordercloud/models/subscription.py +125 -0
  42. ordercloud/models/supplier.py +43 -0
  43. ordercloud/models/sync.py +172 -0
  44. ordercloud/models/user.py +207 -0
  45. ordercloud/models/user_group.py +27 -0
  46. ordercloud/models/webhook.py +58 -0
  47. ordercloud/py.typed +0 -0
  48. ordercloud/resources/__init__.py +65 -0
  49. ordercloud/resources/addresses.py +228 -0
  50. ordercloud/resources/admin_addresses.py +128 -0
  51. ordercloud/resources/admin_user_groups.py +185 -0
  52. ordercloud/resources/admin_users.py +150 -0
  53. ordercloud/resources/api_clients.py +308 -0
  54. ordercloud/resources/approval_rules.py +144 -0
  55. ordercloud/resources/base.py +145 -0
  56. ordercloud/resources/bundle_line_items.py +59 -0
  57. ordercloud/resources/bundle_subscription_items.py +54 -0
  58. ordercloud/resources/bundles.py +278 -0
  59. ordercloud/resources/buyer_groups.py +128 -0
  60. ordercloud/resources/buyers.py +164 -0
  61. ordercloud/resources/cart.py +613 -0
  62. ordercloud/resources/catalogs.py +311 -0
  63. ordercloud/resources/categories.py +392 -0
  64. ordercloud/resources/cost_centers.py +222 -0
  65. ordercloud/resources/credit_cards.py +227 -0
  66. ordercloud/resources/delivery_configurations.py +132 -0
  67. ordercloud/resources/discounts.py +201 -0
  68. ordercloud/resources/entity_syncs.py +534 -0
  69. ordercloud/resources/error_configs.py +71 -0
  70. ordercloud/resources/forgotten_credentials.py +74 -0
  71. ordercloud/resources/group_orders.py +28 -0
  72. ordercloud/resources/impersonation_configs.py +132 -0
  73. ordercloud/resources/incrementors.py +128 -0
  74. ordercloud/resources/integration_events.py +203 -0
  75. ordercloud/resources/inventory_integrations.py +65 -0
  76. ordercloud/resources/inventory_records.py +484 -0
  77. ordercloud/resources/line_items.py +262 -0
  78. ordercloud/resources/locales.py +203 -0
  79. ordercloud/resources/me.py +1882 -0
  80. ordercloud/resources/message_senders.py +261 -0
  81. ordercloud/resources/open_id_connects.py +128 -0
  82. ordercloud/resources/order_returns.py +306 -0
  83. ordercloud/resources/order_syncs.py +65 -0
  84. ordercloud/resources/orders.py +689 -0
  85. ordercloud/resources/payments.py +176 -0
  86. ordercloud/resources/price_schedules.py +164 -0
  87. ordercloud/resources/product_collections.py +116 -0
  88. ordercloud/resources/product_facets.py +128 -0
  89. ordercloud/resources/product_syncs.py +76 -0
  90. ordercloud/resources/products.py +454 -0
  91. ordercloud/resources/promotion_integrations.py +65 -0
  92. ordercloud/resources/promotions.py +203 -0
  93. ordercloud/resources/security_profiles.py +222 -0
  94. ordercloud/resources/seller_approval_rules.py +128 -0
  95. ordercloud/resources/shipments.py +256 -0
  96. ordercloud/resources/specs.py +313 -0
  97. ordercloud/resources/spending_accounts.py +227 -0
  98. ordercloud/resources/subscription_integrations.py +65 -0
  99. ordercloud/resources/subscription_items.py +146 -0
  100. ordercloud/resources/subscriptions.py +128 -0
  101. ordercloud/resources/supplier_addresses.py +144 -0
  102. ordercloud/resources/supplier_user_groups.py +210 -0
  103. ordercloud/resources/supplier_users.py +170 -0
  104. ordercloud/resources/suppliers.py +190 -0
  105. ordercloud/resources/tracking_events.py +130 -0
  106. ordercloud/resources/user_groups.py +210 -0
  107. ordercloud/resources/users.py +254 -0
  108. ordercloud/resources/webhooks.py +128 -0
  109. ordercloud/resources/xp_indices.py +77 -0
  110. ordercloud/sync_client.py +170 -0
  111. ordercloud_python-2026.4.1.dist-info/METADATA +552 -0
  112. ordercloud_python-2026.4.1.dist-info/RECORD +114 -0
  113. ordercloud_python-2026.4.1.dist-info/WHEEL +4 -0
  114. ordercloud_python-2026.4.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1882 @@
1
+ # GENERATED by tools/codegen — DO NOT EDIT
2
+ # Source: ordercloud-openapi-v3.json
3
+ """OrderCloud Me API resource."""
4
+
5
+ from __future__ import annotations
6
+ from typing import Any, Optional, Union
7
+
8
+ from ..models.auth_models import AccessTokenBasic, TokenPasswordReset
9
+ from ..models.buyer import BuyerAddress, BuyerCreditCard, BuyerProduct, BuyerSupplier, ProductSeller
10
+ from ..models.catalog import Catalog
11
+ from ..models.category import Category
12
+ from ..models.cost_center import CostCenter
13
+ from ..models.inventory_record import InventoryRecord
14
+ from ..models.line_item import BundleItems, LineItem
15
+ from ..models.misc import GroupOrderInvitation, SearchType
16
+ from ..models.order import Order
17
+ from ..models.product import Variant
18
+ from ..models.product_collection import (
19
+ ProductCollection,
20
+ ProductCollectionBuyerProduct,
21
+ ProductCollectionEntry,
22
+ ProductCollectionInvitation,
23
+ )
24
+ from ..models.promotion import Promotion
25
+ from ..models.shipment import Shipment, ShipmentItem
26
+ from ..models.spec import Spec
27
+ from ..models.spending_account import SpendingAccount
28
+ from ..models.subscription import Subscription
29
+ from ..models.user import MeUser
30
+ from ..models.user_group import UserGroup
31
+ from ..models.shared import ListPage, MetaWithFacets
32
+ from .base import BaseResource
33
+
34
+ __all__ = ["MeResource"]
35
+
36
+
37
+ class MeResource(BaseResource):
38
+ """Operations on OrderCloud Me."""
39
+
40
+ async def get(
41
+ self,
42
+ ) -> MeUser:
43
+ """Get the currently authenticated user
44
+
45
+ Returns:
46
+ The MeUser object.
47
+ """
48
+ resp = await self._http.get("/me")
49
+ return MeUser(**resp.json())
50
+
51
+ async def save(
52
+ self,
53
+ me_user: Union[MeUser, dict[str, Any]],
54
+ ) -> MeUser:
55
+ """Update the currently authenticated user
56
+
57
+ Args:
58
+ me_user: A ``MeUser`` model or dict. Required fields: Username, FirstName, LastName, Email, Active.
59
+
60
+ Returns:
61
+ The MeUser object.
62
+ """
63
+ resp = await self._http.put(
64
+ "/me",
65
+ json=self._serialize(me_user),
66
+ )
67
+ return MeUser(**resp.json())
68
+
69
+ async def patch(
70
+ self,
71
+ partial: dict[str, Any],
72
+ ) -> MeUser:
73
+ """Patch the currently authenticated user
74
+
75
+ Args:
76
+ partial: A dict of fields to update.
77
+
78
+ Returns:
79
+ The MeUser object.
80
+ """
81
+ resp = await self._http.patch("/me", json=partial)
82
+ return MeUser(**resp.json())
83
+
84
+ async def list_addresses(
85
+ self,
86
+ *,
87
+ search: Optional[str] = None,
88
+ search_on: Optional[str] = None,
89
+ sort_by: Optional[str] = None,
90
+ page: Optional[int] = None,
91
+ page_size: Optional[int] = None,
92
+ filters: Optional[dict[str, Any]] = None,
93
+ ) -> ListPage[BuyerAddress]:
94
+ """List addresses visible to this user
95
+
96
+ Args:
97
+ search: Word or phrase to search for.
98
+ search_on: Comma-delimited list of fields to search on.
99
+ sort_by: Comma-delimited list of fields to sort by.
100
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
101
+ page_size: Number of results to return per page.
102
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
103
+
104
+ Returns:
105
+ A paginated list of BuyerAddress objects.
106
+ """
107
+ params = self._build_list_params(
108
+ search=search,
109
+ search_on=search_on,
110
+ sort_by=sort_by,
111
+ page=page,
112
+ page_size=page_size,
113
+ filters=filters,
114
+ )
115
+ resp = await self._http.get("/me/addresses", **params)
116
+ return self._parse_list(resp.json(), BuyerAddress)
117
+
118
+ async def create_address(
119
+ self,
120
+ buyer_address: Union[BuyerAddress, dict[str, Any]],
121
+ ) -> BuyerAddress:
122
+ """Create an address
123
+
124
+ Args:
125
+ buyer_address: A ``BuyerAddress`` model or dict. Required fields: Street1, City, Country.
126
+
127
+ Returns:
128
+ The BuyerAddress object.
129
+ """
130
+ resp = await self._http.post("/me/addresses", json=self._serialize(buyer_address))
131
+ return BuyerAddress(**resp.json())
132
+
133
+ async def get_address(
134
+ self,
135
+ address_id: str,
136
+ ) -> BuyerAddress:
137
+ """Retrieve an address
138
+
139
+ Args:
140
+ address_id: ID of the address.
141
+
142
+ Returns:
143
+ The BuyerAddress object.
144
+ """
145
+ resp = await self._http.get(f"/me/addresses/{address_id}")
146
+ return BuyerAddress(**resp.json())
147
+
148
+ async def save_address(
149
+ self,
150
+ address_id: str,
151
+ buyer_address: Union[BuyerAddress, dict[str, Any]],
152
+ ) -> BuyerAddress:
153
+ """Update an address
154
+
155
+ Args:
156
+ address_id: ID of the address.
157
+ buyer_address: A ``BuyerAddress`` model or dict. Required fields: Street1, City, Country.
158
+
159
+ Returns:
160
+ The BuyerAddress object.
161
+ """
162
+ resp = await self._http.put(
163
+ f"/me/addresses/{address_id}",
164
+ json=self._serialize(buyer_address),
165
+ )
166
+ return BuyerAddress(**resp.json())
167
+
168
+ async def delete_address(
169
+ self,
170
+ address_id: str,
171
+ ) -> None:
172
+ """Delete an address
173
+
174
+ Args:
175
+ address_id: ID of the address.
176
+ """
177
+ await self._http.delete(f"/me/addresses/{address_id}")
178
+
179
+ async def patch_address(
180
+ self,
181
+ address_id: str,
182
+ partial: dict[str, Any],
183
+ ) -> None:
184
+ """Partially update an address
185
+
186
+ Args:
187
+ address_id: ID of the address.
188
+ partial: A dict of fields to update.
189
+ """
190
+ await self._http.patch(f"/me/addresses/{address_id}", json=partial)
191
+
192
+ async def list_catalogs(
193
+ self,
194
+ *,
195
+ search: Optional[str] = None,
196
+ search_on: Optional[str] = None,
197
+ sort_by: Optional[str] = None,
198
+ page: Optional[int] = None,
199
+ page_size: Optional[int] = None,
200
+ filters: Optional[dict[str, Any]] = None,
201
+ seller_id: Optional[str] = None,
202
+ ) -> ListPage[Catalog]:
203
+ """List catalogs visible to this user
204
+
205
+ Args:
206
+ search: Word or phrase to search for.
207
+ search_on: Comma-delimited list of fields to search on.
208
+ sort_by: Comma-delimited list of fields to sort by.
209
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
210
+ page_size: Number of results to return per page.
211
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
212
+ seller_id: ID of the seller.
213
+
214
+ Returns:
215
+ A paginated list of Catalog objects.
216
+ """
217
+ params = self._build_list_params(
218
+ search=search,
219
+ search_on=search_on,
220
+ sort_by=sort_by,
221
+ page=page,
222
+ page_size=page_size,
223
+ filters=filters,
224
+ )
225
+ if seller_id is not None:
226
+ params["sellerID"] = seller_id
227
+ resp = await self._http.get("/me/catalogs", **params)
228
+ return self._parse_list(resp.json(), Catalog)
229
+
230
+ async def get_catalog(
231
+ self,
232
+ catalog_id: str,
233
+ ) -> Catalog:
234
+ """Retrieve a catalog
235
+
236
+ Args:
237
+ catalog_id: ID of the catalog.
238
+
239
+ Returns:
240
+ The Catalog object.
241
+ """
242
+ resp = await self._http.get(f"/me/catalogs/{catalog_id}")
243
+ return Catalog(**resp.json())
244
+
245
+ async def list_categories(
246
+ self,
247
+ *,
248
+ depth: Optional[str] = None,
249
+ catalog_id: Optional[str] = None,
250
+ product_id: Optional[str] = None,
251
+ search: Optional[str] = None,
252
+ search_on: Optional[str] = None,
253
+ sort_by: Optional[str] = None,
254
+ page: Optional[int] = None,
255
+ page_size: Optional[int] = None,
256
+ filters: Optional[dict[str, Any]] = None,
257
+ ) -> ListPage[Category]:
258
+ """List categories visible to this user
259
+
260
+ Args:
261
+ depth: Indicates how deep down the hierarchy to return results. Valid values are a number of 1 or greater, or 'all'. Relative to ParentID if specified. Default is 1.
262
+ catalog_id: The user’s default CatalogID will be used to return categories if you do not pass another CatalogID explicitly. Listing categories across multiple catalogs is not supported.
263
+ product_id: ID of the product.
264
+ search: Word or phrase to search for.
265
+ search_on: Comma-delimited list of fields to search on.
266
+ sort_by: Comma-delimited list of fields to sort by.
267
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
268
+ page_size: Number of results to return per page.
269
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
270
+
271
+ Returns:
272
+ A paginated list of Category objects.
273
+ """
274
+ params = self._build_list_params(
275
+ depth=depth,
276
+ search=search,
277
+ search_on=search_on,
278
+ sort_by=sort_by,
279
+ page=page,
280
+ page_size=page_size,
281
+ filters=filters,
282
+ )
283
+ if catalog_id is not None:
284
+ params["catalogID"] = catalog_id
285
+ if product_id is not None:
286
+ params["productID"] = product_id
287
+ resp = await self._http.get("/me/categories", **params)
288
+ return self._parse_list(resp.json(), Category)
289
+
290
+ async def get_category(
291
+ self,
292
+ category_id: str,
293
+ *,
294
+ catalog_id: Optional[str],
295
+ ) -> Category:
296
+ """Retrieve a category
297
+
298
+ Args:
299
+ category_id: ID of the category.
300
+ catalog_id: ID of the catalog.
301
+
302
+ Returns:
303
+ The Category object.
304
+ """
305
+ _params: dict[str, Any] = {}
306
+ if catalog_id is not None:
307
+ _params["catalogID"] = catalog_id
308
+ resp = await self._http.get(f"/me/categories/{category_id}", **_params)
309
+ return Category(**resp.json())
310
+
311
+ async def list_cost_centers(
312
+ self,
313
+ *,
314
+ search: Optional[str] = None,
315
+ search_on: Optional[str] = None,
316
+ sort_by: Optional[str] = None,
317
+ page: Optional[int] = None,
318
+ page_size: Optional[int] = None,
319
+ filters: Optional[dict[str, Any]] = None,
320
+ ) -> ListPage[CostCenter]:
321
+ """List cost centers visible to this user
322
+
323
+ Args:
324
+ search: Word or phrase to search for.
325
+ search_on: Comma-delimited list of fields to search on.
326
+ sort_by: Comma-delimited list of fields to sort by.
327
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
328
+ page_size: Number of results to return per page.
329
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
330
+
331
+ Returns:
332
+ A paginated list of CostCenter objects.
333
+ """
334
+ params = self._build_list_params(
335
+ search=search,
336
+ search_on=search_on,
337
+ sort_by=sort_by,
338
+ page=page,
339
+ page_size=page_size,
340
+ filters=filters,
341
+ )
342
+ resp = await self._http.get("/me/costcenters", **params)
343
+ return self._parse_list(resp.json(), CostCenter)
344
+
345
+ async def list_credit_cards(
346
+ self,
347
+ *,
348
+ search: Optional[str] = None,
349
+ search_on: Optional[str] = None,
350
+ sort_by: Optional[str] = None,
351
+ page: Optional[int] = None,
352
+ page_size: Optional[int] = None,
353
+ filters: Optional[dict[str, Any]] = None,
354
+ ) -> ListPage[BuyerCreditCard]:
355
+ """List credit cards visible to this user
356
+
357
+ Args:
358
+ search: Word or phrase to search for.
359
+ search_on: Comma-delimited list of fields to search on.
360
+ sort_by: Comma-delimited list of fields to sort by.
361
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
362
+ page_size: Number of results to return per page.
363
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
364
+
365
+ Returns:
366
+ A paginated list of BuyerCreditCard objects.
367
+ """
368
+ params = self._build_list_params(
369
+ search=search,
370
+ search_on=search_on,
371
+ sort_by=sort_by,
372
+ page=page,
373
+ page_size=page_size,
374
+ filters=filters,
375
+ )
376
+ resp = await self._http.get("/me/creditcards", **params)
377
+ return self._parse_list(resp.json(), BuyerCreditCard)
378
+
379
+ async def create_credit_card(
380
+ self,
381
+ buyer_credit_card: Union[BuyerCreditCard, dict[str, Any]],
382
+ ) -> BuyerCreditCard:
383
+ """Create a credit card
384
+
385
+ Args:
386
+ buyer_credit_card: A ``BuyerCreditCard`` model or dict.
387
+
388
+ Returns:
389
+ The BuyerCreditCard object.
390
+ """
391
+ resp = await self._http.post("/me/creditcards", json=self._serialize(buyer_credit_card))
392
+ return BuyerCreditCard(**resp.json())
393
+
394
+ async def get_credit_card(
395
+ self,
396
+ creditcard_id: str,
397
+ ) -> BuyerCreditCard:
398
+ """Retrieve a credit card
399
+
400
+ Args:
401
+ creditcard_id: ID of the creditcard.
402
+
403
+ Returns:
404
+ The BuyerCreditCard object.
405
+ """
406
+ resp = await self._http.get(f"/me/creditcards/{creditcard_id}")
407
+ return BuyerCreditCard(**resp.json())
408
+
409
+ async def save_credit_card(
410
+ self,
411
+ creditcard_id: str,
412
+ buyer_credit_card: Union[BuyerCreditCard, dict[str, Any]],
413
+ ) -> BuyerCreditCard:
414
+ """Update a credit card
415
+
416
+ Args:
417
+ creditcard_id: ID of the creditcard.
418
+ buyer_credit_card: A ``BuyerCreditCard`` model or dict.
419
+
420
+ Returns:
421
+ The BuyerCreditCard object.
422
+ """
423
+ resp = await self._http.put(
424
+ f"/me/creditcards/{creditcard_id}",
425
+ json=self._serialize(buyer_credit_card),
426
+ )
427
+ return BuyerCreditCard(**resp.json())
428
+
429
+ async def delete_credit_card(
430
+ self,
431
+ creditcard_id: str,
432
+ ) -> None:
433
+ """Delete a credit card
434
+
435
+ Args:
436
+ creditcard_id: ID of the creditcard.
437
+ """
438
+ await self._http.delete(f"/me/creditcards/{creditcard_id}")
439
+
440
+ async def patch_credit_card(
441
+ self,
442
+ creditcard_id: str,
443
+ partial: dict[str, Any],
444
+ ) -> None:
445
+ """Partially update a credit card
446
+
447
+ Args:
448
+ creditcard_id: ID of the creditcard.
449
+ partial: A dict of fields to update.
450
+ """
451
+ await self._http.patch(f"/me/creditcards/{creditcard_id}", json=partial)
452
+
453
+ async def list_group_order_invitations(
454
+ self,
455
+ *,
456
+ search: Optional[str] = None,
457
+ search_on: Optional[str] = None,
458
+ sort_by: Optional[str] = None,
459
+ page: Optional[int] = None,
460
+ page_size: Optional[int] = None,
461
+ filters: Optional[dict[str, Any]] = None,
462
+ ) -> ListPage[GroupOrderInvitation]:
463
+ """List group order invitations visible to this user
464
+
465
+ Args:
466
+ search: Word or phrase to search for.
467
+ search_on: Comma-delimited list of fields to search on.
468
+ sort_by: Comma-delimited list of fields to sort by.
469
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
470
+ page_size: Number of results to return per page.
471
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
472
+
473
+ Returns:
474
+ A paginated list of GroupOrderInvitation objects.
475
+ """
476
+ params = self._build_list_params(
477
+ search=search,
478
+ search_on=search_on,
479
+ sort_by=sort_by,
480
+ page=page,
481
+ page_size=page_size,
482
+ filters=filters,
483
+ )
484
+ resp = await self._http.get("/me/orderinvitations", **params)
485
+ return self._parse_list(resp.json(), GroupOrderInvitation)
486
+
487
+ async def create_group_order_invitation(
488
+ self,
489
+ group_order_invitation: Union[GroupOrderInvitation, dict[str, Any]],
490
+ ) -> GroupOrderInvitation:
491
+ """Create a group order invitation
492
+
493
+ Args:
494
+ group_order_invitation: A ``GroupOrderInvitation`` model or dict. Required fields: ExpirationDate, OrderID.
495
+
496
+ Returns:
497
+ The GroupOrderInvitation object.
498
+ """
499
+ resp = await self._http.post(
500
+ "/me/orderinvitations", json=self._serialize(group_order_invitation)
501
+ )
502
+ return GroupOrderInvitation(**resp.json())
503
+
504
+ async def get_group_order_invitation(
505
+ self,
506
+ invitation_id: str,
507
+ ) -> GroupOrderInvitation:
508
+ """Retrieve a group order invitation
509
+
510
+ Args:
511
+ invitation_id: ID of the invitation.
512
+
513
+ Returns:
514
+ The GroupOrderInvitation object.
515
+ """
516
+ resp = await self._http.get(f"/me/orderinvitations/{invitation_id}")
517
+ return GroupOrderInvitation(**resp.json())
518
+
519
+ async def delete_group_order_invitation(
520
+ self,
521
+ invitation_id: str,
522
+ ) -> None:
523
+ """Delete a group order invitation
524
+
525
+ Args:
526
+ invitation_id: ID of the invitation.
527
+ """
528
+ await self._http.delete(f"/me/orderinvitations/{invitation_id}")
529
+
530
+ async def patch_group_order_invitation(
531
+ self,
532
+ invitation_id: str,
533
+ partial: dict[str, Any],
534
+ ) -> GroupOrderInvitation:
535
+ """Partially update a group order invitation
536
+
537
+ Args:
538
+ invitation_id: ID of the invitation.
539
+ partial: A dict of fields to update.
540
+
541
+ Returns:
542
+ The GroupOrderInvitation object.
543
+ """
544
+ resp = await self._http.patch(f"/me/orderinvitations/{invitation_id}", json=partial)
545
+ return GroupOrderInvitation(**resp.json())
546
+
547
+ async def list_orders(
548
+ self,
549
+ *,
550
+ from_: Optional[str] = None,
551
+ to: Optional[str] = None,
552
+ search: Optional[str] = None,
553
+ search_on: Optional[str] = None,
554
+ search_type: Optional[SearchType] = None,
555
+ sort_by: Optional[str] = None,
556
+ page: Optional[int] = None,
557
+ page_size: Optional[int] = None,
558
+ filters: Optional[dict[str, Any]] = None,
559
+ ) -> ListPage[Order]:
560
+ """List orders visible to this user
561
+
562
+ Args:
563
+ from_: Lower bound of date range that the order was created (if outgoing) or submitted (if incoming).
564
+ to: Upper bound of date range that the order was created (if outgoing) or submitted (if incoming).
565
+ search: Word or phrase to search for.
566
+ search_on: Comma-delimited list of fields to search on.
567
+ search_type: Type of search to perform.
568
+ sort_by: Comma-delimited list of fields to sort by.
569
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
570
+ page_size: Number of results to return per page.
571
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
572
+
573
+ Returns:
574
+ A paginated list of Order objects.
575
+ """
576
+ params = self._build_list_params(
577
+ search=search,
578
+ search_on=search_on,
579
+ sort_by=sort_by,
580
+ page=page,
581
+ page_size=page_size,
582
+ filters=filters,
583
+ )
584
+ if from_ is not None:
585
+ params["from"] = from_
586
+ if to is not None:
587
+ params["to"] = to
588
+ if search_type is not None:
589
+ params["searchType"] = search_type
590
+ resp = await self._http.get("/me/orders", **params)
591
+ return self._parse_list(resp.json(), Order)
592
+
593
+ async def transfer_anon_user_order(
594
+ self,
595
+ *,
596
+ anon_user_token: Optional[str],
597
+ ) -> None:
598
+ """Transfer an anon user order
599
+
600
+ Args:
601
+ anon_user_token: Anon user token of the me.
602
+ """
603
+ _params: dict[str, Any] = {}
604
+ if anon_user_token is not None:
605
+ _params["anonUserToken"] = anon_user_token
606
+ await self._http.put("/me/orders", params=_params or None)
607
+
608
+ async def list_approvable_orders(
609
+ self,
610
+ *,
611
+ from_: Optional[str] = None,
612
+ to: Optional[str] = None,
613
+ search: Optional[str] = None,
614
+ search_on: Optional[str] = None,
615
+ sort_by: Optional[str] = None,
616
+ page: Optional[int] = None,
617
+ page_size: Optional[int] = None,
618
+ filters: Optional[dict[str, Any]] = None,
619
+ ) -> ListPage[Order]:
620
+ """Get a list of orders that this user can approve
621
+
622
+ Args:
623
+ from_: Lower bound of date range that the order was created (if outgoing) or submitted (if incoming).
624
+ to: Upper bound of date range that the order was created (if outgoing) or submitted (if incoming).
625
+ search: Word or phrase to search for.
626
+ search_on: Comma-delimited list of fields to search on.
627
+ sort_by: Comma-delimited list of fields to sort by.
628
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
629
+ page_size: Number of results to return per page.
630
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
631
+
632
+ Returns:
633
+ A paginated list of Order objects.
634
+ """
635
+ params = self._build_list_params(
636
+ search=search,
637
+ search_on=search_on,
638
+ sort_by=sort_by,
639
+ page=page,
640
+ page_size=page_size,
641
+ filters=filters,
642
+ )
643
+ if from_ is not None:
644
+ params["from"] = from_
645
+ if to is not None:
646
+ params["to"] = to
647
+ resp = await self._http.get("/me/orders/approvable", **params)
648
+ return self._parse_list(resp.json(), Order)
649
+
650
+ async def reset_password_by_token(
651
+ self,
652
+ token_password_reset: Union[TokenPasswordReset, dict[str, Any]],
653
+ ) -> None:
654
+ """Reset a password by token
655
+
656
+ Args:
657
+ token_password_reset: A ``TokenPasswordReset`` model or dict. Required fields: NewPassword.
658
+ """
659
+ await self._http.post("/me/password", json=self._serialize(token_password_reset))
660
+
661
+ async def list_product_collections(
662
+ self,
663
+ *,
664
+ search: Optional[str] = None,
665
+ search_on: Optional[str] = None,
666
+ sort_by: Optional[str] = None,
667
+ page: Optional[int] = None,
668
+ page_size: Optional[int] = None,
669
+ filters: Optional[dict[str, Any]] = None,
670
+ ) -> ListPage[ProductCollection]:
671
+ """List product collections visible to this user
672
+
673
+ Args:
674
+ search: Word or phrase to search for.
675
+ search_on: Comma-delimited list of fields to search on.
676
+ sort_by: Comma-delimited list of fields to sort by.
677
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
678
+ page_size: Number of results to return per page.
679
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
680
+
681
+ Returns:
682
+ A paginated list of ProductCollection objects.
683
+ """
684
+ params = self._build_list_params(
685
+ search=search,
686
+ search_on=search_on,
687
+ sort_by=sort_by,
688
+ page=page,
689
+ page_size=page_size,
690
+ filters=filters,
691
+ )
692
+ resp = await self._http.get("/me/productcollections", **params)
693
+ return self._parse_list(resp.json(), ProductCollection)
694
+
695
+ async def create_product_collection(
696
+ self,
697
+ product_collection: Union[ProductCollection, dict[str, Any]],
698
+ ) -> ProductCollection:
699
+ """Create a product collection
700
+
701
+ Args:
702
+ product_collection: A ``ProductCollection`` model or dict. Required fields: Name.
703
+
704
+ Returns:
705
+ The ProductCollection object.
706
+ """
707
+ resp = await self._http.post(
708
+ "/me/productcollections", json=self._serialize(product_collection)
709
+ )
710
+ return ProductCollection(**resp.json())
711
+
712
+ async def get_product_collection(
713
+ self,
714
+ product_collection_id: str,
715
+ ) -> ProductCollection:
716
+ """Retrieve a product collection
717
+
718
+ Args:
719
+ product_collection_id: ID of the product collection.
720
+
721
+ Returns:
722
+ The ProductCollection object.
723
+ """
724
+ resp = await self._http.get(f"/me/productcollections/{product_collection_id}")
725
+ return ProductCollection(**resp.json())
726
+
727
+ async def save_product_collection(
728
+ self,
729
+ product_collection_id: str,
730
+ product_collection: Union[ProductCollection, dict[str, Any]],
731
+ ) -> ProductCollection:
732
+ """Create or update a product collection
733
+
734
+ Args:
735
+ product_collection_id: ID of the product collection.
736
+ product_collection: A ``ProductCollection`` model or dict. Required fields: Name.
737
+
738
+ Returns:
739
+ The ProductCollection object.
740
+ """
741
+ resp = await self._http.put(
742
+ f"/me/productcollections/{product_collection_id}",
743
+ json=self._serialize(product_collection),
744
+ )
745
+ return ProductCollection(**resp.json())
746
+
747
+ async def delete_product_collection(
748
+ self,
749
+ product_collection_id: str,
750
+ ) -> None:
751
+ """Delete a product collection
752
+
753
+ Args:
754
+ product_collection_id: ID of the product collection.
755
+ """
756
+ await self._http.delete(f"/me/productcollections/{product_collection_id}")
757
+
758
+ async def patch_product_collection(
759
+ self,
760
+ product_collection_id: str,
761
+ partial: dict[str, Any],
762
+ ) -> ProductCollection:
763
+ """Partially update a product collection
764
+
765
+ Args:
766
+ product_collection_id: ID of the product collection.
767
+ partial: A dict of fields to update.
768
+
769
+ Returns:
770
+ The ProductCollection object.
771
+ """
772
+ resp = await self._http.patch(
773
+ f"/me/productcollections/{product_collection_id}", json=partial
774
+ )
775
+ return ProductCollection(**resp.json())
776
+
777
+ async def create_product_collection_entry(
778
+ self,
779
+ product_collection_id: str,
780
+ product_id: str,
781
+ ) -> None:
782
+ """Create a product collection entry
783
+
784
+ Args:
785
+ product_collection_id: ID of the product collection.
786
+ product_id: ID of the product.
787
+ """
788
+ await self._http.put(f"/me/productcollections/{product_collection_id}/{product_id}")
789
+
790
+ async def delete_product_collection_entry(
791
+ self,
792
+ product_collection_id: str,
793
+ product_id: str,
794
+ ) -> None:
795
+ """Delete a product collection entry
796
+
797
+ Args:
798
+ product_collection_id: ID of the product collection.
799
+ product_id: ID of the product.
800
+ """
801
+ await self._http.delete(f"/me/productcollections/{product_collection_id}/{product_id}")
802
+
803
+ async def list_product_collection_invitations(
804
+ self,
805
+ product_collection_id: str,
806
+ *,
807
+ search: Optional[str] = None,
808
+ search_on: Optional[str] = None,
809
+ search_type: Optional[SearchType] = None,
810
+ sort_by: Optional[str] = None,
811
+ page: Optional[int] = None,
812
+ page_size: Optional[int] = None,
813
+ filters: Optional[dict[str, Any]] = None,
814
+ ) -> ListPage[ProductCollectionInvitation]:
815
+ """List product collection invitations visible to this user
816
+
817
+ Args:
818
+ product_collection_id: ID of the product collection.
819
+ search: Word or phrase to search for.
820
+ search_on: Comma-delimited list of fields to search on.
821
+ search_type: Type of search to perform.
822
+ sort_by: Comma-delimited list of fields to sort by.
823
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
824
+ page_size: Number of results to return per page.
825
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
826
+
827
+ Returns:
828
+ A paginated list of ProductCollectionInvitation objects.
829
+ """
830
+ params = self._build_list_params(
831
+ search=search,
832
+ search_on=search_on,
833
+ sort_by=sort_by,
834
+ page=page,
835
+ page_size=page_size,
836
+ filters=filters,
837
+ )
838
+ if search_type is not None:
839
+ params["searchType"] = search_type
840
+ resp = await self._http.get(
841
+ f"/me/productcollections/{product_collection_id}/invitations", **params
842
+ )
843
+ return self._parse_list(resp.json(), ProductCollectionInvitation)
844
+
845
+ async def create_product_collection_invitation(
846
+ self,
847
+ product_collection_id: str,
848
+ product_collection_invitation: Union[ProductCollectionInvitation, dict[str, Any]],
849
+ ) -> ProductCollectionInvitation:
850
+ """Create a product collection invitation
851
+
852
+ Args:
853
+ product_collection_id: ID of the product collection.
854
+ product_collection_invitation: A ``ProductCollectionInvitation`` model or dict. Required fields: Name.
855
+
856
+ Returns:
857
+ The ProductCollectionInvitation object.
858
+ """
859
+ resp = await self._http.post(
860
+ f"/me/productcollections/{product_collection_id}/invitations",
861
+ json=self._serialize(product_collection_invitation),
862
+ )
863
+ return ProductCollectionInvitation(**resp.json())
864
+
865
+ async def get_product_collection_invitation(
866
+ self,
867
+ product_collection_id: str,
868
+ invitation_id: str,
869
+ ) -> ProductCollectionInvitation:
870
+ """Retrieve a product collection invitation
871
+
872
+ Args:
873
+ product_collection_id: ID of the product collection.
874
+ invitation_id: ID of the invitation.
875
+
876
+ Returns:
877
+ The ProductCollectionInvitation object.
878
+ """
879
+ resp = await self._http.get(
880
+ f"/me/productcollections/{product_collection_id}/invitations/{invitation_id}"
881
+ )
882
+ return ProductCollectionInvitation(**resp.json())
883
+
884
+ async def delete_product_collection_invitation(
885
+ self,
886
+ product_collection_id: str,
887
+ invitation_id: str,
888
+ ) -> None:
889
+ """Delete a product collection invitation
890
+
891
+ Args:
892
+ product_collection_id: ID of the product collection.
893
+ invitation_id: ID of the invitation.
894
+ """
895
+ await self._http.delete(
896
+ f"/me/productcollections/{product_collection_id}/invitations/{invitation_id}"
897
+ )
898
+
899
+ async def patch_product_collection_invitation(
900
+ self,
901
+ product_collection_id: str,
902
+ invitation_id: str,
903
+ partial: dict[str, Any],
904
+ ) -> ProductCollectionInvitation:
905
+ """Partially update a product collection invitation
906
+
907
+ Args:
908
+ product_collection_id: ID of the product collection.
909
+ invitation_id: ID of the invitation.
910
+ partial: A dict of fields to update.
911
+
912
+ Returns:
913
+ The ProductCollectionInvitation object.
914
+ """
915
+ resp = await self._http.patch(
916
+ f"/me/productcollections/{product_collection_id}/invitations/{invitation_id}",
917
+ json=partial,
918
+ )
919
+ return ProductCollectionInvitation(**resp.json())
920
+
921
+ async def accept_product_collection_invitation(
922
+ self,
923
+ product_collection_id: str,
924
+ invitation_id: str,
925
+ ) -> None:
926
+ """Accept a product collection invitation
927
+
928
+ Args:
929
+ product_collection_id: ID of the product collection.
930
+ invitation_id: ID of the invitation.
931
+ """
932
+ await self._http.post(
933
+ f"/me/productcollections/{product_collection_id}/invitations/accept/{invitation_id}"
934
+ )
935
+
936
+ async def decline_product_collection_invitation(
937
+ self,
938
+ product_collection_id: str,
939
+ invitation_id: str,
940
+ ) -> None:
941
+ """Decline a product collection invitation
942
+
943
+ Args:
944
+ product_collection_id: ID of the product collection.
945
+ invitation_id: ID of the invitation.
946
+ """
947
+ await self._http.post(
948
+ f"/me/productcollections/{product_collection_id}/invitations/decline/{invitation_id}"
949
+ )
950
+
951
+ async def list_product_collection_entries(
952
+ self,
953
+ product_collection_id: str,
954
+ *,
955
+ search: Optional[str] = None,
956
+ search_on: Optional[str] = None,
957
+ search_type: Optional[SearchType] = None,
958
+ sort_by: Optional[str] = None,
959
+ page: Optional[int] = None,
960
+ page_size: Optional[int] = None,
961
+ filters: Optional[dict[str, Any]] = None,
962
+ ) -> ListPage[ProductCollectionBuyerProduct]:
963
+ """List product collection entries visible to this user
964
+
965
+ Args:
966
+ product_collection_id: ID of the product collection.
967
+ search: Word or phrase to search for.
968
+ search_on: Comma-delimited list of fields to search on.
969
+ search_type: Type of search to perform.
970
+ sort_by: Comma-delimited list of fields to sort by.
971
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
972
+ page_size: Number of results to return per page.
973
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
974
+
975
+ Returns:
976
+ A paginated list of ProductCollectionBuyerProduct objects.
977
+ """
978
+ params = self._build_list_params(
979
+ search=search,
980
+ search_on=search_on,
981
+ sort_by=sort_by,
982
+ page=page,
983
+ page_size=page_size,
984
+ filters=filters,
985
+ )
986
+ if search_type is not None:
987
+ params["searchType"] = search_type
988
+ resp = await self._http.get(
989
+ f"/me/productcollections/{product_collection_id}/products", **params
990
+ )
991
+ return self._parse_list(resp.json(), ProductCollectionBuyerProduct, meta_cls=MetaWithFacets)
992
+
993
+ async def save_product_collection_entry(
994
+ self,
995
+ product_collection_id: str,
996
+ product_collection_entry: Union[ProductCollectionEntry, dict[str, Any]],
997
+ ) -> None:
998
+ """Create or update a product collection entry
999
+
1000
+ Args:
1001
+ product_collection_id: ID of the product collection.
1002
+ product_collection_entry: A ``ProductCollectionEntry`` model or dict. Required fields: ProductID.
1003
+ """
1004
+ await self._http.post(
1005
+ f"/me/productcollections/{product_collection_id}/products",
1006
+ json=self._serialize(product_collection_entry),
1007
+ )
1008
+
1009
+ async def list_products(
1010
+ self,
1011
+ *,
1012
+ catalog_id: Optional[str] = None,
1013
+ category_id: Optional[str] = None,
1014
+ depth: Optional[str] = None,
1015
+ search: Optional[str] = None,
1016
+ search_on: Optional[str] = None,
1017
+ search_type: Optional[SearchType] = None,
1018
+ sort_by: Optional[str] = None,
1019
+ page: Optional[int] = None,
1020
+ page_size: Optional[int] = None,
1021
+ filters: Optional[dict[str, Any]] = None,
1022
+ seller_id: Optional[str] = None,
1023
+ ) -> ListPage[BuyerProduct]:
1024
+ """List products visible to this user
1025
+
1026
+ Args:
1027
+ catalog_id: ID of the catalog.
1028
+ category_id: ID of the category.
1029
+ depth: Indicates how deep down the category hierarchy to return results. Valid values are a number of 1 or greater, or 'all'. Relative to CategoryID if specified, otherwise top level of the Catalog. Default is 'all'.
1030
+ search: Word or phrase to search for.
1031
+ search_on: Comma-delimited list of fields to search on.
1032
+ search_type: Type of search to perform.
1033
+ sort_by: Comma-delimited list of fields to sort by.
1034
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1035
+ page_size: Number of results to return per page.
1036
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1037
+ seller_id: ID of the seller.
1038
+
1039
+ Returns:
1040
+ A paginated list of BuyerProduct objects.
1041
+ """
1042
+ params = self._build_list_params(
1043
+ depth=depth,
1044
+ search=search,
1045
+ search_on=search_on,
1046
+ sort_by=sort_by,
1047
+ page=page,
1048
+ page_size=page_size,
1049
+ filters=filters,
1050
+ )
1051
+ if catalog_id is not None:
1052
+ params["catalogID"] = catalog_id
1053
+ if category_id is not None:
1054
+ params["categoryID"] = category_id
1055
+ if search_type is not None:
1056
+ params["searchType"] = search_type
1057
+ if seller_id is not None:
1058
+ params["sellerID"] = seller_id
1059
+ resp = await self._http.get("/me/products", **params)
1060
+ return self._parse_list(resp.json(), BuyerProduct, meta_cls=MetaWithFacets)
1061
+
1062
+ async def get_product(
1063
+ self,
1064
+ product_id: str,
1065
+ *,
1066
+ seller_id: Optional[str] = None,
1067
+ ) -> BuyerProduct:
1068
+ """Retrieve a product
1069
+
1070
+ Args:
1071
+ product_id: ID of the product.
1072
+ seller_id: ID of the seller.
1073
+
1074
+ Returns:
1075
+ The BuyerProduct object.
1076
+ """
1077
+ _params: dict[str, Any] = {}
1078
+ if seller_id is not None:
1079
+ _params["sellerID"] = seller_id
1080
+ resp = await self._http.get(f"/me/products/{product_id}", **_params)
1081
+ return BuyerProduct(**resp.json())
1082
+
1083
+ async def list_product_inventory_records(
1084
+ self,
1085
+ product_id: str,
1086
+ *,
1087
+ search: Optional[str] = None,
1088
+ search_on: Optional[str] = None,
1089
+ sort_by: Optional[str] = None,
1090
+ page: Optional[int] = None,
1091
+ page_size: Optional[int] = None,
1092
+ filters: Optional[dict[str, Any]] = None,
1093
+ include_address: Optional[bool] = None,
1094
+ ) -> ListPage[InventoryRecord]:
1095
+ """List product inventory records visible to this user
1096
+
1097
+ Args:
1098
+ product_id: ID of the product.
1099
+ search: Word or phrase to search for.
1100
+ search_on: Comma-delimited list of fields to search on.
1101
+ sort_by: Comma-delimited list of fields to sort by.
1102
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1103
+ page_size: Number of results to return per page.
1104
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1105
+ include_address: Include address of the inventory record.
1106
+
1107
+ Returns:
1108
+ A paginated list of InventoryRecord objects.
1109
+ """
1110
+ params = self._build_list_params(
1111
+ search=search,
1112
+ search_on=search_on,
1113
+ sort_by=sort_by,
1114
+ page=page,
1115
+ page_size=page_size,
1116
+ filters=filters,
1117
+ )
1118
+ if include_address is not None:
1119
+ params["includeAddress"] = include_address
1120
+ resp = await self._http.get(f"/me/products/{product_id}/inventoryrecords", **params)
1121
+ return self._parse_list(resp.json(), InventoryRecord)
1122
+
1123
+ async def list_product_sellers(
1124
+ self,
1125
+ product_id: str,
1126
+ *,
1127
+ search: Optional[str] = None,
1128
+ search_on: Optional[str] = None,
1129
+ sort_by: Optional[str] = None,
1130
+ page: Optional[int] = None,
1131
+ page_size: Optional[int] = None,
1132
+ filters: Optional[dict[str, Any]] = None,
1133
+ ) -> ListPage[ProductSeller]:
1134
+ """List product sellers visible to this user
1135
+
1136
+ Args:
1137
+ product_id: ID of the product.
1138
+ search: Word or phrase to search for.
1139
+ search_on: Comma-delimited list of fields to search on.
1140
+ sort_by: Comma-delimited list of fields to sort by.
1141
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1142
+ page_size: Number of results to return per page.
1143
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1144
+
1145
+ Returns:
1146
+ A paginated list of ProductSeller objects.
1147
+ """
1148
+ params = self._build_list_params(
1149
+ search=search,
1150
+ search_on=search_on,
1151
+ sort_by=sort_by,
1152
+ page=page,
1153
+ page_size=page_size,
1154
+ filters=filters,
1155
+ )
1156
+ resp = await self._http.get(f"/me/products/{product_id}/sellers", **params)
1157
+ return self._parse_list(resp.json(), ProductSeller)
1158
+
1159
+ async def list_specs(
1160
+ self,
1161
+ product_id: str,
1162
+ *,
1163
+ catalog_id: Optional[str] = None,
1164
+ search: Optional[str] = None,
1165
+ search_on: Optional[str] = None,
1166
+ sort_by: Optional[str] = None,
1167
+ page: Optional[int] = None,
1168
+ page_size: Optional[int] = None,
1169
+ filters: Optional[dict[str, Any]] = None,
1170
+ ) -> ListPage[Spec]:
1171
+ """List specs visible to this user
1172
+
1173
+ Args:
1174
+ product_id: ID of the product.
1175
+ catalog_id: ID of the catalog.
1176
+ search: Word or phrase to search for.
1177
+ search_on: Comma-delimited list of fields to search on.
1178
+ sort_by: Comma-delimited list of fields to sort by.
1179
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1180
+ page_size: Number of results to return per page.
1181
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1182
+
1183
+ Returns:
1184
+ A paginated list of Spec objects.
1185
+ """
1186
+ params = self._build_list_params(
1187
+ search=search,
1188
+ search_on=search_on,
1189
+ sort_by=sort_by,
1190
+ page=page,
1191
+ page_size=page_size,
1192
+ filters=filters,
1193
+ )
1194
+ if catalog_id is not None:
1195
+ params["catalogID"] = catalog_id
1196
+ resp = await self._http.get(f"/me/products/{product_id}/specs", **params)
1197
+ return self._parse_list(resp.json(), Spec)
1198
+
1199
+ async def get_spec(
1200
+ self,
1201
+ product_id: str,
1202
+ spec_id: str,
1203
+ *,
1204
+ catalog_id: Optional[str] = None,
1205
+ ) -> Spec:
1206
+ """Retrieve a spec
1207
+
1208
+ Args:
1209
+ product_id: ID of the product.
1210
+ spec_id: ID of the spec.
1211
+ catalog_id: ID of the catalog.
1212
+
1213
+ Returns:
1214
+ The Spec object.
1215
+ """
1216
+ _params: dict[str, Any] = {}
1217
+ if catalog_id is not None:
1218
+ _params["catalogID"] = catalog_id
1219
+ resp = await self._http.get(f"/me/products/{product_id}/specs/{spec_id}", **_params)
1220
+ return Spec(**resp.json())
1221
+
1222
+ async def list_variants(
1223
+ self,
1224
+ product_id: str,
1225
+ *,
1226
+ search: Optional[str] = None,
1227
+ search_on: Optional[str] = None,
1228
+ sort_by: Optional[str] = None,
1229
+ page: Optional[int] = None,
1230
+ page_size: Optional[int] = None,
1231
+ filters: Optional[dict[str, Any]] = None,
1232
+ ) -> ListPage[Variant]:
1233
+ """List variants visible to this user
1234
+
1235
+ Args:
1236
+ product_id: ID of the product.
1237
+ search: Word or phrase to search for.
1238
+ search_on: Comma-delimited list of fields to search on.
1239
+ sort_by: Comma-delimited list of fields to sort by.
1240
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1241
+ page_size: Number of results to return per page.
1242
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1243
+
1244
+ Returns:
1245
+ A paginated list of Variant objects.
1246
+ """
1247
+ params = self._build_list_params(
1248
+ search=search,
1249
+ search_on=search_on,
1250
+ sort_by=sort_by,
1251
+ page=page,
1252
+ page_size=page_size,
1253
+ filters=filters,
1254
+ )
1255
+ resp = await self._http.get(f"/me/products/{product_id}/variants", **params)
1256
+ return self._parse_list(resp.json(), Variant)
1257
+
1258
+ async def get_variant(
1259
+ self,
1260
+ product_id: str,
1261
+ variant_id: str,
1262
+ ) -> Variant:
1263
+ """Retrieve a variant
1264
+
1265
+ Args:
1266
+ product_id: ID of the product.
1267
+ variant_id: ID of the variant.
1268
+
1269
+ Returns:
1270
+ The Variant object.
1271
+ """
1272
+ resp = await self._http.get(f"/me/products/{product_id}/variants/{variant_id}")
1273
+ return Variant(**resp.json())
1274
+
1275
+ async def list_variant_inventory_records(
1276
+ self,
1277
+ product_id: str,
1278
+ variant_id: str,
1279
+ *,
1280
+ search: Optional[str] = None,
1281
+ search_on: Optional[str] = None,
1282
+ sort_by: Optional[str] = None,
1283
+ page: Optional[int] = None,
1284
+ page_size: Optional[int] = None,
1285
+ filters: Optional[dict[str, Any]] = None,
1286
+ include_address: Optional[bool] = None,
1287
+ ) -> ListPage[InventoryRecord]:
1288
+ """List variant inventory records visible to this user
1289
+
1290
+ Args:
1291
+ product_id: ID of the product.
1292
+ variant_id: ID of the variant.
1293
+ search: Word or phrase to search for.
1294
+ search_on: Comma-delimited list of fields to search on.
1295
+ sort_by: Comma-delimited list of fields to sort by.
1296
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1297
+ page_size: Number of results to return per page.
1298
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1299
+ include_address: Include address of the inventory record.
1300
+
1301
+ Returns:
1302
+ A paginated list of InventoryRecord objects.
1303
+ """
1304
+ params = self._build_list_params(
1305
+ search=search,
1306
+ search_on=search_on,
1307
+ sort_by=sort_by,
1308
+ page=page,
1309
+ page_size=page_size,
1310
+ filters=filters,
1311
+ )
1312
+ if include_address is not None:
1313
+ params["includeAddress"] = include_address
1314
+ resp = await self._http.get(
1315
+ f"/me/products/{product_id}/variants/{variant_id}/inventoryrecords", **params
1316
+ )
1317
+ return self._parse_list(resp.json(), InventoryRecord)
1318
+
1319
+ async def list_promotions(
1320
+ self,
1321
+ *,
1322
+ search: Optional[str] = None,
1323
+ search_on: Optional[str] = None,
1324
+ sort_by: Optional[str] = None,
1325
+ page: Optional[int] = None,
1326
+ page_size: Optional[int] = None,
1327
+ filters: Optional[dict[str, Any]] = None,
1328
+ ) -> ListPage[Promotion]:
1329
+ """List promotions visible to this user
1330
+
1331
+ Args:
1332
+ search: Word or phrase to search for.
1333
+ search_on: Comma-delimited list of fields to search on.
1334
+ sort_by: Comma-delimited list of fields to sort by.
1335
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1336
+ page_size: Number of results to return per page.
1337
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1338
+
1339
+ Returns:
1340
+ A paginated list of Promotion objects.
1341
+ """
1342
+ params = self._build_list_params(
1343
+ search=search,
1344
+ search_on=search_on,
1345
+ sort_by=sort_by,
1346
+ page=page,
1347
+ page_size=page_size,
1348
+ filters=filters,
1349
+ )
1350
+ resp = await self._http.get("/me/promotions", **params)
1351
+ return self._parse_list(resp.json(), Promotion)
1352
+
1353
+ async def get_promotion(
1354
+ self,
1355
+ promotion_id: str,
1356
+ ) -> Promotion:
1357
+ """Retrieve a promotion
1358
+
1359
+ Args:
1360
+ promotion_id: ID of the promotion.
1361
+
1362
+ Returns:
1363
+ The Promotion object.
1364
+ """
1365
+ resp = await self._http.get(f"/me/promotions/{promotion_id}")
1366
+ return Promotion(**resp.json())
1367
+
1368
+ async def register(
1369
+ self,
1370
+ me_user: Union[MeUser, dict[str, Any]],
1371
+ *,
1372
+ anon_user_token: Optional[str],
1373
+ ) -> AccessTokenBasic:
1374
+ """Register a user
1375
+
1376
+ Args:
1377
+ me_user: A ``MeUser`` model or dict. Required fields: Username, FirstName, LastName, Email, Active.
1378
+ anon_user_token: Anon user token of the user.
1379
+
1380
+ Returns:
1381
+ The AccessTokenBasic object.
1382
+ """
1383
+ _params: dict[str, Any] = {}
1384
+ if anon_user_token is not None:
1385
+ _params["anonUserToken"] = anon_user_token
1386
+ resp = await self._http.put(
1387
+ "/me/register",
1388
+ json=self._serialize(me_user),
1389
+ params=_params or None,
1390
+ )
1391
+ return AccessTokenBasic(**resp.json())
1392
+
1393
+ async def list_buyer_sellers(
1394
+ self,
1395
+ *,
1396
+ search: Optional[str] = None,
1397
+ search_on: Optional[str] = None,
1398
+ sort_by: Optional[str] = None,
1399
+ page: Optional[int] = None,
1400
+ page_size: Optional[int] = None,
1401
+ filters: Optional[dict[str, Any]] = None,
1402
+ ) -> ListPage[BuyerSupplier]:
1403
+ """Get a list of sellers this user can purchase from
1404
+
1405
+ Args:
1406
+ search: Word or phrase to search for.
1407
+ search_on: Comma-delimited list of fields to search on.
1408
+ sort_by: Comma-delimited list of fields to sort by.
1409
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1410
+ page_size: Number of results to return per page.
1411
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1412
+
1413
+ Returns:
1414
+ A paginated list of BuyerSupplier objects.
1415
+ """
1416
+ params = self._build_list_params(
1417
+ search=search,
1418
+ search_on=search_on,
1419
+ sort_by=sort_by,
1420
+ page=page,
1421
+ page_size=page_size,
1422
+ filters=filters,
1423
+ )
1424
+ resp = await self._http.get("/me/sellers", **params)
1425
+ return self._parse_list(resp.json(), BuyerSupplier)
1426
+
1427
+ async def list_shipments(
1428
+ self,
1429
+ *,
1430
+ order_id: Optional[str] = None,
1431
+ search: Optional[str] = None,
1432
+ search_on: Optional[str] = None,
1433
+ sort_by: Optional[str] = None,
1434
+ page: Optional[int] = None,
1435
+ page_size: Optional[int] = None,
1436
+ filters: Optional[dict[str, Any]] = None,
1437
+ ) -> ListPage[Shipment]:
1438
+ """List shipments visible to this user
1439
+
1440
+ Args:
1441
+ order_id: ID of the order.
1442
+ search: Word or phrase to search for.
1443
+ search_on: Comma-delimited list of fields to search on.
1444
+ sort_by: Comma-delimited list of fields to sort by.
1445
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1446
+ page_size: Number of results to return per page.
1447
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1448
+
1449
+ Returns:
1450
+ A paginated list of Shipment objects.
1451
+ """
1452
+ params = self._build_list_params(
1453
+ search=search,
1454
+ search_on=search_on,
1455
+ sort_by=sort_by,
1456
+ page=page,
1457
+ page_size=page_size,
1458
+ filters=filters,
1459
+ )
1460
+ if order_id is not None:
1461
+ params["orderID"] = order_id
1462
+ resp = await self._http.get("/me/shipments", **params)
1463
+ return self._parse_list(resp.json(), Shipment)
1464
+
1465
+ async def get_shipment(
1466
+ self,
1467
+ shipment_id: str,
1468
+ ) -> Shipment:
1469
+ """Retrieve a shipment
1470
+
1471
+ Args:
1472
+ shipment_id: ID of the shipment.
1473
+
1474
+ Returns:
1475
+ The Shipment object.
1476
+ """
1477
+ resp = await self._http.get(f"/me/shipments/{shipment_id}")
1478
+ return Shipment(**resp.json())
1479
+
1480
+ async def list_shipment_items(
1481
+ self,
1482
+ shipment_id: str,
1483
+ *,
1484
+ order_id: Optional[str] = None,
1485
+ sort_by: Optional[str] = None,
1486
+ page: Optional[int] = None,
1487
+ page_size: Optional[int] = None,
1488
+ filters: Optional[dict[str, Any]] = None,
1489
+ ) -> ListPage[ShipmentItem]:
1490
+ """List shipment items visible to this user
1491
+
1492
+ Args:
1493
+ shipment_id: ID of the shipment.
1494
+ order_id: ID of the order.
1495
+ sort_by: Comma-delimited list of fields to sort by.
1496
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1497
+ page_size: Number of results to return per page.
1498
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1499
+
1500
+ Returns:
1501
+ A paginated list of ShipmentItem objects.
1502
+ """
1503
+ params = self._build_list_params(
1504
+ sort_by=sort_by,
1505
+ page=page,
1506
+ page_size=page_size,
1507
+ filters=filters,
1508
+ )
1509
+ if order_id is not None:
1510
+ params["orderID"] = order_id
1511
+ resp = await self._http.get(f"/me/shipments/{shipment_id}/items", **params)
1512
+ return self._parse_list(resp.json(), ShipmentItem)
1513
+
1514
+ async def list_spending_accounts(
1515
+ self,
1516
+ *,
1517
+ search: Optional[str] = None,
1518
+ search_on: Optional[str] = None,
1519
+ sort_by: Optional[str] = None,
1520
+ page: Optional[int] = None,
1521
+ page_size: Optional[int] = None,
1522
+ filters: Optional[dict[str, Any]] = None,
1523
+ ) -> ListPage[SpendingAccount]:
1524
+ """List spending accounts visible to this user
1525
+
1526
+ Args:
1527
+ search: Word or phrase to search for.
1528
+ search_on: Comma-delimited list of fields to search on.
1529
+ sort_by: Comma-delimited list of fields to sort by.
1530
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1531
+ page_size: Number of results to return per page.
1532
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1533
+
1534
+ Returns:
1535
+ A paginated list of SpendingAccount objects.
1536
+ """
1537
+ params = self._build_list_params(
1538
+ search=search,
1539
+ search_on=search_on,
1540
+ sort_by=sort_by,
1541
+ page=page,
1542
+ page_size=page_size,
1543
+ filters=filters,
1544
+ )
1545
+ resp = await self._http.get("/me/spendingAccounts", **params)
1546
+ return self._parse_list(resp.json(), SpendingAccount)
1547
+
1548
+ async def get_spending_account(
1549
+ self,
1550
+ spending_account_id: str,
1551
+ ) -> SpendingAccount:
1552
+ """Retrieve a spending account
1553
+
1554
+ Args:
1555
+ spending_account_id: ID of the spending account.
1556
+
1557
+ Returns:
1558
+ The SpendingAccount object.
1559
+ """
1560
+ resp = await self._http.get(f"/me/spendingaccounts/{spending_account_id}")
1561
+ return SpendingAccount(**resp.json())
1562
+
1563
+ async def list_subscriptions(
1564
+ self,
1565
+ *,
1566
+ search: Optional[str] = None,
1567
+ search_on: Optional[str] = None,
1568
+ sort_by: Optional[str] = None,
1569
+ page: Optional[int] = None,
1570
+ page_size: Optional[int] = None,
1571
+ filters: Optional[dict[str, Any]] = None,
1572
+ ) -> ListPage[Subscription]:
1573
+ """List subscriptions visible to this user
1574
+
1575
+ Args:
1576
+ search: Word or phrase to search for.
1577
+ search_on: Comma-delimited list of fields to search on.
1578
+ sort_by: Comma-delimited list of fields to sort by.
1579
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1580
+ page_size: Number of results to return per page.
1581
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1582
+
1583
+ Returns:
1584
+ A paginated list of Subscription objects.
1585
+ """
1586
+ params = self._build_list_params(
1587
+ search=search,
1588
+ search_on=search_on,
1589
+ sort_by=sort_by,
1590
+ page=page,
1591
+ page_size=page_size,
1592
+ filters=filters,
1593
+ )
1594
+ resp = await self._http.get("/me/subscriptions", **params)
1595
+ return self._parse_list(resp.json(), Subscription)
1596
+
1597
+ async def create_subscription(
1598
+ self,
1599
+ subscription: Union[Subscription, dict[str, Any]],
1600
+ ) -> Subscription:
1601
+ """Create a subscription
1602
+
1603
+ Args:
1604
+ subscription: A ``Subscription`` model or dict. Required fields: Frequency, Interval, NextOrderDate.
1605
+
1606
+ Returns:
1607
+ The Subscription object.
1608
+ """
1609
+ resp = await self._http.post("/me/subscriptions", json=self._serialize(subscription))
1610
+ return Subscription(**resp.json())
1611
+
1612
+ async def get_subscription(
1613
+ self,
1614
+ subscription_id: str,
1615
+ ) -> Subscription:
1616
+ """Retrieve a subscription
1617
+
1618
+ Args:
1619
+ subscription_id: ID of the subscription.
1620
+
1621
+ Returns:
1622
+ The Subscription object.
1623
+ """
1624
+ resp = await self._http.get(f"/me/subscriptions/{subscription_id}")
1625
+ return Subscription(**resp.json())
1626
+
1627
+ async def save_subscription(
1628
+ self,
1629
+ subscription_id: str,
1630
+ subscription: Union[Subscription, dict[str, Any]],
1631
+ ) -> Subscription:
1632
+ """Create or update a subscription
1633
+
1634
+ Args:
1635
+ subscription_id: ID of the subscription.
1636
+ subscription: A ``Subscription`` model or dict. Required fields: Frequency, Interval, NextOrderDate.
1637
+
1638
+ Returns:
1639
+ The Subscription object.
1640
+ """
1641
+ resp = await self._http.put(
1642
+ f"/me/subscriptions/{subscription_id}",
1643
+ json=self._serialize(subscription),
1644
+ )
1645
+ return Subscription(**resp.json())
1646
+
1647
+ async def delete_subscription(
1648
+ self,
1649
+ subscription_id: str,
1650
+ ) -> None:
1651
+ """Delete a subscription
1652
+
1653
+ Args:
1654
+ subscription_id: ID of the subscription.
1655
+ """
1656
+ await self._http.delete(f"/me/subscriptions/{subscription_id}")
1657
+
1658
+ async def patch_subscription(
1659
+ self,
1660
+ subscription_id: str,
1661
+ partial: dict[str, Any],
1662
+ ) -> Subscription:
1663
+ """Partially update a subscription
1664
+
1665
+ Args:
1666
+ subscription_id: ID of the subscription.
1667
+ partial: A dict of fields to update.
1668
+
1669
+ Returns:
1670
+ The Subscription object.
1671
+ """
1672
+ resp = await self._http.patch(f"/me/subscriptions/{subscription_id}", json=partial)
1673
+ return Subscription(**resp.json())
1674
+
1675
+ async def list_subscription_items(
1676
+ self,
1677
+ subscription_id: str,
1678
+ *,
1679
+ search: Optional[str] = None,
1680
+ search_on: Optional[str] = None,
1681
+ sort_by: Optional[str] = None,
1682
+ page: Optional[int] = None,
1683
+ page_size: Optional[int] = None,
1684
+ filters: Optional[dict[str, Any]] = None,
1685
+ ) -> ListPage[LineItem]:
1686
+ """List subscription items visible to this user
1687
+
1688
+ Args:
1689
+ subscription_id: ID of the subscription.
1690
+ search: Word or phrase to search for.
1691
+ search_on: Comma-delimited list of fields to search on.
1692
+ sort_by: Comma-delimited list of fields to sort by.
1693
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1694
+ page_size: Number of results to return per page.
1695
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1696
+
1697
+ Returns:
1698
+ A paginated list of LineItem objects.
1699
+ """
1700
+ params = self._build_list_params(
1701
+ search=search,
1702
+ search_on=search_on,
1703
+ sort_by=sort_by,
1704
+ page=page,
1705
+ page_size=page_size,
1706
+ filters=filters,
1707
+ )
1708
+ resp = await self._http.get(f"/me/subscriptions/{subscription_id}/items", **params)
1709
+ return self._parse_list(resp.json(), LineItem)
1710
+
1711
+ async def create_subscription_item(
1712
+ self,
1713
+ subscription_id: str,
1714
+ line_item: Union[LineItem, dict[str, Any]],
1715
+ ) -> LineItem:
1716
+ """Create a subscription item
1717
+
1718
+ Args:
1719
+ subscription_id: ID of the subscription.
1720
+ line_item: A ``LineItem`` model or dict. Required fields: ProductID.
1721
+
1722
+ Returns:
1723
+ The LineItem object.
1724
+ """
1725
+ resp = await self._http.post(
1726
+ f"/me/subscriptions/{subscription_id}/items", json=self._serialize(line_item)
1727
+ )
1728
+ return LineItem(**resp.json())
1729
+
1730
+ async def get_subscription_item(
1731
+ self,
1732
+ subscription_id: str,
1733
+ subscription_item_id: str,
1734
+ ) -> LineItem:
1735
+ """Retrieve a subscription item
1736
+
1737
+ Args:
1738
+ subscription_id: ID of the subscription.
1739
+ subscription_item_id: ID of the subscription item.
1740
+
1741
+ Returns:
1742
+ The LineItem object.
1743
+ """
1744
+ resp = await self._http.get(
1745
+ f"/me/subscriptions/{subscription_id}/items/{subscription_item_id}"
1746
+ )
1747
+ return LineItem(**resp.json())
1748
+
1749
+ async def save_subscription_item(
1750
+ self,
1751
+ subscription_id: str,
1752
+ subscription_item_id: str,
1753
+ line_item: Union[LineItem, dict[str, Any]],
1754
+ ) -> LineItem:
1755
+ """Create or update a subscription item
1756
+
1757
+ Args:
1758
+ subscription_id: ID of the subscription.
1759
+ subscription_item_id: ID of the subscription item.
1760
+ line_item: A ``LineItem`` model or dict. Required fields: ProductID.
1761
+
1762
+ Returns:
1763
+ The LineItem object.
1764
+ """
1765
+ resp = await self._http.put(
1766
+ f"/me/subscriptions/{subscription_id}/items/{subscription_item_id}",
1767
+ json=self._serialize(line_item),
1768
+ )
1769
+ return LineItem(**resp.json())
1770
+
1771
+ async def delete_subscription_item(
1772
+ self,
1773
+ subscription_id: str,
1774
+ subscription_item_id: str,
1775
+ ) -> None:
1776
+ """Delete a subscription item
1777
+
1778
+ Args:
1779
+ subscription_id: ID of the subscription.
1780
+ subscription_item_id: ID of the subscription item.
1781
+ """
1782
+ await self._http.delete(f"/me/subscriptions/{subscription_id}/items/{subscription_item_id}")
1783
+
1784
+ async def patch_subscription_item(
1785
+ self,
1786
+ subscription_id: str,
1787
+ subscription_item_id: str,
1788
+ partial: dict[str, Any],
1789
+ ) -> LineItem:
1790
+ """Partially update a subscription item
1791
+
1792
+ Args:
1793
+ subscription_id: ID of the subscription.
1794
+ subscription_item_id: ID of the subscription item.
1795
+ partial: A dict of fields to update.
1796
+
1797
+ Returns:
1798
+ The LineItem object.
1799
+ """
1800
+ resp = await self._http.patch(
1801
+ f"/me/subscriptions/{subscription_id}/items/{subscription_item_id}", json=partial
1802
+ )
1803
+ return LineItem(**resp.json())
1804
+
1805
+ async def create_subscription_bundle_item(
1806
+ self,
1807
+ subscription_id: str,
1808
+ bundle_id: str,
1809
+ bundle_items: Union[BundleItems, dict[str, Any]],
1810
+ ) -> LineItem:
1811
+ """Create a subscription bundle item
1812
+
1813
+ Args:
1814
+ subscription_id: ID of the subscription.
1815
+ bundle_id: ID of the bundle.
1816
+ bundle_items: A ``BundleItems`` model or dict.
1817
+
1818
+ Returns:
1819
+ The LineItem object.
1820
+ """
1821
+ resp = await self._http.post(
1822
+ f"/me/subscriptions/{subscription_id}/items/bundles/{bundle_id}",
1823
+ json=self._serialize(bundle_items),
1824
+ )
1825
+ return LineItem(**resp.json())
1826
+
1827
+ async def delete_subscription_bundle_item(
1828
+ self,
1829
+ subscription_id: str,
1830
+ bundle_id: str,
1831
+ bundle_item_id: str,
1832
+ ) -> None:
1833
+ """Delete a subscription bundle item
1834
+
1835
+ Args:
1836
+ subscription_id: ID of the subscription.
1837
+ bundle_id: ID of the bundle.
1838
+ bundle_item_id: ID of the bundle item.
1839
+ """
1840
+ await self._http.delete(
1841
+ f"/me/subscriptions/{subscription_id}/items/bundles/{bundle_id}/{bundle_item_id}"
1842
+ )
1843
+
1844
+ async def revoke_tokens(
1845
+ self,
1846
+ ) -> None:
1847
+ """Revoke tokens"""
1848
+ await self._http.delete("/me/tokens")
1849
+
1850
+ async def list_user_groups(
1851
+ self,
1852
+ *,
1853
+ search: Optional[str] = None,
1854
+ search_on: Optional[str] = None,
1855
+ sort_by: Optional[str] = None,
1856
+ page: Optional[int] = None,
1857
+ page_size: Optional[int] = None,
1858
+ filters: Optional[dict[str, Any]] = None,
1859
+ ) -> ListPage[UserGroup]:
1860
+ """List user groups visible to this user
1861
+
1862
+ Args:
1863
+ search: Word or phrase to search for.
1864
+ search_on: Comma-delimited list of fields to search on.
1865
+ sort_by: Comma-delimited list of fields to sort by.
1866
+ page: Page of results to return. When paginating through many items (> page 30), we recommend the "Last ID" method, as outlined in the Advanced Querying documentation.
1867
+ page_size: Number of results to return per page.
1868
+ filters: An object or dictionary representing key/value pairs to apply as filters. Valid keys are top-level properties of the returned model or 'xp.???'
1869
+
1870
+ Returns:
1871
+ A paginated list of UserGroup objects.
1872
+ """
1873
+ params = self._build_list_params(
1874
+ search=search,
1875
+ search_on=search_on,
1876
+ sort_by=sort_by,
1877
+ page=page,
1878
+ page_size=page_size,
1879
+ filters=filters,
1880
+ )
1881
+ resp = await self._http.get("/me/usergroups", **params)
1882
+ return self._parse_list(resp.json(), UserGroup)