licantha-sdk 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. licantha_sdk-0.1.0/.python-version +1 -0
  2. licantha_sdk-0.1.0/LICENSE.txt +7 -0
  3. licantha_sdk-0.1.0/PKG-INFO +340 -0
  4. licantha_sdk-0.1.0/README.md +282 -0
  5. licantha_sdk-0.1.0/pyproject.toml +57 -0
  6. licantha_sdk-0.1.0/requirements/requirements.build.txt +4 -0
  7. licantha_sdk-0.1.0/requirements/requirements.dev.txt +6 -0
  8. licantha_sdk-0.1.0/requirements/requirements.docs.txt +2 -0
  9. licantha_sdk-0.1.0/requirements/requirements.test.txt +5 -0
  10. licantha_sdk-0.1.0/requirements.txt +6 -0
  11. licantha_sdk-0.1.0/setup.cfg +4 -0
  12. licantha_sdk-0.1.0/setup.py +3 -0
  13. licantha_sdk-0.1.0/src/licantha_sdk/__init__.py +44 -0
  14. licantha_sdk-0.1.0/src/licantha_sdk/__main__.py +53 -0
  15. licantha_sdk-0.1.0/src/licantha_sdk/__version__.py +1 -0
  16. licantha_sdk-0.1.0/src/licantha_sdk/_base.py +479 -0
  17. licantha_sdk-0.1.0/src/licantha_sdk/_crypto.py +147 -0
  18. licantha_sdk-0.1.0/src/licantha_sdk/_errors.py +100 -0
  19. licantha_sdk-0.1.0/src/licantha_sdk/_fingerprint.py +19 -0
  20. licantha_sdk-0.1.0/src/licantha_sdk/_heartbeat.py +97 -0
  21. licantha_sdk-0.1.0/src/licantha_sdk/_keygen.py +345 -0
  22. licantha_sdk-0.1.0/src/licantha_sdk/_offline.py +175 -0
  23. licantha_sdk-0.1.0/src/licantha_sdk/_providers.py +131 -0
  24. licantha_sdk-0.1.0/src/licantha_sdk/_utils.py +63 -0
  25. licantha_sdk-0.1.0/src/licantha_sdk/config.py +111 -0
  26. licantha_sdk-0.1.0/src/licantha_sdk.egg-info/PKG-INFO +340 -0
  27. licantha_sdk-0.1.0/src/licantha_sdk.egg-info/SOURCES.txt +33 -0
  28. licantha_sdk-0.1.0/src/licantha_sdk.egg-info/dependency_links.txt +1 -0
  29. licantha_sdk-0.1.0/src/licantha_sdk.egg-info/requires.txt +36 -0
  30. licantha_sdk-0.1.0/src/licantha_sdk.egg-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ 3.10
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2026 Licantha. All rights reserved.
2
+
3
+ This software and associated documentation files (the "Software") are proprietary
4
+ and confidential. Unauthorized copying, distribution, or use of the Software is
5
+ strictly prohibited.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
@@ -0,0 +1,340 @@
1
+ Metadata-Version: 2.4
2
+ Name: licantha-sdk
3
+ Version: 0.1.0
4
+ Summary: License-gated, encrypted-model SDK for on-prem AI services.
5
+ Author-email: Baratov Sokhibjon <sokhin.op@proton.me>
6
+ Project-URL: Homepage, https://github.com/humblebeeai/int-sdk-python-licensing
7
+ Project-URL: Documentation, https://docs.licantha.dev
8
+ Project-URL: Repository, https://github.com/humblebeeai/int-sdk-python-licensing.git
9
+ Project-URL: Issues, https://github.com/humblebeeai/int-sdk-python-licensing/issues
10
+ Project-URL: Changelog, https://github.com/humblebeeai/int-sdk-python-licensing/blob/main/CHANGELOG.md
11
+ Keywords: licantha,licensing,keygen,encryption,on-prem,ai,sdk
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Libraries
15
+ Classifier: Topic :: Security :: Cryptography
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Requires-Python: <4.0,>=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE.txt
25
+ Requires-Dist: python-dotenv<2.0.0,>=1.0.1
26
+ Requires-Dist: pydantic[email,timezone]<3.0.0,>=2.0.3
27
+ Requires-Dist: pydantic-settings<3.0.0,>=2.2.1
28
+ Requires-Dist: requests<3,>=2.32
29
+ Requires-Dist: cryptography<46,>=43
30
+ Requires-Dist: py-machineid<1,>=0.6
31
+ Provides-Extra: test
32
+ Requires-Dist: pytest<10.0.0,>=8.0.2; extra == "test"
33
+ Requires-Dist: pytest-cov<8.0.0,>=5.0.0; extra == "test"
34
+ Requires-Dist: pytest-xdist<4.0.0,>=3.6.1; extra == "test"
35
+ Requires-Dist: pytest-benchmark<6.0.0,>=5.0.1; extra == "test"
36
+ Provides-Extra: build
37
+ Requires-Dist: setuptools<83.0.0,>=70.3.0; extra == "build"
38
+ Requires-Dist: wheel<1.0.0,>=0.43.0; extra == "build"
39
+ Requires-Dist: build<2.0.0,>=1.1.1; extra == "build"
40
+ Requires-Dist: twine<7.0.0,>=6.0.1; extra == "build"
41
+ Provides-Extra: docs
42
+ Requires-Dist: zensical<1.0.0,>=0.0.2; extra == "docs"
43
+ Requires-Dist: mkdocstrings[python]<2.0.0,>=0.24.3; extra == "docs"
44
+ Provides-Extra: dev
45
+ Requires-Dist: pytest<10.0.0,>=8.0.2; extra == "dev"
46
+ Requires-Dist: pytest-cov<8.0.0,>=5.0.0; extra == "dev"
47
+ Requires-Dist: pytest-xdist<4.0.0,>=3.6.1; extra == "dev"
48
+ Requires-Dist: pytest-benchmark<6.0.0,>=5.0.1; extra == "dev"
49
+ Requires-Dist: setuptools<83.0.0,>=70.3.0; extra == "dev"
50
+ Requires-Dist: wheel<1.0.0,>=0.43.0; extra == "dev"
51
+ Requires-Dist: build<2.0.0,>=1.1.1; extra == "dev"
52
+ Requires-Dist: twine<7.0.0,>=6.0.1; extra == "dev"
53
+ Requires-Dist: zensical<1.0.0,>=0.0.2; extra == "dev"
54
+ Requires-Dist: mkdocstrings[python]<2.0.0,>=0.24.3; extra == "dev"
55
+ Requires-Dist: pyright<2.0.0,>=1.1.392; extra == "dev"
56
+ Requires-Dist: pre-commit<5.0.0,>=4.0.1; extra == "dev"
57
+ Dynamic: license-file
58
+
59
+ # Licantha SDK
60
+
61
+ License-gated, encrypted-model SDK for on-prem AI services.
62
+
63
+ The SDK validates a customer's license against a Keygen.sh server (or an
64
+ offline Ed25519-signed `.lic` file for air-gapped deployments), activates
65
+ this machine, runs a background heartbeat, and decrypts AES-256-GCM
66
+ encrypted model files using keys delivered through license metadata.
67
+
68
+ ## โœจ Features
69
+
70
+ - Online activation against a self-hosted Keygen server (`SecureClient`)
71
+ - Offline / air-gapped mode via signed `.lic` files
72
+ - AES-256-GCM model envelope with embedded `model_id` for multi-model licenses
73
+ - Background heartbeat daemon with clean SIGTERM-safe shutdown
74
+ - Pluggable `KeyProvider` abstraction (lease today, GPU-attestation tomorrow)
75
+ - Pydantic-validated config (`SecureClientConfigPM`) and `.env` loader (`SecureClientCliConfig`)
76
+ - Self-contained example mini-apps for every flow
77
+
78
+ ---
79
+
80
+ ## ๐Ÿ›  Installation
81
+
82
+ ### 1. ๐Ÿšง Prerequisites
83
+
84
+ - Install **Python (>= v3.10)** and **pip (>= 23)**:
85
+ - **[RECOMMENDED] [Miniconda (v3)](https://www.anaconda.com/docs/getting-started/miniconda/install)**
86
+ - *[arm64/aarch64] [Miniforge (v3)](https://github.com/conda-forge/miniforge)*
87
+ - *[Python virtual environment] [venv](https://docs.python.org/3/library/venv.html)*
88
+
89
+ [OPTIONAL] For **DEVELOPMENT** environment:
90
+
91
+ - Install [**git**](https://git-scm.com/downloads)
92
+ - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
93
+
94
+ ### 2. ๐Ÿ“ฅ Download or clone the repository
95
+
96
+ [TIP] Skip this step, if you're going to install the package directly from **PyPi** or **GitHub** repository.
97
+
98
+ **2.1.** Prepare projects directory (if not exists):
99
+
100
+ ```sh
101
+ # Create projects directory:
102
+ mkdir -pv ~/workspaces/projects
103
+
104
+ # Enter into projects directory:
105
+ cd ~/workspaces/projects
106
+ ```
107
+
108
+ **2.2.** Follow one of the below options **[A]**, **[B]** or **[C]**:
109
+
110
+ **OPTION A.** Clone the repository:
111
+
112
+ ```sh
113
+ git clone https://github.com/humblebeeai/int-sdk-python-licensing.git && \
114
+ cd int-sdk-python-licensing
115
+ ```
116
+
117
+ **OPTION B.** Clone the repository (for **DEVELOPMENT**: git + ssh key):
118
+
119
+ ```sh
120
+ git clone git@github.com:humblebeeai/int-sdk-python-licensing.git && \
121
+ cd int-sdk-python-licensing
122
+ ```
123
+
124
+ **OPTION C.** Download source code:
125
+
126
+ 1. Download archived **zip** file from [**releases**](https://github.com/humblebeeai/int-sdk-python-licensing/releases).
127
+ 2. Extract it into the projects directory.
128
+
129
+ ### 3. ๐Ÿ“ฆ Install the package
130
+
131
+ [NOTE] Choose one of the following methods to install the package **[A ~ F]**:
132
+
133
+ **OPTION A.** [**RECOMMENDED**] Install from **PyPi**:
134
+
135
+ ```sh
136
+ # Install from staging TestPyPi:
137
+ pip install -i https://test.pypi.org/simple -U licantha-sdk
138
+
139
+ # Or install from production PyPi:
140
+ # pip install -U licantha-sdk
141
+ ```
142
+
143
+ **OPTION B.** Install latest version directly from **GitHub** repository:
144
+
145
+ ```sh
146
+ pip install git+https://github.com/humblebeeai/int-sdk-python-licensing.git
147
+ ```
148
+
149
+ **OPTION C.** Install from the downloaded **source code**:
150
+
151
+ ```sh
152
+ # Install directly from the source code:
153
+ pip install .
154
+
155
+ # Or install with editable mode:
156
+ pip install -e .
157
+ ```
158
+
159
+ **OPTION D.** Install for **DEVELOPMENT** environment:
160
+
161
+ ```sh
162
+ pip install -e .[dev]
163
+
164
+ # Install pre-commit hooks:
165
+ pre-commit install
166
+ ```
167
+
168
+ **OPTION E.** Install from **pre-built release** files:
169
+
170
+ 1. Download **`.whl`** or **`.tar.gz`** file from [**releases**](https://github.com/humblebeeai/int-sdk-python-licensing/releases)
171
+ 2. Install with pip:
172
+
173
+ ```sh
174
+ # Install from .whl file:
175
+ pip install ./licantha-sdk-[VERSION]-py3-none-any.whl
176
+
177
+ # Or install from .tar.gz file:
178
+ pip install ./licantha-sdk-[VERSION].tar.gz
179
+ ```
180
+
181
+ **OPTION F.** Copy the **module** into the project directory (for **testing**):
182
+
183
+ ```sh
184
+ # Install python dependencies:
185
+ pip install -r ./requirements.txt
186
+
187
+ # Copy the module source code into the project:
188
+ cp -r ./src/licantha_sdk [PROJECT_DIR]
189
+ # For example:
190
+ cp -r ./src/licantha_sdk /some/path/project/
191
+ ```
192
+
193
+ ## ๐Ÿšธ Usage/Examples
194
+
195
+ ### Simple
196
+
197
+ [**`examples/simple/main.py`**](./examples/simple/main.py):
198
+
199
+ ```python
200
+ # Standard libraries
201
+ import sys
202
+ import logging
203
+ from pathlib import Path
204
+
205
+ # Third-party libraries
206
+ from dotenv import load_dotenv
207
+
208
+ # Internal modules
209
+ from licantha_sdk import LicenseError, SecureClient, SecureClientCliConfig
210
+
211
+
212
+ HERE = Path(__file__).parent
213
+ load_dotenv(HERE / ".env")
214
+ logger = logging.getLogger("quickstart")
215
+
216
+
217
+ def serve(weights: bytes) -> None:
218
+ logger.info(f"model loaded โ€” {len(weights)} bytes")
219
+
220
+
221
+ def main() -> int:
222
+ logging.basicConfig(level=logging.INFO)
223
+
224
+ _config = SecureClientCliConfig() # picks up LICANTHA_SDK_* from .env / env
225
+ with SecureClient(config=_config) as _client:
226
+ try:
227
+ _weights = _client.decrypt_model(str(HERE / "model.encrypted"))
228
+ except LicenseError as _e:
229
+ logger.critical(f"cannot start: {_e}")
230
+ return 2
231
+ serve(_weights)
232
+ return 0
233
+
234
+
235
+ if __name__ == "__main__":
236
+ sys.exit(main())
237
+ ```
238
+
239
+ See [`examples/`](./examples) for offline / custom-inference / multi-model / manual-lifecycle / error-shape variants.
240
+
241
+ ---
242
+
243
+ ## โš™๏ธ Configuration
244
+
245
+ Production callers construct `SecureClientConfigPM` explicitly โ€” they do
246
+ NOT pull env vars from inside a compiled binary:
247
+
248
+ ```python
249
+ from licantha_sdk import SecureClient, SecureClientConfigPM
250
+
251
+ config = SecureClientConfigPM(
252
+ account_id="...",
253
+ license_key="...",
254
+ public_key="...", # 64-char hex Ed25519
255
+ app_id="my-product",
256
+ api_url="https://licensing.your-company.com",
257
+ )
258
+ with SecureClient(config=config) as client:
259
+ weights = client.decrypt_model("model.enc")
260
+ ```
261
+
262
+ Dev / examples can load from `.env` via `SecureClientCliConfig` instead.
263
+
264
+ ### ๐ŸŒŽ Environment Variables
265
+
266
+ [**`.env.example`**](./.env.example):
267
+
268
+ ```sh
269
+ # Required:
270
+ LICANTHA_SDK_ACCOUNT_ID=
271
+ LICANTHA_SDK_LICENSE_KEY=
272
+ LICANTHA_SDK_PUBLIC_KEY=
273
+
274
+ # Optional:
275
+ # LICANTHA_SDK_APP_ID=licantha-default
276
+ # LICANTHA_SDK_API_URL=https://licensing.your-company.com
277
+ # LICANTHA_SDK_OFFLINE_LICENSE_PATH=./license.lic
278
+ # LICANTHA_SDK_HEARTBEAT_INTERVAL=60
279
+ # LICANTHA_SDK_DEACTIVATE_ON_EXIT=true
280
+ ```
281
+
282
+ ---
283
+
284
+ ## ๐Ÿงช Running Tests
285
+
286
+ To run tests, run the following command:
287
+
288
+ ```sh
289
+ # Install python test dependencies:
290
+ pip install .[test]
291
+
292
+ # Run tests:
293
+ python -m pytest -sv -o log_cli=true
294
+ # Or use the test script:
295
+ ./scripts/test.sh -l -v -c
296
+ ```
297
+
298
+ ## ๐Ÿ—๏ธ Build Package
299
+
300
+ To build the python package, run the following command:
301
+
302
+ ```sh
303
+ # Install python build dependencies:
304
+ pip install -r ./requirements/requirements.build.txt
305
+
306
+ # Build python package:
307
+ python -m build
308
+ # Or use the build script:
309
+ ./scripts/build.sh
310
+ ```
311
+
312
+ ## ๐Ÿ“ Generate Docs
313
+
314
+ To build the documentation, run the following command:
315
+
316
+ ```sh
317
+ # Install python documentation dependencies:
318
+ pip install -r ./requirements/requirements.docs.txt
319
+
320
+ # Serve documentation locally (for development):
321
+ mkdocs serve -a 0.0.0.0:8000 --livereload
322
+ # Or use the docs script:
323
+ ./scripts/docs.sh
324
+
325
+ # Or build documentation:
326
+ mkdocs build
327
+ # Or use the docs script:
328
+ ./scripts/docs.sh -b
329
+ ```
330
+
331
+ ## ๐Ÿ“š Documentation
332
+
333
+ - [Docs](./docs)
334
+
335
+ ---
336
+
337
+ ## ๐Ÿ“‘ References
338
+
339
+ - <https://packaging.python.org/en/latest/tutorials/packaging-projects>
340
+ - <https://python-packaging.readthedocs.io/en/latest>
@@ -0,0 +1,282 @@
1
+ # Licantha SDK
2
+
3
+ License-gated, encrypted-model SDK for on-prem AI services.
4
+
5
+ The SDK validates a customer's license against a Keygen.sh server (or an
6
+ offline Ed25519-signed `.lic` file for air-gapped deployments), activates
7
+ this machine, runs a background heartbeat, and decrypts AES-256-GCM
8
+ encrypted model files using keys delivered through license metadata.
9
+
10
+ ## โœจ Features
11
+
12
+ - Online activation against a self-hosted Keygen server (`SecureClient`)
13
+ - Offline / air-gapped mode via signed `.lic` files
14
+ - AES-256-GCM model envelope with embedded `model_id` for multi-model licenses
15
+ - Background heartbeat daemon with clean SIGTERM-safe shutdown
16
+ - Pluggable `KeyProvider` abstraction (lease today, GPU-attestation tomorrow)
17
+ - Pydantic-validated config (`SecureClientConfigPM`) and `.env` loader (`SecureClientCliConfig`)
18
+ - Self-contained example mini-apps for every flow
19
+
20
+ ---
21
+
22
+ ## ๐Ÿ›  Installation
23
+
24
+ ### 1. ๐Ÿšง Prerequisites
25
+
26
+ - Install **Python (>= v3.10)** and **pip (>= 23)**:
27
+ - **[RECOMMENDED] [Miniconda (v3)](https://www.anaconda.com/docs/getting-started/miniconda/install)**
28
+ - *[arm64/aarch64] [Miniforge (v3)](https://github.com/conda-forge/miniforge)*
29
+ - *[Python virtual environment] [venv](https://docs.python.org/3/library/venv.html)*
30
+
31
+ [OPTIONAL] For **DEVELOPMENT** environment:
32
+
33
+ - Install [**git**](https://git-scm.com/downloads)
34
+ - Setup an [**SSH key**](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh)
35
+
36
+ ### 2. ๐Ÿ“ฅ Download or clone the repository
37
+
38
+ [TIP] Skip this step, if you're going to install the package directly from **PyPi** or **GitHub** repository.
39
+
40
+ **2.1.** Prepare projects directory (if not exists):
41
+
42
+ ```sh
43
+ # Create projects directory:
44
+ mkdir -pv ~/workspaces/projects
45
+
46
+ # Enter into projects directory:
47
+ cd ~/workspaces/projects
48
+ ```
49
+
50
+ **2.2.** Follow one of the below options **[A]**, **[B]** or **[C]**:
51
+
52
+ **OPTION A.** Clone the repository:
53
+
54
+ ```sh
55
+ git clone https://github.com/humblebeeai/int-sdk-python-licensing.git && \
56
+ cd int-sdk-python-licensing
57
+ ```
58
+
59
+ **OPTION B.** Clone the repository (for **DEVELOPMENT**: git + ssh key):
60
+
61
+ ```sh
62
+ git clone git@github.com:humblebeeai/int-sdk-python-licensing.git && \
63
+ cd int-sdk-python-licensing
64
+ ```
65
+
66
+ **OPTION C.** Download source code:
67
+
68
+ 1. Download archived **zip** file from [**releases**](https://github.com/humblebeeai/int-sdk-python-licensing/releases).
69
+ 2. Extract it into the projects directory.
70
+
71
+ ### 3. ๐Ÿ“ฆ Install the package
72
+
73
+ [NOTE] Choose one of the following methods to install the package **[A ~ F]**:
74
+
75
+ **OPTION A.** [**RECOMMENDED**] Install from **PyPi**:
76
+
77
+ ```sh
78
+ # Install from staging TestPyPi:
79
+ pip install -i https://test.pypi.org/simple -U licantha-sdk
80
+
81
+ # Or install from production PyPi:
82
+ # pip install -U licantha-sdk
83
+ ```
84
+
85
+ **OPTION B.** Install latest version directly from **GitHub** repository:
86
+
87
+ ```sh
88
+ pip install git+https://github.com/humblebeeai/int-sdk-python-licensing.git
89
+ ```
90
+
91
+ **OPTION C.** Install from the downloaded **source code**:
92
+
93
+ ```sh
94
+ # Install directly from the source code:
95
+ pip install .
96
+
97
+ # Or install with editable mode:
98
+ pip install -e .
99
+ ```
100
+
101
+ **OPTION D.** Install for **DEVELOPMENT** environment:
102
+
103
+ ```sh
104
+ pip install -e .[dev]
105
+
106
+ # Install pre-commit hooks:
107
+ pre-commit install
108
+ ```
109
+
110
+ **OPTION E.** Install from **pre-built release** files:
111
+
112
+ 1. Download **`.whl`** or **`.tar.gz`** file from [**releases**](https://github.com/humblebeeai/int-sdk-python-licensing/releases)
113
+ 2. Install with pip:
114
+
115
+ ```sh
116
+ # Install from .whl file:
117
+ pip install ./licantha-sdk-[VERSION]-py3-none-any.whl
118
+
119
+ # Or install from .tar.gz file:
120
+ pip install ./licantha-sdk-[VERSION].tar.gz
121
+ ```
122
+
123
+ **OPTION F.** Copy the **module** into the project directory (for **testing**):
124
+
125
+ ```sh
126
+ # Install python dependencies:
127
+ pip install -r ./requirements.txt
128
+
129
+ # Copy the module source code into the project:
130
+ cp -r ./src/licantha_sdk [PROJECT_DIR]
131
+ # For example:
132
+ cp -r ./src/licantha_sdk /some/path/project/
133
+ ```
134
+
135
+ ## ๐Ÿšธ Usage/Examples
136
+
137
+ ### Simple
138
+
139
+ [**`examples/simple/main.py`**](./examples/simple/main.py):
140
+
141
+ ```python
142
+ # Standard libraries
143
+ import sys
144
+ import logging
145
+ from pathlib import Path
146
+
147
+ # Third-party libraries
148
+ from dotenv import load_dotenv
149
+
150
+ # Internal modules
151
+ from licantha_sdk import LicenseError, SecureClient, SecureClientCliConfig
152
+
153
+
154
+ HERE = Path(__file__).parent
155
+ load_dotenv(HERE / ".env")
156
+ logger = logging.getLogger("quickstart")
157
+
158
+
159
+ def serve(weights: bytes) -> None:
160
+ logger.info(f"model loaded โ€” {len(weights)} bytes")
161
+
162
+
163
+ def main() -> int:
164
+ logging.basicConfig(level=logging.INFO)
165
+
166
+ _config = SecureClientCliConfig() # picks up LICANTHA_SDK_* from .env / env
167
+ with SecureClient(config=_config) as _client:
168
+ try:
169
+ _weights = _client.decrypt_model(str(HERE / "model.encrypted"))
170
+ except LicenseError as _e:
171
+ logger.critical(f"cannot start: {_e}")
172
+ return 2
173
+ serve(_weights)
174
+ return 0
175
+
176
+
177
+ if __name__ == "__main__":
178
+ sys.exit(main())
179
+ ```
180
+
181
+ See [`examples/`](./examples) for offline / custom-inference / multi-model / manual-lifecycle / error-shape variants.
182
+
183
+ ---
184
+
185
+ ## โš™๏ธ Configuration
186
+
187
+ Production callers construct `SecureClientConfigPM` explicitly โ€” they do
188
+ NOT pull env vars from inside a compiled binary:
189
+
190
+ ```python
191
+ from licantha_sdk import SecureClient, SecureClientConfigPM
192
+
193
+ config = SecureClientConfigPM(
194
+ account_id="...",
195
+ license_key="...",
196
+ public_key="...", # 64-char hex Ed25519
197
+ app_id="my-product",
198
+ api_url="https://licensing.your-company.com",
199
+ )
200
+ with SecureClient(config=config) as client:
201
+ weights = client.decrypt_model("model.enc")
202
+ ```
203
+
204
+ Dev / examples can load from `.env` via `SecureClientCliConfig` instead.
205
+
206
+ ### ๐ŸŒŽ Environment Variables
207
+
208
+ [**`.env.example`**](./.env.example):
209
+
210
+ ```sh
211
+ # Required:
212
+ LICANTHA_SDK_ACCOUNT_ID=
213
+ LICANTHA_SDK_LICENSE_KEY=
214
+ LICANTHA_SDK_PUBLIC_KEY=
215
+
216
+ # Optional:
217
+ # LICANTHA_SDK_APP_ID=licantha-default
218
+ # LICANTHA_SDK_API_URL=https://licensing.your-company.com
219
+ # LICANTHA_SDK_OFFLINE_LICENSE_PATH=./license.lic
220
+ # LICANTHA_SDK_HEARTBEAT_INTERVAL=60
221
+ # LICANTHA_SDK_DEACTIVATE_ON_EXIT=true
222
+ ```
223
+
224
+ ---
225
+
226
+ ## ๐Ÿงช Running Tests
227
+
228
+ To run tests, run the following command:
229
+
230
+ ```sh
231
+ # Install python test dependencies:
232
+ pip install .[test]
233
+
234
+ # Run tests:
235
+ python -m pytest -sv -o log_cli=true
236
+ # Or use the test script:
237
+ ./scripts/test.sh -l -v -c
238
+ ```
239
+
240
+ ## ๐Ÿ—๏ธ Build Package
241
+
242
+ To build the python package, run the following command:
243
+
244
+ ```sh
245
+ # Install python build dependencies:
246
+ pip install -r ./requirements/requirements.build.txt
247
+
248
+ # Build python package:
249
+ python -m build
250
+ # Or use the build script:
251
+ ./scripts/build.sh
252
+ ```
253
+
254
+ ## ๐Ÿ“ Generate Docs
255
+
256
+ To build the documentation, run the following command:
257
+
258
+ ```sh
259
+ # Install python documentation dependencies:
260
+ pip install -r ./requirements/requirements.docs.txt
261
+
262
+ # Serve documentation locally (for development):
263
+ mkdocs serve -a 0.0.0.0:8000 --livereload
264
+ # Or use the docs script:
265
+ ./scripts/docs.sh
266
+
267
+ # Or build documentation:
268
+ mkdocs build
269
+ # Or use the docs script:
270
+ ./scripts/docs.sh -b
271
+ ```
272
+
273
+ ## ๐Ÿ“š Documentation
274
+
275
+ - [Docs](./docs)
276
+
277
+ ---
278
+
279
+ ## ๐Ÿ“‘ References
280
+
281
+ - <https://packaging.python.org/en/latest/tutorials/packaging-projects>
282
+ - <https://python-packaging.readthedocs.io/en/latest>
@@ -0,0 +1,57 @@
1
+ [build-system]
2
+ requires = ["setuptools>=82.0.1,<83.0.0", "setuptools-scm>=8.0.4,<11.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "licantha-sdk"
7
+ authors = [{ name = "Baratov Sokhibjon", email = "sokhin.op@proton.me" }]
8
+ description = "License-gated, encrypted-model SDK for on-prem AI services."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10,<4.0"
11
+ keywords = ["licantha", "licensing", "keygen", "encryption", "on-prem", "ai", "sdk"]
12
+ license-files = ["LICEN[CS]E*"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "Topic :: Software Development :: Libraries",
17
+ "Topic :: Security :: Cryptography",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ ]
25
+ dynamic = ["version", "dependencies", "optional-dependencies"]
26
+
27
+ [tool.setuptools.packages.find]
28
+ where = ["src"]
29
+ include = ["licantha_sdk*"]
30
+ namespaces = false
31
+
32
+ [tool.setuptools.dynamic]
33
+ version = { attr = "licantha_sdk.__version__.__version__" }
34
+ dependencies = { file = "./requirements.txt" }
35
+
36
+ [tool.setuptools.dynamic.optional-dependencies]
37
+ # Optional dependencies for DEVELOPMENT
38
+ test = { file = ["./requirements/requirements.test.txt"] }
39
+ build = { file = ["./requirements/requirements.build.txt"] }
40
+ docs = { file = ["./requirements/requirements.docs.txt"] }
41
+ dev = { file = [
42
+ "./requirements/requirements.test.txt",
43
+ "./requirements/requirements.build.txt",
44
+ "./requirements/requirements.docs.txt",
45
+ "./requirements/requirements.dev.txt",
46
+ ] }
47
+
48
+ # [tool.pyright]
49
+ # venvPath = "."
50
+ # venv = ".venv"
51
+
52
+ [project.urls]
53
+ Homepage = "https://github.com/humblebeeai/int-sdk-python-licensing"
54
+ Documentation = "https://docs.licantha.dev"
55
+ Repository = "https://github.com/humblebeeai/int-sdk-python-licensing.git"
56
+ Issues = "https://github.com/humblebeeai/int-sdk-python-licensing/issues"
57
+ Changelog = "https://github.com/humblebeeai/int-sdk-python-licensing/blob/main/CHANGELOG.md"
@@ -0,0 +1,4 @@
1
+ setuptools>=70.3.0,<83.0.0
2
+ wheel>=0.43.0,<1.0.0
3
+ build>=1.1.1,<2.0.0
4
+ twine>=6.0.1,<7.0.0
@@ -0,0 +1,6 @@
1
+ # -e .
2
+ # -r ./requirements.test.txt
3
+ # -r ./requirements.build.txt
4
+ # -r ./requirements.docs.txt
5
+ pyright>=1.1.392,<2.0.0
6
+ pre-commit>=4.0.1,<5.0.0
@@ -0,0 +1,2 @@
1
+ zensical>=0.0.2,<1.0.0
2
+ mkdocstrings[python]>=0.24.3,<2.0.0