Metadata-Version: 2.5
Name: sinapkit
Version: 0.2.0
Summary: Download and locally deploy SinapisAI models
Project-URL: Homepage, https://sinapisai.com
Author: SinapisAI
License: Copyright 2026 SinapisAI
        
                                         Apache License
                                   Version 2.0, January 2004
                                http://www.apache.org/licenses/
        
           TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
        
           1. Definitions.
        
              "License" shall mean the terms and conditions for use, reproduction,
              and distribution as defined by Sections 1 through 9 of this document.
        
              "Licensor" shall mean the copyright owner or entity authorized by
              the copyright owner that is granting the License.
        
              "Legal Entity" shall mean the union of the acting entity and all
              other entities that control, are controlled by, or are under common
              control with that entity. For the purposes of this definition,
              "control" means (i) the power, direct or indirect, to cause the
              direction or management of such entity, whether by contract or
              otherwise, or (ii) ownership of fifty percent (50%) or more of the
              outstanding shares, or (iii) beneficial ownership of such entity.
        
              "You" (or "Your") shall mean an individual or Legal Entity
              exercising permissions granted by this License.
        
              "Source" form shall mean the preferred form for making modifications,
              including but not limited to software source code, documentation
              source, and configuration files.
        
              "Object" form shall mean any form resulting from mechanical
              transformation or translation of a Source form, including but
              not limited to compiled object code, generated documentation,
              and conversions to other media types.
        
              "Work" shall mean the work of authorship, whether in Source or
              Object form, made available under the License, as indicated by a
              copyright notice that is included in or attached to the work
              (an example is provided in the Appendix below).
        
              "Derivative Works" shall mean any work, whether in Source or Object
              form, that is based on (or derived from) the Work and for which the
              editorial revisions, annotations, elaborations, or other modifications
              represent, as a whole, an original work of authorship. For the purposes
              of this License, Derivative Works shall not include works that remain
              separable from, or merely link (or bind by name) to the interfaces of,
              the Work and Derivative Works thereof.
        
              "Contribution" shall mean any work of authorship, including
              the original version of the Work and any modifications or additions
              to that Work or Derivative Works thereof, that is intentionally
              submitted to Licensor for inclusion in the Work by the copyright owner
              or by an individual or Legal Entity authorized to submit on behalf of
              the copyright owner. For the purposes of this definition, "submitted"
              means any form of electronic, verbal, or written communication sent
              to the Licensor or its representatives, including but not limited to
              communication on electronic mailing lists, source code control systems,
              and issue tracking systems that are managed by, or on behalf of, the
              Licensor for the purpose of discussing and improving the Work, but
              excluding communication that is conspicuously marked or otherwise
              designated in writing by the copyright owner as "Not a Contribution."
        
              "Contributor" shall mean Licensor and any individual or Legal Entity
              on behalf of whom a Contribution has been received by Licensor and
              subsequently incorporated within the Work.
        
           2. Grant of Copyright License. Subject to the terms and conditions of
              this License, each Contributor hereby grants to You a perpetual,
              worldwide, non-exclusive, no-charge, royalty-free, irrevocable
              copyright license to reproduce, prepare Derivative Works of,
              publicly display, publicly perform, sublicense, and distribute the
              Work and such Derivative Works in Source or Object form.
        
           3. Grant of Patent License. Subject to the terms and conditions of
              this License, each Contributor hereby grants to You a perpetual,
              worldwide, non-exclusive, no-charge, royalty-free, irrevocable
              (except as stated in this section) patent license to make, have made,
              use, offer to sell, sell, import, and otherwise transfer the Work,
              where such license applies only to those patent claims licensable
              by such Contributor that are necessarily infringed by their
              Contribution(s) alone or by combination of their Contribution(s)
              with the Work to which such Contribution(s) was submitted. If You
              institute patent litigation against any entity (including a
              cross-claim or counterclaim in a lawsuit) alleging that the Work
              or a Contribution incorporated within the Work constitutes direct
              or contributory patent infringement, then any patent licenses
              granted to You under this License for that Work shall terminate
              as of the date such litigation is filed.
        
           4. Redistribution. You may reproduce and distribute copies of the
              Work or Derivative Works thereof in any medium, with or without
              modifications, and in Source or Object form, provided that You
              meet the following conditions:
        
              (a) You must give any other recipients of the Work or
                  Derivative Works a copy of this License; and
        
              (b) You must cause any modified files to carry prominent notices
                  stating that You changed the files; and
        
              (c) You must retain, in the Source form of any Derivative Works
                  that You distribute, all copyright, patent, trademark, and
                  attribution notices from the Source form of the Work,
                  excluding those notices that do not pertain to any part of
                  the Derivative Works; and
        
              (d) If the Work includes a "NOTICE" text file as part of its
                  distribution, then any Derivative Works that You distribute must
                  include a readable copy of the attribution notices contained
                  within such NOTICE file, excluding those notices that do not
                  pertain to any part of the Derivative Works, in at least one
                  of the following places: within a NOTICE text file distributed
                  as part of the Derivative Works; within the Source form or
                  documentation, if provided along with the Derivative Works; or,
                  within a display generated by the Derivative Works, if and
                  wherever such third-party notices normally appear. The contents
                  of the NOTICE file are for informational purposes only and
                  do not modify the License. You may add Your own attribution
                  notices within Derivative Works that You distribute, alongside
                  or as an addendum to the NOTICE text from the Work, provided
                  that such additional attribution notices cannot be construed
                  as modifying the License.
        
              You may add Your own copyright statement to Your modifications and
              may provide additional or different license terms and conditions
              for use, reproduction, or distribution of Your modifications, or
              for any such Derivative Works as a whole, provided Your use,
              reproduction, and distribution of the Work otherwise complies with
              the conditions stated in this License.
        
           5. Submission of Contributions. Unless You explicitly state otherwise,
              any Contribution intentionally submitted for inclusion in the Work
              by You to the Licensor shall be under the terms and conditions of
              this License, without any additional terms or conditions.
              Notwithstanding the above, nothing herein shall supersede or modify
              the terms of any separate license agreement you may have executed
              with Licensor regarding such Contributions.
        
           6. Trademarks. This License does not grant permission to use the trade
              names, trademarks, service marks, or product names of the Licensor,
              except as required for reasonable and customary use in describing the
              origin of the Work and reproducing the content of the NOTICE file.
        
           7. Disclaimer of Warranty. Unless required by applicable law or
              agreed to in writing, Licensor provides the Work (and each
              Contributor provides its Contributions) on an "AS IS" BASIS,
              WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
              implied, including, without limitation, any warranties or conditions
              of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
              PARTICULAR PURPOSE. You are solely responsible for determining the
              appropriateness of using or redistributing the Work and assume any
              risks associated with Your exercise of permissions under this License.
        
           8. Limitation of Liability. In no event and under no legal theory,
              whether in tort (including negligence), contract, or otherwise,
              unless required by applicable law (such as deliberate and grossly
              negligent acts) or agreed to in writing, shall any Contributor be
              liable to You for damages, including any direct, indirect, special,
              incidental, or consequential damages of any character arising as a
              result of this License or out of the use or inability to use the
              Work (including but not limited to damages for loss of goodwill,
              work stoppage, computer failure or malfunction, or any and all
              other commercial damages or losses), even if such Contributor
              has been advised of the possibility of such damages.
        
           9. Accepting Warranty or Additional Liability. While redistributing
              the Work or Derivative Works thereof, You may choose to offer,
              and charge a fee for, acceptance of support, warranty, indemnity,
              or other liability obligations and/or rights consistent with this
              License. However, in accepting such obligations, You may act only
              on Your own behalf and on Your sole responsibility, not on behalf
              of any other Contributor, and only if You agree to indemnify,
              defend, and hold each Contributor harmless for any liability
              incurred by, or claims asserted against, such Contributor by reason
              of your accepting any such warranty or additional liability.
        
           END OF TERMS AND CONDITIONS
        
           APPENDIX: How to apply the Apache License to your work.
        
              To apply the Apache License to your work, attach the following
              boilerplate notice, with the fields enclosed by brackets "[]"
              replaced with your own identifying information. (Don't include
              the brackets!)  The text should be enclosed in the appropriate
              comment syntax for the file format. We also recommend that a
              file or class name and description of purpose be included on the
              same "printed page" as the copyright notice for easier
              identification within third-party archives.
        
           Copyright [yyyy] [name of copyright owner]
        
           Licensed under the Apache License, Version 2.0 (the "License");
           you may not use this file except in compliance with the License.
           You may obtain a copy of the License at
        
               http://www.apache.org/licenses/LICENSE-2.0
        
           Unless required by applicable law or agreed to in writing, software
           distributed under the License is distributed on an "AS IS" BASIS,
           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           See the License for the specific language governing permissions and
           limitations under the License.
