simpleapps-com-augur-api 0.8.10__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.
- augur_api/__init__.py +43 -0
- augur_api/client.py +453 -0
- augur_api/core/__init__.py +40 -0
- augur_api/core/config.py +75 -0
- augur_api/core/errors.py +173 -0
- augur_api/core/http_client.py +426 -0
- augur_api/core/schemas.py +105 -0
- augur_api/py.typed +0 -0
- augur_api/services/__init__.py +13 -0
- augur_api/services/agr_info/__init__.py +47 -0
- augur_api/services/agr_info/client.py +326 -0
- augur_api/services/agr_info/schemas.py +123 -0
- augur_api/services/agr_site/__init__.py +79 -0
- augur_api/services/agr_site/client.py +384 -0
- augur_api/services/agr_site/schemas.py +268 -0
- augur_api/services/agr_work/__init__.py +7 -0
- augur_api/services/agr_work/client.py +32 -0
- augur_api/services/agr_work/schemas.py +11 -0
- augur_api/services/avalara/__init__.py +17 -0
- augur_api/services/avalara/client.py +64 -0
- augur_api/services/avalara/schemas.py +34 -0
- augur_api/services/base.py +54 -0
- augur_api/services/basecamp2/__init__.py +65 -0
- augur_api/services/basecamp2/client.py +568 -0
- augur_api/services/basecamp2/schemas.py +227 -0
- augur_api/services/brand_folder/__init__.py +31 -0
- augur_api/services/brand_folder/client.py +206 -0
- augur_api/services/brand_folder/schemas.py +133 -0
- augur_api/services/commerce/__init__.py +56 -0
- augur_api/services/commerce/client.py +298 -0
- augur_api/services/commerce/schemas.py +167 -0
- augur_api/services/customers/__init__.py +69 -0
- augur_api/services/customers/client.py +437 -0
- augur_api/services/customers/schemas.py +273 -0
- augur_api/services/gregorovich/__init__.py +31 -0
- augur_api/services/gregorovich/client.py +151 -0
- augur_api/services/gregorovich/schemas.py +42 -0
- augur_api/services/items/__init__.py +302 -0
- augur_api/services/items/client.py +1223 -0
- augur_api/services/items/schemas.py +722 -0
- augur_api/services/joomla/__init__.py +59 -0
- augur_api/services/joomla/client.py +333 -0
- augur_api/services/joomla/schemas.py +286 -0
- augur_api/services/legacy/__init__.py +66 -0
- augur_api/services/legacy/client.py +391 -0
- augur_api/services/legacy/schemas.py +115 -0
- augur_api/services/logistics/__init__.py +34 -0
- augur_api/services/logistics/client.py +116 -0
- augur_api/services/logistics/schemas.py +65 -0
- augur_api/services/nexus/__init__.py +89 -0
- augur_api/services/nexus/client.py +589 -0
- augur_api/services/nexus/schemas.py +171 -0
- augur_api/services/open_search/__init__.py +58 -0
- augur_api/services/open_search/client.py +285 -0
- augur_api/services/open_search/schemas.py +146 -0
- augur_api/services/orders/__init__.py +51 -0
- augur_api/services/orders/client.py +299 -0
- augur_api/services/orders/schemas.py +195 -0
- augur_api/services/p21_apis/__init__.py +83 -0
- augur_api/services/p21_apis/client.py +420 -0
- augur_api/services/p21_apis/schemas.py +130 -0
- augur_api/services/p21_core/__init__.py +29 -0
- augur_api/services/p21_core/client.py +395 -0
- augur_api/services/p21_core/schemas.py +221 -0
- augur_api/services/p21_pim/__init__.py +51 -0
- augur_api/services/p21_pim/client.py +319 -0
- augur_api/services/p21_pim/schemas.py +128 -0
- augur_api/services/p21_sism/__init__.py +60 -0
- augur_api/services/p21_sism/client.py +334 -0
- augur_api/services/p21_sism/schemas.py +92 -0
- augur_api/services/payments/__init__.py +97 -0
- augur_api/services/payments/client.py +508 -0
- augur_api/services/payments/schemas.py +166 -0
- augur_api/services/pricing/__init__.py +43 -0
- augur_api/services/pricing/client.py +175 -0
- augur_api/services/pricing/schemas.py +146 -0
- augur_api/services/resource.py +141 -0
- augur_api/services/shipping/__init__.py +17 -0
- augur_api/services/shipping/client.py +68 -0
- augur_api/services/shipping/schemas.py +38 -0
- augur_api/services/slack/__init__.py +23 -0
- augur_api/services/slack/client.py +74 -0
- augur_api/services/slack/schemas.py +35 -0
- augur_api/services/smarty_streets/__init__.py +19 -0
- augur_api/services/smarty_streets/client.py +82 -0
- augur_api/services/smarty_streets/schemas.py +32 -0
- augur_api/services/ups/__init__.py +17 -0
- augur_api/services/ups/client.py +72 -0
- augur_api/services/ups/schemas.py +41 -0
- augur_api/services/vmi/__init__.py +157 -0
- augur_api/services/vmi/client.py +586 -0
- augur_api/services/vmi/schemas.py +285 -0
- simpleapps_com_augur_api-0.8.10.dist-info/METADATA +177 -0
- simpleapps_com_augur_api-0.8.10.dist-info/RECORD +96 -0
- simpleapps_com_augur_api-0.8.10.dist-info/WHEEL +4 -0
- simpleapps_com_augur_api-0.8.10.dist-info/licenses/LICENSE +21 -0
augur_api/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Augur API Python Client.
|
|
2
|
+
|
|
3
|
+
A Python client library for Augur API microservices.
|
|
4
|
+
|
|
5
|
+
Example:
|
|
6
|
+
>>> from augur_api import AugurAPI
|
|
7
|
+
>>> api = AugurAPI(token="...", site_id="...")
|
|
8
|
+
>>> response = api.items.health_check()
|
|
9
|
+
>>> print(response.data.site_id)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from augur_api.client import AugurAPI
|
|
13
|
+
from augur_api.core.config import AugurAPIConfig, AugurContext, ContextCreationError
|
|
14
|
+
from augur_api.core.errors import (
|
|
15
|
+
AugurError,
|
|
16
|
+
AuthenticationError,
|
|
17
|
+
NotFoundError,
|
|
18
|
+
RateLimitError,
|
|
19
|
+
ValidationError,
|
|
20
|
+
)
|
|
21
|
+
from augur_api.core.schemas import BaseResponse, HealthCheckData, PingData
|
|
22
|
+
|
|
23
|
+
__version__ = "0.8.10"
|
|
24
|
+
__all__ = [
|
|
25
|
+
# Version
|
|
26
|
+
"__version__",
|
|
27
|
+
# Main client
|
|
28
|
+
"AugurAPI",
|
|
29
|
+
# Configuration
|
|
30
|
+
"AugurAPIConfig",
|
|
31
|
+
"AugurContext",
|
|
32
|
+
"ContextCreationError",
|
|
33
|
+
# Errors
|
|
34
|
+
"AugurError",
|
|
35
|
+
"AuthenticationError",
|
|
36
|
+
"NotFoundError",
|
|
37
|
+
"RateLimitError",
|
|
38
|
+
"ValidationError",
|
|
39
|
+
# Schemas
|
|
40
|
+
"BaseResponse",
|
|
41
|
+
"HealthCheckData",
|
|
42
|
+
"PingData",
|
|
43
|
+
]
|
augur_api/client.py
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
"""Main Augur API client."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from augur_api.core.config import AugurAPIConfig, AugurContext, ContextCreationError
|
|
6
|
+
from augur_api.core.http_client import HTTPClient
|
|
7
|
+
from augur_api.services.agr_info import AgrInfoClient
|
|
8
|
+
from augur_api.services.agr_site import AgrSiteClient
|
|
9
|
+
from augur_api.services.agr_work import AgrWorkClient
|
|
10
|
+
from augur_api.services.avalara import AvalaraClient
|
|
11
|
+
from augur_api.services.basecamp2 import Basecamp2Client
|
|
12
|
+
from augur_api.services.brand_folder import BrandFolderClient
|
|
13
|
+
from augur_api.services.commerce import CommerceClient
|
|
14
|
+
from augur_api.services.customers import CustomersClient
|
|
15
|
+
from augur_api.services.gregorovich import GregorovichClient
|
|
16
|
+
from augur_api.services.items import ItemsClient
|
|
17
|
+
from augur_api.services.joomla import JoomlaClient
|
|
18
|
+
from augur_api.services.legacy import LegacyClient
|
|
19
|
+
from augur_api.services.logistics import LogisticsClient
|
|
20
|
+
from augur_api.services.nexus import NexusClient
|
|
21
|
+
from augur_api.services.open_search import OpenSearchClient
|
|
22
|
+
from augur_api.services.orders import OrdersClient
|
|
23
|
+
from augur_api.services.p21_apis import P21ApisClient
|
|
24
|
+
from augur_api.services.p21_core import P21CoreClient
|
|
25
|
+
from augur_api.services.p21_pim import P21PimClient
|
|
26
|
+
from augur_api.services.p21_sism import P21SismClient
|
|
27
|
+
from augur_api.services.payments import PaymentsClient
|
|
28
|
+
from augur_api.services.pricing import PricingClient
|
|
29
|
+
from augur_api.services.shipping import ShippingClient
|
|
30
|
+
from augur_api.services.slack import SlackClient
|
|
31
|
+
from augur_api.services.smarty_streets import SmartyStreetsClient
|
|
32
|
+
from augur_api.services.ups import UpsClient
|
|
33
|
+
from augur_api.services.vmi import VMIClient
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AugurAPI:
|
|
37
|
+
"""Main client factory for accessing Augur microservices.
|
|
38
|
+
|
|
39
|
+
Provides property-based access to all 27 Augur API services with lazy
|
|
40
|
+
initialization for efficiency.
|
|
41
|
+
|
|
42
|
+
Example:
|
|
43
|
+
>>> # Initialize with token and site_id
|
|
44
|
+
>>> api = AugurAPI(token="your-jwt-token", site_id="your-site-id")
|
|
45
|
+
>>>
|
|
46
|
+
>>> # Check service health
|
|
47
|
+
>>> health = api.items.health_check.get()
|
|
48
|
+
>>> print(health.data.site_id)
|
|
49
|
+
>>>
|
|
50
|
+
>>> # List items with pagination
|
|
51
|
+
>>> from augur_api.services.items import InvMastListParams
|
|
52
|
+
>>> response = api.items.inv_mast.list(InvMastListParams(limit=10))
|
|
53
|
+
>>> for item in response.data:
|
|
54
|
+
... print(item.item_id)
|
|
55
|
+
>>>
|
|
56
|
+
>>> # Access P21 Core service
|
|
57
|
+
>>> from augur_api.services.p21_core import CashDrawerListParams
|
|
58
|
+
>>> drawers = api.p21_core.cash_drawer.list(CashDrawerListParams(drawer_open="Y"))
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
config: The API configuration.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
token: str,
|
|
67
|
+
site_id: str,
|
|
68
|
+
timeout: float = 30.0,
|
|
69
|
+
retries: int = 3,
|
|
70
|
+
retry_delay: float = 1.0,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""Initialize the Augur API client.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
token: JWT bearer token for authentication.
|
|
76
|
+
site_id: Site identifier for the x-site-id header.
|
|
77
|
+
timeout: Request timeout in seconds. Defaults to 30.0.
|
|
78
|
+
retries: Number of retry attempts for failed requests. Defaults to 3.
|
|
79
|
+
retry_delay: Base delay between retries in seconds. Defaults to 1.0.
|
|
80
|
+
"""
|
|
81
|
+
self.config = AugurAPIConfig(
|
|
82
|
+
token=token,
|
|
83
|
+
site_id=site_id,
|
|
84
|
+
timeout=timeout,
|
|
85
|
+
retries=retries,
|
|
86
|
+
retry_delay=retry_delay,
|
|
87
|
+
)
|
|
88
|
+
# Service client caches (lazy initialization)
|
|
89
|
+
self._agr_info: AgrInfoClient | None = None
|
|
90
|
+
self._agr_site: AgrSiteClient | None = None
|
|
91
|
+
self._agr_work: AgrWorkClient | None = None
|
|
92
|
+
self._avalara: AvalaraClient | None = None
|
|
93
|
+
self._basecamp2: Basecamp2Client | None = None
|
|
94
|
+
self._brand_folder: BrandFolderClient | None = None
|
|
95
|
+
self._commerce: CommerceClient | None = None
|
|
96
|
+
self._customers: CustomersClient | None = None
|
|
97
|
+
self._gregorovich: GregorovichClient | None = None
|
|
98
|
+
self._items: ItemsClient | None = None
|
|
99
|
+
self._joomla: JoomlaClient | None = None
|
|
100
|
+
self._legacy: LegacyClient | None = None
|
|
101
|
+
self._logistics: LogisticsClient | None = None
|
|
102
|
+
self._nexus: NexusClient | None = None
|
|
103
|
+
self._open_search: OpenSearchClient | None = None
|
|
104
|
+
self._orders: OrdersClient | None = None
|
|
105
|
+
self._p21_apis: P21ApisClient | None = None
|
|
106
|
+
self._p21_core: P21CoreClient | None = None
|
|
107
|
+
self._p21_pim: P21PimClient | None = None
|
|
108
|
+
self._p21_sism: P21SismClient | None = None
|
|
109
|
+
self._payments: PaymentsClient | None = None
|
|
110
|
+
self._pricing: PricingClient | None = None
|
|
111
|
+
self._shipping: ShippingClient | None = None
|
|
112
|
+
self._slack: SlackClient | None = None
|
|
113
|
+
self._smarty_streets: SmartyStreetsClient | None = None
|
|
114
|
+
self._ups: UpsClient | None = None
|
|
115
|
+
self._vmi: VMIClient | None = None
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def from_config(cls, config: AugurAPIConfig) -> "AugurAPI":
|
|
119
|
+
"""Create an AugurAPI instance from a configuration object.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
config: The API configuration.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
AugurAPI instance.
|
|
126
|
+
"""
|
|
127
|
+
return cls(
|
|
128
|
+
token=config.token,
|
|
129
|
+
site_id=config.site_id,
|
|
130
|
+
timeout=config.timeout,
|
|
131
|
+
retries=config.retries,
|
|
132
|
+
retry_delay=config.retry_delay,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
@classmethod
|
|
136
|
+
def from_context(cls, context: AugurContext, **options: Any) -> "AugurAPI":
|
|
137
|
+
"""Create an AugurAPI instance from a context object.
|
|
138
|
+
|
|
139
|
+
Automatically extracts site_id and authentication token from context,
|
|
140
|
+
eliminating the need for manual configuration boilerplate.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
context: Context object containing site_id and authentication.
|
|
144
|
+
**options: Optional configuration overrides (timeout, retries, retry_delay).
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
AugurAPI instance configured from context.
|
|
148
|
+
|
|
149
|
+
Raises:
|
|
150
|
+
ContextCreationError: When context is invalid or missing required fields.
|
|
151
|
+
|
|
152
|
+
Example:
|
|
153
|
+
>>> # Instead of manual configuration:
|
|
154
|
+
>>> api = AugurAPI(token=context.jwt, site_id=context.site_id)
|
|
155
|
+
>>>
|
|
156
|
+
>>> # Simply use:
|
|
157
|
+
>>> api = AugurAPI.from_context(context)
|
|
158
|
+
>>>
|
|
159
|
+
>>> # With optional overrides:
|
|
160
|
+
>>> api = AugurAPI.from_context(context, timeout=10.0)
|
|
161
|
+
"""
|
|
162
|
+
# Validate context
|
|
163
|
+
if context is None:
|
|
164
|
+
raise ContextCreationError("Context is required", "context")
|
|
165
|
+
|
|
166
|
+
if not context.site_id:
|
|
167
|
+
raise ContextCreationError("Context must contain site_id", "site_id")
|
|
168
|
+
|
|
169
|
+
# Extract bearer token from jwt or bearer_token field
|
|
170
|
+
token = context.jwt or context.bearer_token
|
|
171
|
+
if not token:
|
|
172
|
+
raise ContextCreationError(
|
|
173
|
+
"Context must contain jwt or bearer_token for authentication",
|
|
174
|
+
"bearer_token",
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
return cls(
|
|
178
|
+
token=token,
|
|
179
|
+
site_id=context.site_id,
|
|
180
|
+
timeout=options.get("timeout", 30.0),
|
|
181
|
+
retries=options.get("retries", 3),
|
|
182
|
+
retry_delay=options.get("retry_delay", 1.0),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def _reset_clients(self) -> None:
|
|
186
|
+
"""Reset all cached service clients."""
|
|
187
|
+
self._agr_info = None
|
|
188
|
+
self._agr_site = None
|
|
189
|
+
self._agr_work = None
|
|
190
|
+
self._avalara = None
|
|
191
|
+
self._basecamp2 = None
|
|
192
|
+
self._brand_folder = None
|
|
193
|
+
self._commerce = None
|
|
194
|
+
self._customers = None
|
|
195
|
+
self._gregorovich = None
|
|
196
|
+
self._items = None
|
|
197
|
+
self._joomla = None
|
|
198
|
+
self._legacy = None
|
|
199
|
+
self._logistics = None
|
|
200
|
+
self._nexus = None
|
|
201
|
+
self._open_search = None
|
|
202
|
+
self._orders = None
|
|
203
|
+
self._p21_apis = None
|
|
204
|
+
self._p21_core = None
|
|
205
|
+
self._p21_pim = None
|
|
206
|
+
self._p21_sism = None
|
|
207
|
+
self._payments = None
|
|
208
|
+
self._pricing = None
|
|
209
|
+
self._shipping = None
|
|
210
|
+
self._slack = None
|
|
211
|
+
self._smarty_streets = None
|
|
212
|
+
self._ups = None
|
|
213
|
+
self._vmi = None
|
|
214
|
+
|
|
215
|
+
# Service properties (alphabetical order)
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def agr_info(self) -> AgrInfoClient:
|
|
219
|
+
"""Access AGR Info service endpoints."""
|
|
220
|
+
if self._agr_info is None:
|
|
221
|
+
http_client = HTTPClient("agr-info", self.config)
|
|
222
|
+
self._agr_info = AgrInfoClient(http_client)
|
|
223
|
+
return self._agr_info
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def agr_site(self) -> AgrSiteClient:
|
|
227
|
+
"""Access AGR Site service endpoints."""
|
|
228
|
+
if self._agr_site is None:
|
|
229
|
+
http_client = HTTPClient("agr-site", self.config)
|
|
230
|
+
self._agr_site = AgrSiteClient(http_client)
|
|
231
|
+
return self._agr_site
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def agr_work(self) -> AgrWorkClient:
|
|
235
|
+
"""Access AGR Work service endpoints."""
|
|
236
|
+
if self._agr_work is None:
|
|
237
|
+
http_client = HTTPClient("agr-work", self.config)
|
|
238
|
+
self._agr_work = AgrWorkClient(http_client)
|
|
239
|
+
return self._agr_work
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def avalara(self) -> AvalaraClient:
|
|
243
|
+
"""Access Avalara tax service endpoints."""
|
|
244
|
+
if self._avalara is None:
|
|
245
|
+
http_client = HTTPClient("avalara", self.config)
|
|
246
|
+
self._avalara = AvalaraClient(http_client)
|
|
247
|
+
return self._avalara
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def basecamp2(self) -> Basecamp2Client:
|
|
251
|
+
"""Access Basecamp2 service endpoints."""
|
|
252
|
+
if self._basecamp2 is None:
|
|
253
|
+
http_client = HTTPClient("basecamp2", self.config)
|
|
254
|
+
self._basecamp2 = Basecamp2Client(http_client)
|
|
255
|
+
return self._basecamp2
|
|
256
|
+
|
|
257
|
+
@property
|
|
258
|
+
def brand_folder(self) -> BrandFolderClient:
|
|
259
|
+
"""Access Brand Folder service endpoints."""
|
|
260
|
+
if self._brand_folder is None:
|
|
261
|
+
http_client = HTTPClient("brand-folder", self.config)
|
|
262
|
+
self._brand_folder = BrandFolderClient(http_client)
|
|
263
|
+
return self._brand_folder
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
def commerce(self) -> CommerceClient:
|
|
267
|
+
"""Access Commerce service endpoints."""
|
|
268
|
+
if self._commerce is None:
|
|
269
|
+
http_client = HTTPClient("commerce", self.config)
|
|
270
|
+
self._commerce = CommerceClient(http_client)
|
|
271
|
+
return self._commerce
|
|
272
|
+
|
|
273
|
+
@property
|
|
274
|
+
def customers(self) -> CustomersClient:
|
|
275
|
+
"""Access Customers service endpoints."""
|
|
276
|
+
if self._customers is None:
|
|
277
|
+
http_client = HTTPClient("customers", self.config)
|
|
278
|
+
self._customers = CustomersClient(http_client)
|
|
279
|
+
return self._customers
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def gregorovich(self) -> GregorovichClient:
|
|
283
|
+
"""Access Gregorovich AI service endpoints."""
|
|
284
|
+
if self._gregorovich is None:
|
|
285
|
+
http_client = HTTPClient("gregorovich", self.config)
|
|
286
|
+
self._gregorovich = GregorovichClient(http_client)
|
|
287
|
+
return self._gregorovich
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def items(self) -> ItemsClient:
|
|
291
|
+
"""Access Items service endpoints."""
|
|
292
|
+
if self._items is None:
|
|
293
|
+
http_client = HTTPClient("items", self.config)
|
|
294
|
+
self._items = ItemsClient(http_client)
|
|
295
|
+
return self._items
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def joomla(self) -> JoomlaClient:
|
|
299
|
+
"""Access Joomla CMS service endpoints."""
|
|
300
|
+
if self._joomla is None:
|
|
301
|
+
http_client = HTTPClient("joomla", self.config)
|
|
302
|
+
self._joomla = JoomlaClient(http_client)
|
|
303
|
+
return self._joomla
|
|
304
|
+
|
|
305
|
+
@property
|
|
306
|
+
def legacy(self) -> LegacyClient:
|
|
307
|
+
"""Access Legacy service endpoints."""
|
|
308
|
+
if self._legacy is None:
|
|
309
|
+
http_client = HTTPClient("legacy", self.config)
|
|
310
|
+
self._legacy = LegacyClient(http_client)
|
|
311
|
+
return self._legacy
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def logistics(self) -> LogisticsClient:
|
|
315
|
+
"""Access Logistics service endpoints."""
|
|
316
|
+
if self._logistics is None:
|
|
317
|
+
http_client = HTTPClient("logistics", self.config)
|
|
318
|
+
self._logistics = LogisticsClient(http_client)
|
|
319
|
+
return self._logistics
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def nexus(self) -> NexusClient:
|
|
323
|
+
"""Access Nexus service endpoints."""
|
|
324
|
+
if self._nexus is None:
|
|
325
|
+
http_client = HTTPClient("nexus", self.config)
|
|
326
|
+
self._nexus = NexusClient(http_client)
|
|
327
|
+
return self._nexus
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def open_search(self) -> OpenSearchClient:
|
|
331
|
+
"""Access Open Search service endpoints."""
|
|
332
|
+
if self._open_search is None:
|
|
333
|
+
http_client = HTTPClient("open-search", self.config)
|
|
334
|
+
self._open_search = OpenSearchClient(http_client)
|
|
335
|
+
return self._open_search
|
|
336
|
+
|
|
337
|
+
@property
|
|
338
|
+
def orders(self) -> OrdersClient:
|
|
339
|
+
"""Access Orders service endpoints."""
|
|
340
|
+
if self._orders is None:
|
|
341
|
+
http_client = HTTPClient("orders", self.config)
|
|
342
|
+
self._orders = OrdersClient(http_client)
|
|
343
|
+
return self._orders
|
|
344
|
+
|
|
345
|
+
@property
|
|
346
|
+
def p21_apis(self) -> P21ApisClient:
|
|
347
|
+
"""Access P21 APIs service endpoints."""
|
|
348
|
+
if self._p21_apis is None:
|
|
349
|
+
http_client = HTTPClient("p21-apis", self.config)
|
|
350
|
+
self._p21_apis = P21ApisClient(http_client)
|
|
351
|
+
return self._p21_apis
|
|
352
|
+
|
|
353
|
+
@property
|
|
354
|
+
def p21_core(self) -> P21CoreClient:
|
|
355
|
+
"""Access P21 Core service endpoints."""
|
|
356
|
+
if self._p21_core is None:
|
|
357
|
+
http_client = HTTPClient("p21-core", self.config)
|
|
358
|
+
self._p21_core = P21CoreClient(http_client)
|
|
359
|
+
return self._p21_core
|
|
360
|
+
|
|
361
|
+
@property
|
|
362
|
+
def p21_pim(self) -> P21PimClient:
|
|
363
|
+
"""Access P21 PIM service endpoints."""
|
|
364
|
+
if self._p21_pim is None:
|
|
365
|
+
http_client = HTTPClient("p21-pim", self.config)
|
|
366
|
+
self._p21_pim = P21PimClient(http_client)
|
|
367
|
+
return self._p21_pim
|
|
368
|
+
|
|
369
|
+
@property
|
|
370
|
+
def p21_sism(self) -> P21SismClient:
|
|
371
|
+
"""Access P21 SISM service endpoints."""
|
|
372
|
+
if self._p21_sism is None:
|
|
373
|
+
http_client = HTTPClient("p21-sism", self.config)
|
|
374
|
+
self._p21_sism = P21SismClient(http_client)
|
|
375
|
+
return self._p21_sism
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
def payments(self) -> PaymentsClient:
|
|
379
|
+
"""Access Payments service endpoints."""
|
|
380
|
+
if self._payments is None:
|
|
381
|
+
http_client = HTTPClient("payments", self.config)
|
|
382
|
+
self._payments = PaymentsClient(http_client)
|
|
383
|
+
return self._payments
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def pricing(self) -> PricingClient:
|
|
387
|
+
"""Access Pricing service endpoints."""
|
|
388
|
+
if self._pricing is None:
|
|
389
|
+
http_client = HTTPClient("pricing", self.config)
|
|
390
|
+
self._pricing = PricingClient(http_client)
|
|
391
|
+
return self._pricing
|
|
392
|
+
|
|
393
|
+
@property
|
|
394
|
+
def shipping(self) -> ShippingClient:
|
|
395
|
+
"""Access Shipping service endpoints."""
|
|
396
|
+
if self._shipping is None:
|
|
397
|
+
http_client = HTTPClient("shipping", self.config)
|
|
398
|
+
self._shipping = ShippingClient(http_client)
|
|
399
|
+
return self._shipping
|
|
400
|
+
|
|
401
|
+
@property
|
|
402
|
+
def slack(self) -> SlackClient:
|
|
403
|
+
"""Access Slack service endpoints."""
|
|
404
|
+
if self._slack is None:
|
|
405
|
+
http_client = HTTPClient("slack", self.config)
|
|
406
|
+
self._slack = SlackClient(http_client)
|
|
407
|
+
return self._slack
|
|
408
|
+
|
|
409
|
+
@property
|
|
410
|
+
def smarty_streets(self) -> SmartyStreetsClient:
|
|
411
|
+
"""Access SmartyStreets address validation service endpoints."""
|
|
412
|
+
if self._smarty_streets is None:
|
|
413
|
+
http_client = HTTPClient("smarty-streets", self.config)
|
|
414
|
+
self._smarty_streets = SmartyStreetsClient(http_client)
|
|
415
|
+
return self._smarty_streets
|
|
416
|
+
|
|
417
|
+
@property
|
|
418
|
+
def ups(self) -> UpsClient:
|
|
419
|
+
"""Access UPS service endpoints."""
|
|
420
|
+
if self._ups is None:
|
|
421
|
+
http_client = HTTPClient("ups", self.config)
|
|
422
|
+
self._ups = UpsClient(http_client)
|
|
423
|
+
return self._ups
|
|
424
|
+
|
|
425
|
+
@property
|
|
426
|
+
def vmi(self) -> VMIClient:
|
|
427
|
+
"""Access VMI (Vendor Managed Inventory) service endpoints."""
|
|
428
|
+
if self._vmi is None:
|
|
429
|
+
http_client = HTTPClient("vmi", self.config)
|
|
430
|
+
self._vmi = VMIClient(http_client)
|
|
431
|
+
return self._vmi
|
|
432
|
+
|
|
433
|
+
def set_token(self, token: str) -> None:
|
|
434
|
+
"""Update the authentication token.
|
|
435
|
+
|
|
436
|
+
This will reset all service clients to use the new token.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
token: New JWT bearer token.
|
|
440
|
+
"""
|
|
441
|
+
self.config.token = token
|
|
442
|
+
self._reset_clients()
|
|
443
|
+
|
|
444
|
+
def set_site_id(self, site_id: str) -> None:
|
|
445
|
+
"""Update the site ID.
|
|
446
|
+
|
|
447
|
+
This will reset all service clients to use the new site ID.
|
|
448
|
+
|
|
449
|
+
Args:
|
|
450
|
+
site_id: New site identifier.
|
|
451
|
+
"""
|
|
452
|
+
self.config.site_id = site_id
|
|
453
|
+
self._reset_clients()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Core module for Augur API client.
|
|
2
|
+
|
|
3
|
+
Contains configuration, HTTP client, errors, and base schemas.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from augur_api.core.config import AugurAPIConfig, AugurContext, ContextCreationError
|
|
7
|
+
from augur_api.core.errors import (
|
|
8
|
+
AugurError,
|
|
9
|
+
AuthenticationError,
|
|
10
|
+
NotFoundError,
|
|
11
|
+
RateLimitError,
|
|
12
|
+
ValidationError,
|
|
13
|
+
)
|
|
14
|
+
from augur_api.core.http_client import HTTPClient
|
|
15
|
+
from augur_api.core.schemas import (
|
|
16
|
+
BaseResponse,
|
|
17
|
+
CamelCaseModel,
|
|
18
|
+
HealthCheckData,
|
|
19
|
+
PingData,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
# Config
|
|
24
|
+
"AugurAPIConfig",
|
|
25
|
+
"AugurContext",
|
|
26
|
+
"ContextCreationError",
|
|
27
|
+
# HTTP Client
|
|
28
|
+
"HTTPClient",
|
|
29
|
+
# Errors
|
|
30
|
+
"AugurError",
|
|
31
|
+
"AuthenticationError",
|
|
32
|
+
"NotFoundError",
|
|
33
|
+
"RateLimitError",
|
|
34
|
+
"ValidationError",
|
|
35
|
+
# Schemas
|
|
36
|
+
"BaseResponse",
|
|
37
|
+
"CamelCaseModel",
|
|
38
|
+
"HealthCheckData",
|
|
39
|
+
"PingData",
|
|
40
|
+
]
|
augur_api/core/config.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Configuration classes for the Augur API client."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class AugurAPIConfig:
|
|
11
|
+
"""Configuration for the Augur API client.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
token: JWT bearer token for authentication.
|
|
15
|
+
site_id: Site identifier for the x-site-id header.
|
|
16
|
+
timeout: Request timeout in seconds. Defaults to 30.0.
|
|
17
|
+
retries: Number of retry attempts for failed requests. Defaults to 3.
|
|
18
|
+
retry_delay: Base delay between retries in seconds. Defaults to 1.0.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
token: str
|
|
22
|
+
site_id: str
|
|
23
|
+
timeout: float = 30.0
|
|
24
|
+
retries: int = 3
|
|
25
|
+
retry_delay: float = 1.0
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class AugurContext:
|
|
30
|
+
"""Context object containing authentication and site information.
|
|
31
|
+
|
|
32
|
+
This provides an alternative way to configure the client, useful for
|
|
33
|
+
framework integration where context is passed between components.
|
|
34
|
+
|
|
35
|
+
Attributes:
|
|
36
|
+
site_id: Site identifier.
|
|
37
|
+
jwt: JWT bearer token for authentication (alternative to bearer_token).
|
|
38
|
+
bearer_token: Bearer token for authentication (alternative to jwt).
|
|
39
|
+
parameters: Optional request parameters.
|
|
40
|
+
filters: Optional filter parameters.
|
|
41
|
+
user_id: Optional user identifier.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
site_id: str
|
|
45
|
+
jwt: str | None = None
|
|
46
|
+
bearer_token: str | None = None
|
|
47
|
+
parameters: dict[str, Any] = field(default_factory=dict)
|
|
48
|
+
filters: dict[str, Any] = field(default_factory=dict)
|
|
49
|
+
user_id: str | int | None = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ContextCreationError(Exception):
|
|
53
|
+
"""Error raised when context creation fails due to invalid or missing data.
|
|
54
|
+
|
|
55
|
+
Attributes:
|
|
56
|
+
message: Human-readable error message.
|
|
57
|
+
field: The field that caused the error, if applicable.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, message: str, field: str | None = None) -> None:
|
|
61
|
+
"""Initialize the error.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
message: Human-readable error message.
|
|
65
|
+
field: The field that caused the error, if applicable.
|
|
66
|
+
"""
|
|
67
|
+
super().__init__(message)
|
|
68
|
+
self.message = message
|
|
69
|
+
self.field = field
|
|
70
|
+
|
|
71
|
+
def __str__(self) -> str:
|
|
72
|
+
"""Return string representation of the error."""
|
|
73
|
+
if self.field:
|
|
74
|
+
return f"{self.message} (field: {self.field})"
|
|
75
|
+
return self.message
|