Skip to main content

Python SDK and CLI for Repka artifact storage

Project description

repka-sdk

Python SDK and CLI for Repka artifact storage.

Features

  • Sync client: RepkaClient
  • Async client: AsyncRepkaClient
  • CLI: repka
  • CRUD for repositories, packages, releases
  • Asset upload and download
  • Server metadata, statistics, asset rights, and sync discovery endpoints
  • Repository content helpers for borsch, installer, QGIS, and Debian routes
  • Administrative settings, user/group, jobs, sign-code, and Apple certificate endpoints are available as raw dictionaries through client.admin
  • Resolve by id, name and canonical UI/API URL
  • ensure_package, ensure_release, replace_release, add_assets
  • Client-side latest reconciliation inside a package
  • Config resolution from .env, environment variables and system storage

Installation

pip install repka-sdk

For local development:

pip install -e .

The package name on PyPI is repka-sdk. In Python code the import remains repka_sdk.

For development dependencies:

pip install -e .[dev]

Arch Linux packaging files are available in packaging/arch. After a PyPI release, build and install with:

cd packaging/arch
makepkg -si

Configuration

Read order is fixed:

  1. .env
  2. environment variables
  3. system storage
  4. built-in nextgis server: https://rm.nextgis.com

Supported .env variables:

  • REPKA_SERVER_URL
  • REPKA_USERNAME
  • REPKA_PASSWORD

Example .env:

REPKA_SERVER_URL=https://rm.staging.nextgis.com
REPKA_USERNAME=editor
REPKA_PASSWORD=secret

The .env file is exposed in the CLI as the reserved server name dotenv. The built-in public server is exposed as the reserved server name nextgis. Use --server dotenv to force .env; if REPKA_SERVER_URL is absent, the CLI reports a configuration error.

System server configs are stored in the standard config directory under repka-sdk/servers.json. Passwords for named system servers are stored through keyring.

Sync API

from repka_sdk import BasicAuthProvider
from repka_sdk import RepkaClient
from repka_sdk import ReleaseOptions
from repka_sdk import ReleaseInput

provider = BasicAuthProvider("editor", "secret")

with RepkaClient(auth_provider=provider) as client:
    repositories = client.repositories.list()
    stats = client.server.stats()
    uploaded = client.assets.upload("dist/plugin.zip")
    release = client.releases.ensure(
        "my-package",
        ReleaseInput(
            name="Release 3.2.1",
            tags=["experimental", "latest"],
            options=ReleaseOptions({"dist": "stable"}),
            assets=[uploaded],
        ),
        version_tag="3.2.1",
        enrich_assets=True,
    )

Additional server endpoints are exposed directly when automation needs them. Release publishing itself is repository-type agnostic and goes through client.releases or the repka release CLI commands:

with RepkaClient(auth_provider=provider) as client:
    server_options = client.server.options()
    rights = client.assets.rights(42)
    remote_repos = client.sync.list_remote_repositories("borsch")
    remote_packages = client.sync.list_remote_packages(
        "borsch",
        remote_repos[0]["id"],
    )
    users = client.admin.list_users()

Async API

import asyncio

from repka_sdk import AsyncRepkaClient
from repka_sdk import BasicAuthProvider


async def main() -> None:
    provider = BasicAuthProvider("editor", "secret")
    async with AsyncRepkaClient(
        auth_provider=provider,
    ) as client:
        user = await client.auth.whoami()
        print(user.login)


asyncio.run(main())

CLI

Global options:

  • --server
  • --json
  • --timeout
  • --insecure
  • --verbose
  • --dry-run

Examples:

repka server add staging https://rm.staging.nextgis.com --default
repka server set-url dotenv https://rm.staging.nextgis.com --username editor
repka server get-url dotenv
repka auth login staging --username editor --password-stdin
repka auth login dotenv --username editor --password-stdin --force
repka auth status
repka auth params --json
repka whoami
repka repo list --field id --field type --field name
repka repo list --all
repka repo list --json
repka server list
repka server status
repka server stats --json
repka server remote-repos
repka server remote-packages
repka package ensure --repo my-repo --name my-package --description "SDK managed"
repka release ensure \
  --package my-package \
  --name "Release 1.2.3" \
  --version-tag 1.2.3 \
  --latest \
  --option dist=stable \
  --enrich-assets \
  --file dist/package.zip
repka release get --package my-package "Release 1.2.3"
repka asset list 77 -F id,name,size,downloads
repka asset upload dist/package.zip --json
repka asset download 42 ./downloads/
repka asset download --all 77 ./downloads/
repka asset rights 42 --json
repka browse release 77 --print-url

