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
latestreconciliation 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:
.env- environment variables
- system storage
- built-in
nextgisserver:https://rm.nextgis.com
Supported .env variables:
REPKA_SERVER_URLREPKA_USERNAMEREPKA_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
- Verify the version in pyproject.toml and make sure the changelog or release notes are ready.
- Run the local checks:
ruff check .
ruff format --check .
pytest
- Build and validate the distribution:
rm -rf dist
python -m build
twine check dist/*
- Optionally publish to TestPyPI first:
TWINE_USERNAME=__token__ \
TWINE_PASSWORD="$TEST_PYPI_API_TOKEN" \
python -m twine upload --repository testpypi dist/*
- Publish to PyPI:
TWINE_USERNAME=__token__ \
TWINE_PASSWORD="$PYPI_API_TOKEN" \
python -m twine upload dist/*
- 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
- 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
packetinternally. The SDK exposespackage. - Backend stores release
optionsaskey:value|.... The SDK normalizes them toReleaseOptions. - 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. latestuniqueness is enforced client-side across the whole package.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c364a0c188cc8555bcd8c4a8a491617a1df2de6f4e4c31f9e84282cc72302f93
|
|
| MD5 |
3ce0c7af309f6a922ebe615a82713e26
|
|
| BLAKE2b-256 |
c6e9eab84e576fccd46dbfcabf85aad867c14e02e71ae8c0252ffa5f812dba3c
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62d09ae9acd3e518f22e54c3ae818a0cbaaa3bf07a3b68e1bae3230795dc9bac
|
|
| MD5 |
a1154c930feca2816b69d06b982d32a3
|
|
| BLAKE2b-256 |
37bc21b3e3d29c06ca529d4e6f1a296cb567dc07ced8d0fc08182c6a4af460f4
|