PyQt License Starter

Clone-and-run PyQt6 desktop app with Keymint license activation pre-configured. Activation dialog, machine binding, and deactivation support included.

Quick Start

bash
git clone https://github.com/keymint-dev/keymint-pyqt-starter.git
cd keymint-pyqt-starter
pip install -r requirements.txt
cp .env.example .env
python main.py

Opens a PyQt6 window with an activation dialog. Enter a valid Keymint license key, and the main window appears.

What's Included

  • License activation — calls POST /key/activate with cross-platform machine fingerprint
  • Activation dialog — PyQt6 dialog with key entry, status feedback, pre-fill from stored key
  • Persistent storage — license key and activation state saved via QSettings
  • Deactivation — frees activation seat from preferences menu
  • Cross-platform host ID — works on Windows, macOS, and Linux

Configuration

Set environment variables:

bash
export KEYMINT_CLIENT_API_KEY=km_client_your_key
export KEYMINT_PRODUCT_ID=prod_Nx8K2mLpQ4rVtW9sBc

Or create a .env file and load it with python-dotenv.

VariableWhere to Find It
KEYMINT_CLIENT_API_KEYKeymint Dashboard → Developer → API Keys (client scope)
KEYMINT_PRODUCT_IDKeymint Dashboard → Products

Project Structure

text
├── main.py                 # Entry point, gates app on license check
├── license_manager.py      # Keymint Python SDK wrapper
├── activation_dialog.py    # PyQt6 activation UI
├── main_window.py          # Main app (shown after activation)
├── preferences_dialog.py   # Settings with deactivation button
└── requirements.txt        # Python dependencies

SDK Methods Used

MethodWherePurpose
client.activate_key()license_manager.pyValidate and bind license to machine
client.deactivate_key()license_manager.pyFree activation seat

Host ID Strategy

python
def get_host_id() -> str:
    """Cross-platform stable machine fingerprint."""
    system = platform.system()
    if system == "Windows":
        # WMIC UUID
        output = subprocess.check_output("wmic csproduct get uuid", shell=True)
        raw = output.decode().split("\n")[1].strip()
    elif system == "Darwin":
        # IOPlatformUUID
        output = subprocess.check_output(
            "ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID", shell=True
        )
        raw = output.decode().split('"')[-2]
    else:
        # /etc/machine-id
        with open("/etc/machine-id") as f:
            raw = f.read().strip()
    return hashlib.sha256(raw.encode()).hexdigest()[:16]

Build & Package

bash
# Single-file executable
pyinstaller --onefile --hidden-import=keymint main.py

# macOS .app bundle
pyinstaller --windowed --hidden-import=keymint main.py

The client API key is bundled into the executable. It has client scope — safe for distribution.

Next Steps