License-File: LICENSE
License-File: NOTICE
Keywords: docker,download,inference,model-hub,models,sinapisai,sinapkit
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: filelock<4,>=3.15
Requires-Dist: httpx<1,>=0.27
Requires-Dist: packaging<27,>=24
Requires-Dist: platformdirs<5,>=4
Requires-Dist: tqdm<5,>=4.66
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Requires-Dist: twine>=5; extra == 'dev'
Description-Content-Type: text/markdown

# SinapKit

`sinapkit` downloads SinapisAI model files and deploys models with local Docker runtimes.
The API service supplies an immutable file manifest and short-lived signed URLs; bytes flow directly
from object storage to the user's machine. The package never needs an OSS SDK or a long-lived OSS key.

Requires Python 3.10 through 3.14.

Chinese documentation: [`docs/usage-guide.md`](docs/usage-guide.md)

GPU server commands for the 11 validated model directories:
[`docs/gpu-server-deployment-guide.md`](docs/gpu-server-deployment-guide.md)

CPU server deployment and inference test commands:
[`docs/cpu-server-deployment-guide.md`](docs/cpu-server-deployment-guide.md)

## Install

```bash
pip install sinapkit
```

If the previous distribution is installed, remove it first with
`pip uninstall sinapisai-hub` so only the `sinapkit` command remains.

