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, andreplace_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:
dotenvenv- configured default server
- built-in
nextgisserver: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_URLREPKA_USERNAMEREPKA_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 serverdotenv: server and credentials from.envenv: 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 .envcredentials stay in the dotenv fileenvcredentials are exported back to the shell asexportorunsetcommands
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 dotenvandrepka auth login envdo not prompt for the server URL.- The reserved source URL is taken from
server set-urlwhen configured; otherwise the command authenticates against the active server resolved by the priority order. repka auth logoutasks for confirmation when the server is not passed explicitly.repka auth logout envandrepka auth logout dotenvremain explicit and do not ask for confirmation.eval "$(...)"is required forenvcommands 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 finduses substring matching by default.- Use
--exactfor exact name matching. - Use
--typeto limit repository, package, or release search to a repository type:any,ubuntu,docker,borsch,installer,qgis,maven. - Use
--limitto cap the number of printed rows. - Release search shows
assets_countby default. - Use
--field allto print every available table field. - Sorting supports local fields such as
assets_count; server-side sort values are normalized automatically to+fieldor-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 asrepka auth, and commands that need required arguments such asrepka findprints help instead of a raw usage error. - In table output,
server listis grouped by source in this order:builtin,system,env,dotenv. - The
defaultandactivecolumns 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 allinstead of the old--alloutput flag. - The short release tag option is
-t(previously-g). - Global
--json,--server, and logging options precede the command. - Release writes accept
--repofor package names and--packagefor release names; numeric IDs do not require name lookup. package update IDworks without a repository argument.
Notes
- Backend uses
packetinternally; the SDK exposespackage. - Backend stores release options as
key:value|...; the SDK normalizes them toReleaseOptions. - 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.
latestuniqueness is enforced client-side within a package.- Supply the parent
Packageto release writes to avoid parent discovery on servers that omitpacket_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)
| File | Size | Uploaded | |
|---|---|---|---|
| repka_sdk-1.1.0.tar.gz | 84.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|