airpuls-sdk — command-line tool for airpuls Near-RT RIC xApps
Scaffolds, validates, runs, packages, and deploys xApp projects for the
airpuls Near-RT RIC. Distributed as airpuls-sdk-cli; the command it
installs is airpuls-sdk.
pip install airpuls-sdk-cli
Pure Python, published as a py3-none-any wheel: the tool installs
wherever Python 3.9+ runs, so a project can be created from any
developer machine. Linux and macOS are the supported platforms for the
full workflow — see Platform support.
Two distributions, two jobs
| Distribution | What it is | Platforms |
|---|---|---|
airpuls-sdk-cli |
this tool — scaffolding, lifecycle, deployment | Linux, macOS (installs anywhere Python runs) |
airpuls-ric-sdk |
the xApp runtime: Python bindings for the C client library | Linux x86_64 and aarch64 (binary wheels) |
Most commands need only the CLI. Running an xApp locally —
xapp run, and xapp test for suites that import the SDK — needs the
runtime in the same environment; install it where that applies:
pip install airpuls-sdk-cli[runtime] # Linux x86_64 / aarch64
On macOS and Windows the runtime has no wheel, which is what the
generated Dev Container is for: xapp new writes a .devcontainer/
whose Dockerfile pins an x86_64 Debian base, reproducing the
environment the runtime needs, so the project is created natively and
run inside the container. airpuls-sdk doctor reports which half is
present, and xapp run explains the missing runtime rather than
failing on an import error.
The container's architecture is the PLATFORM build argument in the
generated .devcontainer/devcontainer.json, and it is a trade-off:
linux/amd64 (the default) matches the runtime wheel so the xApp runs
and tests inside the container, at emulation speed on an arm64 host;
linux/arm64 is native and covers everything that does not execute the
xApp, since no arm64 runtime wheel exists. Creating the container
succeeds either way — the arm64 case reports why the runtime is absent
instead of failing.
Platform support
| Linux | macOS | Windows | |
|---|---|---|---|
install, xapp new, validate, info, build, add sink, config, doctor |
yes | yes | yes |
xapp deploy, undeploy, credentials |
yes | yes | SSH keys only |
xapp run, xapp test |
yes (x86_64) | Dev Container | Dev Container |
xapp package |
needs docker | needs docker | needs docker |
The deployment commands drive the OpenSSH tools. Windows ships an
OpenSSH client, so key-based authentication works, but three things do
not: the interactive password fallback (it uses the POSIX
SSH_ASKPASS mechanism), the one-time ssh-copy-id offer, and the
restrictive mode applied to a fetched client key. A Windows user
therefore needs a key the deployment host already trusts. CI runs the
suite on Linux; macOS is covered by development use, and Windows is not
exercised at all.
Quick start
airpuls-sdk xapp new my-xapp # interactive wizard; --defaults for CI
# (generates the project and git-inits it)
cd my-xapp
airpuls-sdk xapp validate # xapp.yml against xapp.schema.json
airpuls-sdk xapp build # per-language build, output captured
airpuls-sdk xapp test # run the project's tests/
airpuls-sdk xapp run # foreground run against the RIC
airpuls-sdk xapp package # <name>-<lang>:latest on airpuls-xapp-sdk
airpuls-sdk xapp info # project summary
airpuls-sdk xapp add sink --file … # configure a telemetry destination
airpuls-sdk xapp deploy # entry → nrtric-ctrl host over SFTP
airpuls-sdk xapp undeploy # remove the entry from the host
airpuls-sdk xapp credentials # register identity + fetch mTLS material
airpuls-sdk config ric add lab … # register a RIC (several allowed)
airpuls-sdk doctor # environment diagnostics
Telemetry sinks
An xApp emits into two channels — timeseries for numeric samples and
structured for event records — and xapp add sink configures a
destination for them in xapp.yml:
airpuls-sdk xapp add sink # asks what to add
airpuls-sdk xapp add sink --file ./events.jsonl # structured
airpuls-sdk xapp add sink --redis redis://host:6379/0 # both channels
airpuls-sdk xapp add sink --influxdb http://host:8086 # timeseries
Invoked without a destination on a terminal, the command asks which one
to add and for the values it needs, each with its default in brackets.
The InfluxDB organization and bucket default to what the deployment
provisions — its InfluxDB setup creates a fixed xapp_metrics bucket
for xApps beside the RIC's own — so a URL alone is a complete
destination; --org and --bucket override them.
A destination serving both channels is added to both; --channel timeseries|structured narrows it. Only the keys the destination
determines are written — every other setting keeps its schema default —
and the manifest is validated before it is saved, so a sink never
leaves xapp.yml violating its own contract. An already-configured
sink is reported rather than replaced, and comments in the file
survive the edit.
Credentials never appear on the command line or in the manifest:
--token-env NAME (InfluxDB, default INFLUX_TOKEN) and
--password-env NAME (Redis) record the name of the environment
variable holding the secret. A secret typed as an argument would be
kept in the shell history and written into xapp.yml, which is
committed with the project and uploaded to the deployment host, so a
value that is not a variable name is refused rather than stored — and
the prompts ask for the variable name too, never the secret. Add a
destination without switching it on with --disabled.
Deployment
Deployment follows the nrtric-ctrl pattern: every generated project
includes an executable <name>.xapp docker-run launcher, and
xapp deploy uploads the entry the stack consumes — launcher,
xapp.yml, xapp.schema.json — into <nrtric-ctrl>/xapps/<name>/ on
a registered host. The project source is never uploaded; the runtime
artifact is the docker image the launcher references (--image on
xapp new, default the local xapp package tag). The image reaches
the host through a registry, or directly with
xapp deploy --with-image (docker save streamed into docker load
over SSH).
Several RICs can be registered (config ric add/list/use/remove);
operations pick one with --ric, the registry default, or an
interactive list. Transfers use the OpenSSH tools: key authentication
first (an identity file can be stored per RIC or passed per command),
and when the host denies it on an interactive terminal the CLI asks for
the SSH password — masked, held only in process memory for that
invocation, fed to OpenSSH through askpass so it never reaches a
command line or a log — while config ric add offers a one-time
ssh-copy-id that makes every later connection passwordless.
TLS
tls:// is first-class through the whole flow, and the RIC's own listener configuration is the source of truth for the transport:
xapp newwith atls://endpoint emits theric.tlsfile set the schema requires, at the paths the launcher mounts, and registers the xApp's identity with the RIC when a target is already configured.xapp deployreads the RIC's listener configuration before uploading. Against a tls:// listener it mints the client certificate (CN = deployment name, the RIC's identity binding), places CA, certificate, and key beside the deployed launcher, and — when the project still dials tcp:// — adapts the uploadedxapp.ymlcopy so a scheme mismatch cannot be deployed. Against a plaintext listener a tls:// project is refused: the CLI never downgrades a secured configuration.xapp credentialsregisters the identity and fetches CA + client pair into the project'scerts/directory, whichxapp runpicks up automatically.
Output
Subcommand output is never passed through to the terminal: the CLI
captures it, reports the outcome with its cause and an excerpt on
failure, and writes the full transcript under the project's
.airpuls/logs/. Exit codes are typed: 1 generic, 2 usage,
3 validation, 4 subprocess, 5 toolchain/environment.
JSON output for editor integrations
--json, placed before the command (or AIRPULS_SDK_JSON=1), makes
every command write exactly one JSON document on stdout instead of
rendered text:
airpuls-sdk --json xapp info
airpuls-sdk --json doctor # one record per environment check
airpuls-sdk --json config ric list # registered targets, for a picker
{"schema": 1, "ok": true, "command": "xapp info",
"data": {"name": "my-xapp", "endpoint": "tls://ric:36422", "…": "…"},
"warnings": []}
schema, ok, command, data, and warnings are common to every
command; data fields are per command. A failure adds an error
block — kind (usage, validation, subprocess, toolchain,
interrupted, internal), message, cause, hint, detail, and
the transcript path in log — and the process exit status is the same
in both modes, so a caller can branch on the status and read the
document only when it is non-zero.
--json --help answers with the command surface as data — the
subcommands a group holds, and the arguments and options a command
accepts, with their defaults and required flags — so an integration can
build its own affordances without scraping help text.
The mode also makes every command non-interactive: nothing prompts, so
a missing answer fails with a usage error naming the option to pass
(xapp new needs its options or --defaults, xapp undeploy needs
--yes) rather than blocking on a question nothing can answer.
Warnings become warnings entries instead of terminal lines, and the
streamed output of xapp run moves to stderr, keeping stdout a single
document; its transcript path is in data.log.
Development
The suite runs without the xApp runtime and without a native build:
pip install -e .[test]
pytest tests
Metadata
Release files for airpuls-sdk-cli 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| airpuls_sdk_cli-0.1.4-py3-none-any.whl | Python 3 | none | any | Details for airpuls_sdk_cli-0.1.4-py3-none-any.whl |
Release files / airpuls_sdk_cli-0.1.4-py3-none-any.whl
| Download URL | airpuls_sdk_cli-0.1.4-py3-none-any.whl |
|---|---|
| Size | 103.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b854a0e1763f05388eebd79f020eb48ea5276b6dbb3497c0e0970e62875440fb
|
|
BLAKE2b-256 checksum How to use checksums |
88fe11f5ebd8dd50d2c96a26a79b3fc97bdd35dbde698c204030be298c113d3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.11
|
Security for airpuls-sdk-cli 0.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.