Skip to main content

A batteries-included CLI framework for building standalone DevOps tools.

Project description

untaped

untaped is a batteries-included CLI framework for building standalone DevOps tools on cyclopts. It is an SDK, not an app: there is no central untaped command. You build a tool, depend on the SDK, and ship an independent CLI.

The SDK gives every tool, for free:

  • Config — a shared ~/.untaped/config.yml with top-level active: / profiles:, per-profile SDK http / ui settings, and each tool's own profile settings plus tool-managed top-level state.
  • Profiles — named overlays (dev, prod, homelab) and a --profile root option, built in.
  • Themes — built-in theme presets for consistent terminal styling.
  • Output — consistent --format json|yaml|table|raw|pipe and --columns, so commands compose. pipe is a self-describing NDJSON record stream another untaped tool can read back. emit(...) renders a single entity as a vertical detail view or a sequence as a collection, dispatching by shape.
  • HTTP / UI helpers — an HttpClient with profile-aware TLS, automatic retries for transient failures (RetryPolicy), and pagination helpers, plus a UiContext for messages, prompts, and progress.
  • Config tooling<tool> config doctor diagnoses the shared file and <tool> config edit opens it in $VISUAL/$EDITOR; a --quiet root option mutes progress and success/info chatter.
  • Installed version reporting<tool> --version prints the tool's own installed distribution version, not the SDK version.

You import the surface from untaped.api (re-exported from the untaped package root), declare a ToolSpec, and call run_tool(app, spec) from your tool's main(). The contract surface is the __all__ list in src/untaped/api.py.

# my_tool/__main__.py
from untaped.api import create_app, run_tool, ToolSpec
from my_tool.settings import MyProfile

app = create_app(...)

def main() -> None:
    run_tool(app, ToolSpec(
        command="untaped-mytool",
        section="mytool",
        profile_model=MyProfile,
    ))
# pyproject.toml
[project]
dependencies = [
    "untaped>=3.1.0,<4",
]

[project.scripts]
untaped-mytool = "my_tool.__main__:main"

run_tool wires --version to installed package metadata. By default, ToolSpec.distribution uses command; when the executable and distribution names differ, set the package explicitly, for example ToolSpec(command="acme", ..., distribution="acme-cli"). Metadata lookup is lazy, so it happens only for --version, whose stdout remains the version alone (for example, 0.4.2).

Tools resolve the SDK from PyPI in development and CI alike. Published wheels are built with uv build --no-sources as defense in depth, so package metadata always resolves from the declared PyPI range.

Requirements

Python 3.14 and uv.

The suite

Seven tools are built on the SDK. Each is an independent CLI installed into its own uv tool environment. As each PyPI-backed tool completes its first package release, install it by package name:

uv tool install untaped-github
uv tool install untaped-jira
uv tool install untaped-awx
uv tool install untaped-ansible
uv tool install untaped-workspace
uv tool install untaped-recipe
uv tool install git+https://github.com/alexisbeaulieu97/untaped-apple-health.git

untaped-apple-health is outside the current PyPI release wave; install it from git until that repo owns a package release workflow.

Because every tool reads the same ~/.untaped/config.yml and shares the same --format pipe envelope, independently installed tools interoperate and compose:

untaped-awx job-templates list --format raw --columns name \
  | fzf \
  | untaped-awx job-templates get --stdin --format json

Documentation

User-facing docs live in docs/:

Per-tool command references live in each tool's own repo:

Security

Please report suspected vulnerabilities privately. See SECURITY.md.

Contributing

See CONTRIBUTING.md and AGENTS.md for the local workflow, architecture rules, and recipes for extending the SDK and its tools.

License

MIT. See LICENSE.

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

untaped-3.1.0.tar.gz (77.5 kB view details)

Uploaded Source

Built Distribution

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

untaped-3.1.0-py3-none-any.whl (98.9 kB view details)

Uploaded Python 3

File details

Details for the file untaped-3.1.0.tar.gz.

File metadata

  • Download URL: untaped-3.1.0.tar.gz
  • Upload date:
  • Size: 77.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for untaped-3.1.0.tar.gz
Algorithm Hash digest
SHA256 71019b6ec347f0559403e8cb9a5abfb285f34c65c5f9821c4de9fe11ebc4dafa
MD5 0aebd398f1329528ab1cfd942659b205
BLAKE2b-256 95fce42405d33d6d59d06a6b5e10b5203a30a480d9ddc83964abf811b17d5ce8

See more details on using hashes here.

Provenance

The following attestation bundles were made for untaped-3.1.0.tar.gz:

Publisher: release.yml on alexisbeaulieu97/untaped

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file untaped-3.1.0-py3-none-any.whl.

File metadata

  • Download URL: untaped-3.1.0-py3-none-any.whl
  • Upload date:
  • Size: 98.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for untaped-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f264cf9ad5211c82354e89e15316463f791e357fdbbc5cb00a2edeb0dbe59198
MD5 3071366d0396992c81d6ff254a020728
BLAKE2b-256 bb22c87290d62ed8fabdfb65f0c66b8f6cc38d182dde2aedae954337f4806ca2

See more details on using hashes here.

Provenance

The following attestation bundles were made for untaped-3.1.0-py3-none-any.whl:

Publisher: release.yml on alexisbeaulieu97/untaped

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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