shipthisapi-python 3.0.5__tar.gz → 3.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shipthisapi-python
3
- Version: 3.0.5
3
+ Version: 3.1.0
4
4
  Summary: ShipthisAPI async utility package
5
5
  Home-page: https://github.com/shipthisco/shipthisapi-python
6
6
  Author: Mayur Rawte
@@ -107,6 +107,7 @@ class ShipthisAPI:
107
107
  self.custom_headers = custom_headers or {}
108
108
  self.organisation_info = None
109
109
  self.is_connected = False
110
+ self._client: httpx.AsyncClient = None
110
111
 
111
112
  def set_region_location(self, region_id: str, location_id: str) -> None:
112
113
  """Set the region and location for subsequent requests.
@@ -146,6 +147,19 @@ class ShipthisAPI:
146
147
  headers.update(override_headers)
147
148
  return headers
148
149
 
150
+ async def _ensure_client(self) -> httpx.AsyncClient:
151
+ """Get or create the shared HTTP client."""
152
+ if self._client is None:
153
+ self._client = httpx.AsyncClient(timeout=self.timeout)
154
+ return self._client
155
+
156
+ async def __aenter__(self):
157
+ await self.connect()
158
+ return self
159
+
160
+ async def __aexit__(self, *args):
161
+ await self.disconnect()
162
+
149
163
  async def _make_request(
150
164
  self,
151
165
  method: str,
@@ -172,31 +186,31 @@ class ShipthisAPI:
172
186
  """
173
187
  url = self.base_api_endpoint + path
174
188
  request_headers = self._get_headers(headers)
189
+ client = await self._ensure_client()
175
190
 
176
- async with httpx.AsyncClient(timeout=self.timeout) as client:
177
- try:
178
- response = await client.request(
179
- method,
180
- url,
181
- headers=request_headers,
182
- params=query_params,
183
- json=request_data,
184
- )
185
- except httpx.TimeoutException:
186
- raise ShipthisRequestError(
187
- message="Request timed out",
188
- status_code=408,
189
- )
190
- except httpx.ConnectError as e:
191
- raise ShipthisRequestError(
192
- message=f"Connection error: {str(e)}",
193
- status_code=0,
194
- )
195
- except httpx.RequestError as e:
196
- raise ShipthisRequestError(
197
- message=f"Request failed: {str(e)}",
198
- status_code=0,
199
- )
191
+ try:
192
+ response = await client.request(
193
+ method,
194
+ url,
195
+ headers=request_headers,
196
+ params=query_params,
197
+ json=request_data,
198
+ )
199
+ except httpx.TimeoutException:
200
+ raise ShipthisRequestError(
201
+ message="Request timed out",
202
+ status_code=408,
203
+ )
204
+ except httpx.ConnectError as e:
205
+ raise ShipthisRequestError(
206
+ message=f"Connection error: {str(e)}",
207
+ status_code=0,
208
+ )
209
+ except httpx.RequestError as e:
210
+ raise ShipthisRequestError(
211
+ message=f"Request failed: {str(e)}",
212
+ status_code=0,
213
+ )
200
214
 
201
215
  # Handle authentication errors
202
216
  if response.status_code == 401:
@@ -275,9 +289,13 @@ class ShipthisAPI:
275
289
  "organisation": self.organisation_info,
276
290
  }
277
291
 
278
- def disconnect(self) -> None:
279
- """Disconnect and clear credentials."""
292
+ async def disconnect(self) -> None:
293
+ """Disconnect, close the HTTP client, and clear credentials."""
294
+ if self._client is not None:
295
+ await self._client.aclose()
296
+ self._client = None
280
297
  self.x_api_key = None
298
+ self.organisation_info = None
281
299
  self.is_connected = False
282
300
 
283
301
  # ==================== Info ====================
@@ -505,9 +523,10 @@ class ShipthisAPI:
505
523
  self,
506
524
  collection_name: str,
507
525
  object_id: str,
508
- update_fields: Dict[str, Any],
526
+ update_fields: Dict[str, Any] = None,
527
+ workflow: List[Dict[str, Any]] = None,
509
528
  ) -> Dict[str, Any]:
510
- """Patch specific fields of an item.
529
+ """Patch specific fields of an item and/or trigger workflow transitions.
511
530
 
512
531
  This is the recommended way to update document fields. It goes through
513
532
  full field validation, workflow triggers, audit logging, and business logic.
@@ -516,24 +535,57 @@ class ShipthisAPI:
516
535
  collection_name: Name of the collection (e.g., "sea_shipment", "fcl_load").
517
536
  object_id: Document ID.