## Update notices

Interactive `download`, `login`, `whoami`, and network-enabled `deploy` commands check public PyPI
in the background at most once per 24 hours per user/Python version. If a newer stable release
supports your Python version, SinapKit prints an upgrade suggestion on stderr after the command,
at most once per 24 hours. It never installs updates or waits for the check before exiting.
Very short commands may finish before a result is available; a later command can use cached results.
Failed/interrupted attempts also count towards the daily check interval.

Python SDK calls, help/version, CI, redirected/non-interactive commands, `--quiet`,
`--local-files-only`, local-model deployment, dry runs, `runtime`, and `logout` do not check.
Set `SINAPKIT_NO_UPDATE_CHECK=1` to disable checks and notices completely.
Network/cache failures are silently ignored. Activate the environment containing SinapKit before
running the suggested `python -m pip install --upgrade sinapkit` command; pip uses your configured
package index. See the [update notification design](docs/2026-09-14-sinapkit-update-notification-design.md).

## CLI command overview

| Command | Purpose |
| --- | --- |
| `sinapkit login` | Optionally sign in with an account and hidden password input |
| `sinapkit whoami` | Verify the current platform identity |
| `sinapkit logout` | Remove this endpoint's saved session |
| `sinapkit download MODEL_ID` | Download a complete model or one selected file |
| `sinapkit runtime list` | List the runtime profiles bundled with this SinapKit version |
| `sinapkit runtime show RUNTIME` | Show a runtime's image, devices, API paths and constraints |
| `sinapkit deploy MODEL_ID` | Prepare a model and start its runtime container |

Use the built-in help to inspect every option:

```bash
sinapkit runtime --help
sinapkit runtime list --help
sinapkit runtime show --help
sinapkit deploy --help
```

## Download a complete model

```bash
sinapkit download incoai/glm-5.3-flash-dflash2 --local-dir ./models/glm
```

