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,190 @@
1
+ # GENERATED by tools/codegen — DO NOT EDIT
2
+ # Source: ordercloud-openapi-v3.json
3
+ """OrderCloud Suppliers API resource."""
4
+
5
+ from __future__ import annotations
6
+ from typing import Any, Optional, Union
7
+
8
+ from ..models.supplier import Supplier, SupplierBuyer
9
+ from ..models.shared import ListPage
10
+ from .base import BaseResource
11
+
12
+ __all__ = ["SuppliersResource"]
13
+
14
+
15
+ class SuppliersResource(BaseResource):
16
+ """Operations on OrderCloud Suppliers."""
17
+
18
+ async def list(
19
+ self,
20
+ *,
21
+ search: Optional[str] = None,
22
+ search_on: Optional[str] = None,
23
+ sort_by: Optional[str] = None,
24
+ page: Optional[int] = None,
25
+ page_size: Optional[int] = None,
26
+ filters: Optional[dict[str, Any]] = None,
27
+ ) -> ListPage[Supplier]:
28
+ """List suppliers
29
+
30
+ Args:
31
+ search: Word or phrase to search for.
32
+ search_on: Comma-delimited list of fields to search on.
33
+ sort_by: Comma-delimited list of fields to sort by.
34
+ 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.
35
+ page_size: Number of results to return per page.
36
+ 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.???'
37
+
38
+ Returns:
39
+ A paginated list of Supplier objects.
40
+ """
41
+ params = self._build_list_params(
42
+ search=search,
43
+ search_on=search_on,
44
+ sort_by=sort_by,
45
+ page=page,
46
+ page_size=page_size,
47
+ filters=filters,
48
+ )
49
+ resp = await self._http.get("/suppliers", **params)
50
+ return self._parse_list(resp.json(), Supplier)
51
+
52
+ async def create(
53
+ self,
54
+ supplier: Union[Supplier, dict[str, Any]],
55
+ ) -> Supplier:
56
+ """Create a supplier
57
+
58
+ Args:
59
+ supplier: A ``Supplier`` model or dict. Required fields: Name.
60
+
61
+ Returns:
62
+ The Supplier object.
63
+ """
64
+ resp = await self._http.post("/suppliers", json=self._serialize(supplier))
65
+ return Supplier(**resp.json())
66
+
67
+ async def get(
68
+ self,
69
+ supplier_id: str,
70
+ ) -> Supplier:
71
+ """Retrieve a supplier
72
+
73
+ Args:
74
+ supplier_id: ID of the supplier.
75
+
76
+ Returns:
77
+ The Supplier object.
78
+ """
79
+ resp = await self._http.get(f"/suppliers/{supplier_id}")
80
+ return Supplier(**resp.json())
81
+
82
+ async def save(
83
+ self,
84
+ supplier_id: str,
85
+ supplier: Union[Supplier, dict[str, Any]],
86
+ ) -> Supplier:
87
+ """Create or update a supplier
88
+
89
+ Args:
90
+ supplier_id: ID of the supplier.
91
+ supplier: A ``Supplier`` model or dict. Required fields: Name.
92
+
93
+ Returns:
94
+ The Supplier object.
95
+ """
96
+ resp = await self._http.put(
97
+ f"/suppliers/{supplier_id}",
98
+ json=self._serialize(supplier),
99
+ )
100
+ return Supplier(**resp.json())
101
+
102
+ async def delete(
103
+ self,
104
+ supplier_id: str,
105
+ ) -> None:
106
+ """Delete a supplier
107
+
108
+ Args:
109
+ supplier_id: ID of the supplier.
110
+ """
111
+ await self._http.delete(f"/suppliers/{supplier_id}")
112
+
113
+ async def patch(
114
+ self,
115
+ supplier_id: str,
116
+ partial: dict[str, Any],
117
+ ) -> Supplier:
118
+ """Partially update a supplier
119
+
120
+ Args:
121
+ supplier_id: ID of the supplier.
122
+ partial: A dict of fields to update.
123
+
124
+ Returns:
125
+ The Supplier object.
126
+ """
127
+ resp = await self._http.patch(f"/suppliers/{supplier_id}", json=partial)
128
+ return Supplier(**resp.json())
129
+
130
+ async def list_buyers(
131
+ self,
132
+ supplier_id: str,
133
+ *,
134
+ search: Optional[str] = None,
135
+ search_on: Optional[str] = None,
136
+ sort_by: Optional[str] = None,
137
+ page: Optional[int] = None,
138
+ page_size: Optional[int] = None,
139
+ filters: Optional[dict[str, Any]] = None,
140
+ ) -> ListPage[SupplierBuyer]:
141
+ """List supplier buyers
142
+
143
+ Args:
144
+ supplier_id: ID of the supplier.
145
+ search: Word or phrase to search for.
146
+ search_on: Comma-delimited list of fields to search on.
147
+ sort_by: Comma-delimited list of fields to sort by.
148
+ 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.
149
+ page_size: Number of results to return per page.
150
+ 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.???'
151
+
152
+ Returns:
153
+ A paginated list of SupplierBuyer objects.
154
+ """
155
+ params = self._build_list_params(
156
+ search=search,
157
+ search_on=search_on,
158
+ sort_by=sort_by,
159
+ page=page,
160
+ page_size=page_size,
161
+ filters=filters,
162
+ )
163
+ resp = await self._http.get(f"/suppliers/{supplier_id}/buyers", **params)
164
+ return self._parse_list(resp.json(), SupplierBuyer)
165
+
166
+ async def save_buyer(
167
+ self,
168
+ supplier_id: str,
169
+ buyer_id: str,
170
+ ) -> None:
171
+ """Create or update a supplier buyer
172
+
173
+ Args:
174
+ supplier_id: ID of the supplier.
175
+ buyer_id: ID of the buyer.
176
+ """
177
+ await self._http.put(f"/suppliers/{supplier_id}/buyers/{buyer_id}")
178
+
179
+ async def delete_buyer(
180
+ self,
181
+ supplier_id: str,
182
+ buyer_id: str,
183
+ ) -> None:
184
+ """Delete a supplier buyer
185
+
186
+ Args:
187
+ supplier_id: ID of the supplier.
188
+ buyer_id: ID of the buyer.
189
+ """
190
+ await self._http.delete(f"/suppliers/{supplier_id}/buyers/{buyer_id}")
@@ -0,0 +1,130 @@
1
+ # GENERATED by tools/codegen — DO NOT EDIT
2
+ # Source: ordercloud-openapi-v3.json
3
+ """OrderCloud TrackingEvents API resource."""
4
+
5
+ from __future__ import annotations
6
+ from typing import Any, Optional, Union
7
+
8
+ from ..models.integration import TrackingEvent
9
+ from ..models.shared import ListPage
10
+ from .base import BaseResource
11
+
12
+ __all__ = ["TrackingEventsResource"]
13
+
14
+
15
+ class TrackingEventsResource(BaseResource):
16
+ """Operations on OrderCloud TrackingEvents."""
17
+
18
+ async def list(
19
+ self,
20
+ *,
21
+ search: Optional[str] = None,
22
+ search_on: Optional[str] = None,
23
+ sort_by: Optional[str] = None,
24
+ page: Optional[int] = None,
25
+ page_size: Optional[int] = None,
26
+ filters: Optional[dict[str, Any]] = None,
27
+ ) -> ListPage[TrackingEvent]:
28
+ """List tracking events
29
+
30
+ Args:
31
+ search: Word or phrase to search for.
32
+ search_on: Comma-delimited list of fields to search on.
33
+ sort_by: Comma-delimited list of fields to sort by.
34
+ 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.
35
+ page_size: Number of results to return per page.
36
+ 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.???'
37
+
38
+ Returns:
39
+ A paginated list of TrackingEvent objects.
40
+ """
41
+ params = self._build_list_params(
42
+ search=search,
43
+ search_on=search_on,
44
+ sort_by=sort_by,
45
+ page=page,
46
+ page_size=page_size,
47
+ filters=filters,
48
+ )
49
+ resp = await self._http.get("/integrations/trackingEvents", **params)
50
+ return self._parse_list(resp.json(), TrackingEvent)
51
+
52
+ async def create(
53
+ self,
54
+ tracking_event: Union[TrackingEvent, dict[str, Any]],
55
+ ) -> TrackingEvent:
56
+ """Create a tracking event
57
+
58
+ Args:
59
+ tracking_event: A ``TrackingEvent`` model or dict. Required fields: EventType, ClientID, Name, DeliveryConfigID.
60
+
61
+ Returns:
62
+ The TrackingEvent object.
63
+ """
64
+ resp = await self._http.post(
65
+ "/integrations/trackingEvents", json=self._serialize(tracking_event)
66
+ )
67
+ return TrackingEvent(**resp.json())
68
+
69
+ async def get(
70
+ self,
71
+ event_id: str,
72
+ ) -> TrackingEvent:
73
+ """Retrieve a tracking event
74
+
75
+ Args:
76
+ event_id: ID of the event.
77
+
78
+ Returns:
79
+ The TrackingEvent object.
80
+ """
81
+ resp = await self._http.get(f"/integrations/trackingEvents/{event_id}")
82
+ return TrackingEvent(**resp.json())
83
+
84
+ async def save(
85
+ self,
86
+ event_id: str,
87
+ tracking_event: Union[TrackingEvent, dict[str, Any]],
88
+ ) -> TrackingEvent:
89
+ """Create or update a tracking event
90
+
91
+ Args:
92
+ event_id: ID of the event.
93
+ tracking_event: A ``TrackingEvent`` model or dict. Required fields: EventType, ClientID, Name, DeliveryConfigID.
94
+
95
+ Returns:
96
+ The TrackingEvent object.
97
+ """
98
+ resp = await self._http.put(
99
+ f"/integrations/trackingEvents/{event_id}",
100
+ json=self._serialize(tracking_event),
101
+ )
102
+ return TrackingEvent(**resp.json())
103
+
104
+ async def delete(
105
+ self,
106
+ event_id: str,
107
+ ) -> None:
108
+ """Delete a tracking event
109
+
110
+ Args:
111
+ event_id: ID of the event.
112
+ """
113
+ await self._http.delete(f"/integrations/trackingEvents/{event_id}")
114
+
115
+ async def patch(
116
+ self,
117
+ event_id: str,
118
+ partial: dict[str, Any],
119
+ ) -> TrackingEvent:
120
+ """Partially update a tracking event
121
+
122
+ Args:
123
+ event_id: ID of the event.
124
+ partial: A dict of fields to update.
125
+
126
+ Returns:
127
+ The TrackingEvent object.
128
+ """
129
+ resp = await self._http.patch(f"/integrations/trackingEvents/{event_id}", json=partial)
130
+ return TrackingEvent(**resp.json())
@@ -0,0 +1,210 @@
1
+ # GENERATED by tools/codegen — DO NOT EDIT
2
+ # Source: ordercloud-openapi-v3.json
3
+ """OrderCloud UserGroups API resource."""
4
+
5
+ from __future__ import annotations
6
+ from typing import Any, Optional, Union
7
+
8
+ from ..models.assignments import UserGroupAssignment
9
+ from ..models.user_group import UserGroup
10
+ from ..models.shared import ListPage
11
+ from .base import BaseResource
12
+
13
+ __all__ = ["UserGroupsResource"]
14
+
15
+
16
+ class UserGroupsResource(BaseResource):
17
+ """Operations on OrderCloud UserGroups."""
18
+
19
+ async def list(
20
+ self,
21
+ buyer_id: str,
22
+ *,
23
+ search: Optional[str] = None,
24
+ search_on: Optional[str] = None,
25
+ sort_by: Optional[str] = None,
26
+ page: Optional[int] = None,
27
+ page_size: Optional[int] = None,
28
+ filters: Optional[dict[str, Any]] = None,
29
+ ) -> ListPage[UserGroup]:
30
+ """List user groups
31
+
32
+ Args:
33
+ buyer_id: ID of the buyer.
34
+ search: Word or phrase to search for.
35
+ search_on: Comma-delimited list of fields to search on.
36
+ sort_by: Comma-delimited list of fields to sort by.
37
+ 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.
38
+ page_size: Number of results to return per page.
39
+ 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.???'
40
+
41
+ Returns:
42
+ A paginated list of UserGroup objects.
43
+ """
44
+ params = self._build_list_params(
45
+ search=search,
46
+ search_on=search_on,
47
+ sort_by=sort_by,
48
+ page=page,
49
+ page_size=page_size,
50
+ filters=filters,
51
+ )
52
+ resp = await self._http.get(f"/buyers/{buyer_id}/usergroups", **params)
53
+ return self._parse_list(resp.json(), UserGroup)
54
+
55
+ async def create(
56
+ self,
57
+ buyer_id: str,
58
+ user_group: Union[UserGroup, dict[str, Any]],
59
+ ) -> UserGroup:
60
+ """Create a user group
61
+
62
+ Args:
63
+ buyer_id: ID of the buyer.
64
+ user_group: A ``UserGroup`` model or dict. Required fields: Name.
65
+
66
+ Returns:
67
+ The UserGroup object.
68
+ """
69
+ resp = await self._http.post(
70
+ f"/buyers/{buyer_id}/usergroups", json=self._serialize(user_group)
71
+ )
72
+ return UserGroup(**resp.json())
73
+
74
+ async def get(
75
+ self,
76
+ buyer_id: str,
77
+ user_group_id: str,
78
+ ) -> UserGroup:
79
+ """Retrieve a user group
80
+
81
+ Args:
82
+ buyer_id: ID of the buyer.
83
+ user_group_id: ID of the user group.
84
+
85
+ Returns:
86
+ The UserGroup object.
87
+ """
88
+ resp = await self._http.get(f"/buyers/{buyer_id}/usergroups/{user_group_id}")
89
+ return UserGroup(**resp.json())
90
+
91
+ async def save(
92
+ self,
93
+ buyer_id: str,
94
+ user_group_id: str,
95
+ user_group: Union[UserGroup, dict[str, Any]],
96
+ ) -> UserGroup:
97
+ """Create or update a user group
98
+
99
+ Args:
100
+ buyer_id: ID of the buyer.
101
+ user_group_id: ID of the user group.
102
+ user_group: A ``UserGroup`` model or dict. Required fields: Name.
103
+
104
+ Returns:
105
+ The UserGroup object.
106
+ """
107
+ resp = await self._http.put(
108
+ f"/buyers/{buyer_id}/usergroups/{user_group_id}",
109
+ json=self._serialize(user_group),
110
+ )
111
+ return UserGroup(**resp.json())
112
+
113
+ async def delete(
114
+ self,
115
+ buyer_id: str,
116
+ user_group_id: str,
117
+ ) -> None:
118
+ """Delete a user group
119
+
120
+ Args:
121
+ buyer_id: ID of the buyer.
122
+ user_group_id: ID of the user group.
123
+ """
124
+ await self._http.delete(f"/buyers/{buyer_id}/usergroups/{user_group_id}")
125
+
126
+ async def patch(
127
+ self,
128
+ buyer_id: str,
129
+ user_group_id: str,
130
+ partial: dict[str, Any],
131
+ ) -> UserGroup:
132
+ """Partially update a user group
133
+
134
+ Args:
135
+ buyer_id: ID of the buyer.
136
+ user_group_id: ID of the user group.
137
+ partial: A dict of fields to update.
138
+
139
+ Returns:
140
+ The UserGroup object.
141
+ """
142
+ resp = await self._http.patch(
143
+ f"/buyers/{buyer_id}/usergroups/{user_group_id}", json=partial
144
+ )
145
+ return UserGroup(**resp.json())
146
+
147
+ async def delete_user_assignment(
148
+ self,
149
+ buyer_id: str,
150
+ user_group_id: str,
151
+ user_id: str,
152
+ ) -> None:
153
+ """Delete a user group user assignment
154
+
155
+ Args:
156
+ buyer_id: ID of the buyer.
157
+ user_group_id: ID of the user group.
158
+ user_id: ID of the user.
159
+ """
160
+ await self._http.delete(
161
+ f"/buyers/{buyer_id}/usergroups/{user_group_id}/assignments/{user_id}"
162
+ )
163
+
164
+ async def list_user_assignments(
165
+ self,
166
+ buyer_id: str,
167
+ *,
168
+ user_group_id: Optional[str] = None,
169
+ user_id: Optional[str] = None,
170
+ page: Optional[int] = None,
171
+ page_size: Optional[int] = None,
172
+ ) -> ListPage[UserGroupAssignment]:
173
+ """List user group user assignments
174
+
175
+ Args:
176
+ buyer_id: ID of the buyer.
177
+ user_group_id: ID of the user group.
178
+ user_id: ID of the user.
179
+ 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.
180
+ page_size: Number of results to return per page.
181
+
182
+ Returns:
183
+ A paginated list of UserGroupAssignment objects.
184
+ """
185
+ params = self._build_list_params(
186
+ page=page,
187
+ page_size=page_size,
188
+ )
189
+ if user_group_id is not None:
190
+ params["userGroupID"] = user_group_id
191
+ if user_id is not None:
192
+ params["userID"] = user_id
193
+ resp = await self._http.get(f"/buyers/{buyer_id}/usergroups/assignments", **params)
194
+ return self._parse_list(resp.json(), UserGroupAssignment)
195
+
196
+ async def save_user_assignment(
197
+ self,
198
+ buyer_id: str,
199
+ user_group_assignment: Union[UserGroupAssignment, dict[str, Any]],
200
+ ) -> None:
201
+ """Create or update a user group user assignment
202
+
203
+ Args:
204
+ buyer_id: ID of the buyer.
205
+ user_group_assignment: A ``UserGroupAssignment`` model or dict. Required fields: UserGroupID, UserID.
206
+ """
207
+ await self._http.post(
208
+ f"/buyers/{buyer_id}/usergroups/assignments",
209
+ json=self._serialize(user_group_assignment),
210
+ )