airwallex-sdk 0.1.0__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 (39) hide show
  1. airwallex/__init__.py +74 -0
  2. airwallex/api/__init__.py +37 -0
  3. airwallex/api/account.py +107 -0
  4. airwallex/api/account_detail.py +469 -0
  5. airwallex/api/base.py +488 -0
  6. airwallex/api/beneficiary.py +156 -0
  7. airwallex/api/financial_transaction.py +123 -0
  8. airwallex/api/invoice.py +257 -0
  9. airwallex/api/issuing_authorization.py +313 -0
  10. airwallex/api/issuing_card.py +411 -0
  11. airwallex/api/issuing_cardholder.py +234 -0
  12. airwallex/api/issuing_config.py +80 -0
  13. airwallex/api/issuing_digital_wallet_token.py +249 -0
  14. airwallex/api/issuing_transaction.py +231 -0
  15. airwallex/api/issuing_transaction_dispute.py +339 -0
  16. airwallex/api/payment.py +148 -0
  17. airwallex/client.py +396 -0
  18. airwallex/exceptions.py +222 -0
  19. airwallex/models/__init__.py +69 -0
  20. airwallex/models/account.py +51 -0
  21. airwallex/models/account_detail.py +259 -0
  22. airwallex/models/base.py +121 -0
  23. airwallex/models/beneficiary.py +70 -0
  24. airwallex/models/financial_transaction.py +30 -0
  25. airwallex/models/fx.py +58 -0
  26. airwallex/models/invoice.py +102 -0
  27. airwallex/models/issuing_authorization.py +41 -0
  28. airwallex/models/issuing_card.py +135 -0
  29. airwallex/models/issuing_cardholder.py +52 -0
  30. airwallex/models/issuing_common.py +83 -0
  31. airwallex/models/issuing_config.py +62 -0
  32. airwallex/models/issuing_digital_wallet_token.py +38 -0
  33. airwallex/models/issuing_transaction.py +42 -0
  34. airwallex/models/issuing_transaction_dispute.py +59 -0
  35. airwallex/models/payment.py +81 -0
  36. airwallex/utils.py +107 -0
  37. airwallex_sdk-0.1.0.dist-info/METADATA +202 -0
  38. airwallex_sdk-0.1.0.dist-info/RECORD +39 -0
  39. airwallex_sdk-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,123 @@
