shipthisapi-python 2.1.0__tar.gz → 2.2.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: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: ShipthisAPI utility package
5
5
  Home-page: https://github.com/shipthisco/shipthisapi-python
6
6
  Author: Mayur Rawte
@@ -1,5 +1,5 @@
1
1
  # __variables__ with double-quoted values will be available in setup.py
2
- __version__ = "2.1.0"
2
+ __version__ = "2.2.0"
3
3
 
4
4
  from .shipthisapi import (
5
5
  ShipthisAPI,
@@ -5,6 +5,7 @@ A Python client for the Shipthis public API.
5
5
  Usage:
6
6
  from ShipthisAPI import ShipthisAPI
7
7
 
8
+ # Standard usage with API key
8
9
  client = ShipthisAPI(
9
10
  organisation="your_org_id",
10
11
  x_api_key="your_api_key",
@@ -12,6 +13,15 @@ Usage:
12
13
  location_id="your_location"
13
14
  )
14
15
 
16
+ # Server-to-server usage with custom headers
17
+ client = ShipthisAPI(
18
+ organisation="your_org_id",
19
+ custom_headers={
20
+ "st-server-key": "your_server_key",
21
+ "st-server-name": "your_service_name",
22
+ }
23
+ )
24
+
15
25
  # Connect and validate
16
26
  client.connect()
17
27
 
@@ -20,6 +30,9 @@ Usage:
20
30
 
21
31
  # Get a single item
22
32
  item = client.get_one_item("shipment", doc_id="abc123")
33
+
34
+ # Webhook sync update
35
+ client.webhook_sync("fcl_load", doc_id, fields=[{"status": "completed"}])
23
36
  """
24
37
 
25
38
  from typing import Any, Dict, List, Optional, Union
@@ -60,6 +73,7 @@ class ShipthisAPI:
60
73
  region_id: Region ID for requests.
61
74
  location_id: Location ID for requests.
62
75
  timeout: Request timeout in seconds.
76
+ custom_headers: Custom headers to override defaults.
63
77
  """
64
78
 
65
79
  DEFAULT_TIMEOUT = 30
@@ -68,28 +82,28 @@ class ShipthisAPI:
68
82
  def __init__(
69
83
  self,
70
84
  organisation: str,
71
- x_api_key: str,
85
+ x_api_key: str = None,
72
86
  user_type: str = "employee",
73
87
  region_id: str = None,
74
88
  location_id: str = None,
75
89
  timeout: int = None,
76
90
  base_url: str = None,
91
+ custom_headers: Dict[str, str] = None,
77
92
  ) -> None:
78
93
  """Initialize the Shipthis API client.
79
94
 
80
95
  Args:
81
96
  organisation: Your organisation ID.
82
- x_api_key: Your API key.
97
+ x_api_key: Your API key (optional if using custom_headers with auth).
83
98
  user_type: User type for requests (default: "employee").
84
99
  region_id: Region ID for requests.
85
100
  location_id: Location ID for requests.
86
101
  timeout: Request timeout in seconds (default: 30).
87
102
  base_url: Custom base URL (optional, for testing).
103
+ custom_headers: Custom headers that override defaults (e.g., for server-to-server auth).
88
104
  """
89
105
  if not organisation:
90
106
  raise ValueError("organisation is required")
91
- if not x_api_key:
92
- raise ValueError("x_api_key is required")
93
107
 
94
108
  self.x_api_key = x_api_key
95
109
  self.organisation_id = organisation
@@ -98,6 +112,7 @@ class ShipthisAPI:
98
112
  self.location_id = location_id
99
113
  self.timeout = timeout or self.DEFAULT_TIMEOUT
100
114
  self.base_api_endpoint = base_url or self.BASE_API_ENDPOINT
115
+ self.custom_headers = custom_headers or {}
101
116
  self.organisation_info = None
102
117
  self.is_connected = False
103
118
 
@@ -111,23 +126,32 @@ class ShipthisAPI:
111
126
  self.region_id = region_id
112
127
  self.location_id = location_id
113
128
 
114
- def _get_headers(self) -> Dict[str, str]:
129
+ def _get_headers(self, override_headers: Dict[str, str] = None) -> Dict[str, str]:
115
130
  """Build request headers.
116
131
 
132
+ Args:
133
+ override_headers: Headers to override for this specific request.
134
+
117
135
  Returns:
118
136
  Dictionary of headers.
119
137
  """
120
138
  headers = {
121
- "x-api-key": self.x_api_key,
122
139
  "organisation": self.organisation_id,
123
140
  "usertype": self.user_type,
124
141
  "Content-Type": "application/json",
125
142
  "Accept": "application/json",
126
143
  }
144
+ if self.x_api_key:
145
+ headers["x-api-key"] = self.x_api_key
127
146
  if self.region_id:
128
147
  headers["region"] = self.region_id
129
148
  if self.location_id:
130
149
  headers["location"] = self.location_id
150
+ # Apply custom headers from init
151
+ headers.update(self.custom_headers)
152
+ # Apply per-request override headers
153
+ if override_headers:
154
+ headers.update(override_headers)
131
155
  return headers
132
156
 
133
157
  def _make_request(
@@ -136,6 +160,7 @@ class ShipthisAPI:
136
160
  path: str,
137
161
  query_params: Dict[str, Any] = None,
138
162
  request_data: Dict[str, Any] = None,
163
+ headers: Dict[str, str] = None,
139
164
  ) -> Dict[str, Any]:
140
165
  """Make an HTTP request to the API.
141
166
 
@@ -144,6 +169,7 @@ class ShipthisAPI:
144
169
  path: API endpoint path.
145
170
  query_params: Query parameters.
146
171
  request_data: Request body data.
172
+ headers: Headers to override for this request.
147
173
 
148
174
  Returns:
149
175
  API response data.
@@ -153,7 +179,7 @@ class ShipthisAPI:
153
179
  ShipthisRequestError: If the request fails.
154
180
  """
155
181
  url = self.base_api_endpoint + path
156
- headers = self._get_headers()
182
+ request_headers = self._get_headers(headers)
157
183
 
158
184
  try:
159
185
  if request_data:
@@ -161,7 +187,7 @@ class ShipthisAPI:
161
187
  method,
162
188
  url,
163
189
  json=request_data,
164
- headers=headers,
190
+ headers=request_headers,
165
191
  params=query_params,
166
192
  timeout=self.timeout,
167
193
  )
