shippingboapy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. shippingboapy-0.1.0/LICENSE +21 -0
  2. shippingboapy-0.1.0/PKG-INFO +292 -0
  3. shippingboapy-0.1.0/README.md +251 -0
  4. shippingboapy-0.1.0/pyproject.toml +90 -0
  5. shippingboapy-0.1.0/setup.cfg +4 -0
  6. shippingboapy-0.1.0/shippingboapy/__init__.py +0 -0
  7. shippingboapy-0.1.0/shippingboapy/auth.py +117 -0
  8. shippingboapy-0.1.0/shippingboapy/client.py +222 -0
  9. shippingboapy-0.1.0/shippingboapy/config.py +15 -0
  10. shippingboapy-0.1.0/shippingboapy/exceptions.py +54 -0
  11. shippingboapy-0.1.0/shippingboapy/models/__init__.py +0 -0
  12. shippingboapy-0.1.0/shippingboapy/models/address.py +101 -0
  13. shippingboapy-0.1.0/shippingboapy/models/address_label.py +14 -0
  14. shippingboapy-0.1.0/shippingboapy/models/address_label_config.py +113 -0
  15. shippingboapy-0.1.0/shippingboapy/models/address_label_summaries.py +77 -0
  16. shippingboapy-0.1.0/shippingboapy/models/carrier.py +14 -0
  17. shippingboapy-0.1.0/shippingboapy/models/client_order_origin.py +24 -0
  18. shippingboapy-0.1.0/shippingboapy/models/client_order_source.py +24 -0
  19. shippingboapy-0.1.0/shippingboapy/models/dangerous_good_product_information.py +48 -0
  20. shippingboapy-0.1.0/shippingboapy/models/filter.py +31 -0
  21. shippingboapy-0.1.0/shippingboapy/models/kit_component.py +32 -0
  22. shippingboapy-0.1.0/shippingboapy/models/logistician_service_config.py +15 -0
  23. shippingboapy-0.1.0/shippingboapy/models/order.py +339 -0
  24. shippingboapy-0.1.0/shippingboapy/models/order_dispatch.py +17 -0
  25. shippingboapy-0.1.0/shippingboapy/models/order_document.py +28 -0
  26. shippingboapy-0.1.0/shippingboapy/models/order_event.py +31 -0
  27. shippingboapy-0.1.0/shippingboapy/models/order_item_product_mapping.py +26 -0
  28. shippingboapy-0.1.0/shippingboapy/models/pack_component.py +22 -0
  29. shippingboapy-0.1.0/shippingboapy/models/package.py +26 -0
  30. shippingboapy-0.1.0/shippingboapy/models/product.py +283 -0
  31. shippingboapy-0.1.0/shippingboapy/models/tag.py +23 -0
  32. shippingboapy-0.1.0/shippingboapy/models/types.py +19 -0
  33. shippingboapy-0.1.0/shippingboapy/py.typed +0 -0
  34. shippingboapy-0.1.0/shippingboapy/resources/__init__.py +0 -0
  35. shippingboapy-0.1.0/shippingboapy/resources/address.py +124 -0
  36. shippingboapy-0.1.0/shippingboapy/resources/address_label.py +45 -0
  37. shippingboapy-0.1.0/shippingboapy/resources/address_label_config.py +67 -0
  38. shippingboapy-0.1.0/shippingboapy/resources/address_label_summaries.py +29 -0
  39. shippingboapy-0.1.0/shippingboapy/resources/background_job.py +30 -0
  40. shippingboapy-0.1.0/shippingboapy/resources/carrier.py +30 -0
  41. shippingboapy-0.1.0/shippingboapy/resources/client_order_origin.py +30 -0
  42. shippingboapy-0.1.0/shippingboapy/resources/client_order_source.py +30 -0
  43. shippingboapy-0.1.0/shippingboapy/resources/dangerous_good_product_informations.py +118 -0
  44. shippingboapy-0.1.0/shippingboapy/resources/kit_component.py +59 -0
  45. shippingboapy-0.1.0/shippingboapy/resources/logistician_service_config.py +30 -0
  46. shippingboapy-0.1.0/shippingboapy/resources/order.py +211 -0
  47. shippingboapy-0.1.0/shippingboapy/resources/order_dispatch.py +27 -0
  48. shippingboapy-0.1.0/shippingboapy/resources/order_document.py +62 -0
  49. shippingboapy-0.1.0/shippingboapy/resources/order_event.py +45 -0
  50. shippingboapy-0.1.0/shippingboapy/resources/order_item_product_mapping.py +90 -0
  51. shippingboapy-0.1.0/shippingboapy/resources/order_tag.py +62 -0
  52. shippingboapy-0.1.0/shippingboapy/resources/pack_component.py +79 -0
  53. shippingboapy-0.1.0/shippingboapy/resources/package.py +27 -0
  54. shippingboapy-0.1.0/shippingboapy/resources/product.py +173 -0
  55. shippingboapy-0.1.0/shippingboapy.egg-info/PKG-INFO +292 -0
  56. shippingboapy-0.1.0/shippingboapy.egg-info/SOURCES.txt +82 -0
  57. shippingboapy-0.1.0/shippingboapy.egg-info/dependency_links.txt +1 -0
  58. shippingboapy-0.1.0/shippingboapy.egg-info/requires.txt +15 -0
  59. shippingboapy-0.1.0/shippingboapy.egg-info/top_level.txt +1 -0
  60. shippingboapy-0.1.0/tests/test_address.py +65 -0
  61. shippingboapy-0.1.0/tests/test_address_label.py +15 -0
  62. shippingboapy-0.1.0/tests/test_address_label_config.py +18 -0
  63. shippingboapy-0.1.0/tests/test_address_label_summaries.py +9 -0
  64. shippingboapy-0.1.0/tests/test_auth_code.py +20 -0
  65. shippingboapy-0.1.0/tests/test_background_job.py +10 -0
  66. shippingboapy-0.1.0/tests/test_carrier.py +10 -0
  67. shippingboapy-0.1.0/tests/test_client.py +86 -0
  68. shippingboapy-0.1.0/tests/test_client_order_origin.py +19 -0
  69. shippingboapy-0.1.0/tests/test_client_order_source.py +19 -0
  70. shippingboapy-0.1.0/tests/test_config.py +11 -0
  71. shippingboapy-0.1.0/tests/test_dangerous_good_product_information.py +86 -0
  72. shippingboapy-0.1.0/tests/test_get_package.py +9 -0
  73. shippingboapy-0.1.0/tests/test_global.py +17 -0
  74. shippingboapy-0.1.0/tests/test_kit_component.py +40 -0
  75. shippingboapy-0.1.0/tests/test_logistician_service_config.py +10 -0
  76. shippingboapy-0.1.0/tests/test_order_dispatch.py +9 -0
  77. shippingboapy-0.1.0/tests/test_order_document.py +34 -0
  78. shippingboapy-0.1.0/tests/test_order_event.py +22 -0
  79. shippingboapy-0.1.0/tests/test_order_item_product_mapping.py +34 -0
  80. shippingboapy-0.1.0/tests/test_order_tag.py +39 -0
  81. shippingboapy-0.1.0/tests/test_orders.py +121 -0
  82. shippingboapy-0.1.0/tests/test_pack_component.py +56 -0
  83. shippingboapy-0.1.0/tests/test_products.py +57 -0
  84. shippingboapy-0.1.0/tests/test_refresh_token.py +22 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tryno
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,292 @@
1
+ Metadata-Version: 2.4
2
+ Name: shippingboapy
3
+ Version: 0.1.0
4
+ Summary: A Python client for the Shippingbo API.
5
+ Author-email: Tryno <trynogaunt@gmail.com>
6
+ Maintainer-email: Tryno <trynogaunt@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/trynogaunt/ShippingboAPY
9
+ Project-URL: Repository, https://github.com/trynogaunt/ShippingboAPY
10
+ Project-URL: Issues, https://github.com/trynogaunt/ShippingboAPY/issues
11
+ Keywords: shippingbo,api,client,python
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Libraries
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Framework :: AsyncIO
22
+ Classifier: Typing :: Typed
23
+ Classifier: Operating System :: OS Independent
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: httpx>=0.28.1
28
+ Requires-Dist: pydantic>=2.12.5
29
+ Requires-Dist: pydantic-settings>=2.13.5
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest; extra == "dev"
32
+ Requires-Dist: pytest-cov; extra == "dev"
33
+ Requires-Dist: pytest-asyncio; extra == "dev"
34
+ Requires-Dist: black; extra == "dev"
35
+ Requires-Dist: isort; extra == "dev"
36
+ Requires-Dist: pre-commit; extra == "dev"
37
+ Provides-Extra: publish
38
+ Requires-Dist: build; extra == "publish"
39
+ Requires-Dist: twine; extra == "publish"
40
+ Dynamic: license-file
41
+
42
+ # shippingboapy
43
+
44
+ [![PyPI version](https://img.shields.io/pypi/v/shippingboapy.svg)](https://pypi.org/project/shippingboapy/)
45
+ [![Python versions](https://img.shields.io/pypi/pyversions/shippingboapy.svg)](https://pypi.org/project/shippingboapy/)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
47
+
48
+ An async Python SDK for the [ShippingBo API](https://app.shippingbo.com).
49
+
50
+ `shippingboapy` is a faithful, low-level wrapper around the ShippingBo REST API. The SDK structure mirrors the actual API endpoints rather than introducing ergonomic abstractions that hide them — inspired by the design of the Stripe and Anthropic Python SDKs.
51
+
52
+ > ⚠️ **Alpha:** this SDK is in early development. The public API may change before v1.0.
53
+
54
+ - 📦 [PyPI](https://pypi.org/project/shippingboapy/)
55
+ - 🐙 [GitHub](https://github.com/Tryno/shippingboapy)
56
+ - 🐛 [Issues](https://github.com/Tryno/shippingboapy/issues)
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install shippingboapy
62
+ ```
63
+
64
+ ## Requirements
65
+
66
+ - Python 3.10+
67
+
68
+ ## Usage
69
+
70
+ ### Initialization
71
+
72
+ If you already have an access token and refresh token:
73
+
74
+ ```python
75
+ from shippingboapy import Client
76
+
77
+ client = Client(
78
+ access_token="your_access_token",
79
+ refresh_token="your_refresh_token",
80
+ app_id="your_app_id",
81
+ api_version="your_api_version",
82
+ client_id="your_client_id",
83
+ client_secret="your_client_secret",
84
+ )
85
+ ```
86
+
87
+ ### OAuth — first-time authentication
88
+
89
+ If you don't have tokens yet, use the OAuth flow with an authorization code:
90
+
91
+ ```python
92
+ from shippingboapy import Client
93
+
94
+ client = await Client.from_auth_code(
95
+ auth_code="your_auth_code",
96
+ app_id="your_app_id",
97
+ api_version="your_api_version",
98
+ client_id="your_client_id",
99
+ client_secret="your_client_secret",
100
+ redirect_uri="your_redirect_uri",
101
+ )
102
+ ```
103
+
104
+ ### Context manager
105
+
106
+ ```python
107
+ async with Client(...) as client:
108
+ products = await client.products.list()
109
+ ```
110
+
111
+ Or with explicit cleanup:
112
+
113
+ ```python
114
+ client = Client(...)
115
+ try:
116
+ products = await client.products.list()
117
+ finally:
118
+ await client.close()
119
+ ```
120
+
121
+ ### Configuration
122
+
123
+ ```python
124
+ client.set_config(
125
+ timeout=30,
126
+ max_retries=3,
127
+ retry_backoff_factor=0.5,
128
+ api_url="https://app.shippingbo.com",
129
+ )
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Products
135
+
136
+ ### List products
137
+
138
+ ```python
139
+ products = await client.products.list()
140
+ ```
141
+
142
+ With filters:
143
+
144
+ ```python
145
+ products = await client.products.list(
146
+ limit=50,
147
+ offset=0,
148
+ is_pack=False,
149
+ search=[("user-ref", "eq", "123456")],
150
+ sort=[("updated_at": "asc")],
151
+ )
152
+ ```
153
+
154
+ ### Get a product
155
+
156
+ ```python
157
+ product = await client.products.get(product_id=123)
158
+ ```
159
+
160
+ ### Create a product
161
+
162
+ ```python
163
+ from shippingboapy import ProductCreate
164
+
165
+ product = await client.products.create(
166
+ ProductCreate(
167
+ user_ref="MY-REF-001",
168
+ title="My Product",
169
+ weight=500,
170
+ width=200,
171
+ length=300,
172
+ height=100,
173
+ )
174
+ )
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Orders
180
+
181
+ ### List orders
182
+
183
+ ```python
184
+ orders = await client.orders.list(limit=50)
185
+ ```
186
+
187
+ ### Get an order
188
+
189
+ ```python
190
+ order = await client.orders.get(order_id=456)
191
+ ```
192
+
193
+ ### Create an order
194
+
195
+ ```python
196
+ from shippingboapy import OrderCreate, OrderItemCreate
197
+
198
+ order = await client.orders.create(
199
+ OrderCreate(
200
+ product_source= "product_src_str",
201
+ source="source"
202
+ title="Order Title"
203
+ ...
204
+ )
205
+ )
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Token refresh
211
+
212
+ Token refresh is handled automatically on `401` responses. After any request, the current tokens are accessible on the client:
213
+
214
+ ```python
215
+ client.token.access_token
216
+ client.token.refresh_token
217
+ ```
218
+
219
+ ### Persisting refreshed tokens
220
+
221
+ To persist tokens after an automatic refresh, register a callback at init:
222
+
223
+ ```python
224
+ async def save_tokens(access_token: str, refresh_token: str):
225
+ # Persist to your database, file, or any storage
226
+ await db.save(access_token=access_token, refresh_token=refresh_token)
227
+
228
+ client = Client(
229
+ access_token="your_access_token",
230
+ refresh_token="your_refresh_token",
231
+ ...,
232
+ on_token_refresh=save_tokens,
233
+ )
234
+ ```
235
+
236
+ Token storage is intentionally left to the caller, the SDK does not persist tokens itself.
237
+
238
+ ---
239
+
240
+ ## Error handling
241
+
242
+ The SDK raises typed exceptions for predictable failure modes:
243
+
244
+ ```
245
+ ShippingboAPYException
246
+ ├── AuthenticationError
247
+ │ ├── TokenExpiredError
248
+ │ └── TokenRefreshError
249
+ └── APIRequestError # exposes .status_code and .message
250
+ ├── BadRequestError # 400
251
+ ├── UnauthorizedError # 401
252
+ ├── ForbiddenError # 403
253
+ ├── NotFoundError # 404
254
+ ├── RateLimitError # 429
255
+ ├── ServerError # 5xx
256
+ └── UnexpectedError # any other status
257
+ ```
258
+
259
+ ```python
260
+ from shippingboapy import TokenRefreshError, ShippingBoAPIError
261
+
262
+ try:
263
+ await client.products.get(product_id=123)
264
+ except TokenRefreshError:
265
+ # Re-authenticate the user
266
+ ...
267
+ except ShippingBoAPIError as e:
268
+ print(e.status_code, e.message)
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Available Resources
274
+
275
+ | Resource | Status |
276
+ | --- | --- |
277
+ | Products | ✅ Available |
278
+ | Orders | ✅ Available |
279
+ | Addresses | ✅ Available |
280
+ | Address Labels | ✅ Available |
281
+ | Order Tags | ✅ Available |
282
+ | Order Documents | ✅ Available |
283
+ | Stock Variations | 🚧 Planned |
284
+ | Suppliers | 🚧 Planned |
285
+
286
+ Missing a resource? Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
287
+
288
+ ---
289
+
290
+ ## License
291
+
292
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,251 @@
1
+ # shippingboapy
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/shippingboapy.svg)](https://pypi.org/project/shippingboapy/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/shippingboapy.svg)](https://pypi.org/project/shippingboapy/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ An async Python SDK for the [ShippingBo API](https://app.shippingbo.com).
8
+
9
+ `shippingboapy` is a faithful, low-level wrapper around the ShippingBo REST API. The SDK structure mirrors the actual API endpoints rather than introducing ergonomic abstractions that hide them — inspired by the design of the Stripe and Anthropic Python SDKs.
10
+
11
+ > ⚠️ **Alpha:** this SDK is in early development. The public API may change before v1.0.
12
+
13
+ - 📦 [PyPI](https://pypi.org/project/shippingboapy/)
14
+ - 🐙 [GitHub](https://github.com/Tryno/shippingboapy)
15
+ - 🐛 [Issues](https://github.com/Tryno/shippingboapy/issues)
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install shippingboapy
21
+ ```
22
+
23
+ ## Requirements
24
+
25
+ - Python 3.10+
26
+
27
+ ## Usage
28
+
29
+ ### Initialization
30
+
31
+ If you already have an access token and refresh token:
32
+
33
+ ```python
34
+ from shippingboapy import Client
35
+
36
+ client = Client(
37
+ access_token="your_access_token",
38
+ refresh_token="your_refresh_token",
39
+ app_id="your_app_id",
40
+ api_version="your_api_version",
41
+ client_id="your_client_id",
42
+ client_secret="your_client_secret",
43
+ )
44
+ ```
45
+
46
+ ### OAuth — first-time authentication
47
+
48
+ If you don't have tokens yet, use the OAuth flow with an authorization code:
49
+
50
+ ```python
51
+ from shippingboapy import Client
52
+
53
+ client = await Client.from_auth_code(
54
+ auth_code="your_auth_code",
55
+ app_id="your_app_id",
56
+ api_version="your_api_version",
57
+ client_id="your_client_id",
58
+ client_secret="your_client_secret",
59
+ redirect_uri="your_redirect_uri",
60
+ )
61
+ ```
62
+
63
+ ### Context manager
64
+
65
+ ```python
66
+ async with Client(...) as client:
67
+ products = await client.products.list()
68
+ ```
69
+
70
+ Or with explicit cleanup:
71
+
72
+ ```python
73
+ client = Client(...)
74
+ try:
75
+ products = await client.products.list()
76
+ finally:
77
+ await client.close()
78
+ ```
79
+
80
+ ### Configuration
81
+
82
+ ```python
83
+ client.set_config(
84
+ timeout=30,
85
+ max_retries=3,
86
+ retry_backoff_factor=0.5,
87
+ api_url="https://app.shippingbo.com",
88
+ )
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Products
94
+
95
+ ### List products
96
+
97
+ ```python
98
+ products = await client.products.list()
99
+ ```
100
+
101
+ With filters:
102
+
103
+ ```python
104
+ products = await client.products.list(
105
+ limit=50,
106
+ offset=0,
107
+ is_pack=False,
108
+ search=[("user-ref", "eq", "123456")],
109
+ sort=[("updated_at": "asc")],
110
+ )
111
+ ```
112
+
113
+ ### Get a product
114
+
115
+ ```python
116
+ product = await client.products.get(product_id=123)
117
+ ```
118
+
119
+ ### Create a product
120
+
121
+ ```python
122
+ from shippingboapy import ProductCreate
123
+
124
+ product = await client.products.create(
125
+ ProductCreate(
126
+ user_ref="MY-REF-001",
127
+ title="My Product",
128
+ weight=500,
129
+ width=200,
130
+ length=300,
131
+ height=100,
132
+ )
133
+ )
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Orders
139
+
140
+ ### List orders
141
+
142
+ ```python
143
+ orders = await client.orders.list(limit=50)
144
+ ```
145
+
146
+ ### Get an order
147
+
148
+ ```python
149
+ order = await client.orders.get(order_id=456)
150
+ ```
151
+
152
+ ### Create an order
153
+
154
+ ```python
155
+ from shippingboapy import OrderCreate, OrderItemCreate
156
+
157
+ order = await client.orders.create(
158
+ OrderCreate(
159
+ product_source= "product_src_str",
160
+ source="source"
161
+ title="Order Title"
162
+ ...
163
+ )
164
+ )
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Token refresh
170
+
171
+ Token refresh is handled automatically on `401` responses. After any request, the current tokens are accessible on the client:
172
+
173
+ ```python
174
+ client.token.access_token
175
+ client.token.refresh_token
176
+ ```
177
+
178
+ ### Persisting refreshed tokens
179
+
180
+ To persist tokens after an automatic refresh, register a callback at init:
181
+
182
+ ```python
183
+ async def save_tokens(access_token: str, refresh_token: str):
184
+ # Persist to your database, file, or any storage
185
+ await db.save(access_token=access_token, refresh_token=refresh_token)
186
+
187
+ client = Client(
188
+ access_token="your_access_token",
189
+ refresh_token="your_refresh_token",
190
+ ...,
191
+ on_token_refresh=save_tokens,
192
+ )
193
+ ```
194
+
195
+ Token storage is intentionally left to the caller, the SDK does not persist tokens itself.
196
+
197
+ ---
198
+
199
+ ## Error handling
200
+
201
+ The SDK raises typed exceptions for predictable failure modes:
202
+
203
+ ```
204
+ ShippingboAPYException
205
+ ├── AuthenticationError
206
+ │ ├── TokenExpiredError
207
+ │ └── TokenRefreshError
208
+ └── APIRequestError # exposes .status_code and .message
209
+ ├── BadRequestError # 400
210
+ ├── UnauthorizedError # 401
211
+ ├── ForbiddenError # 403
212
+ ├── NotFoundError # 404
213
+ ├── RateLimitError # 429
214
+ ├── ServerError # 5xx
215
+ └── UnexpectedError # any other status
216
+ ```
217
+
218
+ ```python
219
+ from shippingboapy import TokenRefreshError, ShippingBoAPIError
220
+
221
+ try:
222
+ await client.products.get(product_id=123)
223
+ except TokenRefreshError:
224
+ # Re-authenticate the user
225
+ ...
226
+ except ShippingBoAPIError as e:
227
+ print(e.status_code, e.message)
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Available Resources
233
+
234
+ | Resource | Status |
235
+ | --- | --- |
236
+ | Products | ✅ Available |
237
+ | Orders | ✅ Available |
238
+ | Addresses | ✅ Available |
239
+ | Address Labels | ✅ Available |
240
+ | Order Tags | ✅ Available |
241
+ | Order Documents | ✅ Available |
242
+ | Stock Variations | 🚧 Planned |
243
+ | Suppliers | 🚧 Planned |
244
+
245
+ Missing a resource? Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
246
+
247
+ ---
248
+
249
+ ## License
250
+
251
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,90 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "shippingboapy"
7
+ version = "0.1.0"
8
+ requires-python = ">=3.10"
9
+ dependencies = [
10
+ "httpx>=0.28.1",
11
+ "pydantic>=2.12.5",
12
+ "pydantic-settings>=2.13.5",
13
+ ]
14
+
15
+ authors = [
16
+ { name = "Tryno", email = "trynogaunt@gmail.com" }
17
+ ]
18
+
19
+ maintainers = [
20
+ { name = "Tryno", email = "trynogaunt@gmail.com" }
21
+ ]
22
+
23
+ description = "A Python client for the Shippingbo API."
24
+
25
+ readme = { file = "README.md", content-type = "text/markdown" }
26
+
27
+ keywords = [
28
+ "shippingbo",
29
+ "api",
30
+ "client",
31
+ "python",
32
+ ]
33
+
34
+ classifiers = [
35
+ "Development Status :: 3 - Alpha",
36
+ "Intended Audience :: Developers",
37
+ "Topic :: Software Development :: Libraries",
38
+ "Programming Language :: Python :: 3",
39
+ "Programming Language :: Python :: 3.10",
40
+ "Programming Language :: Python :: 3.11",
41
+ "Programming Language :: Python :: 3.12",
42
+ "Programming Language :: Python :: 3.13",
43
+ "Programming Language :: Python :: 3.14",
44
+ "Framework :: AsyncIO",
45
+ "Typing :: Typed",
46
+ "Operating System :: OS Independent",
47
+ ]
48
+
49
+ license = "MIT"
50
+ license-files = ["LICENSE"]
51
+
52
+ [project.urls]
53
+ Homepage = "https://github.com/trynogaunt/ShippingboAPY"
54
+ Repository = "https://github.com/trynogaunt/ShippingboAPY"
55
+ Issues = "https://github.com/trynogaunt/ShippingboAPY/issues"
56
+
57
+ [project.optional-dependencies]
58
+ dev = [
59
+ "pytest",
60
+ "pytest-cov",
61
+ "pytest-asyncio",
62
+ "black",
63
+ "isort",
64
+ "pre-commit",
65
+ ]
66
+ publish = [
67
+ "build",
68
+ "twine",
69
+ ]
70
+
71
+ [tool.pytest.ini_options]
72
+ pythonpath = ["."]
73
+ asyncio_mode = "auto"
74
+
75
+ [tool.pyright]
76
+ pythonVersion = "3.10"
77
+ typeCheckingMode = "strict"
78
+ venvPath = "."
79
+ venv = "venv"
80
+
81
+ [[tool.pyright.executionEnvironments]]
82
+ root = "shippingboapy/resources"
83
+ reportPrivateUsage = "none"
84
+
85
+ [tool.setuptools.packages.find]
86
+ include = ["shippingboapy*"]
87
+ exclude = ["tests*"]
88
+
89
+ [tool.setuptools.package-data]
90
+ shippingboapy = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes