Skip to main content

Client SDK for Licers — verify software license keys with tamper-proof, signed responses.

Project description

pylicensify

Client SDK for Licers — verify software license keys with tamper-proof, signed responses. A cracked "fake server" can't grant access, because every response is verified against your public key.

pip install pylicensify

Brand vs. endpoint: Licers lives at licers.com (dashboard, docs, account). The SDK talks to the validation API at https://license.pyobfuscate.com by default — a stable, long-lived host your shipped apps rely on. Override it only for self-hosting (see below).

Quick start

Get your public key from the Licers dashboardIntegration page (safe to embed in your distributed app; the private key never leaves the server).

from pylicensify import LicenseClient

client = LicenseClient(public_key="YOUR_PUBLIC_KEY")

result = client.validate("PY-XXXXXXXXXXXXXXXX")
if result:
    print("Licensed. Entitlements:", result.features)
    if result.feature("pro"):
        enable_pro_features()
else:
    print("Not licensed:", result.error)
    raise SystemExit(1)

validate() sends a nonce, verifies the Ed25519 signature, and rejects stale / replayed responses automatically. It raises SignatureError on tampering and NetworkError if the server is unreachable.

Feature gating

result = client.validate(key)
seats = result.feature("seats", 1)
if result.feature("pro"):
    ...

Offline license files (air-gapped)

Issue a signed .lic file from a license row in the dashboard, ship it with the app, and verify it locally with zero network calls:

from pylicensify import verify_offline_license

data = verify_offline_license("YOUR_PUBLIC_KEY", "license.lic")
print("Valid for:", data.get("customer"), data.get("features"))

Checks signature, expiry, device binding, and OS lock.

Floating / concurrent licenses

For keys with a concurrent-session limit — the SDK checks out a seat, heartbeats in the background, and releases on exit:

from pylicensify import LicenseClient, SeatUnavailable

client = LicenseClient(public_key="YOUR_PUBLIC_KEY")
try:
    with client.session("PY-XXXX...") as sess:
        print("Seat acquired:", sess.seats)   # {'used': 1, 'max': 5}
        run_app()                              # released automatically on exit
except SeatUnavailable:
    print("All seats are in use — try again later.")

Update checks

info = client.check_update("PY-XXXX...", current_version="1.0.0")
if info["update_available"]:
    print("New version:", info["version"], info["notes"])
    # info["download_url"] is a license-gated download link

Self-hosted / custom domain

By default the SDK calls the managed cloud API at https://license.pyobfuscate.com (your account and dashboard live at licers.com). To target a self-hosted deployment, pass api_url:

client = LicenseClient(public_key="...", api_url="https://license.yourdomain.com")

Hardware ID

By default the SDK derives a machine id from uuid.getnode(). Pass your own for a stronger fingerprint:

client.validate(key, hwid=my_custom_fingerprint())

Errors

Exception Meaning
InvalidLicense Server rejected the key (invalid/expired/revoked/blocked)
SignatureError Signature/nonce/timestamp failed — forged or replayed
NetworkError Couldn't reach the license server
SeatUnavailable Floating license has no free seats

All inherit from LicenseError.

Hardening

Obfuscate your client so the check itself can't be trivially patched out — e.g. with PyObfuscate.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pylicensify-1.0.1.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pylicensify-1.0.1-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file pylicensify-1.0.1.tar.gz.

File metadata

  • Download URL: pylicensify-1.0.1.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for pylicensify-1.0.1.tar.gz
Algorithm Hash digest
SHA256 b3dbf1d51640fe1e6fc10a98282021df89fe41c83f6ea0a0e8379f12f90f87d9
MD5 9b3f9993e2f9fe70c56275a6cfa20c57
BLAKE2b-256 b4bdb0705fb7b9e96a70f37a086b8840d62ce0444d666ad6fb25645b341cb34f

See more details on using hashes here.

File details

Details for the file pylicensify-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pylicensify-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for pylicensify-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 766ab32e2bae7d31163a047439ee469d6b63e8ee4e924a91685907d14d6d068a
MD5 7bc44ec4d63d502a79c911e9d893267f
BLAKE2b-256 db58921e7a655cb0c709b57c85c640833904832cf744834baf0a3538776f5300

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page