Skip to main content

repka-sdk

Python SDK and CLI for Repka artifact storage.

Overview

repka-sdk provides a typed Python client and a practical CLI for working with Repka repositories, packages, releases, assets, and selected administrative endpoints.

Highlights:

  • Synchronous client: RepkaClient
  • Asynchronous client: AsyncRepkaClient
  • CLI: repka
  • CRUD operations for repositories, packages, releases, and assets
  • Sync discovery endpoints and repository-specific helpers
  • Name, ID, URL, and UI URL resolution helpers
  • Idempotent workflows such as ensure_package, ensure_release, and replace_release

Installation

Install from PyPI:

pip install repka-sdk

The distribution name is repka-sdk, while the Python import name remains repka_sdk.

For local development:

pip install -e .[dev]

Arch Linux packaging files are available in packaging/arch.

Configuration

Resolution order

When the server is not specified explicitly, the active server is resolved in this order:

  1. dotenv
  2. env
  3. configured default server
  4. built-in nextgis server: https://rm.nextgis.com

Credential overlays follow the same rule. .env credentials win over process environment credentials, and both can be applied to the active server even when they do not define their own REPKA_SERVER_URL. Credentials that specify another server URL are never overlaid onto the active server. An explicit --server URL works without a saved server definition.

Supported variables

The SDK and CLI recognize these variables in .env and in the process environment:

  • REPKA_SERVER_URL
  • REPKA_USERNAME
  • REPKA_PASSWORD

Example .env:

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

Reserved server names

The CLI exposes three reserved names:

  • nextgis: built-in public server
  • dotenv: server and credentials from .env
  • env: server and credentials from the current shell environment

When REPKA_USERNAME and REPKA_PASSWORD are present without REPKA_SERVER_URL, they are applied to the currently active server resolved by the priority above rather than creating a standalone dotenv or env server.

Storage model

  • System server definitions are stored in repka-sdk/servers.json
  • System credentials are stored in keyring
  • .env credentials stay in the dotenv file
  • env credentials are exported back to the shell as export or unset commands

Python API

Sync client

CLI configuration resolution is separate from the Python constructors: RepkaClient() and AsyncRepkaClient() use the built-in public server unless you pass base_url. Pass an authentication provider explicitly in Python.

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


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

with RepkaClient(auth_provider=provider) as client:
    uploaded = client.assets.upload("dist/plugin.zip")
    release = client.releases.ensure(
        42,  # Package ID; name lookup requires a repository.
        ReleaseInput(
            name="Release 3.2.1",
            tags=["experimental", "latest"],
            options=ReleaseOptions({"dist": "stable"}),
            assets=[uploaded],
        ),
        version_tag="3.2.1",
        enrich_assets=True,
    )
    print(release.id)

Additional endpoints remain available for automation-heavy workflows:

from repka_sdk import BasicAuthProvider
from repka_sdk import RepkaClient


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

with RepkaClient(auth_provider=provider) as client:
    print(client.server.stats())
    print(client.server.options())
    print(client.assets.rights(42))
    print(client.sync.list_remote_repositories("borsch"))
    print(client.admin.list_users())

Async client

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
  • --log-file PATH
  • --log-level LEVEL (requires --log-file, default: INFO)
  • --dry-run

Place global options before the command, for example repka --json repo list. Use -h or --help on any command. --dry-run never uploads files or changes stored credentials. Repository creation defaults to --no-cleanup; retention values default to 1 because the current server rejects zero values.

Authentication and server management

repka server add staging https://rm.staging.nextgis.com --default
repka server set-url dotenv https://rm.staging.nextgis.com
eval "$(repka server set-url env https://rm.staging.nextgis.com)"

repka auth login staging --username editor --password-stdin
repka auth login dotenv --username editor --password-stdin
eval "$(repka auth login env --username editor --password-stdin)"

repka auth list
repka auth status
repka auth params
repka --json auth params
repka auth params --show-password
repka server list
repka server status

Notes:

  • repka auth login dotenv and repka auth login env do not prompt for the server URL.
  • The reserved source URL is taken from server set-url when configured; otherwise the command authenticates against the active server resolved by the priority order.
  • repka auth logout asks for confirmation when the server is not passed explicitly.
  • repka auth logout env and repka auth logout dotenv remain explicit and do not ask for confirmation.
  • eval "$(...)" is required for env commands because a child process cannot modify the parent shell environment directly.

When --verbose is enabled, the CLI writes HTTP request and response logs to stderr. --log-file PATH enables persistent diagnostic logging; --log-level DEBUG includes HTTP timings. Unexpected failures report a private temporary log with stack locations and exception types, without credentials or response payloads.

auth params prints one field per line, including url, server source, auth_source, and auth_type (basic or anonymous). Passwords are omitted unless --show-password is passed, including in JSON mode. This command shows local configuration; use auth status to check it against the server.

Search behavior

repka find package plugin
repka find package identifyplus --exact
repka find package --repo 4 identifyplus --limit 10

repka find repo qgis --type qgis

repka find release 2
repka find release --option arch=x64 --sort=name
repka find release --type installer --sort=-assets_count
repka find release --option arch=x64 --field all

Search rules:

  • repka find uses substring matching by default.
  • Use --exact for exact name matching.
  • Use --type to limit repository, package, or release search to a repository type: any, ubuntu, docker, borsch, installer, qgis, maven.
  • Use --limit to cap the number of printed rows.
  • Release search shows assets_count by default.
  • Use --field all to print every available table field.
  • Sorting supports local fields such as assets_count; server-side sort values are normalized automatically to +field or -field.

