Skip to content

Commit c6eb1b4

Browse files
committed
Add KeyMint SDK implementation with API methods and error handling
0 parents  commit c6eb1b4

File tree

5 files changed

+465
-0
lines changed

5 files changed

+465
-0
lines changed

README.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.

keymint/__init__.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

keymint/types.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

setup.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 commit comments

Comments
 (0)