--dry-run never performs write operations. It emits the planned action and the payload that would be sent.

Examples

See examples/_common.py, synchronous scripts, and async scripts such as async_whoami.py and async_list_entities.py.

Tests

pytest

Integration tests are skipped unless .env or explicit environment variables point to a live Repka server.

Manual Release Smoke Test

These commands exercise the CLI release flow against a configured server. Use a test repository because the release creation commands modify server state.

export REPKA_SERVER=staging
export REPKA_REPO=repka-sdk-smoke-repo
export REPKA_PACKAGE=repka-sdk-smoke-package
export REPKA_VERSION=1.0.0-smoke

printf 'repka sdk smoke asset\n' > /tmp/repka-sdk-smoke.txt

repka --server "$REPKA_SERVER" repo list -F id,type,name,description
repka --server "$REPKA_SERVER" package ensure \
  --repo "$REPKA_REPO" \
  --name "$REPKA_PACKAGE" \
  --description "Created by repka-sdk smoke test"

repka --server "$REPKA_SERVER" release create \
  --package "$REPKA_PACKAGE" \
  --name "Smoke $REPKA_VERSION" \
  --version-tag "$REPKA_VERSION" \
  --latest \
  --option channel=smoke \
  --option arch=any \
  --file /tmp/repka-sdk-smoke.txt

repka --server "$REPKA_SERVER" release get \
  --package "$REPKA_PACKAGE" \
  "Smoke $REPKA_VERSION"

repka --server "$REPKA_SERVER" asset list \
  "Smoke $REPKA_VERSION" \
  --package "$REPKA_PACKAGE" \
  -F id,name,size,downloads

For idempotent checks, replace release create with release ensure. Add --enrich-assets when a repeated publish should keep existing files whose names are absent from the new upload set; files with matching names are replaced. To test download, take the release ID from release get and run:

repka --server "$REPKA_SERVER" asset download --all <release-id> /tmp

Publishing to PyPI

  1. Verify the version in pyproject.toml and make sure the changelog or release notes are ready.
  2. Run the local checks:
ruff check .
ruff format --check .
pytest
  1. Build and validate the distribution:
rm -rf dist
python -m build
twine check dist/*
  1. Optionally publish to TestPyPI first:
TWINE_USERNAME=__token__ \
TWINE_PASSWORD="$TEST_PYPI_API_TOKEN" \
python -m twine upload --repository testpypi dist/*
  1. Publish to PyPI:
TWINE_USERNAME=__token__ \
TWINE_PASSWORD="$PYPI_API_TOKEN" \
python -m twine upload dist/*
  1. Install the published package in a clean environment and smoke-test the CLI:
python -m venv /tmp/repka-sdk-release-check
/tmp/repka-sdk-release-check/bin/pip install repka-sdk==1.0.0
/tmp/repka-sdk-release-check/bin/repka --version
/tmp/repka-sdk-release-check/bin/repka server list
  1. If the PyPI sdist changed, update packaging/arch/PKGBUILD with the final sha256sum dist/repka_sdk-<version>.tar.gz.

Build artifact filenames use the normalized Python distribution form, so the sdist and wheel filenames keep the underscore: repka_sdk-<version>....

Notes

  • Backend uses packet internally. The SDK exposes package.
  • Backend stores release options as key:value|.... The SDK normalizes them to ReleaseOptions.
  • Release update is file-replacing on the server, so the SDK preserves existing asset ids when doing metadata-only updates.
  • Clearing all assets from an existing release is intentionally rejected by the SDK until the server can safely handle files: []; the SDK will not recreate a release because that changes its ID.
  • latest uniqueness is enforced client-side across the whole package.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

repka_sdk-1.0.0.tar.gz (58.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

repka_sdk-1.0.0-py3-none-any.whl (57.6 kB view details)

Uploaded Python 3

File details

Details for the file repka_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: repka_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 58.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for repka_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c364a0c188cc8555bcd8c4a8a491617a1df2de6f4e4c31f9e84282cc72302f93
MD5 3ce0c7af309f6a922ebe615a82713e26
BLAKE2b-256 c6e9eab84e576fccd46dbfcabf85aad867c14e02e71ae8c0252ffa5f812dba3c

See more details on using hashes here.

File details

Details for the file repka_sdk-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: repka_sdk-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 57.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for repka_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 62d09ae9acd3e518f22e54c3ae818a0cbaaa3bf07a3b68e1bae3230795dc9bac
MD5 a1154c930feca2816b69d06b982d32a3
BLAKE2b-256 37bc21b3e3d29c06ca529d4e6f1a296cb567dc07ced8d0fc08182c6a4af460f4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page