Skip to main content

CLI tool to send prompts to an AI API and save JSON/Markdown outputs.

Project description

ai-prompt-runner

CI PyPI version Python License

Modular Python CLI that sends prompts to an AI API and saves outputs as JSON and Markdown.

Design Philosophy

ai-prompt-runner is intentionally designed as a stateless execution layer:

1 input โ†’ 1 API call โ†’ 1 structured output

It does not manage conversational state, orchestration, agents, or multi-step workflows.

The project focuses on:

  • deterministic execution
  • explicit configuration precedence
  • contract-driven provider abstraction
  • strict failure-path handling
  • reproducible CI validation

Provider implementations must conform to a shared contract validated through reusable contract tests.

An official MockProvider is included to guarantee deterministic behavior and network-independent validation.

Public Roadmap & Engineering Approach

This project includes a detailed public roadmap and documentation of its structured AI-assisted development approach.

Explore the full project overview, roadmap and methodology here:

๐Ÿ”— AI Prompt Runner โ€“ Project Page

Table of Contents

Requirements

  • Python 3.11+
  • Virtual environment recommended

Installation

Recommended for CLI usage with pipx:

pipx install ai-prompt-runner

Verify the installed command:

ai-prompt-runner --version

Install from PyPI with pip (fallback):

python3 -m pip install ai-prompt-runner

If the installed command is not found, your Python script directory may not be on PATH. In that case, prefer pipx for CLI usage or run the module directly:

python3 -m ai_prompt_runner.cli --version

Install from source for development:

python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -e ".[dev]"

uv Workflow

uv is supported as the modern dependency and task runner workflow for local development.

Sync the project with development dependencies:

uv sync --extra dev

Run the test suite:

uv run pytest

Run tests with the CI coverage gate:

uv run pytest --cov=src --cov-report=term-missing --cov-fail-under=95

Run lint checks:

uv run ruff check .

Build package distributions:

uv run python3 -m build

pip-based commands remain supported, but uv is the recommended workflow for local development.

Environment Variables

Create a local .env file (or use CLI flags directly):

AI_API_ENDPOINT=
AI_API_KEY=
AI_API_MODEL=default

You can start from .env.example.

Configuration File (Optional)

You can provide a TOML config file with --config for non-sensitive runtime defaults.

Example (config.toml):

[ai_prompt_runner]
provider = "http"
api_endpoint = "http://localhost:11434/api/generate"
api_model = "llama3.2"
timeout = 30
retries = 0
out_json = "outputs/response.json"
out_md = "outputs/response.md"

You can start from config.example.toml and copy it to a local config.toml (do not store secrets in this file)

Configuration precedence is:

CLI > environment variables (.env / shell env) > TOML config > built-in defaults

Security note:

  • api_key is intentionally not supported in the TOML config file.
  • Use AI_API_KEY (recommended) or --api-key for secrets.

CLI Usage

Use either command style:

  • Installed console script: ai-prompt-runner ...
  • Module fallback: python3 -m ai_prompt_runner.cli ...

Show help:

ai-prompt-runner --help
python3 -m ai_prompt_runner.cli --help

Run with .env values:

ai-prompt-runner --prompt "Hello world"
python3 -m ai_prompt_runner.cli --prompt "Hello world"

Run with an optional TOML config file:

ai-prompt-runner --config config.toml --prompt "Hello world"
python3 -m ai_prompt_runner.cli --config config.toml --prompt "Hello world"

CLI flags and environment variables override values from the config file.

Supported Providers

The provider factory is protocol-first and registry-driven.

OpenAI-compatible protocol providers (same runtime class, different defaults/aliases):

  • openai_compatible
  • openai
  • openrouter
  • groq
  • together
  • fireworks
  • perplexity
  • inception
  • x
  • xai
  • lmstudio
  • ollama

Other protocol providers:

  • anthropic
  • google
  • http (legacy generic JSON-over-HTTP provider)

Run with explicit API values:

ai-prompt-runner \
  --prompt "Hello world" \
  --api-endpoint "http://localhost:11434/api/generate" \
  --api-key "dummy" \
  --api-model "llama3.2"

python3 -m ai_prompt_runner.cli \
  --prompt "Hello world" \
  --api-endpoint "http://localhost:11434/api/generate" \
  --api-key "dummy" \
  --api-model "llama3.2"

