Distributing to a Client Without Exposing IP
Goal: let a client install the package and exercise every feature, while keeping your intellectual property protected.
What is and isn’t already protected
Section titled “What is and isn’t already protected”| Component | Where the IP lives | Default exposure |
|---|---|---|
| Storage engine (TPI/FMI/WAL/PSI, parser) | hypermesh_core/*.c | Compiled to a .so in the wheel. C source is only in the sdist. |
| Python SDK layer (analytics algorithms, query orchestration, ingest strategies, connectors) | hypermesh*/**.py | Readable .py in a normal wheel. |
So the engine — your crown jewel — is already shipped as a compiled binary. Two rules follow immediately:
- Ship wheels, never the sdist. The sdist contains the C source.
- Decide how hard to protect the Python layer (options below).
Protection tiers for the Python layer
Section titled “Protection tiers for the Python layer”| Tier | How | Protection | Effort | Client can run locally? |
|---|---|---|---|---|
| 0. Source wheel + EULA | normal wheel | Legal only (readable .py) | none | ✅ |
| 1. Bytecode-only wheel | strip .py, ship .pyc | Deters casual copying (decompilable) | low (tooling included) | ✅ |
| 2. Native-compiled Python | Cython/Nuitka the sensitive modules → .so | Strong | medium–high | ✅ |
| 3. Hosted evaluation | client uses the remote Client; engine stays on your server | Strongest (no code shipped) | medium (host it) | ❌ (remote only) |
Recommendation for a client eval: Tier 1 (bytecode-only) + an evaluation
license + the EULA, and Tier 3 (hosted) if the client must never hold the
engine. Move to Tier 2 for the few modules with real algorithmic IP
(_analytics.py, ingest strategies) when you go to a paid deployment.
Build a client evaluation package (Tier 1)
Section titled “Build a client evaluation package (Tier 1)”One command produces an IP-safe handoff — bytecode-only wheels, the EULA, and
install instructions, with no sdist and no .py:
# From CI cibuildwheel output (preferred: manylinux x86_64 + aarch64):WHEELHOUSE=./wheelhouse ./tools/build_client_eval.sh
# Or a quick single-platform build:./tools/build_client_eval.sh# → hypermesh-eval/ and hypermesh-eval.tar.gzUnder the hood it calls tools/make_sourceless_wheel.py,
which compiles each .py to a sourceless .pyc, removes the source, and
regenerates the wheel RECORD. The compiled engine .so is left intact.
The client installs offline:
python3.11 -m venv venv && . venv/bin/activatepip install --no-index --find-links ./hypermesh-eval "hypermesh[engine]"python -c "import hypermesh as hm; print(hm.__version__)"They can then exercise the entire Python Manual — every query, analytics measure, ingestion path, and connector — with no readable source and the engine as an opaque binary.
Adding an evaluation time-limit
Section titled “Adding an evaluation time-limit”To bound an eval, pair the package with an expiring license:
- Issue a signed license token (client id + expiry + enabled features).
- Verify it at startup; refuse to open a database after expiry.
Because a pure-Python check can be edited out of readable/bytecode code, put the enforcement where it can’t easily be removed:
- Best: in the C engine (the
.so) — verified onopen(). - Good: in a Cython-compiled Python module (Tier 2).
- Deterrent only: plain Python (fine alongside a EULA for trusted evals).
We can wire any of these on request.
Hosted evaluation (Tier 3)
Section titled “Hosted evaluation (Tier 3)”Give the client only the thin remote client (hypermesh-client, ~21 KB, no
engine and no proprietary code); you run the engine:
import hypermesh as hmdb = hm.connect("https://eval.hypermesh.yourco.com", api_key="<eval-key>")Build the thin client with ./tools/build_thin_client.sh, deploy the server
with deploy/docker-compose.eval.yml, and mint scoped, revocable keys with
hmdb add-key. The client gets the full API surface; the engine and all data
processing never leave your infrastructure.
See the dedicated Hosted Evaluation guide for the full client + server workflow and security checklist.
Checklist
Section titled “Checklist”- [] Distribute wheels only (never the sdist).
- [] Strip to bytecode-only with
build_client_eval.sh(Tier 1+). - [] Include the EULA (
EULA-EVAL.md) and require acceptance. - [] Add an expiry/license if the eval must be time-bounded.
- [] Consider Cython for
_analytics/strategies, or a hosted eval, for stronger protection. - [] Publish to a private index (not public PyPI).