1
+ """
2
+ Airwallex Financial Transaction API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from datetime import datetime
6
+ from ..models.financial_transaction import FinancialTransaction
7
+ from .base import AirwallexAPIBase
8
+
9
+ T = TypeVar("T", bound=FinancialTransaction)
10
+
11
+
12
+ class FinancialTransaction(AirwallexAPIBase[FinancialTransaction]):
13
+ """
14
+ Operations for Airwallex financial transactions.
15
+
16
+ Financial transactions represent the transactions that contributed to the Airwallex account balance.
17
+ """
18
+ endpoint = "financial_transactions"
19
+ model_class = cast(Type[FinancialTransaction], FinancialTransaction)
20
+
21
+ def list_with_filters(
22
+ self,
23
+ batch_id: Optional[str] = None,
24
+ currency: Optional[str] = None,
25
+ from_created_at: Optional[Union[str, datetime]] = None,
26
+ to_created_at: Optional[Union[str, datetime]] = None,
27
+ source_id: Optional[str] = None,
28
+ status: Optional[str] = None,
29
+ page_num: int = 0,
30
+ page_size: int = 100
31
+ ) -> List[FinancialTransaction]:
32
+ """
33
+ List financial transactions with filtering options.
34
+
35
+ Args:
36
+ batch_id: Filter by batch ID
37
+ currency: Filter by currency (3-letter ISO-4217 code)
38
+ from_created_at: Filter by creation date (start, inclusive)
39
+ to_created_at: Filter by creation date (end, inclusive)
40
+ source_id: Filter by source ID
41
+ status: Filter by status (PENDING, SETTLED)
42
+ page_num: Page number (0-indexed) for pagination
43
+ page_size: Number of transactions per page (max 1000)
44
+
45
+ Returns:
46
+ List[FinancialTransaction]: List of matching financial transactions
47
+ """
48
+ params = {
49
+ "page_num": page_num,
50
+ "page_size": page_size
51
+ }
52
+
53
+ if batch_id:
54
+ params["batch_id"] = batch_id
55
+
56
+ if currency:
57
+ params["currency"] = currency
58
+
59
+ if source_id:
60
+ params["source_id"] = source_id
61
+
62
+ if status:
63
+ params["status"] = status
64
+
65
+ if from_created_at:
66
+ params["from_created_at"] = from_created_at
67
+
68
+ if to_created_at:
69
+ params["to_created_at"] = to_created_at
70
+
71
+ return self.list(**params)
72
+
73
+ async def list_with_filters_async(
74
+ self,
75
+ batch_id: Optional[str] = None,
76
+ currency: Optional[str] = None,
77
+ from_created_at: Optional[Union[str, datetime]] = None,
78
+ to_created_at: Optional[Union[str, datetime]] = None,
79
+ source_id: Optional[str] = None,
80
+ status: Optional[str] = None,
81
+ page_num: int = 0,
82
+ page_size: int = 100
83
+ ) -> List[FinancialTransaction]:
84
+ """
85
+ List financial transactions with filtering options asynchronously.
86
+
87
+ Args:
88
+ batch_id: Filter by batch ID
89
+ currency: Filter by currency (3-letter ISO-4217 code)
90
+ from_created_at: Filter by creation date (start, inclusive)
91
+ to_created_at: Filter by creation date (end, inclusive)
92
+ source_id: Filter by source ID
93
+ status: Filter by status (PENDING, SETTLED)
94
+ page_num: Page number (0-indexed) for pagination
95
+ page_size: Number of transactions per page (max 1000)
96
+
97
+ Returns:
98
+ List[FinancialTransaction]: List of matching financial transactions
99
+ """
100
+ params = {
101
+ "page_num": page_num,
102
+ "page_size": page_size
103
+ }
104
+
105
+ if batch_id:
106
+ params["batch_id"] = batch_id
107
+
108
+ if currency:
109
+ params["currency"] = currency
110
+
111
+ if source_id:
112
+ params["source_id"] = source_id
113
+
114
+ if status:
115
+ params["status"] = status
116
+
117
+ if from_created_at:
118
+ params["from_created_at"] = from_created_at
119
+
120
+ if to_created_at:
121
+ params["to_created_at"] = to_created_at
122
+
123
+ return await self.list_async(**params)
@@ -0,0 +1,257 @@
1
+ """
2
+ Airwallex Invoice API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from datetime import datetime
6
+ from ..models.invoice import Invoice, InvoiceItem, InvoicePreviewRequest, InvoicePreviewResponse
7
+ from .base import AirwallexAPIBase
8
+
9
+ T = TypeVar("T", bound=Invoice)
10
+
11
+
12
+ class Invoice(AirwallexAPIBase[Invoice]):
13
+ """
14
+ Operations for Airwallex invoices.
15
+
16
+ Invoices record one-off sales transactions between you and your customers.
17
+ """
18
+ endpoint = "invoices"
19
+ model_class = cast(Type[Invoice], Invoice)
20
+
21
+ def preview(self, preview_request: InvoicePreviewRequest) -> InvoicePreviewResponse:
22
+ """
23
+ Preview an upcoming invoice.
24
+
25
+ This method allows you to preview the upcoming invoice of an existing subscription
26
+ or the first invoice before creating a new subscription.
27
+
28
+ Args:
29
+ preview_request: InvoicePreviewRequest model with preview details
30
+
31
+ Returns:
32
+ InvoicePreviewResponse: The preview of the upcoming invoice
33
+ """
34
+ url = self._build_url(suffix="preview")
35
+
36
+ if not self.client.__class__.__name__.startswith('Async'):
37
+ response = self.client._request("POST", url, json=preview_request.to_api_dict())
38
+ return InvoicePreviewResponse.from_api_response(response.json())
39
+ else:
40
+ raise ValueError("Use preview_async for async clients")
41
+
42
+ async def preview_async(self, preview_request: InvoicePreviewRequest) -> InvoicePreviewResponse:
43
+ """
44
+ Preview an upcoming invoice asynchronously.
45
+
46
+ This method allows you to preview the upcoming invoice of an existing subscription
47
+ or the first invoice before creating a new subscription.
48
+
49
+ Args:
50
+ preview_request: InvoicePreviewRequest model with preview details
51
+
52
+ Returns:
53
+ InvoicePreviewResponse: The preview of the upcoming invoice
54
+ """
55
+ url = self._build_url(suffix="preview")
56
+
57
+ if self.client.__class__.__name__.startswith('Async'):
58
+ response = await self.client._request("POST", url, json=preview_request.to_api_dict())
59
+ return InvoicePreviewResponse.from_api_response(response.json())
60
+ else:
61
+ raise ValueError("Use preview for sync clients")
62
+
63
+ def list_items(self, invoice_id: str, page_num: int = 0, page_size: int = 20) -> List[InvoiceItem]:
64
+ """
65
+ List all items for a specific invoice.
66
+
67
+ Args:
68
+ invoice_id: The ID of the invoice to fetch items for
69
+ page_num: Page number (0-indexed) for pagination
70
+ page_size: Number of items per page
71
+
72
+ Returns:
73
+ List[InvoiceItem]: List of invoice items
74
+ """
75
+ url = f"{self._build_url(invoice_id)}/items"
76
+ params = {
77
+ "page_num": page_num,
78
+ "page_size": page_size
79
+ }
80
+
81
+ if not self.client.__class__.__name__.startswith('Async'):
82
+ response = self.client._request("GET", url, params=params)
83
+ data = response.json()
84
+
85
+ if "items" in data:
86
+ return [InvoiceItem.from_api_response(item) for item in data["items"]]
87
+ return []
88
+ else:
89
+ raise ValueError("Use list_items_async for async clients")
90
+
91
+ async def list_items_async(self, invoice_id: str, page_num: int = 0, page_size: int = 20) -> List[InvoiceItem]:
92
+ """
93
+ List all items for a specific invoice asynchronously.
94
+
95
+ Args:
96
+ invoice_id: The ID of the invoice to fetch items for
97
+ page_num: Page number (0-indexed) for pagination
98
+ page_size: Number of items per page
99
+
100
+ Returns:
101
+ List[InvoiceItem]: List of invoice items
102
+ """
103
+ url = f"{self._build_url(invoice_id)}/items"
104
+ params = {
105
+ "page_num": page_num,
106
+ "page_size": page_size
107
+ }
108
+
109
+ if self.client.__class__.__name__.startswith('Async'):
110
+ response = await self.client._request("GET", url, params=params)
111
+ data = response.json()
112
+
113
+ if "items" in data:
114
+ return [InvoiceItem.from_api_response(item) for item in data["items"]]
115
+ return []
116
+ else:
117
+ raise ValueError("Use list_items for sync clients")
118
+
119
+ def get_item(self, invoice_id: str, item_id: str) -> InvoiceItem:
120
+ """
121
+ Retrieve a specific invoice item.
122
+
123
+ Args:
124
+ invoice_id: The ID of the invoice that contains the item
125
+ item_id: The ID of the invoice item to retrieve
126
+
127
+ Returns:
128
+ InvoiceItem: The requested invoice item
129
+ """
130
+ url = f"{self._build_url(invoice_id)}/items/{item_id}"
131
+
132
+ if not self.client.__class__.__name__.startswith('Async'):
133
+ response = self.client._request("GET", url)
134
+ return InvoiceItem.from_api_response(response.json())
135
+ else:
136
+ raise ValueError("Use get_item_async for async clients")
137
+
138
+ async def get_item_async(self, invoice_id: str, item_id: str) -> InvoiceItem:
139
+ """
140
+ Retrieve a specific invoice item asynchronously.
141
+
142
+ Args:
143
+ invoice_id: The ID of the invoice that contains the item
144
+ item_id: The ID of the invoice item to retrieve
145
+
146
+ Returns:
147
+ InvoiceItem: The requested invoice item
148
+ """
149
+ url = f"{self._build_url(invoice_id)}/items/{item_id}"
150
+
151
+ if self.client.__class__.__name__.startswith('Async'):
152
+ response = await self.client._request("GET", url)
153
+ return InvoiceItem.from_api_response(response.json())
154
+ else:
155
+ raise ValueError("Use get_item for sync clients")
156
+
157
+ def list_with_filters(
158
+ self,
159
+ customer_id: Optional[str] = None,
160
+ subscription_id: Optional[str] = None,
161
+ status: Optional[str] = None,
162
+ from_created_at: Optional[Union[str, datetime]] = None,
163
+ to_created_at: Optional[Union[str, datetime]] = None,
164
+ page_num: int = 0,
165
+ page_size: int = 20
166
+ ) -> List[Invoice]:
167
+ """
168
+ List invoices with filtering options.
169
+
170
+ Args:
171
+ customer_id: Filter by customer ID
172
+ subscription_id: Filter by subscription ID
173
+ status: Filter by status (SENT, PAID, PAYMENT_FAILED)
174
+ from_created_at: Filter by creation date (start, inclusive)
175
+ to_created_at: Filter by creation date (end, exclusive)
176
+ page_num: Page number (0-indexed) for pagination
177
+ page_size: Number of invoices per page
178
+
179
+ Returns:
180
+ List[Invoice]: List of matching invoices
181
+ """
182
+ params = {
183
+ "page_num": page_num,
184
+ "page_size": page_size
185
+ }
186
+
187
+ if customer_id:
188
+ params["customer_id"] = customer_id
189
+
190
+ if subscription_id:
191
+ params["subscription_id"] = subscription_id
192
+
193
+ if status:
194
+ params["status"] = status
195
+
196
+ if from_created_at:
197
+ if isinstance(from_created_at, datetime):
198
+ from_created_at = from_created_at.isoformat()
199
+ params["from_created_at"] = from_created_at
200
+
201
+ if to_created_at:
202
+ if isinstance(to_created_at, datetime):
203
+ to_created_at = to_created_at.isoformat()
204
+ params["to_created_at"] = to_created_at
205
+
206
+ return self.list(**params)
207
+
208
+ async def list_with_filters_async(
209
+ self,
210
+ customer_id: Optional[str] = None,
211
+ subscription_id: Optional[str] = None,
212
+ status: Optional[str] = None,
213
+ from_created_at: Optional[Union[str, datetime]] = None,
214
+ to_created_at: Optional[Union[str, datetime]] = None,
215
+ page_num: int = 0,
216
+ page_size: int = 20
217
+ ) -> List[Invoice]:
218
+ """
219
+ List invoices with filtering options asynchronously.
220
+
221
+ Args:
222
+ customer_id: Filter by customer ID
223
+ subscription_id: Filter by subscription ID
224
+ status: Filter by status (SENT, PAID, PAYMENT_FAILED)
225
+ from_created_at: Filter by creation date (start, inclusive)
226
+ to_created_at: Filter by creation date (end, exclusive)
227
+ page_num: Page number (0-indexed) for pagination
228
+ page_size: Number of invoices per page
229
+
230
+ Returns:
231
+ List[Invoice]: List of matching invoices
232
+ """
233
+ params = {
234
+ "page_num": page_num,
235
+ "page_size": page_size
236
+ }
237
+
238
+ if customer_id:
239
+ params["customer_id"] = customer_id
240
+
241
+ if subscription_id:
242
+ params["subscription_id"] = subscription_id
243
+
244
+ if status:
245
+ params["status"] = status
246
+
247
+ if from_created_at:
248
+ if isinstance(from_created_at, datetime):
249
+ from_created_at = from_created_at.isoformat()
250
+ params["from_created_at"] = from_created_at
251
+
252
+ if to_created_at:
253
+ if isinstance(to_created_at, datetime):
254
+ to_created_at = to_created_at.isoformat()
255
+ params["to_created_at"] = to_created_at
256
+
257
+ return await self.list_async(**params)
@@ -0,0 +1,313 @@
1
+ """
2
+ Airwallex Issuing Authorization API.
3
+ """
4
+ from typing import Dict, Any, List, Optional, Type, TypeVar, Union, cast
5
+ from datetime import datetime
6
+ from ..models.issuing_authorization import Authorization, AuthorizationListResponse
7
+ from .base import AirwallexAPIBase
8
+
9
+ T = TypeVar("T", bound=Authorization)
10
+
11
+
12
+ class IssuingAuthorization(AirwallexAPIBase[Authorization]):
13
+ """
14
+ Operations for Airwallex issuing authorizations.
15
+
16
+ Authorizations represent pre-auth and capture processed against individual cards.
17
+ """
18
+ endpoint = "issuing/authorizations"
19
+ model_class = cast(Type[Authorization], Authorization)
20
+
21
+ def list_with_filters(
22
+ self,
23
+ billing_currency: Optional[str] = None,
24
+ card_id: Optional[str] = None,
25
+ digital_wallet_token_id: Optional[str] = None,
26
+ from_created_at: Optional[Union[str, datetime]] = None,
27
+ lifecycle_id: Optional[str] = None,
28
+ page_num: int = 0,
29
+ page_size: int = 10,
30
+ retrieval_ref: Optional[str] = None,
31
+ status: Optional[str] = None,
32
+ to_created_at: Optional[Union[str, datetime]] = None,
33
+ ) -> List[Authorization]:
34
+ """
35
+ List authorizations with filtering options.
36
+
37
+ Args:
38
+ billing_currency: Currency in which transition was billed (3-letter ISO-4217 code)
39
+ card_id: Unique Identifier for card
40
+ digital_wallet_token_id: Unique Identifier for digital token
41
+ from_created_at: Start of Transaction Date in ISO8601 format (inclusive)
42
+ lifecycle_id: Unique Identifier for lifecycle
43
+ page_num: Page number, starts from 0
44
+ page_size: Number of results per page
45
+ retrieval_ref: Retrieval reference number
46
+ status: Authorization status (CLEARED, EXPIRED, FAILED, PENDING, REVERSED)
47
+ to_created_at: End of Transaction Date in ISO8601 format (exclusive)
48
+
49
+ Returns:
50
+ List[Authorization]: List of matching authorizations
51
+ """
52
+ params = {
53
+ "page_num": page_num,
54
+ "page_size": page_size
55
+ }
56
+
57
+ if billing_currency:
58
+ params["billing_currency"] = billing_currency
59
+
60
+ if card_id:
61
+ params["card_id"] = card_id
62
+
63
+ if digital_wallet_token_id:
64
+ params["digital_wallet_token_id"] = digital_wallet_token_id
65
+
66
+ if from_created_at:
67
+ if isinstance(from_created_at, datetime):
68
+ from_created_at = from_created_at.isoformat()
69
+ params["from_created_at"] = from_created_at
70
+
71
+ if lifecycle_id:
72
+ params["lifecycle_id"] = lifecycle_id
73
+
74
+ if retrieval_ref:
75
+ params["retrieval_ref"] = retrieval_ref
76
+
77
+ if status:
78
+ params["status"] = status
79
+
80
+ if to_created_at:
81
+ if isinstance(to_created_at, datetime):
82
+ to_created_at = to_created_at.isoformat()
83
+ params["to_created_at"] = to_created_at
84
+
85
+ if not self.client.__class__.__name__.startswith('Async'):
86
+ response = self.client._request("GET", self._build_url(), params=params)
87
+ data = response.json()
88
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
89
+ else:
90
+ raise ValueError("Use list_with_filters_async for async clients")
91
+
92
+ async def list_with_filters_async(
93
+ self,
94
+ billing_currency: Optional[str] = None,
95
+ card_id: Optional[str] = None,
96
+ digital_wallet_token_id: Optional[str] = None,
97
+ from_created_at: Optional[Union[str, datetime]] = None,
98
+ lifecycle_id: Optional[str] = None,
99
+ page_num: int = 0,
100
+ page_size: int = 10,
101
+ retrieval_ref: Optional[str] = None,
102
+ status: Optional[str] = None,
103
+ to_created_at: Optional[Union[str, datetime]] = None,
104
+ ) -> List[Authorization]:
105
+ """
106
+ List authorizations with filtering options asynchronously.
107
+
108
+ Args:
109
+ billing_currency: Currency in which transition was billed (3-letter ISO-4217 code)
110
+ card_id: Unique Identifier for card
111
+ digital_wallet_token_id: Unique Identifier for digital token
112
+ from_created_at: Start of Transaction Date in ISO8601 format (inclusive)
113
+ lifecycle_id: Unique Identifier for lifecycle
114
+ page_num: Page number, starts from 0
115
+ page_size: Number of results per page
116
+ retrieval_ref: Retrieval reference number
117
+ status: Authorization status (CLEARED, EXPIRED, FAILED, PENDING, REVERSED)
118
+ to_created_at: End of Transaction Date in ISO8601 format (exclusive)
119
+
120
+ Returns:
121
+ List[Authorization]: List of matching authorizations
122
+ """
123
+ params = {
124
+ "page_num": page_num,
125
+ "page_size": page_size
126
+ }
127
+
128
+ if billing_currency:
129
+ params["billing_currency"] = billing_currency
130
+
131
+ if card_id:
132
+ params["card_id"] = card_id
133
+
134
+ if digital_wallet_token_id:
135
+ params["digital_wallet_token_id"] = digital_wallet_token_id
136
+
137
+ if from_created_at:
138
+ if isinstance(from_created_at, datetime):
139
+ from_created_at = from_created_at.isoformat()
140
+ params["from_created_at"] = from_created_at
141
+
142
+ if lifecycle_id:
143
+ params["lifecycle_id"] = lifecycle_id
144
+
145
+ if retrieval_ref:
146
+ params["retrieval_ref"] = retrieval_ref
147
+
148
+ if status:
149
+ params["status"] = status
150
+
151
+ if to_created_at:
152
+ if isinstance(to_created_at, datetime):
153
+ to_created_at = to_created_at.isoformat()
154
+ params["to_created_at"] = to_created_at
155
+
156
+ if self.client.__class__.__name__.startswith('Async'):
157
+ response = await self.client._request("GET", self._build_url(), params=params)
158
+ data = response.json()
159
+ return [self.model_class.from_api_response(item) for item in data.get("items", [])]
160
+ else:
161
+ raise ValueError("Use list_with_filters for sync clients")
162
+
163
+ def paginate(self, **params: Any) -> List[Authorization]:
164
+ """
165
+ Fetch all pages of authorizations.
166
+
167
+ Args:
168
+ **params: Filter parameters to pass to the API
169
+
170
+ Returns:
171
+ List[Authorization]: All authorizations matching the filters
172
+ """
173
+ if str(self.client.__class__.__name__).startswith('Async'):
174
+ raise ValueError("This method requires a sync client.")
175
+
176
+ all_items: List[Dict[str, Any]] = []
177
+ page_num = params.get("page_num", 0)
178
+ page_size = params.get("page_size", 10)
179
+
180
+ while True:
181
+ params["page_num"] = page_num
182
+ params["page_size"] = page_size
183
+
184
+ response = self.client._request("GET", self._build_url(), params=params)
185
+ data = response.json()
186
+
187
+ items = data.get("items", [])
188
+ has_more = data.get("has_more", False)
189
+
190
+ if not items:
191
+ break
192
+
193
+ all_items.extend(items)
194
+
195
+ if not has_more:
196
+ break
197
+
198
+ page_num += 1
199
+
200
+ return [self.model_class.from_api_response(item) for item in all_items]
201
+
202
+ async def paginate_async(self, **params: Any) -> List[Authorization]:
203
+ """
204
+ Fetch all pages of authorizations asynchronously.
205
+
206
+ Args:
207
+ **params: Filter parameters to pass to the API
208
+
209
+ Returns:
210
+ List[Authorization]: All authorizations matching the filters
211
+ """
212
+ if not self.client.__class__.__name__.startswith('Async'):
213
+ raise ValueError("This method requires an async client.")
214
+
215
+ all_items: List[Dict[str, Any]] = []
216
+ page_num = params.get("page_num", 0)
217
+ page_size = params.get("page_size", 10)
218
+
219
+ while True:
220
+ params["page_num"] = page_num
221
+ params["page_size"] = page_size
222
+
223
+ response = await self.client._request("GET", self._build_url(), params=params)
224
+ data = response.json()
225
+
226
+ items = data.get("items", [])
227
+ has_more = data.get("has_more", False)
228
+
229
+ if not items:
230
+ break
231
+
232
+ all_items.extend(items)
233
+
234
+ if not has_more:
235
+ break
236
+
237
+ page_num += 1
238
+
239
+ return [self.model_class.from_api_response(item) for item in all_items]
240
+
241
+ def paginate_generator(self, **params: Any):
242
+ """
243
+ Generate items one by one from paginated results.
244
+
245
+ Args:
246
+ **params: Filter parameters to pass to the API
247
+
248
+ Yields:
249
+ Authorization: Authorization objects one by one
250
+ """
251
+ if self.client.__class__.__name__.startswith('Async'):
252
+ raise ValueError("This method requires a sync client.")
253
+
254
+ page_num = params.get("page_num", 0)
255
+ page_size = params.get("page_size", 10)
256
+
257
+ while True:
258
+ params["page_num"] = page_num
259
+ params["page_size"] = page_size
260
+
261
+ response = self.client._request("GET", self._build_url(), params=params)
262
+ data = response.json()
263
+
264
+ items = data.get("items", [])
265
+ has_more = data.get("has_more", False)
266
+
267
+ if not items:
268
+ break
269
+
270
+ for item in items:
271
+ yield self.model_class.from_api_response(item)
272
+
273
+ if not has_more:
274
+ break
275
+
276
+ page_num += 1
277
+
278
+ async def paginate_async_generator(self, **params: Any):
279
+ """
280
+ Generate items one by one from paginated results asynchronously.
281
+
282
+ Args:
283
+ **params: Filter parameters to pass to the API
284
+
285
+ Yields:
286
+ Authorization: Authorization objects one by one
287
+ """
288
+ if not self.client.__class__.__name__.startswith('Async'):
289
+ raise ValueError("This method requires an async client.")
290
+
291
+ page_num = params.get("page_num", 0)
292
+ page_size = params.get("page_size", 10)
293
+
294
+ while True:
295
+ params["page_num"] = page_num
296
+ params["page_size"] = page_size
297
+
298
+ response = await self.client._request("GET", self._build_url(), params=params)
299
+ data = response.json()
300
+
301
+ items = data.get("items", [])
302
+ has_more = data.get("has_more", False)
303
+
304
+ if not items:
305
+ break
306
+
307
+ for item in items:
308
+ yield self.model_class.from_api_response(item)
309
+
310
+ if not has_more:
311
+ break
312
+
313
+ page_num += 1