keymint 2.2.0__tar.gz → 2.3.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.
- {keymint-2.2.0/keymint.egg-info → keymint-2.3.0}/PKG-INFO +11 -1
- {keymint-2.2.0 → keymint-2.3.0}/README.md +10 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint/__init__.py +45 -29
- {keymint-2.2.0 → keymint-2.3.0}/keymint/_version.py +1 -1
- {keymint-2.2.0 → keymint-2.3.0/keymint.egg-info}/PKG-INFO +11 -1
- {keymint-2.2.0 → keymint-2.3.0}/setup.py +1 -1
- {keymint-2.2.0 → keymint-2.3.0}/LICENSE +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/MANIFEST.in +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint/identity.py +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint/types.py +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint.egg-info/SOURCES.txt +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint.egg-info/dependency_links.txt +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint.egg-info/requires.txt +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/keymint.egg-info/top_level.txt +0 -0
- {keymint-2.2.0 → keymint-2.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: keymint
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Official Python SDK for KeyMint license management with comprehensive API coverage.
|
|
5
5
|
Home-page: https://github.com/keymint-dev/keymint-python
|
|
6
6
|
Author: KeyMint
|
|
@@ -131,6 +131,16 @@ Keymint provides utilities to uniquely identify machines for node-locking:
|
|
|
131
131
|
|-------------------------|--------------------------------------------------|
|
|
132
132
|
| `verify_webhook_signature`| Verifies the signature of a webhook request payload. |
|
|
133
133
|
|
|
134
|
+
## Idempotency
|
|
135
|
+
|
|
136
|
+
All mutating SDK methods support idempotency keys to safely retry requests in case of network drops. Pass a unique string (recommended: UUID v4) as the optional `idempotency_key` keyword argument:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
result = sdk.create_key({
|
|
140
|
+
'productId': product_id,
|
|
141
|
+
}, idempotency_key='9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d')
|
|
142
|
+
```
|
|
143
|
+
|
|
134
144
|
## License
|
|
135
145
|
MIT
|
|
136
146
|
|
|
@@ -82,6 +82,16 @@ Keymint provides utilities to uniquely identify machines for node-locking:
|
|
|
82
82
|
|-------------------------|--------------------------------------------------|
|
|
83
83
|
| `verify_webhook_signature`| Verifies the signature of a webhook request payload. |
|
|
84
84
|
|
|
85
|
+
## Idempotency
|
|
86
|
+
|
|
87
|
+
All mutating SDK methods support idempotency keys to safely retry requests in case of network drops. Pass a unique string (recommended: UUID v4) as the optional `idempotency_key` keyword argument:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
result = sdk.create_key({
|
|
91
|
+
'productId': product_id,
|
|
92
|
+
}, idempotency_key='9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d')
|
|
93
|
+
```
|
|
94
|
+
|
|
85
95
|
## License
|
|
86
96
|
MIT
|
|
87
97
|
|
|
@@ -16,17 +16,21 @@ class KeyMint:
|
|
|
16
16
|
'Content-Type': 'application/json'
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
def _handle_request(self, method: str, endpoint: str, params: dict = None, query_params: dict = None):
|
|
19
|
+
def _handle_request(self, method: str, endpoint: str, params: dict = None, query_params: dict = None, idempotency_key: str = None):
|
|
20
20
|
url = f'{self.base_url}{endpoint}'
|
|
21
|
+
headers = self.headers.copy()
|
|
22
|
+
if idempotency_key:
|
|
23
|
+
headers['Idempotency-Key'] = idempotency_key
|
|
24
|
+
|
|
21
25
|
try:
|
|
22
26
|
if method.upper() == 'GET':
|
|
23
|
-
response = requests.get(url, params=query_params, headers=
|
|
27
|
+
response = requests.get(url, params=query_params, headers=headers)
|
|
24
28
|
elif method.upper() == 'POST':
|
|
25
|
-
response = requests.post(url, json=params, headers=
|
|
29
|
+
response = requests.post(url, json=params, headers=headers)
|
|
26
30
|
elif method.upper() == 'PUT':
|
|
27
|
-
response = requests.put(url, json=params, headers=
|
|
31
|
+
response = requests.put(url, json=params, headers=headers)
|
|
28
32
|
elif method.upper() == 'DELETE':
|
|
29
|
-
response = requests.delete(url, params=query_params, headers=
|
|
33
|
+
response = requests.delete(url, params=query_params, headers=headers)
|
|
30
34
|
else:
|
|
31
35
|
raise ValueError(f"Unsupported HTTP method: {method}")
|
|
32
36
|
|
|
@@ -49,15 +53,16 @@ class KeyMint:
|
|
|
49
53
|
except Exception as err:
|
|
50
54
|
raise KeyMintApiError(message=str(err), code=-1)
|
|
51
55
|
|
|
52
|
-
def create_key(self, params: CreateKeyParams) -> CreateKeyResponse:
|
|
56
|
+
def create_key(self, params: CreateKeyParams, idempotency_key: str = None) -> CreateKeyResponse:
|
|
53
57
|
"""
|
|
54
58
|
Creates a new license key.
|
|
55
59
|
:param params: Parameters for creating the key.
|
|
60
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
56
61
|
:returns: The created key information.
|
|
57
62
|
"""
|
|
58
|
-
return self._handle_request('POST', '/key', params)
|
|
63
|
+
return self._handle_request('POST', '/key', params, idempotency_key=idempotency_key)
|
|
59
64
|
|
|
60
|
-
def activate_key(self, params: ActivateKeyParams) -> ActivateKeyResponse:
|
|
65
|
+
def activate_key(self, params: ActivateKeyParams, idempotency_key: str = None) -> ActivateKeyResponse:
|
|
61
66
|
"""
|
|
62
67
|
Activates a license key for a specific device.
|
|
63
68
|
|
|
@@ -67,41 +72,46 @@ class KeyMint:
|
|
|
67
72
|
MUST cache the validation result locally.
|
|
68
73
|
|
|
69
74
|
:param params: Activation parameters including productId, licenseKey, and optional hostId.
|
|
75
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
70
76
|
:return: Activation success message and licensee information.
|
|
71
77
|
"""
|
|
72
|
-
return self._handle_request('POST', '/key/activate', params)
|
|
78
|
+
return self._handle_request('POST', '/key/activate', params, idempotency_key=idempotency_key)
|
|
73
79
|
|
|
74
|
-
def deactivate_key(self, params: DeactivateKeyParams) -> DeactivateKeyResponse:
|
|
80
|
+
def deactivate_key(self, params: DeactivateKeyParams, idempotency_key: str = None) -> DeactivateKeyResponse:
|
|
75
81
|
"""
|
|
76
82
|
Deactivates a device from a license key.
|
|
77
83
|
:param params: Parameters for deactivating the key.
|
|
84
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
78
85
|
:returns: The deactivation confirmation.
|
|
79
86
|
"""
|
|
80
|
-
return self._handle_request('POST', '/key/deactivate', params)
|
|
87
|
+
return self._handle_request('POST', '/key/deactivate', params, idempotency_key=idempotency_key)
|
|
81
88
|
|
|
82
|
-
def floating_checkout(self, params: FloatingCheckoutParams) -> FloatingCheckoutResponse:
|
|
89
|
+
def floating_checkout(self, params: FloatingCheckoutParams, idempotency_key: str = None) -> FloatingCheckoutResponse:
|
|
83
90
|
"""
|
|
84
91
|
Checks out a floating license seat.
|
|
85
92
|
:param params: Parameters for checking out the license.
|
|
93
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
86
94
|
:returns: The checkout response containing sessionId and sessionSecret.
|
|
87
95
|
"""
|
|
88
|
-
return self._handle_request('POST', '/key/checkout', params)
|
|
96
|
+
return self._handle_request('POST', '/key/checkout', params, idempotency_key=idempotency_key)
|
|
89
97
|
|
|
90
|
-
def floating_heartbeat(self, params: FloatingHeartbeatParams) -> FloatingHeartbeatResponse:
|
|
98
|
+
def floating_heartbeat(self, params: FloatingHeartbeatParams, idempotency_key: str = None) -> FloatingHeartbeatResponse:
|
|
91
99
|
"""
|
|
92
100
|
Sends a heartbeat to keep a floating license session alive.
|
|
93
101
|
:param params: Parameters for the heartbeat (includes rotating signature).
|
|
102
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
94
103
|
:returns: The heartbeat response with extended expiry and new nonce.
|
|
95
104
|
"""
|
|
96
|
-
return self._handle_request('POST', '/key/heartbeat', params)
|
|
105
|
+
return self._handle_request('POST', '/key/heartbeat', params, idempotency_key=idempotency_key)
|
|
97
106
|
|
|
98
|
-
def floating_checkin(self, params: FloatingCheckinParams) -> FloatingCheckinResponse:
|
|
107
|
+
def floating_checkin(self, params: FloatingCheckinParams, idempotency_key: str = None) -> FloatingCheckinResponse:
|
|
99
108
|
"""
|
|
100
109
|
Checks in a floating license session, releasing the seat.
|
|
101
110
|
:param params: Parameters for checking in the license (includes rotating signature).
|
|
111
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
102
112
|
:returns: The checkin confirmation.
|
|
103
113
|
"""
|
|
104
|
-
return self._handle_request('POST', '/key/checkin', params)
|
|
114
|
+
return self._handle_request('POST', '/key/checkin', params, idempotency_key=idempotency_key)
|
|
105
115
|
|
|
106
116
|
def get_key(self, params: GetKeyParams) -> GetKeyResponse:
|
|
107
117
|
"""
|
|
@@ -115,31 +125,34 @@ class KeyMint:
|
|
|
115
125
|
}
|
|
116
126
|
return self._handle_request('GET', '/key', query_params=query_params)
|
|
117
127
|
|
|
118
|
-
def block_key(self, params: BlockKeyParams) -> BlockKeyResponse:
|
|
128
|
+
def block_key(self, params: BlockKeyParams, idempotency_key: str = None) -> BlockKeyResponse:
|
|
119
129
|
"""
|
|
120
130
|
Blocks a specific license key.
|
|
121
131
|
:param params: Parameters for blocking the key.
|
|
132
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
122
133
|
:returns: The block confirmation.
|
|
123
134
|
"""
|
|
124
|
-
return self._handle_request('POST', '/key/block', params)
|
|
135
|
+
return self._handle_request('POST', '/key/block', params, idempotency_key=idempotency_key)
|
|
125
136
|
|
|
126
|
-
def unblock_key(self, params: UnblockKeyParams) -> UnblockKeyResponse:
|
|
137
|
+
def unblock_key(self, params: UnblockKeyParams, idempotency_key: str = None) -> UnblockKeyResponse:
|
|
127
138
|
"""
|
|
128
139
|
Unblocks a previously blocked license key.
|
|
129
140
|
:param params: Parameters for unblocking the key.
|
|
141
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
130
142
|
:returns: The unblock confirmation.
|
|
131
143
|
"""
|
|
132
|
-
return self._handle_request('POST', '/key/unblock', params)
|
|
144
|
+
return self._handle_request('POST', '/key/unblock', params, idempotency_key=idempotency_key)
|
|
133
145
|
|
|
134
146
|
# Customer Management Methods
|
|
135
147
|
|
|
136
|
-
def create_customer(self, params: CreateCustomerParams) -> CreateCustomerResponse:
|
|
148
|
+
def create_customer(self, params: CreateCustomerParams, idempotency_key: str = None) -> CreateCustomerResponse:
|
|
137
149
|
"""
|
|
138
150
|
Creates a new customer.
|
|
139
151
|
:param params: Parameters for creating the customer.
|
|
152
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
140
153
|
:returns: The created customer information.
|
|
141
154
|
"""
|
|
142
|
-
return self._handle_request('POST', '/customer', params)
|
|
155
|
+
return self._handle_request('POST', '/customer', params, idempotency_key=idempotency_key)
|
|
143
156
|
|
|
144
157
|
def get_all_customers(self, params: Optional[GetAllCustomersParams] = None) -> GetAllCustomersResponse:
|
|
145
158
|
"""
|
|
@@ -158,22 +171,24 @@ class KeyMint:
|
|
|
158
171
|
query_params = {'customerId': params['customerId']}
|
|
159
172
|
return self._handle_request('GET', '/customer/by-id', query_params=query_params)
|
|
160
173
|
|
|
161
|
-
def update_customer(self, params: UpdateCustomerParams) -> UpdateCustomerResponse:
|
|
174
|
+
def update_customer(self, params: UpdateCustomerParams, idempotency_key: str = None) -> UpdateCustomerResponse:
|
|
162
175
|
"""
|
|
163
176
|
Updates an existing customer's information.
|
|
164
177
|
:param params: Parameters for updating the customer.
|
|
178
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
165
179
|
:returns: The update confirmation.
|
|
166
180
|
"""
|
|
167
|
-
return self._handle_request('PUT', '/customer/by-id', params)
|
|
181
|
+
return self._handle_request('PUT', '/customer/by-id', params, idempotency_key=idempotency_key)
|
|
168
182
|
|
|
169
|
-
def delete_customer(self, params: DeleteCustomerParams) -> DeleteCustomerResponse:
|
|
183
|
+
def delete_customer(self, params: DeleteCustomerParams, idempotency_key: str = None) -> DeleteCustomerResponse:
|
|
170
184
|
"""
|
|
171
185
|
Permanently deletes a customer and all associated license keys.
|
|
172
186
|
:param params: Parameters containing the customer ID.
|
|
187
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
173
188
|
:returns: The deletion confirmation.
|
|
174
189
|
"""
|
|
175
190
|
query_params = {'customerId': params['customerId']}
|
|
176
|
-
return self._handle_request('DELETE', '/customer/by-id', query_params=query_params)
|
|
191
|
+
return self._handle_request('DELETE', '/customer/by-id', query_params=query_params, idempotency_key=idempotency_key)
|
|
177
192
|
|
|
178
193
|
def get_customer_with_keys(self, params: GetCustomerWithKeysParams) -> GetCustomerWithKeysResponse:
|
|
179
194
|
"""
|
|
@@ -184,14 +199,15 @@ class KeyMint:
|
|
|
184
199
|
query_params = {'customerId': params['customerId']}
|
|
185
200
|
return self._handle_request('GET', '/customer/keys', query_params=query_params)
|
|
186
201
|
|
|
187
|
-
def toggle_customer_status(self, params: ToggleCustomerStatusParams) -> ToggleCustomerStatusResponse:
|
|
202
|
+
def toggle_customer_status(self, params: ToggleCustomerStatusParams, idempotency_key: str = None) -> ToggleCustomerStatusResponse:
|
|
188
203
|
"""
|
|
189
204
|
Toggles the active status of a customer account (disable or enable).
|
|
190
205
|
:param params: Parameters containing the customer ID.
|
|
206
|
+
:param idempotency_key: Optional unique identifier to ensure request idempotency.
|
|
191
207
|
:returns: The status toggle confirmation.
|
|
192
208
|
"""
|
|
193
209
|
query_params = {'customerId': params['customerId']}
|
|
194
|
-
return self._handle_request('POST', '/customer/disable', params=None, query_params=query_params)
|
|
210
|
+
return self._handle_request('POST', '/customer/disable', params=None, query_params=query_params, idempotency_key=idempotency_key)
|
|
195
211
|
|
|
196
212
|
@staticmethod
|
|
197
213
|
def verify_webhook_signature(payload: str, header: str, secret: str, tolerance_seconds: int = 300) -> bool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: keymint
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Official Python SDK for KeyMint license management with comprehensive API coverage.
|
|
5
5
|
Home-page: https://github.com/keymint-dev/keymint-python
|
|
6
6
|
Author: KeyMint
|
|
@@ -131,6 +131,16 @@ Keymint provides utilities to uniquely identify machines for node-locking:
|
|
|
131
131
|
|-------------------------|--------------------------------------------------|
|
|
132
132
|
| `verify_webhook_signature`| Verifies the signature of a webhook request payload. |
|
|
133
133
|
|
|
134
|
+
## Idempotency
|
|
135
|
+
|
|
136
|
+
All mutating SDK methods support idempotency keys to safely retry requests in case of network drops. Pass a unique string (recommended: UUID v4) as the optional `idempotency_key` keyword argument:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
result = sdk.create_key({
|
|
140
|
+
'productId': product_id,
|
|
141
|
+
}, idempotency_key='9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d')
|
|
142
|
+
```
|
|
143
|
+
|
|
134
144
|
## License
|
|
135
145
|
MIT
|
|
136
146
|
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="keymint",
|
|
8
|
-
version="2.
|
|
8
|
+
version="2.3.0",
|
|
9
9
|
author="KeyMint",
|
|
10
10
|
author_email="cliff@keymint.dev",
|
|
11
11
|
description="Official Python SDK for KeyMint license management with comprehensive API coverage.",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|