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.pyOpens 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/activatewith 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_Nx8K2mLpQ4rVtW9sBcOr create a .env file and load it with python-dotenv.
| Variable | Where to Find It |
|---|---|
KEYMINT_CLIENT_API_KEY | Keymint Dashboard → Developer → API Keys (client scope) |
KEYMINT_PRODUCT_ID | Keymint 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 dependenciesSDK Methods Used
| Method | Where | Purpose |
|---|---|---|
client.activate_key() | license_manager.py | Validate and bind license to machine |
client.deactivate_key() | license_manager.py | Free 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.pyThe client API key is bundled into the executable. It has client scope — safe for distribution.
Next Steps
- Add optional offline license support for air-gapped deployments
- Integrate with Stripe for subscription licensing
- Customize the activation dialog styling with your brand
- Add a trial mode using
expiryDateon trial license keys