Run with Anthropic defaults:

ai-prompt-runner \
  --provider anthropic \
  --api-key "$AI_API_KEY" \
  --prompt "Explain retry logic"

Run with OpenAI defaults:

ai-prompt-runner \
  --provider openai \
  --api-key "$AI_API_KEY" \
  --prompt "Explain configuration precedence"

Run with Google defaults:

ai-prompt-runner \
  --provider google \
  --api-key "$AI_API_KEY" \
  --prompt "Summarize this architecture"

Run with xAI defaults:

ai-prompt-runner \
  --provider xai \
  --api-key "$AI_API_KEY" \
  --prompt "Generate a concise changelog entry"

Run locally with Ollama defaults:

ai-prompt-runner \
  --provider ollama \
  --api-key "dummy" \
  --prompt "Hello from local Ollama"

Streaming (--stream)

Use --stream to print response chunks progressively when the selected provider supports streaming.

Streaming-capable providers:

  • openai_compatible and all OpenAI-compatible aliases (openai, openrouter, groq, together, fireworks, perplexity, inception, x, xai, lmstudio, ollama)
  • anthropic
  • google
  • mock (test-only deterministic stream)

Non-stream provider behavior:

  • http falls back to non-stream execution even if --stream is set.

Example:

ai-prompt-runner \
  --provider openai \
  --api-key "$AI_API_KEY" \
  --stream \
  --prompt "Explain retry strategy"

--stream changes console UX only. Final JSON and Markdown outputs still contain the complete final response payload.

Custom output paths:

ai-prompt-runner \
  --prompt "Hello world" \
  --out-json outputs/my_response.json \
  --out-md outputs/my_response.md

python3 -m ai_prompt_runner.cli \
  --prompt "Hello world" \
  --out-json outputs/my_response.json \
  --out-md outputs/my_response.md

Project Structure

Root/
โ”‚
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ ai_prompt_runner/
โ”‚       โ”œโ”€โ”€ cli.py
โ”‚       โ”œโ”€โ”€ core/
โ”‚       โ”‚   โ”œโ”€โ”€ errors.py
โ”‚       โ”‚   โ”œโ”€โ”€ models.py
โ”‚       โ”‚   โ”œโ”€โ”€ runner.py
โ”‚       โ”‚   โ””โ”€โ”€ validators.py
โ”‚       โ”œโ”€โ”€ services/
โ”‚       โ”‚   โ”œโ”€โ”€ anthropic_provider.py
โ”‚       โ”‚   โ”œโ”€โ”€ base.py
โ”‚       โ”‚   โ”œโ”€โ”€ google_provider.py
โ”‚       โ”‚   โ”œโ”€โ”€ http_provider.py
โ”‚       โ”‚   โ”œโ”€โ”€ mock_provider.py
โ”‚       โ”‚   โ”œโ”€โ”€ openai_compatible_provider.py
โ”‚       โ”‚   โ””โ”€โ”€ provider_factory.py
โ”‚       โ””โ”€โ”€ utils/
โ”‚           โ””โ”€โ”€ file_io.py
โ”‚
โ”œโ”€โ”€ schemas/
โ”‚   โ””โ”€โ”€ response.schema.json
โ”‚
โ”œโ”€โ”€ docs/
โ”‚   โ”œโ”€โ”€ architecture.md
โ”‚   โ”œโ”€โ”€ cli-reference.md
โ”‚   โ”œโ”€โ”€ configuration.md
โ”‚   โ”œโ”€โ”€ migration.md
โ”‚   โ”œโ”€โ”€ output-contract.md
โ”‚   โ”œโ”€โ”€ release-checklist.md
โ”‚   โ””โ”€โ”€ testing.md
โ”‚
โ”œโ”€โ”€ prompts/
โ”‚
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ fixtures/
โ”‚   โ”œโ”€โ”€ unit/
โ”‚   โ””โ”€โ”€ e2e/
โ”‚
โ”œโ”€โ”€ .github/workflows/ci.yml
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ uv.lock
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ AGENT.md