Common CLI examples

QtIFW installer repositories

Publish a repository produced by Qt Installer Framework's repogen into a Repka repository of type installer:

repka release create --repo installers --package stable --name 2.0.0 \
  --qtifw ./repogen-output --repository-name repository-linux

For a directory, the default archive/root name is repository; the example uploads repository-linux.zip containing repository-linux/Updates.xml and the component files. A supplied ZIP is validated and uploaded unchanged: its only top-level directory must match its filename stem. --repository-name cannot rename an existing ZIP. A single --file ZIP/directory in an installer repository also selects this workflow. Other installer artifacts use normal file uploads.

Validation checks XML structure, component names/versions, referenced data archives, declared component or unified metadata archives, and required SHA1 sidecar files. ZIP integrity, paths, and server-supported compression are checked before upload. This validates the repository layout, not the contents of inner 7z archives or an actual installer run. --dry-run validates without packing or uploading.

Normal output is the URL to pass to QtIFW, for example:

https://rm.example.com/api/repo/42/installer/stable/repository-linux

JSON output contains url, url_query_string, and release. With --no-latest, pass the separately printed UrlQueryString=release_tag=... argument to the installer too. Do not append this query to the repository URL: QtIFW appends /Updates.xml and archive paths itself. The default URL follows the package's latest release; keep the same archive/root name across updates.

Release publication defaults

release create, ensure, update, and replace mark the release latest by default. Use --no-latest to omit/remove that tag. QGIS publications always omit latest: the plugin index selects versions itself. When no version tags are supplied, publication uses the release name as its version tag. Repository type is resolved before uploading, including for package IDs without parent metadata; --repo can narrow that lookup. Dry runs perform these reads but no writes. Low-level SDK methods continue to use the explicitly supplied tags.

repka whoami
repka repo list --field id --field type --field name
repka repo list --field all
repka --json repo list

repka package ensure --repo my-repo --name my-package --description "SDK managed"

repka release ensure \
  --package 42 \
  --name "Release 1.2.3" \
  --version-tag 1.2.3 \
  --latest \
  --option dist=stable \
  --enrich-assets \
  --file dist/package.zip

repka release get --package 42 "Release 1.2.3"
repka asset list 77 -F id,name,size,downloads
repka --json asset upload dist/package.zip
repka asset download --all 77 ./downloads/
repka --json asset rights 42
repka browse release 77 --print-url
repka --json browse --print-url

Output behavior

  • Calling repka, command groups such as repka auth, and commands that need required arguments such as repka find prints help instead of a raw usage error.
  • In table output, server list is grouped by source in this order: builtin, system, env, dotenv.
  • The default and active columns use ✓.
  • In JSON mode, scalar values are wrapped into an object:
{"value": "https://rm.staging.nextgis.com"}

Search propagates authentication, network, and server failures with a nonzero exit code rather than reporting an empty successful result. Empty API lists serialized as null are still accepted. Explicit --sort order is preserved in both tables and JSON. Search/upload/download status goes to stderr, with a spinner on terminals and stable lines when redirected.

Examples

See examples/_common.py, examples/async_whoami.py, and examples/async_list_entities.py.

CLI migration notes

  • List commands use --field all instead of the old --all output flag.
  • The short release tag option is -t (previously -g).
  • Global --json, --server, and logging options precede the command.
  • Release writes accept --repo for package names and --package for release names; numeric IDs do not require name lookup.
  • package update ID works without a repository argument.

Notes

  • Backend uses packet internally; the SDK exposes package.
  • Backend stores release options as key:value|...; the SDK normalizes them to ReleaseOptions.
  • Metadata-only release updates preserve existing asset IDs when possible.
  • Clearing all assets from an existing release is intentionally rejected until the server can safely handle files: [].
  • Clearing a nonempty release description, all tags, or all options is rejected because the current server silently ignores those empty values.
  • latest uniqueness is enforced client-side within a package.
  • Supply the parent Package to release writes to avoid parent discovery on servers that omit packet_id. Client-side reconciliation is not atomic across concurrent publishers; the server must enforce uniqueness for that guarantee.
  • Downloads sanitize server-provided filenames and replace local files only after the response is received successfully.

Metadata

Release files for repka-sdk 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for repka-sdk 1.1.0
File Size Uploaded
repka_sdk-1.1.0.tar.gz 84.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for repka-sdk 1.1.0
File Interpreter ABI Platform
repka_sdk-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 157.7 kB

Release files / repka_sdk-1.1.0.tar.gz

Download URL repka_sdk-1.1.0.tar.gz
Size 84.1 kB
Tags Source
SHA-256 checksum
How to use checksums
7db22de73fa38224b2c016c0339f8e49af5abd4bfd055c91d3c8a51b5589b192
BLAKE2b-256 checksum
How to use checksums
e24f1319cde6b19f8f9b5f7285ef1bbf1579f075a6f7a529c817178b48e70c6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.20

Release files / repka_sdk-1.1.0-py3-none-any.whl

Download URL repka_sdk-1.1.0-py3-none-any.whl
Size 73.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a04f8c44bafca788ea639a778f0efd56db2570b9e25161a6038f3318cbe10aff
BLAKE2b-256 checksum
How to use checksums
1a10888546df46640436a619ad3de31d0a1624dd9c65732f316e772ccf4d31ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.20

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page