@@ -169,7 +195,7 @@ class ShipthisAPI:
169
195
  response = requests.request(
170
196
  method,
171
197
  url,
172
- headers=headers,
198
+ headers=request_headers,
173
199
  params=query_params,
174
200
  timeout=self.timeout,
175
201
  )
@@ -959,4 +985,106 @@ class ShipthisAPI:
959
985
  raise ShipthisRequestError(
960
986
  message=f"Upload failed with status {response.status_code}",
961
987
  status_code=response.status_code,
988
+ )
989
+
990
+ # ==================== Webhook Operations ====================
991
+
992
+ def webhook_sync(
993
+ self,
994
+ view_name: str,
995
+ doc_id: str,
996
+ fields: List[Dict[str, Any]],
997
+ ) -> Dict[str, Any]:
998
+ """Update document via webhook-sync (synchronous update).
999
+
1000
+ Args:
1001
+ view_name: View/collection name (e.g., "sea_shipment", "fcl_load").
1002
+ doc_id: Document ID.
1003
+ fields: List of field dicts to update.
1004
+
1005
+ Returns:
1006
+ API response with success status and data.
1007
+
1008
+ Raises:
1009
+ ShipthisAPIError: If the request fails.
1010
+
1011
+ Example:
1012
+ client.webhook_sync(
1013
+ "fcl_load",
1014
+ "68a4f906743189ad061429a7",
1015
+ fields=[{"container_no": "CONT123"}, {"seal_no": "SEAL456"}]
1016
+ )
1017
+ """
1018
+ payload = {"fields": fields}
1019
+ return self._make_request(
1020
+ "PUT",
1021
+ f"webhook-sync/{self.organisation_id}/{view_name}/{doc_id}",
1022
+ request_data=payload,
1023
+ )
1024
+
1025
+ def webhook_update(
1026
+ self,
1027
+ view_name: str,
1028
+ doc_id: str,
1029
+ actions: List[Dict[str, Any]],
1030
+ ) -> Dict[str, Any]:
1031
+ """Update document via webhook (async update with actions).
1032
+
1033
+ Args:
1034
+ view_name: View/collection name.
1035
+ doc_id: Document ID.
1036
+ actions: List of action dicts to execute.
1037
+
1038
+ Returns:
1039
+ API response with success status and data.
1040
+
1041
+ Raises:
1042
+ ShipthisAPIError: If the request fails.
1043
+
1044
+ Example:
1045
+ client.webhook_update(
1046
+ "sea_shipment",
1047
+ "68a4f906743189ad061429a7",
1048
+ actions=[{"action": "update_status", "value": "completed"}]
1049
+ )
1050
+ """
1051
+ payload = {"actions": actions}
1052
+ return self._make_request(
1053
+ "PUT",
1054
+ f"webhook/{self.organisation_id}/{view_name}/{doc_id}",
1055
+ request_data=payload,
1056
+ )
1057
+
1058
+ # ==================== Reference Linked Fields ====================
1059
+
1060
+ def create_reference_linked_field(
1061
+ self,
1062
+ collection_name: str,
1063
+ doc_id: str,
1064
+ payload: Dict[str, Any],
1065
+ ) -> Dict[str, Any]:
1066
+ """Create a reference-linked field on a document.
1067
+
1068
+ Args:
1069
+ collection_name: Collection name.
1070
+ doc_id: Document ID.
1071
+ payload: Field data to create.
1072
+
1073
+ Returns:
1074
+ API response.
1075
+
1076
+ Raises:
1077
+ ShipthisAPIError: If the request fails.
1078
+
1079
+ Example:
1080
+ client.create_reference_linked_field(
1081
+ "sea_shipment",
1082
+ "68a4f906743189ad061429a7",
1083
+ payload={"field_name": "containers", "data": {...}}
1084
+ )
1085
+ """
1086
+ return self._make_request(
1087
+ "POST",
1088
+ f"incollection/create-reference-linked-field/{collection_name}/{doc_id}",
1089
+ request_data=payload,
962
1090
  )
@@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
6
6
 
7
7
  setuptools.setup(
8
8
  name='shipthisapi-python',
9
- version='2.1.0',
9
+ version='2.2.0',
10
10
  author="Mayur Rawte",
11
11
  author_email="mayur@shipthis.co",
12
12
  description="ShipthisAPI utility package",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shipthisapi-python
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: ShipthisAPI utility package
5
5
  Home-page: https://github.com/shipthisco/shipthisapi-python
6
6
  Author: Mayur Rawte