keymint 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.
- keymint-0.1.0/PKG-INFO +184 -0
- keymint-0.1.0/README.md +161 -0
- keymint-0.1.0/keymint/__init__.py +85 -0
- keymint-0.1.0/keymint/types.py +90 -0
- keymint-0.1.0/keymint.egg-info/PKG-INFO +184 -0
- keymint-0.1.0/keymint.egg-info/SOURCES.txt +10 -0
- keymint-0.1.0/keymint.egg-info/dependency_links.txt +1 -0
- keymint-0.1.0/keymint.egg-info/requires.txt +1 -0
- keymint-0.1.0/keymint.egg-info/top_level.txt +1 -0
- keymint-0.1.0/setup.cfg +4 -0
- keymint-0.1.0/setup.py +25 -0
- keymint-0.1.0/tests/test_keymint.py +104 -0
keymint-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: keymint
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python SDK for the KeyMint API.
|
|
5
|
+
Home-page: https://github.com/keymint-dev/keymint-python
|
|
6
|
+
Author: Keymint
|
|
7
|
+
Author-email: admin@keymint.dev
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: requires-dist
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# KeyMint Python SDK
|
|
25
|
+
|
|
26
|
+
Welcome to the official KeyMint SDK for Python! This library provides a simple and convenient way to interact with the KeyMint API, allowing you to manage license keys for your applications with ease.
|
|
27
|
+
|
|
28
|
+
## ✨ Features
|
|
29
|
+
|
|
30
|
+
* **Simple & Intuitive**: A clean and modern API that is easy to learn and use.
|
|
31
|
+
* **Type Hinting**: Uses Python's type hinting for a better developer experience.
|
|
32
|
+
* **Comprehensive**: Covers all the essential KeyMint API endpoints.
|
|
33
|
+
* **Well-Documented**: Clear and concise documentation with plenty of examples.
|
|
34
|
+
* **Error Handling**: Standardized error handling to make debugging a breeze.
|
|
35
|
+
|
|
36
|
+
## 🚀 Quick Start
|
|
37
|
+
|
|
38
|
+
Here's a complete example of how to use the SDK to create and activate a license key:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import os
|
|
42
|
+
from keymint import KeyMintSDK
|
|
43
|
+
|
|
44
|
+
def main():
|
|
45
|
+
access_token = os.environ.get('KEYMINT_ACCESS_TOKEN')
|
|
46
|
+
if not access_token:
|
|
47
|
+
print('Please set the KEYMINT_ACCESS_TOKEN environment variable.')
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
sdk = KeyMintSDK(access_token)
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# 1. Create a new license key
|
|
54
|
+
create_response = sdk.create_key({
|
|
55
|
+
'productId': 'YOUR_PRODUCT_ID',
|
|
56
|
+
})
|
|
57
|
+
license_key = create_response['key']
|
|
58
|
+
print(f'Key created: {license_key}')
|
|
59
|
+
|
|
60
|
+
# 2. Activate the license key
|
|
61
|
+
activate_response = sdk.activate_key({
|
|
62
|
+
'productId': 'YOUR_PRODUCT_ID',
|
|
63
|
+
'licenseKey': license_key,
|
|
64
|
+
'hostId': 'UNIQUE_DEVICE_ID',
|
|
65
|
+
})
|
|
66
|
+
print(f"Key activated: {activate_response['message']}")
|
|
67
|
+
except Exception as e:
|
|
68
|
+
print(f'An error occurred: {e}')
|
|
69
|
+
|
|
70
|
+
if __name__ == '__main__':
|
|
71
|
+
main()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 📦 Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install keymint
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 🛠️ Usage
|
|
81
|
+
|
|
82
|
+
### Initialization
|
|
83
|
+
|
|
84
|
+
First, import the `KeyMintSDK` and initialize it with your access token. You can find your access token in your [KeyMint dashboard](https://keymint.dev/app/settings/api).
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from keymint import KeyMintSDK
|
|
88
|
+
|
|
89
|
+
access_token = 'YOUR_ACCESS_TOKEN'
|
|
90
|
+
sdk = KeyMintSDK(access_token)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### API Methods
|
|
94
|
+
|
|
95
|
+
All methods return a dictionary.
|
|
96
|
+
|
|
97
|
+
| Method | Description |
|
|
98
|
+
| --------------- | ----------------------------------------------- |
|
|
99
|
+
| `create_key` | Creates a new license key. |
|
|
100
|
+
| `activate_key` | Activates a license key for a device. |
|
|
101
|
+
| `deactivate_key`| Deactivates a device from a license key. |
|
|
102
|
+
| `get_key` | Retrieves detailed information about a key. |
|
|
103
|
+
| `block_key` | Blocks a license key. |
|
|
104
|
+
| `unblock_key` | Unblocks a previously blocked license key. |
|
|
105
|
+
|
|
106
|
+
For more detailed information about the API methods and their parameters, please refer to the [API Reference](#api-reference) section below.
|
|
107
|
+
|
|
108
|
+
## 🚨 Error Handling
|
|
109
|
+
|
|
110
|
+
If an API call fails, the SDK will raise a `KeyMintApiError` exception. This object contains a `message`, `code`, and `status` attribute that you can use to handle the error.
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from keymint import KeyMintApiError
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
# ...
|
|
117
|
+
except KeyMintApiError as e:
|
|
118
|
+
print(f'API Error: {e.message}')
|
|
119
|
+
print(f'Status: {e.status}')
|
|
120
|
+
print(f'Code: {e.code}')
|
|
121
|
+
except Exception as e:
|
|
122
|
+
print(f'An unexpected error occurred: {e}')
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 📚 API Reference
|
|
126
|
+
|
|
127
|
+
### `KeyMintSDK(access_token, base_url)`
|
|
128
|
+
|
|
129
|
+
| Parameter | Type | Description |
|
|
130
|
+
| -------------- | -------- | --------------------------------------------------------------------------- |
|
|
131
|
+
| `access_token` | `str` | **Required.** Your KeyMint API access token. |
|
|
132
|
+
| `base_url` | `str` | *Optional.* The base URL for the KeyMint API. Defaults to `https://api.keymint.dev`. |
|
|
133
|
+
|
|
134
|
+
### `create_key(params)`
|
|
135
|
+
|
|
136
|
+
| Parameter | Type | Description |
|
|
137
|
+
| ---------------- | -------- | --------------------------------------------------------------------------- |
|
|
138
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
139
|
+
| `maxActivations` | `str` | *Optional.* The maximum number of activations for the key. |
|
|
140
|
+
| `expiryDate` | `str` | *Optional.* The expiration date of the key in ISO 8601 format. |
|
|
141
|
+
| `customerId` | `str` | *Optional.* The ID of an existing customer to associate with the key. |
|
|
142
|
+
| `newCustomer` | `dict` | *Optional.* A dictionary containing the name and email of a new customer. |
|
|
143
|
+
|
|
144
|
+
### `activate_key(params)`
|
|
145
|
+
|
|
146
|
+
| Parameter | Type | Description |
|
|
147
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
148
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
149
|
+
| `licenseKey` | `str` | **Required.** The license key to activate. |
|
|
150
|
+
| `hostId` | `str` | *Optional.* A unique identifier for the device. |
|
|
151
|
+
| `deviceTag` | `str` | *Optional.* A user-friendly name for the device. |
|
|
152
|
+
|
|
153
|
+
### `deactivate_key(params)`
|
|
154
|
+
|
|
155
|
+
| Parameter | Type | Description |
|
|
156
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
157
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
158
|
+
| `licenseKey` | `str` | **Required.** The license key to deactivate. |
|
|
159
|
+
| `hostId` | `str` | *Optional.* The ID of the device to deactivate. If omitted, all devices are deactivated. |
|
|
160
|
+
|
|
161
|
+
### `get_key(params)`
|
|
162
|
+
|
|
163
|
+
| Parameter | Type | Description |
|
|
164
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
165
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
166
|
+
| `licenseKey` | `str` | **Required.** The license key to retrieve. |
|
|
167
|
+
|
|
168
|
+
### `block_key(params)`
|
|
169
|
+
|
|
170
|
+
| Parameter | Type | Description |
|
|
171
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
172
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
173
|
+
| `licenseKey` | `str` | **Required.** The license key to block. |
|
|
174
|
+
|
|
175
|
+
### `unblock_key(params)`
|
|
176
|
+
|
|
177
|
+
| Parameter | Type | Description |
|
|
178
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
179
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
180
|
+
| `licenseKey` | `str` | **Required.** The license key to unblock. |
|
|
181
|
+
|
|
182
|
+
## 📜 License
|
|
183
|
+
|
|
184
|
+
This SDK is licensed under the MIT License.
|
keymint-0.1.0/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# KeyMint Python SDK
|
|
2
|
+
|
|
3
|
+
Welcome to the official KeyMint SDK for Python! This library provides a simple and convenient way to interact with the KeyMint API, allowing you to manage license keys for your applications with ease.
|
|
4
|
+
|
|
5
|
+
## ✨ Features
|
|
6
|
+
|
|
7
|
+
* **Simple & Intuitive**: A clean and modern API that is easy to learn and use.
|
|
8
|
+
* **Type Hinting**: Uses Python's type hinting for a better developer experience.
|
|
9
|
+
* **Comprehensive**: Covers all the essential KeyMint API endpoints.
|
|
10
|
+
* **Well-Documented**: Clear and concise documentation with plenty of examples.
|
|
11
|
+
* **Error Handling**: Standardized error handling to make debugging a breeze.
|
|
12
|
+
|
|
13
|
+
## 🚀 Quick Start
|
|
14
|
+
|
|
15
|
+
Here's a complete example of how to use the SDK to create and activate a license key:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
import os
|
|
19
|
+
from keymint import KeyMintSDK
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
access_token = os.environ.get('KEYMINT_ACCESS_TOKEN')
|
|
23
|
+
if not access_token:
|
|
24
|
+
print('Please set the KEYMINT_ACCESS_TOKEN environment variable.')
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
sdk = KeyMintSDK(access_token)
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
# 1. Create a new license key
|
|
31
|
+
create_response = sdk.create_key({
|
|
32
|
+
'productId': 'YOUR_PRODUCT_ID',
|
|
33
|
+
})
|
|
34
|
+
license_key = create_response['key']
|
|
35
|
+
print(f'Key created: {license_key}')
|
|
36
|
+
|
|
37
|
+
# 2. Activate the license key
|
|
38
|
+
activate_response = sdk.activate_key({
|
|
39
|
+
'productId': 'YOUR_PRODUCT_ID',
|
|
40
|
+
'licenseKey': license_key,
|
|
41
|
+
'hostId': 'UNIQUE_DEVICE_ID',
|
|
42
|
+
})
|
|
43
|
+
print(f"Key activated: {activate_response['message']}")
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(f'An error occurred: {e}')
|
|
46
|
+
|
|
47
|
+
if __name__ == '__main__':
|
|
48
|
+
main()
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 📦 Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install keymint
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 🛠️ Usage
|
|
58
|
+
|
|
59
|
+
### Initialization
|
|
60
|
+
|
|
61
|
+
First, import the `KeyMintSDK` and initialize it with your access token. You can find your access token in your [KeyMint dashboard](https://keymint.dev/app/settings/api).
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from keymint import KeyMintSDK
|
|
65
|
+
|
|
66
|
+
access_token = 'YOUR_ACCESS_TOKEN'
|
|
67
|
+
sdk = KeyMintSDK(access_token)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### API Methods
|
|
71
|
+
|
|
72
|
+
All methods return a dictionary.
|
|
73
|
+
|
|
74
|
+
| Method | Description |
|
|
75
|
+
| --------------- | ----------------------------------------------- |
|
|
76
|
+
| `create_key` | Creates a new license key. |
|
|
77
|
+
| `activate_key` | Activates a license key for a device. |
|
|
78
|
+
| `deactivate_key`| Deactivates a device from a license key. |
|
|
79
|
+
| `get_key` | Retrieves detailed information about a key. |
|
|
80
|
+
| `block_key` | Blocks a license key. |
|
|
81
|
+
| `unblock_key` | Unblocks a previously blocked license key. |
|
|
82
|
+
|
|
83
|
+
For more detailed information about the API methods and their parameters, please refer to the [API Reference](#api-reference) section below.
|
|
84
|
+
|
|
85
|
+
## 🚨 Error Handling
|
|
86
|
+
|
|
87
|
+
If an API call fails, the SDK will raise a `KeyMintApiError` exception. This object contains a `message`, `code`, and `status` attribute that you can use to handle the error.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from keymint import KeyMintApiError
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
# ...
|
|
94
|
+
except KeyMintApiError as e:
|
|
95
|
+
print(f'API Error: {e.message}')
|
|
96
|
+
print(f'Status: {e.status}')
|
|
97
|
+
print(f'Code: {e.code}')
|
|
98
|
+
except Exception as e:
|
|
99
|
+
print(f'An unexpected error occurred: {e}')
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 📚 API Reference
|
|
103
|
+
|
|
104
|
+
### `KeyMintSDK(access_token, base_url)`
|
|
105
|
+
|
|
106
|
+
| Parameter | Type | Description |
|
|
107
|
+
| -------------- | -------- | --------------------------------------------------------------------------- |
|
|
108
|
+
| `access_token` | `str` | **Required.** Your KeyMint API access token. |
|
|
109
|
+
| `base_url` | `str` | *Optional.* The base URL for the KeyMint API. Defaults to `https://api.keymint.dev`. |
|
|
110
|
+
|
|
111
|
+
### `create_key(params)`
|
|
112
|
+
|
|
113
|
+
| Parameter | Type | Description |
|
|
114
|
+
| ---------------- | -------- | --------------------------------------------------------------------------- |
|
|
115
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
116
|
+
| `maxActivations` | `str` | *Optional.* The maximum number of activations for the key. |
|
|
117
|
+
| `expiryDate` | `str` | *Optional.* The expiration date of the key in ISO 8601 format. |
|
|
118
|
+
| `customerId` | `str` | *Optional.* The ID of an existing customer to associate with the key. |
|
|
119
|
+
| `newCustomer` | `dict` | *Optional.* A dictionary containing the name and email of a new customer. |
|
|
120
|
+
|
|
121
|
+
### `activate_key(params)`
|
|
122
|
+
|
|
123
|
+
| Parameter | Type | Description |
|
|
124
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
125
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
126
|
+
| `licenseKey` | `str` | **Required.** The license key to activate. |
|
|
127
|
+
| `hostId` | `str` | *Optional.* A unique identifier for the device. |
|
|
128
|
+
| `deviceTag` | `str` | *Optional.* A user-friendly name for the device. |
|
|
129
|
+
|
|
130
|
+
### `deactivate_key(params)`
|
|
131
|
+
|
|
132
|
+
| Parameter | Type | Description |
|
|
133
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
134
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
135
|
+
| `licenseKey` | `str` | **Required.** The license key to deactivate. |
|
|
136
|
+
| `hostId` | `str` | *Optional.* The ID of the device to deactivate. If omitted, all devices are deactivated. |
|
|
137
|
+
|
|
138
|
+
### `get_key(params)`
|
|
139
|
+
|
|
140
|
+
| Parameter | Type | Description |
|
|
141
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
142
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
143
|
+
| `licenseKey` | `str` | **Required.** The license key to retrieve. |
|
|
144
|
+
|
|
145
|
+
### `block_key(params)`
|
|
146
|
+
|
|
147
|
+
| Parameter | Type | Description |
|
|
148
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
149
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
150
|
+
| `licenseKey` | `str` | **Required.** The license key to block. |
|
|
151
|
+
|
|
152
|
+
### `unblock_key(params)`
|
|
153
|
+
|
|
154
|
+
| Parameter | Type | Description |
|
|
155
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
156
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
157
|
+
| `licenseKey` | `str` | **Required.** The license key to unblock. |
|
|
158
|
+
|
|
159
|
+
## 📜 License
|
|
160
|
+
|
|
161
|
+
This SDK is licensed under the MIT License.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from .types import *
|
|
3
|
+
|
|
4
|
+
class KeyMintSDK:
|
|
5
|
+
def __init__(self, access_token: str, base_url: str = "https://api.keymint.dev"):
|
|
6
|
+
if not access_token:
|
|
7
|
+
raise ValueError("Access token is required to initialize the SDK.")
|
|
8
|
+
|
|
9
|
+
self.access_token = access_token
|
|
10
|
+
self.base_url = base_url
|
|
11
|
+
self.headers = {
|
|
12
|
+
'Authorization': f'Bearer {self.access_token}',
|
|
13
|
+
'Content-Type': 'application/json'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def _handle_request(self, endpoint: str, params: dict):
|
|
17
|
+
url = f'{self.base_url}{endpoint}'
|
|
18
|
+
try:
|
|
19
|
+
response = requests.post(url, json=params, headers=self.headers)
|
|
20
|
+
response.raise_for_status()
|
|
21
|
+
return response.json()
|
|
22
|
+
except requests.exceptions.HTTPError as http_err:
|
|
23
|
+
try:
|
|
24
|
+
error_data = http_err.response.json()
|
|
25
|
+
raise KeyMintApiError(
|
|
26
|
+
message=error_data.get('message', 'An API error occurred'),
|
|
27
|
+
code=error_data.get('code', -1),
|
|
28
|
+
status=http_err.response.status_code
|
|
29
|
+
)
|
|
30
|
+
except ValueError:
|
|
31
|
+
raise KeyMintApiError(
|
|
32
|
+
message=str(http_err),
|
|
33
|
+
code=-1,
|
|
34
|
+
status=http_err.response.status_code
|
|
35
|
+
)
|
|
36
|
+
except Exception as err:
|
|
37
|
+
raise KeyMintApiError(message=str(err), code=-1)
|
|
38
|
+
|
|
39
|
+
def create_key(self, params: CreateKeyParams) -> CreateKeyResponse:
|
|
40
|
+
"""
|
|
41
|
+
Creates a new license key.
|
|
42
|
+
:param params: Parameters for creating the key.
|
|
43
|
+
:returns: The created key information.
|
|
44
|
+
"""
|
|
45
|
+
return self._handle_request('/create-key', params)
|
|
46
|
+
|
|
47
|
+
def activate_key(self, params: ActivateKeyParams) -> ActivateKeyResponse:
|
|
48
|
+
"""
|
|
49
|
+
Activates a license key for a specific device.
|
|
50
|
+
:param params: Parameters for activating the key.
|
|
51
|
+
:returns: The activation status.
|
|
52
|
+
"""
|
|
53
|
+
return self._handle_request('/activate-key', params)
|
|
54
|
+
|
|
55
|
+
def deactivate_key(self, params: DeactivateKeyParams) -> DeactivateKeyResponse:
|
|
56
|
+
"""
|
|
57
|
+
Deactivates a device from a license key.
|
|
58
|
+
:param params: Parameters for deactivating the key.
|
|
59
|
+
:returns: The deactivation confirmation.
|
|
60
|
+
"""
|
|
61
|
+
return self._handle_request('/deactivate-key', params)
|
|
62
|
+
|
|
63
|
+
def get_key(self, params: GetKeyParams) -> GetKeyResponse:
|
|
64
|
+
"""
|
|
65
|
+
Retrieves detailed information about a specific license key.
|
|
66
|
+
:param params: Parameters for fetching the key details.
|
|
67
|
+
:returns: The license key details.
|
|
68
|
+
"""
|
|
69
|
+
return self._handle_request('/get-key', params)
|
|
70
|
+
|
|
71
|
+
def block_key(self, params: BlockKeyParams) -> BlockKeyResponse:
|
|
72
|
+
"""
|
|
73
|
+
Blocks a specific license key.
|
|
74
|
+
:param params: Parameters for blocking the key.
|
|
75
|
+
:returns: The block confirmation.
|
|
76
|
+
"""
|
|
77
|
+
return self._handle_request('/block-key', params)
|
|
78
|
+
|
|
79
|
+
def unblock_key(self, params: UnblockKeyParams) -> UnblockKeyResponse:
|
|
80
|
+
"""
|
|
81
|
+
Unblocks a previously blocked license key.
|
|
82
|
+
:param params: Parameters for unblocking the key.
|
|
83
|
+
:returns: The unblock confirmation.
|
|
84
|
+
"""
|
|
85
|
+
return self._handle_request('/unblock-key', params)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from typing import TypedDict, Optional, List, Dict, Any
|
|
2
|
+
|
|
3
|
+
class NewCustomer(TypedDict):
|
|
4
|
+
name: str
|
|
5
|
+
email: Optional[str]
|
|
6
|
+
|
|
7
|
+
class CreateKeyParams(TypedDict):
|
|
8
|
+
productId: str
|
|
9
|
+
maxActivations: Optional[str]
|
|
10
|
+
expiryDate: Optional[str]
|
|
11
|
+
customerId: Optional[str]
|
|
12
|
+
newCustomer: Optional[NewCustomer]
|
|
13
|
+
|
|
14
|
+
class CreateKeyResponse(TypedDict):
|
|
15
|
+
code: int
|
|
16
|
+
key: str
|
|
17
|
+
|
|
18
|
+
class KeyMintApiError(Exception):
|
|
19
|
+
def __init__(self, message: str, code: int, status: Optional[int] = None):
|
|
20
|
+
super().__init__(message)
|
|
21
|
+
self.message = message
|
|
22
|
+
self.code = code
|
|
23
|
+
self.status = status
|
|
24
|
+
|
|
25
|
+
class ActivateKeyParams(TypedDict):
|
|
26
|
+
productId: str
|
|
27
|
+
licenseKey: str
|
|
28
|
+
hostId: Optional[str]
|
|
29
|
+
deviceTag: Optional[str]
|
|
30
|
+
|
|
31
|
+
class ActivateKeyResponse(TypedDict):
|
|
32
|
+
code: int
|
|
33
|
+
message: str
|
|
34
|
+
licensee_name: Optional[str]
|
|
35
|
+
licensee_email: Optional[str]
|
|
36
|
+
|
|
37
|
+
class DeactivateKeyParams(TypedDict):
|
|
38
|
+
productId: str
|
|
39
|
+
licenseKey: str
|
|
40
|
+
hostId: Optional[str]
|
|
41
|
+
|
|
42
|
+
class DeactivateKeyResponse(TypedDict):
|
|
43
|
+
message: str
|
|
44
|
+
code: int
|
|
45
|
+
|
|
46
|
+
class DeviceDetails(TypedDict):
|
|
47
|
+
host_id: str
|
|
48
|
+
device_tag: Optional[str]
|
|
49
|
+
ip_address: Optional[str]
|
|
50
|
+
activation_time: str
|
|
51
|
+
|
|
52
|
+
class LicenseDetails(TypedDict):
|
|
53
|
+
id: str
|
|
54
|
+
key: str
|
|
55
|
+
product_id: str
|
|
56
|
+
max_activations: int
|
|
57
|
+
activations: int
|
|
58
|
+
devices: List[DeviceDetails]
|
|
59
|
+
activated: bool
|
|
60
|
+
expiration_date: Optional[str]
|
|
61
|
+
|
|
62
|
+
class CustomerDetails(TypedDict):
|
|
63
|
+
id: str
|
|
64
|
+
name: Optional[str]
|
|
65
|
+
email: Optional[str]
|
|
66
|
+
active: bool
|
|
67
|
+
|
|
68
|
+
class GetKeyParams(TypedDict):
|
|
69
|
+
productId: str
|
|
70
|
+
licenseKey: str
|
|
71
|
+
|
|
72
|
+
class GetKeyResponse(TypedDict):
|
|
73
|
+
code: int
|
|
74
|
+
data: Dict[str, Any]
|
|
75
|
+
|
|
76
|
+
class BlockKeyParams(TypedDict):
|
|
77
|
+
productId: str
|
|
78
|
+
licenseKey: str
|
|
79
|
+
|
|
80
|
+
class BlockKeyResponse(TypedDict):
|
|
81
|
+
message: str
|
|
82
|
+
code: int
|
|
83
|
+
|
|
84
|
+
class UnblockKeyParams(TypedDict):
|
|
85
|
+
productId: str
|
|
86
|
+
licenseKey: str
|
|
87
|
+
|
|
88
|
+
class UnblockKeyResponse(TypedDict):
|
|
89
|
+
message: str
|
|
90
|
+
code: int
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: keymint
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python SDK for the KeyMint API.
|
|
5
|
+
Home-page: https://github.com/keymint-dev/keymint-python
|
|
6
|
+
Author: Keymint
|
|
7
|
+
Author-email: admin@keymint.dev
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: requires-dist
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# KeyMint Python SDK
|
|
25
|
+
|
|
26
|
+
Welcome to the official KeyMint SDK for Python! This library provides a simple and convenient way to interact with the KeyMint API, allowing you to manage license keys for your applications with ease.
|
|
27
|
+
|
|
28
|
+
## ✨ Features
|
|
29
|
+
|
|
30
|
+
* **Simple & Intuitive**: A clean and modern API that is easy to learn and use.
|
|
31
|
+
* **Type Hinting**: Uses Python's type hinting for a better developer experience.
|
|
32
|
+
* **Comprehensive**: Covers all the essential KeyMint API endpoints.
|
|
33
|
+
* **Well-Documented**: Clear and concise documentation with plenty of examples.
|
|
34
|
+
* **Error Handling**: Standardized error handling to make debugging a breeze.
|
|
35
|
+
|
|
36
|
+
## 🚀 Quick Start
|
|
37
|
+
|
|
38
|
+
Here's a complete example of how to use the SDK to create and activate a license key:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import os
|
|
42
|
+
from keymint import KeyMintSDK
|
|
43
|
+
|
|
44
|
+
def main():
|
|
45
|
+
access_token = os.environ.get('KEYMINT_ACCESS_TOKEN')
|
|
46
|
+
if not access_token:
|
|
47
|
+
print('Please set the KEYMINT_ACCESS_TOKEN environment variable.')
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
sdk = KeyMintSDK(access_token)
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# 1. Create a new license key
|
|
54
|
+
create_response = sdk.create_key({
|
|
55
|
+
'productId': 'YOUR_PRODUCT_ID',
|
|
56
|
+
})
|
|
57
|
+
license_key = create_response['key']
|
|
58
|
+
print(f'Key created: {license_key}')
|
|
59
|
+
|
|
60
|
+
# 2. Activate the license key
|
|
61
|
+
activate_response = sdk.activate_key({
|
|
62
|
+
'productId': 'YOUR_PRODUCT_ID',
|
|
63
|
+
'licenseKey': license_key,
|
|
64
|
+
'hostId': 'UNIQUE_DEVICE_ID',
|
|
65
|
+
})
|
|
66
|
+
print(f"Key activated: {activate_response['message']}")
|
|
67
|
+
except Exception as e:
|
|
68
|
+
print(f'An error occurred: {e}')
|
|
69
|
+
|
|
70
|
+
if __name__ == '__main__':
|
|
71
|
+
main()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 📦 Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install keymint
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 🛠️ Usage
|
|
81
|
+
|
|
82
|
+
### Initialization
|
|
83
|
+
|
|
84
|
+
First, import the `KeyMintSDK` and initialize it with your access token. You can find your access token in your [KeyMint dashboard](https://keymint.dev/app/settings/api).
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from keymint import KeyMintSDK
|
|
88
|
+
|
|
89
|
+
access_token = 'YOUR_ACCESS_TOKEN'
|
|
90
|
+
sdk = KeyMintSDK(access_token)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### API Methods
|
|
94
|
+
|
|
95
|
+
All methods return a dictionary.
|
|
96
|
+
|
|
97
|
+
| Method | Description |
|
|
98
|
+
| --------------- | ----------------------------------------------- |
|
|
99
|
+
| `create_key` | Creates a new license key. |
|
|
100
|
+
| `activate_key` | Activates a license key for a device. |
|
|
101
|
+
| `deactivate_key`| Deactivates a device from a license key. |
|
|
102
|
+
| `get_key` | Retrieves detailed information about a key. |
|
|
103
|
+
| `block_key` | Blocks a license key. |
|
|
104
|
+
| `unblock_key` | Unblocks a previously blocked license key. |
|
|
105
|
+
|
|
106
|
+
For more detailed information about the API methods and their parameters, please refer to the [API Reference](#api-reference) section below.
|
|
107
|
+
|
|
108
|
+
## 🚨 Error Handling
|
|
109
|
+
|
|
110
|
+
If an API call fails, the SDK will raise a `KeyMintApiError` exception. This object contains a `message`, `code`, and `status` attribute that you can use to handle the error.
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from keymint import KeyMintApiError
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
# ...
|
|
117
|
+
except KeyMintApiError as e:
|
|
118
|
+
print(f'API Error: {e.message}')
|
|
119
|
+
print(f'Status: {e.status}')
|
|
120
|
+
print(f'Code: {e.code}')
|
|
121
|
+
except Exception as e:
|
|
122
|
+
print(f'An unexpected error occurred: {e}')
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 📚 API Reference
|
|
126
|
+
|
|
127
|
+
### `KeyMintSDK(access_token, base_url)`
|
|
128
|
+
|
|
129
|
+
| Parameter | Type | Description |
|
|
130
|
+
| -------------- | -------- | --------------------------------------------------------------------------- |
|
|
131
|
+
| `access_token` | `str` | **Required.** Your KeyMint API access token. |
|
|
132
|
+
| `base_url` | `str` | *Optional.* The base URL for the KeyMint API. Defaults to `https://api.keymint.dev`. |
|
|
133
|
+
|
|
134
|
+
### `create_key(params)`
|
|
135
|
+
|
|
136
|
+
| Parameter | Type | Description |
|
|
137
|
+
| ---------------- | -------- | --------------------------------------------------------------------------- |
|
|
138
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
139
|
+
| `maxActivations` | `str` | *Optional.* The maximum number of activations for the key. |
|
|
140
|
+
| `expiryDate` | `str` | *Optional.* The expiration date of the key in ISO 8601 format. |
|
|
141
|
+
| `customerId` | `str` | *Optional.* The ID of an existing customer to associate with the key. |
|
|
142
|
+
| `newCustomer` | `dict` | *Optional.* A dictionary containing the name and email of a new customer. |
|
|
143
|
+
|
|
144
|
+
### `activate_key(params)`
|
|
145
|
+
|
|
146
|
+
| Parameter | Type | Description |
|
|
147
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
148
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
149
|
+
| `licenseKey` | `str` | **Required.** The license key to activate. |
|
|
150
|
+
| `hostId` | `str` | *Optional.* A unique identifier for the device. |
|
|
151
|
+
| `deviceTag` | `str` | *Optional.* A user-friendly name for the device. |
|
|
152
|
+
|
|
153
|
+
### `deactivate_key(params)`
|
|
154
|
+
|
|
155
|
+
| Parameter | Type | Description |
|
|
156
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
157
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
158
|
+
| `licenseKey` | `str` | **Required.** The license key to deactivate. |
|
|
159
|
+
| `hostId` | `str` | *Optional.* The ID of the device to deactivate. If omitted, all devices are deactivated. |
|
|
160
|
+
|
|
161
|
+
### `get_key(params)`
|
|
162
|
+
|
|
163
|
+
| Parameter | Type | Description |
|
|
164
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
165
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
166
|
+
| `licenseKey` | `str` | **Required.** The license key to retrieve. |
|
|
167
|
+
|
|
168
|
+
### `block_key(params)`
|
|
169
|
+
|
|
170
|
+
| Parameter | Type | Description |
|
|
171
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
172
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
173
|
+
| `licenseKey` | `str` | **Required.** The license key to block. |
|
|
174
|
+
|
|
175
|
+
### `unblock_key(params)`
|
|
176
|
+
|
|
177
|
+
| Parameter | Type | Description |
|
|
178
|
+
| ------------ | -------- | --------------------------------------------------------------------------- |
|
|
179
|
+
| `productId` | `str` | **Required.** The ID of the product. |
|
|
180
|
+
| `licenseKey` | `str` | **Required.** The license key to unblock. |
|
|
181
|
+
|
|
182
|
+
## 📜 License
|
|
183
|
+
|
|
184
|
+
This SDK is licensed under the MIT License.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
keymint
|
keymint-0.1.0/setup.cfg
ADDED
keymint-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="keymint",
|
|
8
|
+
version="0.1.0",
|
|
9
|
+
author="Keymint",
|
|
10
|
+
author_email="admin@keymint.dev",
|
|
11
|
+
description="A Python SDK for the KeyMint API.",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/keymint-dev/keymint-python",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
],
|
|
21
|
+
python_requires='>=3.6',
|
|
22
|
+
install_requires=[
|
|
23
|
+
'requests',
|
|
24
|
+
],
|
|
25
|
+
)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import patch, MagicMock
|
|
3
|
+
import requests
|
|
4
|
+
from keymint import KeyMintSDK, KeyMintApiError
|
|
5
|
+
from keymint.types import *
|
|
6
|
+
|
|
7
|
+
class TestKeyMintSDK(unittest.TestCase):
|
|
8
|
+
|
|
9
|
+
def setUp(self):
|
|
10
|
+
self.sdk = KeyMintSDK(access_token="test_token")
|
|
11
|
+
|
|
12
|
+
@patch('requests.post')
|
|
13
|
+
def test_create_key_success(self, mock_post):
|
|
14
|
+
mock_response = MagicMock()
|
|
15
|
+
mock_response.json.return_value = {'code': 0, 'key': 'test_key'}
|
|
16
|
+
mock_response.raise_for_status = MagicMock()
|
|
17
|
+
mock_post.return_value = mock_response
|
|
18
|
+
|
|
19
|
+
params: CreateKeyParams = {'productId': 'prod_123'}
|
|
20
|
+
response = self.sdk.create_key(params)
|
|
21
|
+
|
|
22
|
+
self.assertEqual(response['key'], 'test_key')
|
|
23
|
+
mock_post.assert_called_once()
|
|
24
|
+
|
|
25
|
+
@patch('requests.post')
|
|
26
|
+
def test_create_key_failure(self, mock_post):
|
|
27
|
+
mock_response = MagicMock()
|
|
28
|
+
mock_response.json.return_value = {'message': 'Error', 'code': 1}
|
|
29
|
+
mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError(response=mock_response)
|
|
30
|
+
mock_post.return_value = mock_response
|
|
31
|
+
|
|
32
|
+
params: CreateKeyParams = {'productId': 'prod_123'}
|
|
33
|
+
with self.assertRaises(KeyMintApiError) as context:
|
|
34
|
+
self.sdk.create_key(params)
|
|
35
|
+
|
|
36
|
+
self.assertEqual(context.exception.code, 1)
|
|
37
|
+
|
|
38
|
+
@patch('requests.post')
|
|
39
|
+
def test_activate_key_success(self, mock_post):
|
|
40
|
+
mock_response = MagicMock()
|
|
41
|
+
mock_response.json.return_value = {'code': 0, 'message': 'activated'}
|
|
42
|
+
mock_response.raise_for_status = MagicMock()
|
|
43
|
+
mock_post.return_value = mock_response
|
|
44
|
+
|
|
45
|
+
params: ActivateKeyParams = {'productId': 'prod_123', 'licenseKey': 'key_123'}
|
|
46
|
+
response = self.sdk.activate_key(params)
|
|
47
|
+
|
|
48
|
+
self.assertEqual(response['message'], 'activated')
|
|
49
|
+
mock_post.assert_called_once()
|
|
50
|
+
|
|
51
|
+
@patch('requests.post')
|
|
52
|
+
def test_deactivate_key_success(self, mock_post):
|
|
53
|
+
mock_response = MagicMock()
|
|
54
|
+
mock_response.json.return_value = {'code': 0, 'message': 'deactivated'}
|
|
55
|
+
mock_response.raise_for_status = MagicMock()
|
|
56
|
+
mock_post.return_value = mock_response
|
|
57
|
+
|
|
58
|
+
params: DeactivateKeyParams = {'productId': 'prod_123', 'licenseKey': 'key_123'}
|
|
59
|
+
response = self.sdk.deactivate_key(params)
|
|
60
|
+
|
|
61
|
+
self.assertEqual(response['message'], 'deactivated')
|
|
62
|
+
mock_post.assert_called_once()
|
|
63
|
+
|
|
64
|
+
@patch('requests.post')
|
|
65
|
+
def test_get_key_success(self, mock_post):
|
|
66
|
+
mock_response = MagicMock()
|
|
67
|
+
mock_response.json.return_value = {'code': 0, 'data': {'license': {}}}
|
|
68
|
+
mock_response.raise_for_status = MagicMock()
|
|
69
|
+
mock_post.return_value = mock_response
|
|
70
|
+
|
|
71
|
+
params: GetKeyParams = {'productId': 'prod_123', 'licenseKey': 'key_123'}
|
|
72
|
+
response = self.sdk.get_key(params)
|
|
73
|
+
|
|
74
|
+
self.assertIn('license', response['data'])
|
|
75
|
+
mock_post.assert_called_once()
|
|
76
|
+
|
|
77
|
+
@patch('requests.post')
|
|
78
|
+
def test_block_key_success(self, mock_post):
|
|
79
|
+
mock_response = MagicMock()
|
|
80
|
+
mock_response.json.return_value = {'code': 0, 'message': 'blocked'}
|
|
81
|
+
mock_response.raise_for_status = MagicMock()
|
|
82
|
+
mock_post.return_value = mock_response
|
|
83
|
+
|
|
84
|
+
params: BlockKeyParams = {'productId': 'prod_123', 'licenseKey': 'key_123'}
|
|
85
|
+
response = self.sdk.block_key(params)
|
|
86
|
+
|
|
87
|
+
self.assertEqual(response['message'], 'blocked')
|
|
88
|
+
mock_post.assert_called_once()
|
|
89
|
+
|
|
90
|
+
@patch('requests.post')
|
|
91
|
+
def test_unblock_key_success(self, mock_post):
|
|
92
|
+
mock_response = MagicMock()
|
|
93
|
+
mock_response.json.return_value = {'code': 0, 'message': 'unblocked'}
|
|
94
|
+
mock_response.raise_for_status = MagicMock()
|
|
95
|
+
mock_post.return_value = mock_response
|
|
96
|
+
|
|
97
|
+
params: UnblockKeyParams = {'productId': 'prod_123', 'licenseKey': 'key_123'}
|
|
98
|
+
response = self.sdk.unblock_key(params)
|
|
99
|
+
|
|
100
|
+
self.assertEqual(response['message'], 'unblocked')
|
|
101
|
+
mock_post.assert_called_once()
|
|
102
|
+
|
|
103
|
+
if __name__ == '__main__':
|
|
104
|
+
unittest.main()
|