Architecture Principles

  • src/ai_prompt_runner/cli.py: argument parsing and process-level I/O only.
  • src/ai_prompt_runner/core/: business rules and payload validation.
  • src/ai_prompt_runner/services/: external integrations (AI provider implementations).
  • Provider layer follows an explicit contract enforced by reusable contract tests.
  • MockProvider ensures deterministic behavior and decouples validation from network dependencies.
  • src/ai_prompt_runner/utils/: file persistence helpers.

Technical Docs

Additional versioned technical documentation is available under docs/:

Output Contract

The normalized JSON response is treated as a stable contract and is formally defined by schemas/response.schema.json.

Detailed contract documentation is available in docs/output-contract.md.

Output Examples

Generated JSON (outputs/response.json):

{
  "prompt": "Hello world",
  "response": "Echo: Hello world",
  "metadata": {
    "provider": "http",
    "timestamp_utc": "2026-02-18T13:43:51.236575+00:00"
  }
}

Generated Markdown (outputs/response.md):

# AI Prompt Response

## Prompt

Hello world

## Response

Echo: Hello world

## Metadata

- Provider: http
- Timestamp (UTC): 2026-02-18T13:43:51.236575+00:00

Testing

Run all tests:

python3 -m pytest

Using uv:

uv run pytest

Run unit tests only:

python3 -m pytest tests/unit

Run E2E tests only:

python3 -m pytest tests/e2e

Coverage (requires pytest-cov):

python3 -m pytest --cov=src --cov-report=term-missing -q

Using uv:

uv run pytest --cov=src --cov-report=term-missing -q

Generate an HTML coverage report:

python3 -m pytest --cov=src --cov-report=term-missing --cov-report=html -q

Using uv:

uv run pytest --cov=src --cov-report=term-missing --cov-report=html -q

Coverage gate used in CI:

python3 -m pytest --cov=src --cov-report=term-missing --cov-fail-under=95

Open htmlcov/index.html in a browser to inspect file-by-file coverage.

Lint

ruff check .

Using uv:

uv run ruff check .

CI

GitHub Actions workflow runs on:

  • push
  • pull_request

Pipeline includes:

  • dependency installation
  • lint (ruff check .)
  • package build verification (python3 -m build)
  • build artifact verification
  • tests with coverage enforcement (--cov-fail-under=95)

uv is supported for local development workflows, while CI currently installs dependencies from requirements.txt.

Versioning

This project follows semantic versioning.

Create release tags such as:

  • v0.1.0
  • v1.0.0

Release history and notes should be published through GitHub Releases.

Release Notes

See CHANGELOG.md for version history.

Release Checklist

See docs/release-checklist.md for the standardized release preparation flow.

Troubleshooting

  • ModuleNotFoundError: No module named 'ai_prompt_runner': run commands from repository root and use python3 -m ... syntax.
  • Connection refused on API call: verify AI_API_ENDPOINT, provider availability, and local network access.
  • requests/pytest not found: activate .venv and reinstall dependencies with python3 -m pip install -r requirements.txt.

Security

  • Never commit .env files containing secrets.
  • Never hardcode API keys in source code.
  • Prefer environment variables over CLI flags for sensitive values like AI_API_KEY.

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

ai_prompt_runner-1.2.0.tar.gz (24.5 kB view details)

Uploaded Source

Built Distribution

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

ai_prompt_runner-1.2.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file ai_prompt_runner-1.2.0.tar.gz.

File metadata

  • Download URL: ai_prompt_runner-1.2.0.tar.gz
  • Upload date:
  • Size: 24.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.14.0

File hashes

Hashes for ai_prompt_runner-1.2.0.tar.gz
Algorithm Hash digest
SHA256 1bfa700e372c5532946fab5f53e45fc0a2ce598f5497166fd127600ed2e2c47e
MD5 ea514cd2c1d446e38c8791e1b7b21b29
BLAKE2b-256 9de1bf3e5ac3e38341847e1ace2a22b29f7841081c7a66a0482e8ffae1febec2

See more details on using hashes here.

File details

Details for the file ai_prompt_runner-1.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ai_prompt_runner-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 20dce05597cddd374ef8348a62e27438af5ed92fcd81564b9f29c3dfb0e137d5
MD5 19f66513ea275984a499034a60b5f0e1
BLAKE2b-256 4ec1a12504851791dcbe2cee8182e582da6085390c4be37e9dca0f38675ec41d

See more details on using hashes here.

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