Production is used by default (`https://api.sinapisai.com`).

```python
from sinapkit import snapshot_download

directory = snapshot_download(
    "incoai/glm-5.3-flash-dflash2",
    local_dir="./models/glm",
    max_workers=4,
)
```

This downloads all files rather than a ZIP and preserves every relative directory. Use `--include`
and `--exclude` to filter paths.

## Download one file

```bash
sinapkit download incoai/glm-5.3-flash-dflash2 \
  --file tokenizer/tokenizer.json \
  --local-dir ./models/glm
```

```python
from sinapkit import model_file_download

filename = model_file_download(
    "incoai/glm-5.3-flash-dflash2",
    "tokenizer/tokenizer.json",
    local_dir="./models/glm",
)
```

Paths are exact and relative to the model root; bare-name fuzzy matching is intentionally unsupported.

## Discover model runtimes

```bash
sinapkit runtime list
sinapkit runtime list --json
sinapkit runtime show llm
sinapkit runtime show embedding
sinapkit runtime show llm --json
```

The bundled catalog currently includes LLM, embedding, rerank, Chronos, vision, ASR, OCR and
segmentation runtimes. The same catalog drives both discovery and deployment. These commands only
inspect the bundled runtime catalog and do not require Docker or network access.

`sinapkit runtime` does not currently manage running containers. After deployment, use the Docker
commands printed by SinapKit, for example `docker ps`, `docker logs -f CONTAINER`, and
`docker stop CONTAINER`.

## Deploy a model

Deployment requires a local Linux AMD64 Docker Engine, or Docker Desktop using Linux containers.
CUDA deployment additionally requires an NVIDIA GPU, driver and NVIDIA Container Toolkit.
SinapKit checks these requirements before downloading the model.

Download or reuse a complete cached snapshot, then deploy it:

```bash
sinapkit deploy incoai/glm-5.3-flash-dflash2 \
  --runtime llm \
  --device cuda \
  --gpu 0 \
  --runtime-arg=--language-model-only
```

Use an existing local model without any hub or object-storage request:

```bash
sinapkit deploy incoai/glm-5.3-flash-dflash2 \
  --model-path ./models/glm \
  --runtime llm \
  --device cpu
```

`--port` is the host port; the container continues to listen on port 8000. The default served model
name is the final segment of the model ID. Override it with `--served-model-name`.

Preview the Docker command without checking Docker, pulling an image, downloading a model or creating
a container:

```bash
sinapkit deploy owner/model --runtime llm --device cpu --dry-run
```

### Deploy command reference

```text
sinapkit deploy MODEL_ID --runtime RUNTIME --device {cpu,cuda} [OPTIONS]
```

`MODEL_ID`, `--runtime`, and `--device` are required. Run `sinapkit runtime list` to discover the
available runtime names and `sinapkit runtime show RUNTIME` to inspect a runtime's image, supported
devices and API paths.

Model source and download options:

| Option | Description |
| --- | --- |
| `MODEL_ID` | Model identifier in `owner/name` form; also used for download and deployment labels |
| `--model-path DIRECTORY` | Use an existing complete model directory and skip all hub/OSS requests |
| `--model-dir DIRECTORY` | Automatically download the complete model into this directory, then mount it |
| neither location option | Automatically download or reuse the model in the SinapKit snapshot cache |
| `--revision REVISION` | Select the model snapshot revision |
| `--cache-dir DIRECTORY` | Override the SinapKit cache root |
| `--endpoint URL` | Override the model API endpoint; defaults to `https://api.sinapisai.com` |
| `--token TOKEN` | Platform Bearer token; prefer the `SINAPISAI_TOKEN` environment variable |
| `--max-workers NUMBER` | Parallel file downloads; default `4` |
| `--resume` / `--no-resume` | Resume partial files or restart them; resume is enabled by default |
| `--force-download` | Download files again even if the local copies pass validation |
| `--local-files-only` | Forbid network access and require a complete valid local snapshot |

Runtime, service and container options:

