Skip to main content

Official Python SDK for SublimeKeys — license activation and verification with offline-capable signed leases

Project description

sublimekeys

Official Python SDK for SublimeKeys — license key generation, activation, verification and trials for indie desktop apps, with offline-capable verification: once a license is activated, your app can verify it locally in milliseconds with no network call, for up to 7 days at a time, before quietly re-syncing online.

pip install sublimekeys

Quickstart

This mirrors the lifecycle described in the SublimeKeys docs: first run activates, every later run verifies (offline-first), uninstall deactivates.

from sublimekeys import SublimeKeysClient

client = SublimeKeysClient(product_id="my-app")

# First run — ask the user for their key once.
result = client.activate(license_key=user_entered_key)
if result.valid:
    unlock_full_version()

# Every later launch — offline-first, instant, falls back online
# automatically once the cached lease's 7-day trust window lapses.
result = client.verify(license_key=saved_key)
if result.valid:
    unlock_full_version()
print(result.source)  # "offline_cache" most days, "online" roughly weekly

# Uninstall / sign out.
client.deactivate(license_key=saved_key)

client.get_machine_id() gives you a stable, locally-persisted identifier if you need to store it yourself — every method above also generates and caches one automatically the first time it's needed, so passing it explicitly is optional.

Trials

result = client.start_trial()       # get-or-create a 7-day trial; idempotent —
                                     # reinstalling never resets the clock
if result.status == "active":
    print(f"{result.days_left} days left")

result = client.trial_status()      # read-only check, never starts one

How offline verification works

When activate() or verify() succeeds, the server returns a lease — a small Ed25519-signed token proving "this license is valid for this machine, as of now." The SDK caches it locally and, on every later verify() call, checks the signature against a pinned public key built into this package — no network call, no dependency on the server being reachable.

The lease itself expires after 7 days (server-controlled). Once it does, the next verify() call transparently goes online, gets a fresh lease, and the cycle repeats. This means a revoked or expired license can take up to 7 days to be caught while a machine stays fully offline — an intentional tradeoff for instant, network-independent checks the rest of the time, not a bug.

API

Method What it does
activate(license_key, machine_id=None) First run. Always online.
verify(license_key, machine_id=None, allow_offline=True) Every later run. Offline-first by default.
deactivate(license_key, machine_id=None) Uninstall/sign-out. Frees the seat, clears the local cache.
start_trial(machine_id=None) Get-or-create a trial.
trial_status(machine_id=None) Read-only trial check.
get_machine_id() Stable per-install identifier (auto-generated, persisted locally).

All methods return a small dataclass (LicenseResult or TrialResult) — never raise for a normal "not valid" outcome. Network failures are caught internally too; verify() falls back to the offline cache or a valid=False, source="offline_cache_miss" result rather than raising.

Packaging with PyInstaller

cryptography's compiled backend is the kind of dependency that works fine under python app.py and only breaks in a frozen build. Before shipping:

  • pyinstaller-hooks-contrib ships an official hook-cryptography and is usually auto-discovered. If you hit ModuleNotFoundError: _cffi_backend, add --collect-all cryptography (or --hidden-import=_cffi_backend) to your PyInstaller command.
  • Test the frozen executable's activate()/verify() calls, not just the unfrozen dev script — this is the single highest-value check before shipping to real users.
  • On macOS, notarizing a PyInstaller bundle that includes OpenSSL/rust-openssl dylibs is a known extra step — sign all bundled dylibs and test the signed, notarized build specifically.

See examples/pyinstaller/ for a minimal buildable example.

License

MIT

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

sublimekeys-0.1.0.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

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

sublimekeys-0.1.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file sublimekeys-0.1.0.tar.gz.

File metadata

  • Download URL: sublimekeys-0.1.0.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sublimekeys-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8365d60e8fa6c336ba832eaa0a2c4abe730680ba33053f09668d0c311527bcfc
MD5 073df85d142bb3967b76c7193128d8d8
BLAKE2b-256 156d1e13ca00670f4d9df10d4f7fa5bcb0aad311309b80e4a6391a744d6d5080

See more details on using hashes here.

Provenance

The following attestation bundles were made for sublimekeys-0.1.0.tar.gz:

Publisher: publish.yml on Volume00/sublimekeys-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sublimekeys-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sublimekeys-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sublimekeys-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e4cb763c32d2d7e92fa137e7fc56318d3489ed7b103cc33425bb5c5558af835
MD5 c36f54885a37b41665e233cf01bb561a
BLAKE2b-256 aeac327bee94672fb6a18cee34317451c73dff64459c2bd52e169907a2fffe53

See more details on using hashes here.

Provenance

The following attestation bundles were made for sublimekeys-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Volume00/sublimekeys-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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