Metadata-Version: 2.4
Name: juntai-artifact-client
Version: 1.0.2
Summary: Internal gRPC metadata and direct OCI artifact client for Juntai
Project-URL: Repository, https://github.com/zephytiju/JuntaiArtifactClient
Project-URL: Issues, https://github.com/zephytiju/JuntaiArtifactClient/issues
License: Proprietary
Requires-Python: >=3.11
Requires-Dist: grpcio<2.0.0,>=1.81.1
Requires-Dist: oras==0.2.42
Requires-Dist: protobuf==6.33.6
Provides-Extra: dev
Requires-Dist: build==1.3.0; extra == 'dev'
Requires-Dist: pytest==9.0.2; extra == 'dev'
Requires-Dist: ruff==0.14.14; extra == 'dev'
Description-Content-Type: text/markdown

# Juntai Artifact Client

`juntai-artifact-client` is the backend Python client for immutable, OCI-backed Juntai artifacts.
It consumes Artifact Registry's pinned `juntai.registry.artifact.v1` Protobuf contract through
generated gRPC stubs. Artifact bytes move directly between backend Python code and OCI; Artifact
Registry receives metadata only over authenticated internal gRPC.

Deterministic build-time generation uses the immutable FuseAPI profile requirement
`juntai-fuse-api[grpc-generated]==1.1.2` (`juntai.fuse.profile.grpc-generated` v1.0.0), with
`grpcio-tools==1.81.1` and `protobuf==6.33.6`. The Registry—not FuseAPI or this client—owns the
versioned `.proto` semantics. FuseAPI 1.1.2 is consumed only as its normal public PyPI requirement
from source commit `198ada7436bffefdd035f92d7e5158283f9b14f0` during generation and verification.
It is not a runtime dependency: the wheel ships the generated stubs, whose runtime dependencies are
`grpcio` and `protobuf`.

## Install

```bash
python -m pip install "juntai-artifact-client>=1,<2"
```

Stable imports are under `juntai.artifact`. Generated stubs are an internal implementation detail
under `juntai.artifact.generated.juntai.registry.artifact.v1`.

```python
from juntai.artifact import ArtifactClient, ArtifactLayer
from juntai.artifact.oci import OrasOCITransport

oci = OrasOCITransport(
    registry=internal_oci_registry,
    repository_prefix="juntai/artifacts",
    client=oras_client,
)

artifacts = ArtifactClient.connect(
    registry_target="dns:///artifact-registry.platform.svc:7443",
    registry_credentials=workload_or_mtls_credentials,
    oci=oci,
)
published = artifacts.publish(
    namespace="lattice",
    name="fraud-ontology",
    kind="lattice.ontology",
    version="3.2.0",
    layers=[
        ArtifactLayer(
            media_type="application/vnd.juntai.lattice.ontology.v1+json",
            data=ontology_bytes,
        )
    ],
    provenance={
        "producer_identity": "build/lattice",
        "source_revision": git_sha,
        "build_id": build_id,
        "created_at": "2026-08-13T12:00:00Z",
    },
    idempotency_key=request_id,
)

layers = artifacts.resolve_and_download(published.reference)
```

Backend services that only need authoritative exact metadata do not construct or receive an OCI
transport. TLS or mTLS channel credentials prove the service workload identity; the original
caller or delegated identity is supplied separately as per-request gRPC call credentials:

```python
from juntai.artifact import ArtifactClient

metadata_client = ArtifactClient.connect(
    registry_target="dns:///artifact-registry.platform.svc:7443",
    registry_credentials=mtls_channel_credentials,
)
metadata = metadata_client.resolve_metadata(
    artifact_id=reference.artifact_id,
    version_id=reference.version_id,
    digest=reference.manifest_digest,
    caller_credentials=request_call_credentials,
    timeout=5.0,
    correlation_id=request_id,
    cancellation=cancellation,
)
if metadata.deprecated:
    raise DeprecatedArtifactError(metadata.deprecated_at)
```

`caller_credentials` is required for metadata-only resolution and accepts either
`grpc.CallCredentials` or a `CallCredentialsProvider`. Providers are resolved again for every RPC
attempt so short-lived or rotated caller/delegation credentials are honored. Credential values
cannot be supplied through generic metadata and are excluded from client representations and
translated errors. `resolve_metadata` invokes only Artifact Registry's service-owned
`GetArtifactVersion` RPC; it validates the exact `artifact_id`, `version_id`, and digest and returns
an `ArtifactReference` preserving `tenant_id`, `deprecated`, and `deprecated_at` without any OCI
construction or call.

The publisher pushes every content-addressed blob and the canonical manifest before registering
metadata. The resolver pulls by the exact `sha256` manifest digest and fails closed on digest,
media-type, identity, or provenance mismatch. Metadata registration failure is classified as a
partial failure and can be retried with the same idempotency key; an unreferenced OCI manifest may
remain for ordinary registry retention.

A durable `ArtifactReference` preserves both Registry-issued identities: the stable `artifact_id`
and the immutable `version_id`. Neither identity is collapsed into a generic resource ID, and exact
resolution also verifies the tenant, owner, manifest digest, and deprecation state carried by that
reference.

Channels and credentials remain behind the stable client. Workload identity or mTLS, explicit
deadlines, cooperative cancellation, correlation IDs, idempotent retries, and canonical gRPC
status translation are supported without exposing Registry or OCI capabilities to browser code.

This package intentionally has no REST/OpenAPI client, TypeScript/npm output, activation,
deployment, rollback, database, service runtime, or domain-schema behavior.

The superseded distribution name `juntai-artifact` is not an alias and is never republished by
this repository. The stable import remains `juntai.artifact`.

## Verification

```bash
python -m pip install -e '.[dev]'
python -m pip install -r requirements/generation.txt
pytest -q
ruff check .
ruff format --check .
python -m build
python scripts/verify_clean_install.py dist
```

Acceptance requires both a real OCI Distribution-compatible registry and a real 01F Artifact
Registry gRPC service. Fixture registries and in-memory metadata authorities are unit-test aids,
not acceptance evidence.

The generated stubs are pinned to Artifact Registry v1.0.1 at source commit
`0552d9f4a62d81d58452e1106b0e24d2b02c8700` and immutable Protobuf bundle
`oci://ghcr.io/zephytiju/juntai-artifact-registry-protobuf@sha256:d7da1ceedb1098f19e5f6dc77dbef41c5bc797caa8c92969a9b08a7e10ce736d`.
Artifact Registry v1.0.0 and earlier REST/OpenAPI releases are superseded and are not accepted as
contract or release evidence.

Release and PyPI Trusted Publisher coordinates are documented in
[`RELEASING.md`](RELEASING.md). The canonical source repository is
[`zephytiju/JuntaiArtifactClient`](https://github.com/zephytiju/JuntaiArtifactClient); release
evidence must use that exact owner/name rather than a redirect.