| Option | Description |
| --- | --- |
| `--runtime RUNTIME` | Required: `llm`, `embedding`, `rerank`, `chronos`, `vision`, `asr`, `ocr`, or `segmentation` |
| `--device cpu\|cuda` | Required inference device; the selected runtime must support it |
| `--gpu GPU_ID` | Host GPU index for CUDA deployment; default `0` |
| `--served-model-name NAME` | Name exposed by the inference API; defaults to the final `MODEL_ID` segment |
| `--host ADDRESS` | Published host address; default `127.0.0.1`; `0.0.0.0` exposes the service externally |
| `--port PORT` | Published host port; default `8000`; container port remains `8000` |
| `--name CONTAINER_NAME` | Docker container name; defaults to `sinapkit-<served-model-name>-cpu` or `sinapkit-<served-model-name>-gpu` according to `--device` |
| `--env KEY=VALUE` | Add a runtime environment variable; repeat the option for multiple values |
| `--env-file FILE` | Load additional runtime environment variables from a file |
| `--runtime-arg ARG` | Pass an argument allowed by the selected Runtime Profile; repeatable |

Docker resource, image and execution options:

| Option | Description |
| --- | --- |
| `--memory LIMIT` | Docker memory limit, for example `16g` |
| `--cpus NUMBER` | Docker CPU limit |
| `--shm-size SIZE` | Container shared-memory size; Runtime Profiles currently default to `2g` |
| `--restart POLICY` | `no`, `on-failure`, `unless-stopped`, or `always`; default `no` |
| `--image IMAGE` | Override the full image selected by the Runtime Profile |
| `--pull POLICY` | `missing`, `always`, or `never`; default `missing` |
| `--replace` | Replace an existing same-name container only when it is managed by SinapKit |
| `--timeout SECONDS` | Health-check timeout; default `300` seconds |
| `--dry-run` | Print the Docker command without Docker checks, image pull, download or container creation |
| `--quiet` | Suppress progress output |
| `--verbose` | Enable debug logging |

Containers created before device suffixes were introduced keep their original unsuffixed names and
are not selected by the new default `--replace` target. Stop and remove the legacy container first,
or pass its existing name explicitly with `--name` during migration.

`--model-path` and `--model-dir` are mutually exclusive. Download-related options only affect
automatic model resolution; `--endpoint` is unrelated to the Docker image registry. Core variables
such as `MODEL_PATH`, `PORT`, `DEVICE`, and `SERVED_MODEL_NAME` are managed by SinapKit and cannot be
overridden with `--env` or `--env-file`.

For complete commands covering the 11 GPU-server models and their inference tests, see
[`docs/gpu-server-deployment-guide.md`](docs/gpu-server-deployment-guide.md).

For CPU deployment commands, unsupported runtimes, performance cautions, and inference tests, see
[`docs/cpu-server-deployment-guide.md`](docs/cpu-server-deployment-guide.md).

## Authentication and configuration

Public models continue to work anonymously.

Each interactive anonymous download prints one optional login hint. Users sharing a public IP
share an anonymous allowance; login uses the account's allowance, whose limits are set by the
platform. Quiet, non-interactive, CI and offline operations suppress this hint. Run `sinapkit --help`,
`sinapkit download --help` or `sinapkit deploy --help` to see the same login guidance at any time.

To use your platform account, sign in once:

```bash
sinapkit login
sinapkit whoami
sinapkit download owner/model
sinapkit logout
```

Passwords are never saved. Sessions are stored per endpoint in the current user's configuration
directory. Access tokens use the lifetime returned by the server. When a refresh cookie is available,
the SDK refreshes only when an API request needs it; there is no background refresh process. A saved
session that has expired requires login again, or logout to return to anonymous use.

Use the same `--endpoint URL` for login, download, whoami and logout when selecting a custom service.
Authentication priority is an explicit `token`/`--token`, then `SINAPISAI_TOKEN`, then the saved session,
then anonymous access. Explicit and environment tokens are not refreshed automatically. Automation
can continue to supply a token:

```bash
set SINAPISAI_TOKEN=your-token
sinapkit download owner/model
```

