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.