518
537
  update_fields: Dictionary of field_id to value mappings.
538
+ workflow: List of workflow actions to execute. Each action is a dict with:
539
+ - workflow_id (str): The workflow identifier (e.g., "status").
540
+ - value (str, optional): Target state for direct-mode workflows.
541
+ - action_id (str, optional): Action ID for action-based workflows.
542
+ - payload (any, optional): Extra data for the action.
519
543
 
520
544
  Returns:
521
- Updated document data.
545
+ Updated document data and/or workflow results.
522
546
 
523
547
  Raises:
524
548
  ShipthisAPIError: If the request fails.
525
549
 
526
550
  Example:
551
+ # Update fields only
527
552
  await client.patch_item(
528
553
  "fcl_load",
529
554
  "68a4f906743189ad061429a7",
530
555
  update_fields={"container_no": "CONT123", "seal_no": "SEAL456"}
531
556
  )
557
+
558
+ # Workflow transition only (direct mode)
559
+ await client.patch_item(
560
+ "sea_shipment",
561
+ "68a4f906743189ad061429a7",
562
+ workflow=[{"workflow_id": "status", "value": "approved"}]
563
+ )
564
+
565
+ # Workflow transition only (action-based)
566
+ await client.patch_item(
567
+ "sea_shipment",
568
+ "68a4f906743189ad061429a7",
569
+ workflow=[{"workflow_id": "status", "action_id": "submit_review"}]
570
+ )
571
+
572
+ # Fields + workflow in one call
573
+ await client.patch_item(
574
+ "sea_shipment",
575
+ "68a4f906743189ad061429a7",
576
+ update_fields={"notes": "ready"},
577
+ workflow=[{"workflow_id": "status", "action_id": "submit_review"}]
578
+ )
532
579
  """
580
+ request_data = {}
581
+ if update_fields is not None:
582
+ request_data["update_fields"] = update_fields
583
+ if workflow is not None:
584
+ request_data["workflow"] = workflow
533
585
  return await self._make_request(
534
586
  "PATCH",
535
587
  f"incollection/{collection_name}/{object_id}",
536
- request_data={"update_fields": update_fields},
588
+ request_data=request_data,
537
589
  )
538
590
 
539
591
  async def delete_item(self, collection_name: str, object_id: str) -> Dict[str, Any]:
@@ -686,7 +738,12 @@ class ShipthisAPI:
686
738
 
687
739
  return await self._make_request(
688
740
  "GET",
689
- f"thirdparty/currency?source={source_currency}&target={target_currency}&date={date}",
741
+ "thirdparty/currency",
742
+ query_params={
743
+ "source": source_currency,
744
+ "target": target_currency,
745
+ "date": date,
746
+ },
690
747
  )
691
748
 
692
749
  async def autocomplete(
@@ -731,7 +788,8 @@ class ShipthisAPI:
731
788
  """
732
789
  return await self._make_request(
733
790
  "GET",
734
- f"thirdparty/search-place-autocomplete?query={query}",
791
+ "thirdparty/search-place-autocomplete",
792
+ query_params={"query": query},
735
793
  )
736
794
 
737
795
  async def get_place_details(
@@ -753,7 +811,8 @@ class ShipthisAPI:
753
811
  """
754
812
  return await self._make_request(
755
813
  "GET",
756
- f"thirdparty/select-google-place?query={place_id}&description={description}",
814
+ "thirdparty/select-google-place",
815
+ query_params={"query": place_id, "description": description},
757
816
  )
758
817
 
759
818
  # ==================== Conversations ====================
@@ -987,8 +1046,8 @@ class ShipthisAPI:
987
1046
  try:
988
1047
  with open(file_path, "rb") as f:
989
1048
  files = {"file": (file_name, f)}
990
- async with httpx.AsyncClient(timeout=self.timeout * 2) as client:
991
- response = await client.post(
1049
+ async with httpx.AsyncClient(timeout=self.timeout * 2) as upload_client:
1050
+ response = await upload_client.post(
992
1051
  upload_url,
993
1052
  headers=headers,
994
1053
  files=files,
@@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
6
6
 
7
7
  setuptools.setup(
8
8
  name='shipthisapi-python',
9
- version='3.0.5',
9
+ version='3.1.0',
10
10
  author="Mayur Rawte",
11
11
  author_email="mayur@shipthis.co",
12
12
  description="ShipthisAPI async utility package",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shipthisapi-python
3
- Version: 3.0.5
3
+ Version: 3.1.0
4
4
  Summary: ShipthisAPI async utility package
5
5
  Home-page: https://github.com/shipthisco/shipthisapi-python
6
6
  Author: Mayur Rawte