Configuration:

| Setting | Purpose |
| --- | --- |
| `--endpoint URL` / Python `endpoint="URL"` | Optional API service endpoint; defaults to `https://api.sinapisai.com` |
| `SINAPISAI_TOKEN` | Optional platform Bearer token |
| `SINAPISAI_ENDPOINT` | API service endpoint; defaults to `https://api.sinapisai.com` |
| `SINAPISAI_CACHE` | Cache root |
| `SINAPISAI_DOWNLOAD_TIMEOUT` | Streaming read timeout in seconds |
| `SINAPISAI_DOWNLOAD_RETRIES` | Retry count per file |
| `SINAPISAI_DOWNLOAD_WORKERS` | Default concurrent file count |
| `--rate-limit-max-wait SECONDS` / Python `rate_limit_max_wait` | Cumulative platform HTTP retry wait budget; default 300 seconds; 0 disables these waits |
| `SINAPISAI_DOWNLOAD_RATE_LIMIT_MAX_WAIT` | Default wait budget when no explicit value is supplied |

`endpoint`/`--endpoint` takes precedence over `SINAPISAI_ENDPOINT`, then the production default.
HTTP endpoints are rejected except for localhost development. The platform token is sent only to the
configured API service and is never
sent with object-storage requests.

## Download rate limits

The SDK requests links in batches of `min(20, max_workers * 2)` files. This does not limit the total
files in a model. Rate limits apply at the platform link API; actual file bytes still come from OSS.

- Frequency limits respect the full `Retry-After`, bounded by the retry count and cumulative wait budget.
- Daily allowance failures stop immediately and preserve completed files and partial downloads.
- Rejected multi-file batches are split sequentially; an unserviceable single file reports an error.
- Temporarily unavailable download admission retries within the same budget.

Retry messages distinguish anonymous/account/global link limits from service outages. Interactive
terminals show a single updating countdown in whole seconds; fractional values round up for display
without shortening the actual wait. Quiet mode suppresses retry output; scripts, redirected output
and CI receive one reason-and-delay message per retry wait. Ctrl+C clears the countdown and preserves
download progress. Daily allowance failures stop without starting a countdown.

Run the same command again to resume after the limit clears. The wait budget does not limit OSS
transfer duration. `download` and automatically downloading `deploy` both accept
`--rate-limit-max-wait`; offline operations do not read or refresh login sessions.

See the [Chinese login and download-limit guide](docs/login-and-download-limits.md) for examples,
error codes, session storage details and release validation steps.

## Reliability

- Streams into `<filename>.part`, then atomically renames after verification.
- Resumes with HTTP Range when object storage supports it.
- Restarts safely if Range is ignored and refreshes expiring signed URLs.
- Verifies expected size and SHA-256 before exposing the final filename.
- Uses file locks to protect concurrent processes.
- Stores only model metadata in `.sinapisai-manifest.json`; credentials stay in the separate private
  session file and signed URLs are never persisted.
- Rejects absolute paths, traversal, Windows device names and escaping symbolic links.

`--force-download` downloads again. `--no-resume` discards an old partial file. `--local-files-only`
performs no network access and fails if the requested cached files are incomplete.

## Development

```bash
python -m pip install -e ".[dev]"
ruff check .
ruff format --check .
mypy src
pytest
python -m build
```

The backend contract and acceptance criteria are documented in
[`docs/2026-09-04-sinapkit-python-sdk-design.md`](docs/2026-09-04-sinapkit-python-sdk-design.md).

The optional login session and model download rate-limit integration design is documented in
[`docs/2026-09-14-sinapkit-login-and-download-rate-limit-design.md`](docs/2026-09-14-sinapkit-login-and-download-rate-limit-design.md).

The local Docker deployment design and acceptance criteria are documented in
[`docs/2026-09-09-sinapkit-deploy-design.md`](docs/2026-09-09-sinapkit-deploy-design.md).

The build, TestPyPI and production PyPI release process is documented in
[`docs/release-guide.md`](docs/release-guide.md).
