Hardware-locked (HWID) licensing management system supporting MySQL and MongoDB
Project description
pyhwid-license
A secure, hardware-locked (HWID) licensing management system for Python applications. It features native, automated support for both MySQL and MongoDB databases, timezone-aware expiration checks, and license status toggling.
Key Features
- 🔐 Cross-Platform HWID Locking: Generates a secure, stable, and unique Hardware ID (HWID) based on machine characteristics (works on Windows, Linux, and macOS).
- 🗄️ Dual Database Support: Fully automated integration with MySQL/MariaDB (using
PyMySQL) and MongoDB (usingPyMongo). Databases, tables, collections, and unique indexes are created automatically on connect. - 🕒 Timezone-Aware Expiration: Automatically handles and compares all datetime records using timezone-aware UTC format to avoid
offset-naivevsoffset-awarecomparison exceptions. - 🛠️ Full License Lifecycle Actions: Easily create, validate, update, extend (+30 days, etc.), suspend/unsuspend, and delete licenses.
Installation
To install the package directly from PyPI:
pip install pyhwid-license
Or to install the package locally in developer/editable mode from the source directory:
pip install -e .
Quick Start Guide
1. Initializing LicenseManager
The LicenseManager is the primary entry point for managing licenses. It automatically creates the necessary database schema or collection indexes upon connection.
MySQL Connection
from pyhwid_license import LicenseManager
# Config dict matching pymysql.connect parameters
mysql_config = {
"host": "localhost",
"user": "root",
"password": "your_secure_password",
"database": "my_app_licenses",
"port": 3306
}
manager = LicenseManager(db_type="mysql", **mysql_config)
MongoDB Connection
from pyhwid_license import LicenseManager
manager = LicenseManager(
db_type="mongodb",
uri="mongodb://localhost:27017/",
database="my_app_licenses"
)
2. Basic Operations
Create a License Key
You can specify the maximum number of hardware bindings (max_hwids), validity duration, and client details.
res = manager.create_license(
client_name="John Doe",
client_email="john@example.com",
max_hwids=2, # Can be validated on up to 2 distinct machines
duration_days=30, # Expiration limit (Optional)
prefix="APP", # License key prefix (Optional, defaults to "LIC")
notes="Pro Plan Client"
)
if res["success"]:
license_data = res["license"]
print(f"Generated Key: {license_data['license_key']}")
Validate a License Key
When validating, the system reads the machine's HWID and binds it to the license automatically if there are open slots.
# Typically run inside your distributed client application
validation = manager.validate_license("APP-A93C-ML1L-NDOJ-784M", check_hwid=True)
if validation["status"] == "valid":
print("License is active and valid!")
print(f"Bound HWIDs: {validation['license']['used_hwids']}")
elif validation["status"] == "expired":
print("This license has expired.")
elif validation["status"] == "suspended":
print("This license was suspended by the administrator.")
elif validation["status"] == "hwid_limit_reached":
print("The maximum number of devices has been reached for this key.")
else:
print(f"Validation failed: {validation['message']}")
Manage and Update Licenses
# Suspend a license key
manager.update_license("LIC-KEY", {"status": "suspended"})
# Reset all bound Hardware IDs for a license (e.g., if client buys a new PC)
manager.reset_hwids("LIC-KEY")
# Extend expiration date by 30 days
from datetime import datetime, timezone, timedelta
lic = manager.get_license("LIC-KEY")
if lic["expires_at"]:
new_expiry = lic["expires_at"] + timedelta(days=30)
manager.update_license("LIC-KEY", {"expires_at": new_expiry, "status": "active"})
# Delete license
manager.delete_license("LIC-KEY")
API Reference
LicenseManager(db_type: Optional[str], db_instance: Optional[Any], **db_config)
Initializes database connections.
db_type:"mysql"or"mongodb".db_instance: Custom mock database adapter (useful for testing).**db_config: Connection settings matching the chosen database type.
create_license(client_name, client_email, max_hwids=1, duration_days=None, notes="", custom_key=None, prefix="LIC") -> dict
Creates a new license entry in the database.
validate_license(license_key, check_hwid=True, custom_hwid=None) -> dict
Performs status, expiration, and HWID validation. Returns a dictionary containing status ("valid", "expired", "suspended", "hwid_limit_reached", "invalid") and message.
list_licenses() -> list
Returns a list of all registered license records.
update_license(license_key, update_data) -> bool
Updates license attributes in the database.
delete_license(license_key) -> bool
Deletes a license record from the database.
reset_hwids(license_key) -> bool
Clears the list of registered HWIDs for the license.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyhwid_license-1.0.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: pyhwid_license-1.0.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 547.2 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
509e638a86d07f9c8c4d8c1cc91d94c617c11d0d1c697c9cd417c7636abce15d
|
|
| MD5 |
fe097e351cca023e9eed4f36ba43a99f
|
|
| BLAKE2b-256 |
794d808291c72a657587eca799611ecc96da3b7c73a7274954767894b575f9c5
|