Skip to main content

pyhwid-license

PyPI Version Supported Python Versions License: MIT

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 (using PyMongo). 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-naive vs offset-aware comparison 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.

Metadata

Release files for pyhwid-license 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for pyhwid-license 1.0.0
File Interpreter ABI Platform
pyhwid_license-1.0.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details

Release files / pyhwid_license-1.0.0-cp313-cp313-win_amd64.whl

Download URL pyhwid_license-1.0.0-cp313-cp313-win_amd64.whl
Size 547.2 kB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
509e638a86d07f9c8c4d8c1cc91d94c617c11d0d1c697c9cd417c7636abce15d
BLAKE2b-256 checksum
How to use checksums
794d808291c72a657587eca799611ecc96da3b7c73a7274954767894b575f9c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.1

Security for pyhwid-license 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.0.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page