Skip to content

cli

Command-line interface for owui_client.

A thin Cyclopts-based CLI exposing convenience workflows (e.g. syncing a local skill file to a remote Open WebUI instance). This module contains no business logic: it binds CLI flags and environment variables to the async client / shortcuts layer and prints human-readable results.

Connection defaults come from environment variables:

  • OWUI_SERVER: base API URL (default http://127.0.0.1:8080/api).
  • OWUI_API_KEY: bearer API key (no default; required by most servers).

Both can be overridden on the command line via --server / --api-key.

Classes

Functions

sync_skill

sync_skill(
    path: Path,
    *,
    server: Annotated[
        str,
        Parameter(
            env_var=OWUI_SERVER,
            help="Open WebUI API base URL (e.g. http://127.0.0.1:8080/api).",
        ),
    ] = "http://127.0.0.1:8080/api",
    api_key: Annotated[
        Optional[str],
        Parameter(
            env_var=OWUI_API_KEY,
            help="Open WebUI API key (bearer token).",
        ),
    ] = None
) -> None

Sync a local skill Markdown file to the Open WebUI server.

Creates the skill if it does not exist, updates it if its content/name/ description changed, and reports unchanged (with no write) when nothing differs. See Shortcuts.sync_skill for the full semantics.

Source code in src/owui_client/cli.py
@app.command(name="sync-skill")
async def sync_skill(
    path: Path,
    *,
    server: Annotated[
        str,
        Parameter(
            env_var="OWUI_SERVER",
            help="Open WebUI API base URL (e.g. http://127.0.0.1:8080/api).",
        ),
    ] = "http://127.0.0.1:8080/api",
    api_key: Annotated[
        Optional[str],
        Parameter(
            env_var="OWUI_API_KEY",
            help="Open WebUI API key (bearer token).",
        ),
    ] = None,
) -> None:
    """Sync a local skill Markdown file to the Open WebUI server.

    Creates the skill if it does not exist, updates it if its content/name/
    description changed, and reports ``unchanged`` (with no write) when nothing
    differs. See `Shortcuts.sync_skill` for the full semantics.
    """
    async with _connect(server, api_key) as client:
        result = await client.shortcuts.sync_skill(path)

    print(_format_skill_result_line(result))

sync_skills

sync_skills(
    dir_path: Path,
    *,
    server: Annotated[
        str,
        Parameter(
            env_var=OWUI_SERVER,
            help="Open WebUI API base URL (e.g. http://127.0.0.1:8080/api).",
        ),
    ] = "http://127.0.0.1:8080/api",
    api_key: Annotated[
        Optional[str],
        Parameter(
            env_var=OWUI_API_KEY,
            help="Open WebUI API key (bearer token).",
        ),
    ] = None
) -> None

Recursively sync every skill Markdown file under a directory.

Walks dir_path at arbitrary depth, syncing each valid skill file with the same create / unchanged / update semantics as sync-skill (see Shortcuts.sync_skill). Non-skill files are skipped, a server error on one file does not abort the rest, and nothing is ever deleted.

Source code in src/owui_client/cli.py
@app.command(name="sync-skills")
async def sync_skills(
    dir_path: Path,
    *,
    server: Annotated[
        str,
        Parameter(
            env_var="OWUI_SERVER",
            help="Open WebUI API base URL (e.g. http://127.0.0.1:8080/api).",
        ),
    ] = "http://127.0.0.1:8080/api",
    api_key: Annotated[
        Optional[str],
        Parameter(
            env_var="OWUI_API_KEY",
            help="Open WebUI API key (bearer token).",
        ),
    ] = None,
) -> None:
    """Recursively sync every skill Markdown file under a directory.

    Walks `dir_path` at arbitrary depth, syncing each valid skill file with the
    same create / unchanged / update semantics as `sync-skill` (see
    `Shortcuts.sync_skill`). Non-skill files are skipped, a server error on one
    file does not abort the rest, and nothing is ever deleted.
    """
    async with _connect(server, api_key) as client:
        results = await client.shortcuts.sync_skills(dir_path)

    for result in results:
        print(_format_skill_result_line(result))

    counts: dict[str, int] = {}
    for result in results:
        counts[result.action] = counts.get(result.action, 0) + 1
    summary = ", ".join(f"{action}={n}" for action, n in sorted(counts.items())) or "none"
    total = len(results)
    print(f"summary: {summary} ({total} file{'s' if total != 1 else ''})")

main

main() -> None

Entry point for the console script / python -m owui_client.cli.

Source code in src/owui_client/cli.py
def main() -> None:
    """Entry point for the console script / ``python -m owui_client.cli``."""
    app()