Quick Start

From zero to a licensed Python app in about five minutes.

1 · Install

pip install py-rizmi          # core (validation + issuance + CLI)
pip install py-rizmi[gui]     # optional PyQt6 desktop toolkit

2 · Scaffold your product

rizmi init MyApp --out ./licensing

This generates private_key.pem + public_key.pem, prints the public key's SHA-256 fingerprint, and emits a paste-ready LicenseGate snippet with everything filled in.

Keep private_key.pem on your issuing machine. Only the public key ever ships inside your app.

3 · Paste the snippet into your app

from py_rizmi import LicenseGate, pin_fingerprint

VENDOR_PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
...from rizmi init...
-----END PUBLIC KEY-----"""
VENDOR_KEY_FINGERPRINT = "abc123..."   # from rizmi init

pin_fingerprint(VENDOR_PUBLIC_KEY, VENDOR_KEY_FINGERPRINT)  # startup gate

gate = LicenseGate(
    app_name="MyApp",
    public_key=VENDOR_PUBLIC_KEY,
    expected_fingerprint=VENDOR_KEY_FINGERPRINT,
    config_dir="~/.config/MyApp",
)

status = gate.start()   # first run starts a 14-day trial automatically
if not status:
    print(status.message)
    raise SystemExit(1)

4 · Issue a license for a customer's machine

# on the customer machine:
rizmi machine-id --raw
# → fb50b7767d233a9e… (they send you this hash)

# on your machine:
rizmi license issue \
  --private-key licensing/private_key.pem \
  --client "Acme Corp" --license-id deploy-001 \
  --hwid <their-hash> --exp-days 365 -o acme.lic

5 · Customer activates in your app

Either paste the token into your UI:

result = gate.activate_token(pasted_text)
if result.ok:
    print(f"Licensed to {result.payload.client}")

…or pick the file:

result = gate.activate_file("acme.lic")

Both run the full validation chain (signature → expiry → HWID → revocation → clock) before anything is stored. Invalid licenses are never written.

6 · Compile and ship

nuitka --standalone --onefile --include-package=py_rizmi main.py

See Packaging for Nuitka/PyInstaller specifics.

When something breaks

rizmi doctor --app-name MyApp

prints a ✓/✗ checklist of every subsystem. Ask customers to run it and send the output — see Troubleshooting.