This release is a pre-release and may not be stable for production use.
insightfactory-cli
Profile-based authentication CLI for the InsightFactory Interfaces API. It
installs the if-cli command: browser OAuth login (authorization-code + PKCE),
token refresh, and authenticated API calls, with profiles stored in
~/.insightfactory in the same layout as the Node @insightfactory-ai/if-cli
so the two implementations can share a config directory.
This is the production Python CLI, published to public PyPI. Python 3.10 or newer is required.
Install
uv tool install insightfactory-cli # persistent install, on PATH
uvx insightfactory-cli profiles # or zero-install, run-once
uv tool upgrade insightfactory-cli # updates
uv fetches a managed Python automatically if the machine lacks one. Fallbacks:
pipx install insightfactory-cli
pip install insightfactory-cli
Develop-branch builds are published as PEP 440 .devN pre-releases. Install the
bleeding edge with:
pip install --pre insightfactory-cli
uv tool install --prerelease allow insightfactory-cli
PEP 440 orders 1.0.0.devN before 1.0.0, so a dependency spec of
insightfactory-cli>=1.0.0 does not match a develop-channel dev build.
An in-process consumer that wants those builds must use a pre-release-bearing
spec such as insightfactory-cli>=1.0.0.dev0, which matches both .devN
builds and the final 1.0.0 release.
Usage
# Create a profile and authenticate through the browser.
if-cli login -p example-dev --host https://factory.example
# Inspect profiles and cached-token status. Statuses are colour-coded on a TTY
# (green valid, yellow refreshable-but-expired, red missing or broken); set
# NO_COLOR=1 to disable or FORCE_COLOR=1 to keep colour when piping.
if-cli profiles
if-cli profiles --json
# Read a single non-secret profile value for scripting.
if-cli config get host -p example-dev
# Print a valid token, refreshing it when a refresh token is available.
if-cli token -p example-dev
if-cli token -p example-dev --env
if-cli token -p example-dev --env-name INSIGHTFACTORY_ACCESS_TOKEN_DEV
# Make an authenticated API request.
if-cli api -p example-dev /api/agent-projects
if-cli api -p example-dev -X POST -d '{"name":"example"}' /api/example
# Discover API routes from the factory's OpenAPI document.
if-cli api routes -p example-dev
if-cli api routes -p example-dev agent-projects
if-cli api describe -p example-dev GET /api/agent-projects/{id}
# Remove the cached credential for a profile.
if-cli logout -p example-dev
# Fallback for factories where browser OAuth is not available.
if-cli set-token -p example-dev
if-cli --version
Profile selection uses -p, then INSIGHTFACTORY_CONFIG_PROFILE, then
[DEFAULT]. Route discovery reads {host}/swagger/v1/swagger.json and does
not require a login. Authenticated API requests are restricted to the selected
factory origin so a profile token cannot be forwarded to another host. Profile
hosts must be bare origins rather than URLs containing application path
prefixes.
Override the config directory with INSIGHTFACTORY_CONFIG_DIR (useful in tests
and CI). The default is ~/.insightfactory.
On Git Bash (MSYS2) on Windows, path conversion rewrites a leading-slash
argument such as /api/agent-projects into a Windows path. Prefix the command
with MSYS_NO_PATHCONV=1:
MSYS_NO_PATHCONV=1 if-cli api -p example-dev /api/agent-projects
Scripting against profiles
profiles --json and config get are the supported machine-readable
interfaces; the padded profiles columns are for humans and are not a
contract, and neither is the layout of ~/.insightfactory/config.
if-cli profiles --json prints an array — one entry per configured profile, in
file order — of name, host, and token:
[
{
"name": "example-dev",
"host": "https://factory.example",
"token": { "status": "valid", "expires_at": 1785918336, "refreshable": true }
},
{ "name": "other", "host": "https://other.factory.example", "token": { "status": "none" } }
]
token.status is valid, expired, none, or unknown; expires_at and
refreshable are present only when a cached token exists. valid means
if-cli token will hand back the cached token as-is, so a token inside the
60-second slack window that command refreshes within is reported as expired —
use the raw expires_at if you need the literal expiry instant instead. A
profile that cannot be resolved has a host of null (or its raw configured
value) and a top-level error describing the problem, and does not stop the
other profiles from being listed; token.error is set only when the token
cache itself could not be read.
if-cli config get <key> -p <profile> prints one newline-terminated value and
exits non-zero if the profile cannot be resolved, or the key is not configured
within it. A profile with no host cannot be resolved at all, so every key on it
fails, not just host. A key present but empty (client_id =) counts as not
configured:
curl -H "Authorization: Bearer $(if-cli token -p example-dev)" \
"$(if-cli config get host -p example-dev)/api/agent-projects"
The readable keys are host, audience, callback_port, client_id, and
organization — all non-secret, and resolved the same way the CLI itself
resolves them, so audience and callback_port return their defaults when the
profile omits them. Tokens are deliberately not readable this way; use
if-cli token.
Programmatic API
insightfactory-cli may be imported in-process as a library to resolve a
profile to a factory host and a fresh access token. These four symbols are a
supported programmatic surface for in-process consumers:
if_cli.config.load_configif_cli.config.get_profileif_cli.oauth.get_valid_tokenif_cli.runtime.CliError
They raise CliError on failure (never SystemExit or sys.exit), never
write to stdout, never launch a browser or block on interactive input, and use
only bounded waits. Changing or removing any of them is a breaking change and
requires a major version bump.
How authentication works
- Profiles are stored in
~/.insightfactory/config, one per customer/environment. - The profile file is managed by the CLI and is regenerated on updates; comments and empty sections are not preserved.
- Tokens are cached by host in
~/.insightfactory/token-cache.jsonwith file mode0600. - The configuration directory is
0700; configuration and cache updates are atomic. - Remote factory, authorization, and token endpoints must use HTTPS. HTTP is accepted only for loopback development.
- Login discovers OAuth metadata from
{host}/.well-known/oauth-authorization-server. - Authorization uses PKCE through the factory
/authorizeproxy with a loopback-only (127.0.0.1) callback. The CLI is a public OAuth client: the client ID is read from the factory's discovery document at runtime (no client secret).
Development
uv sync
uv run pytest
uv run ruff check .
uv run ty check
Smoke-test against a throwaway config directory, never ~/.insightfactory:
uv run if-cli --help
uv run if-cli --version
INSIGHTFACTORY_CONFIG_DIR=$(mktemp -d) uv run if-cli profiles
Python 3.10 or newer is required. Runtime code is stdlib-only.
Release
Publishing is automatic from GitHub Actions on merge. Verify and build live in
the reusable workflow
if_s_insightfactory_cli.yml
in insightfactory-ai/if_sre_github_actions
(PR #300
must merge before these stubs go green). This repository's
.github/workflows/release.yml keeps only the OIDC publish job, because PyPI
Trusted Publishing is registered for this repo, workflow release.yml, and
environment pypi — a reusable workflow cannot be registered.
A one-time trusted-publisher registration is required on the PyPI project for
that triple. The publish job downloads the dist-release artifact staged by
the reusable workflow and uploads it with pypa/gh-action-pypi-publish.
| Trigger | Published version | PyPI role |
|---|---|---|
Push / merge to develop |
1.0.0.dev{N} |
pre-release (pip install --pre) |
Push / merge to main |
1.0.0 (the version in pyproject.toml) |
latest |
Push of a v* tag |
same as main |
retry / explicit cut of that version |
N is github.run_number of the reusable workflow: a per-workflow integer
that goes up on every run and stays the same across re-runs of that run (so a
failed publish can be retried under the same version). It does not depend on
git history or clone depth. After a successful main publish, bump version
in pyproject.toml on develop so later .devN builds sort after what just
landed; PEP 440 puts 1.0.0.devN before 1.0.0. Because of that ordering, a
dependency spec of insightfactory-cli>=1.0.0 does not match develop-channel
.devN builds; an in-process consumer that wants them must specify a
pre-release-bearing spec such as insightfactory-cli>=1.0.0.dev0 (which also
matches the final 1.0.0 release).
A version that is already on PyPI is skipped rather than failing, so a second
push to main (or a v* tag for the same version) is a no-op. A v* tag
whose name does not match pyproject.toml fails before publishing.
Differences from the Node CLI
Behaviour matches @insightfactory-ai/if-cli except where the platforms
genuinely diverge:
- Unknown-option wording is aligned (
Unknown option '--flag'). Other argparse messages (for example a missing option value) still differ from Node'sutil.parseArgs. - Expiry timestamps in human-readable output use the C-locale
%cformat rather than JavaScriptDate#toLocaleString(). --versionreads the installed package metadata (1.0.0and later) rather than an npmpackage.json.
On-disk profile and token-cache paths, JSON shapes, and file permissions stay compatible with the Node CLI, so you can switch implementations without re-authenticating.
Metadata
Release files for insightfactory-cli 1.0.0.dev1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| insightfactory_cli-1.0.0.dev1.tar.gz | 55.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| insightfactory_cli-1.0.0.dev1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 84.8 kB
Release files / insightfactory_cli-1.0.0.dev1.tar.gz
| Download URL | insightfactory_cli-1.0.0.dev1.tar.gz |
|---|---|
| Size | 55.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fa1116619e4afbc0121815c99c79ea8a74aaa5dd3a537eee21f7df85026a05dc
|
|
BLAKE2b-256 checksum How to use checksums |
2e5e3712f9a9aae97ab6978f4f37a20d993a24bc02b3149214b64d12bd106fc9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 18, 2026.
Transparency logRelease files / insightfactory_cli-1.0.0.dev1-py3-none-any.whl
| Download URL | insightfactory_cli-1.0.0.dev1-py3-none-any.whl |
|---|---|
| Size | 29.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c39924ea3bb3c06715948c75426b0f1aec7fe04265d4d20cc89834cbfc61b25c
|
|
BLAKE2b-256 checksum How to use checksums |
d5e1d6e104ed628f32cab75a18d933f5dd7e1eb57915af5915c42c7fbbb885e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 18, 2026.
Transparency logSecurity for insightfactory-cli 1.0.0.dev1
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for insightfactory_cli-1.0.0.dev1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 18, 2026.
Transparency logA 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.