Metadata-Version: 2.4
Name: modelpack-client
Version: 0.1.0
Summary: Python client for pushing and pulling CNCF ModelPack OCI artifacts
Keywords: 
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
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: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Python :: 3.16
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: jsonschema>=4.18
Requires-Dist: oras>=0.2.43,<0.3
Requires-Dist: zstandard>=0.23
Requires-Python: >=3.10
Project-URL: Homepage, https://github.com/SiLeader/modelpack-py
Project-URL: Issue, https://github.com/SiLeader/modelpack-py/issues
Description-Content-Type: text/markdown

# modelpack

Python client for pushing and pulling
[CNCF ModelPack](https://github.com/modelpack/model-spec) artifacts through any
OCI Distribution-compatible registry, including Harbor, Docker Hub, and GHCR.

## Installation

```console
pip install modelpack-client
```

## Python API

```python
from modelpack_client import (
    ModelDescriptor,
    ModelLayer,
    ModelPackClient,
    ModelPackConfig,
    ModelTechnicalConfig,
)

client = ModelPackClient()
client.login(
    "ghcr.io",
    username="octocat",
    password="TOKEN",
)

config = ModelPackConfig(
    descriptor=ModelDescriptor(
        name="example-model",
        version="1.0.0",
        licenses=("Apache-2.0",),
    ),
    config=ModelTechnicalConfig(
        architecture="transformer",
        format="safetensors",
        param_size="7B",
        precision="float16",
    ),
)

result = client.push(
    "ghcr.io/example/models/example:1.0.0",
    layers=[
        ModelLayer("model.safetensors"),
        ModelLayer(
            "tokenizer.json",
            media_type="application/vnd.cncf.model.weight.config.v1.raw",
        ),
    ],
    config=config,
)
print(result.digest)

pulled = client.pull(
    "ghcr.io/example/models/example:1.0.0",
    "./example-model",
)
print(pulled.files)
print(pulled.config)
```

Directories passed as layers are packed as tar layers: a raw media type becomes
the matching tar type, and the `+gzip` and `+zstd` tar types are compressed.
Entries are sorted, and owners, timestamps and permissions (except the
executable bit) are normalized, so the same tree gets the same digest on any
machine. Hard links are stored as regular files; symbolic links are rejected.

The client sets the required ModelPack artifact/config media types, generates
`modelfs.diffIds`, validates configs against the specification's JSON schema,
verifies manifests and blobs against their digests, and rejects unsafe artifact
and archive paths.

`pull()` unpacks tar layers into the destination directory. With
`unpack=False`, they are saved as archives named after the layer's file path,
such as `weights.tar`. `push()` streams each blob in a single request; pass
`chunked=True` for registries that require chunked uploads. Each layer must be
pulled to its own path, so give files that share a name an `artifact_path`.

To use Docker's existing credential file, omit `login()`. `oras-py` loads
credentials from the standard registry configuration. A custom file can be
passed as `config_path` to `push()` or `pull()`, and its entries take
precedence. Credential files are read again on every call. `login()` saves
credentials to Docker's file or `config_path`, and `logout()` removes them from
the same file. Credentials and tokens are only sent to the registry they belong
to; an upload that the registry sends to another host goes without them.

## CLI

```console
modelpack push ghcr.io/example/models/example:1.0.0 \
  --config model-config.json \
  --layer model.safetensors \
  --layer 'tokenizer.json:application/vnd.cncf.model.weight.config.v1.raw'

modelpack pull ghcr.io/example/models/example:1.0.0 ./model
```

`python -m modelpack_client` runs the same CLI.
