Metadata-Version: 2.2
Name: pyhwid-license
Version: 1.0.0
Summary: Hardware-locked (HWID) licensing management system supporting MySQL and MongoDB
Author: IbrahimBkt
License: MIT
Project-URL: Homepage, https://github.com/ibrahim12651/pyhwid_license
Project-URL: Bug Tracker, https://github.com/ibrahim12651/pyhwid_license/issues
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: pymysql>=1.0.0
Requires-Dist: pymongo>=4.0.0
Requires-Dist: cryptography>=36.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Dynamic: requires-python

# pyhwid-license

[![PyPI Version](https://img.shields.io/pypi/v/pyhwid-license.svg)](https://pypi.org/project/pyhwid-license/)
[![Supported Python Versions](https://img.shields.io/pypi/pyversions/pyhwid-license.svg)](https://img.shields.io/pypi/pyversions/pyhwid-license.)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/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:

```bash
pip install pyhwid-license
```

Or to install the package locally in developer/editable mode from the source directory:

```bash
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
```python
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
```python
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.

```python
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.

```python
# 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
```python
# 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.
