Skip to content

ranog/api-bootstrapper-cli

Repository files navigation

api-bootstrapper-cli

License: MIT Code style: ruff Tests

A modular and extensible CLI for bootstrapping Python projects with opinionated platform defaults.

Automates the setup of pyenv + Poetry or uv, plus VSCode configuration and environment variables in a single command, following manual setup best practices.


✨ Features

  • 🐍 Python Version Management - Automatic installation and configuration via pyenv or uv
  • 📦 Dependency Management - Poetry or uv setup with in-project virtualenv
  • 📁 Project Scaffold - Generates a runnable FastAPI API with PostgreSQL-ready config and test structure
  • 🔧 VSCode Integration - Auto-generated settings for Python interpreter and testing
  • 🪝 Pre-commit Hooks - Automated setup with Ruff and Commitizen
  • 🐳 Docker Support - Production-ready Dockerfile plus local PostgreSQL via docker-compose.yml
  • 🌱 Environment Variables - Creates .env.example template with PYTHONDONTWRITEBYTECODE=1
  • 🚀 Smart Detection - Skips setup if environment already exists
  • 🎯 Zero Configuration - Creates minimal pyproject.toml and adds default API dependencies for new projects
  • 🔒 Environment Isolation - Clean environment to prevent version conflicts
  • 🔄 Pluggable Backends - Choose between pyenv/Poetry (default) or uv via --manager
  • 🌐 HTTP Platform API - Run a FastAPI server and trigger bootstrap flows via HTTP
  • Battle-tested - Comprehensive test suite with high coverage

📦 Installation

With pipx (recommended)

First, install pipx if you don't have it:

# macOS
brew install pipx
pipx ensurepath

# Linux (Debian/Ubuntu)
sudo apt install pipx
pipx ensurepath

# Or using pip
python3 -m pip install --user pipx
python3 -m pipx ensurepath

Then install the CLI:

pipx install git+https://github.com/ranog/api-bootstrapper-cli.git

After installation, reload your shell:

source ~/.bashrc  # or ~/.zshrc if using zsh

Why pipx? Installs the CLI in an isolated environment, making it available globally regardless of your current Python version.

Note: If you previously installed via pip, uninstall it first: pip uninstall api-bootstrapper-cli

From source (for development)

git clone https://github.com/ranog/api-bootstrapper-cli
cd api-bootstrapper-cli
poetry install

Updating

To update to the latest version:

If installed via pipx from git:

pipx install git+https://github.com/ranog/api-bootstrapper-cli.git --force

Then install/update bundled Codex skills:

api-bootstrapper install-skills

Then install/update bundled Agent Skills (open format):

api-bootstrapper install-agent-skills

Enable shell completion (optional)

Enable tab completion for commands and options:

# Install completion for your shell
api-bootstrapper --install-completion

# Restart your shell or run:
source ~/.bashrc  # or ~/.zshrc

Now you can use tab completion:

api-bootstrapper <TAB>           # Shows: init, bootstrap-env, add-alembic, add-docker, add-pre-commit, add-mypy, install-skills, install-agent-skills
api-bootstrapper bootstrap-env --<TAB>  # Shows: --path, --python, --install

🚀 Quick Start

Option 1: All-in-One (Recommended)

Initialize a complete Python project with a single command:

# Complete setup with pyenv + Poetry (default)
api-bootstrapper init --python 3.12.12 --path ./my-project

# Complete setup with uv (faster, single tool)
api-bootstrapper init --python 3.12.12 --path ./my-project --manager uv

# Navigate and activate
cd my-project
source .venv/bin/activate

# With pyenv+Poetry backend:
python --version  # Python 3.12.12
poetry --version  # Poetry (version 2.x.x)

# With uv backend:
python --version  # Python 3.12.12
uv --version      # uv 0.x.x

Option 2: Step-by-Step

For more control, run commands individually:

# Step 1: Setup Python environment (default: pyenv + Poetry)
api-bootstrapper bootstrap-env --python 3.12.12 --path ./my-project

# Step 1 (alternative): Setup with uv
api-bootstrapper bootstrap-env --python 3.12.12 --path ./my-project --manager uv

# Step 2: Add pre-commit hooks (optional)
api-bootstrapper add-pre-commit --path ./my-project

# Step 3: Add mypy type-checking config (optional)
api-bootstrapper add-mypy --path ./my-project

# Navigate and activate
cd my-project
source .venv/bin/activate

Note: The CLI automatically detects paths with spaces or accents (e.g., /Área de Trabalho/project) and shows source $(poetry env info --path)/bin/activate which handles special characters reliably.


🌐 HTTP API (Platform Mode)

You can run the same bootstrap engine through an HTTP API (FastAPI), not only via CLI.

Start the API

# From source checkout
make run-api

# Equivalent command
poetry run api-bootstrapper-api

Server default:

  • Base URL: http://localhost:8000
  • OpenAPI docs: http://localhost:8000/docs

Health check

curl -s http://localhost:8000/health

Expected response:

{"status":"ok"}

Bootstrap environment via API

curl -s -X POST "http://localhost:8000/bootstrap-env" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "./my-project",
    "python_version": "3.12.12",
    "install_dependencies": true,
    "manager": "uv"
  }'

Example success response:

{
  "python_version": "3.12.12",
  "python_path": "/home/user/.local/share/uv/python/cpython-3.12.12/bin/python3.12",
  "venv_path": "/home/user/my-project/.venv",
  "venv_python": "/home/user/my-project/.venv/bin/python",
  "editor_config_path": "/home/user/my-project/.vscode/settings.json",
  "has_poetry_project": true
}

Error behavior

  • 400: invalid bootstrap preconditions (for example, manager not installed)
  • 500: execution failed while running bootstrap operations

📖 Usage

Agent Skills Catalog

This repository now includes a dual skill distribution for agent runtimes:

  • skills/agentskills - canonical open-format Agent Skills source
  • skills/codex - Codex-compatible mirror with agents/openai.yaml

Available skills:

  • api-bootstrapper-init
  • api-bootstrapper-bootstrap-env
  • api-bootstrapper-add-pre-commit
  • api-bootstrapper-add-docker
  • api-bootstrapper-add-alembic
  • api-bootstrapper-bootstrap-flow (orchestrator)
  • api-bootstrapper-sync-branch
  • api-bootstrapper-generate-commit-message
  • api-bootstrapper-create-tests
  • api-bootstrapper-debug-issue
  • api-bootstrapper-review-code
  • api-bootstrapper-prepare-task
  • api-bootstrapper-staff-review
  • api-bootstrapper-understand-system
  • api-bootstrapper-implement-feature-tdd
  • api-bootstrapper-refactor-safely
  • api-bootstrapper-add-tool-support
  • api-bootstrapper-prepare-pr
  • api-bootstrapper-execute-task-universal

If the CLI was installed with pipx, no repository clone is required. Install skills directly from the packaged CLI:

api-bootstrapper install-skills
api-bootstrapper install-agent-skills

Keep both trees in sync with:

make sync-skills
make validate-skills

Two Ways to Use This CLI

🎯 Use init when:

  • Starting a new project from scratch
  • You want everything configured in one command
  • Recommended for most users

🔧 Use individual commands when:

  • You already have a project and want to add specific features
  • You need more granular control over the setup
  • You want to configure environment and hooks separately

Prerequisites

For using the CLI:

  • pipx (recommended) or pip
  • macOS or Linux
  • Backend: pyenv (default)pyenv installed
    Backend: uvuv installed (pip install uv or curl -LsSf https://astral.sh/uv/install.sh | sh)

Target project can be:

  • Empty directory - Will create a minimal pyproject.toml and setup full environment
  • Existing project - With pyproject.toml already present

Python Version Support

Default behavior:

  • bootstrap-env uses 3.12.12 when --python is omitted
  • init requires an explicit --python value
  • pyproject.toml constraints always follow the requested version (major.minor)

Example (--python 3.12.12):

[tool.poetry.dependencies]
python = "^3.12"

Why Python 3.10+ is still supported for target projects?

  • ✅ Still under official security support (EOL: October 2026)
  • ✅ Compatible with all development tools (ruff, pre-commit, mypy, pytest)
  • ✅ Balances compatibility with modern Python features
  • ✅ Enterprises focused on security have already migrated from 3.9

You can use any Python version you want:

# Use Python 3.11
api-bootstrapper init --python 3.11.5

# Use Python 3.12
api-bootstrapper init --python 3.12.0

# Use Python 3.13
api-bootstrapper init --python 3.13.2

The tool will automatically set the correct Python constraint in pyproject.toml based on the version you specify.

Note: The CLI itself requires Python 3.12+ to run, but can bootstrap projects with Python 3.10+.


📋 Commands

init

Initialize a complete Python project with all features in one command.

This command combines bootstrap-env, environment configuration, and add-pre-commit into a single workflow, giving you a fully configured development environment.

Basic usage:

# Initialize new project (default: pyenv + Poetry)
api-bootstrapper init --python 3.12.12 --path ./my-project

# Initialize new project with uv
api-bootstrapper init --python 3.12.12 --path ./my-project --manager uv

# In current directory
api-bootstrapper init --python 3.13.9

# Skip dependency installation
api-bootstrapper init --python 3.12.12 --no-install

What it does:

  1. ✅ Creates a runnable FastAPI scaffold (src/main.py, database.py, models.py, schemas.py) and test folders (unit/, integration/, e2e/)
  2. ✅ Sets up Python environment (pyenv or uv + VSCode)
  3. ✅ Creates Dockerfile and docker-compose.yml (PostgreSQL service)
  4. ✅ Creates .env.example with PYTHONDONTWRITEBYTECODE=1
  5. ✅ Updates .gitignore to exclude .env files (if .gitignore exists)
  6. ✅ Adds default API dependencies on new projects (fastapi, uvicorn, sqlalchemy, psycopg[binary], alembic, pytest, httpx)
  7. ✅ Configures pre-commit hooks
  8. ✅ Shows clear next steps

This is the recommended command for new projects!

See --manager option below for choosing between pyenv+Poetry and uv.


bootstrap-env

Sets up a complete Python development environment and VSCode configuration.

Supports two backends via --manager:

  • pyenv (default) — uses pyenv for Python installation + Poetry for dependencies
  • uv — uses uv for both Python installation and dependency management (faster)

💡 Tip: If you want environment + pre-commit in one command, use init instead.

Basic usage:

# Default backend: pyenv + Poetry
api-bootstrapper bootstrap-env --python 3.12.12
api-bootstrapper bootstrap-env --python 3.13.9 --path ./my-api
api-bootstrapper bootstrap-env --python 3.12.12 --no-install

# uv backend (faster, single tool)
api-bootstrapper bootstrap-env --python 3.12.12 --manager uv
api-bootstrapper bootstrap-env --python 3.13.9 --path ./my-api --manager uv

What it does (pyenv + Poetry backend):

  1. ✅ Installs Python version via pyenv (if not installed)
  2. ✅ Creates .python-version file
  3. ✅ Installs pip, setuptools, wheel, and poetry in project's Python
  4. ✅ Creates minimal pyproject.toml if missing (Poetry format, never overwrites)
  5. ✅ Configures Poetry with in-project virtualenv (.venv)
  6. ✅ Creates Poetry environment
  7. ✅ Installs dependencies (unless --no-install)
  8. ✅ Generates VSCode settings.json with Python interpreter

What it does (uv backend):

  1. ✅ Installs Python version via uv python install (if not installed)
  2. ✅ Creates .python-version file via uv python pin
  3. ✅ Creates minimal pyproject.toml if missing (PEP 621 format, never overwrites)
  4. ✅ Creates in-project virtualenv (.venv) via uv venv
  5. ✅ Installs/syncs dependencies via uv sync (unless --no-install)
  6. ✅ Generates VSCode settings.json with Python interpreter

Smart detection: Running the command a second time on the same project will skip setup if the environment is already configured.

# First run: Full setup
api-bootstrapper bootstrap-env --python 3.12.12

# Second run: Skips setup
api-bootstrapper bootstrap-env --python 3.12.12
# Output: environment already configured ✓

--manager option

All commands that bootstrap an environment accept --manager pyenv (default) or --manager uv.

Option Python version tool Dependency tool pyproject.toml format
--manager pyenv pyenv install poetry install [tool.poetry] (Poetry)
--manager uv uv python install uv sync [project] (PEP 621)

When to use uv? uv is significantly faster and requires only one tool to install. Choose pyenv when the project already uses Poetry or requires a specific pyenv workflow.

add-pre-commit

Configures pre-commit hooks with Ruff (linter/formatter) and Commitizen (conventional commits).

💡 Tip: If you're starting a new project, use init which includes this automatically.

Basic usage:

# In current directory
api-bootstrapper add-pre-commit

# In a specific directory
api-bootstrapper add-pre-commit --path ./my-project

What it does:

  1. ✅ Creates .pre-commit-config.yaml with Ruff and Commitizen hooks
  2. ✅ Adds pre-commit, ruff, and commitizen to dev dependencies via Poetry or uv (based on selected manager)
  3. ✅ Updates hook versions in config to match installed packages
  4. ✅ Installs pre-commit hooks (pre-commit and commit-msg)

Generated hooks:

  • Ruff - Runs linting with auto-fix on pre-commit
  • Ruff Format - Formats code automatically
  • Commitizen - Validates commit messages follow conventional commits

Example workflow:

# After running add-pre-commit
git add .
git commit -m "fix: correct bug"  # ✓ Valid conventional commit

# Hooks automatically run:
# 1. Ruff checks and fixes code
# 2. Ruff formats code
# 3. Commitizen validates commit message

Requires:

  • Git repository initialized (.git/ directory)
  • Poetry or uv environment configured

add-mypy

Adds mypy type-checking configuration to your project and ensures mypy is installed in dev dependencies.

Basic usage:

# In current directory
api-bootstrapper add-mypy

# In a specific directory
api-bootstrapper add-mypy --path ./my-project

# Explicitly use uv backend
api-bootstrapper add-mypy --path ./my-project --manager uv

What it does:

  1. ✅ Adds mypy to dev dependencies (Poetry or uv format)
  2. ✅ Creates [tool.mypy] config in pyproject.toml when missing
  3. ✅ Preserves existing mypy config if already present
  4. ✅ Syncs dependencies (poetry lock/install or uv sync)

Next step:

  • Run poetry run mypy src (pyenv/Poetry) or uv run mypy src (uv)

add-docker

Adds a production-ready Dockerfile to your Python project.

Creates a multi-stage Docker image optimized for Python applications using uvicorn.

Basic usage:

# Add Dockerfile with default Python 3.13
api-bootstrapper add-docker

# Add Dockerfile with specific Python version
api-bootstrapper add-docker --python 3.12

# Add Dockerfile to specific project
api-bootstrapper add-docker --path ./my-project --python 3.13

What it does:

  1. ✅ Creates Dockerfile with multi-stage build
  2. ✅ Uses Python slim image for smaller size
  3. ✅ Configures uvicorn to run FastAPI app on port 8080
  4. ✅ Optimizes for production with proper dependency caching

Generated Dockerfile features:

  • Multi-stage build - Separates build dependencies from runtime
  • Virtual environment - Uses /opt/venv for isolated dependencies
  • Minimal size - Based on python:X.Y-slim-bookworm image
  • FastAPI ready - Configured for src.main:app with uvicorn

Example workflow:

# After running add-docker
echo "fastapi==0.104.1" > requirements.txt
echo "uvicorn[standard]==0.24.0" >> requirements.txt

# Create your FastAPI app
mkdir -p src
cat > src/main.py << 'EOF'
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}
EOF

# Build and run
docker build -t my-api .
docker run -p 8080:8080 my-api

# Access at http://localhost:8080

Requires:

  • requirements.txt with dependencies
  • src/main.py with FastAPI app

add-alembic

Adds Alembic migration support to your project and can optionally run initial migrations.

Basic usage:

# Setup Alembic only (creates/updates alembic.ini + alembic/env.py)
api-bootstrapper add-alembic --path ./my-project

# Setup and run initial migration flow with local PostgreSQL
api-bootstrapper add-alembic --path ./my-project --with-db --create-initial-items --upgrade-head

# Explicitly use uv backend
api-bootstrapper add-alembic --path ./my-project --manager uv --with-db --upgrade-head

What it does:

  1. ✅ Initializes Alembic when missing
  2. ✅ Rewrites alembic/env.py to use project Base.metadata
  3. ✅ Can start db service with Docker Compose (--with-db)
  4. ✅ Can generate initial items migration (--create-initial-items)
  5. ✅ Can apply migrations (--upgrade-head)

Notes:

  • When --create-initial-items or --upgrade-head is used, the command automatically starts the local DB service (db) before running migrations.
  • The generated revision message is create items table.

install-skills

Installs bundled Codex skills from the CLI package into your local Codex skills folder.

This command is useful for users who install the CLI via pipx and do not clone this repository.

Basic usage:

# Install/update skills to default target:
# $CODEX_HOME/skills or ~/.codex/skills
api-bootstrapper install-skills

# Install to a custom target directory
api-bootstrapper install-skills --target ~/.codex/skills

# Avoid overwriting existing skills
api-bootstrapper install-skills --no-overwrite

What it does:

  1. ✅ Loads embedded skill files bundled in the CLI package
  2. ✅ Copies all api-bootstrapper-* skills to your Codex skills directory
  3. ✅ Overwrites existing skill folders by default (or skips with --no-overwrite)

install-agent-skills

Installs bundled Agent Skills (open format) from the CLI package into your local Agent Skills folder.

Basic usage:

# Install/update skills to default target:
# $AGENT_SKILLS_HOME or ~/.agent-skills
api-bootstrapper install-agent-skills

# Install to a custom target directory
api-bootstrapper install-agent-skills --target ~/.agent-skills

# Avoid overwriting existing skills
api-bootstrapper install-agent-skills --no-overwrite

What it does:

  1. ✅ Loads embedded open-format Agent Skills from the packaged CLI
  2. ✅ Copies all api-bootstrapper-* skills to your Agent Skills directory
  3. ✅ Overwrites existing skill folders by default (or skips with --no-overwrite)

📁 Project Structure

After running init or bootstrap-env, your project will have:

my-project/
├── .env.example             # Environment variables template (created by init)
├── .git/                    # Git repository
├── .gitignore               # Git ignore rules (updated by init if exists)
├── .pre-commit-config.yaml  # Pre-commit hooks (if add-pre-commit used)
├── .python-version          # Python version (pyenv or uv)
├── .venv/                   # Virtual environment
├── .vscode/
│   └── settings.json        # VSCode Python configuration
├── Dockerfile               # Docker configuration (created by init)
├── Makefile                 # Common dev/build/test commands (created by init)
├── docker-compose.yml       # Local PostgreSQL service (created by init)
├── src/
│   ├── __init__.py
│   ├── main.py              # FastAPI app (healthcheck + CRUD)
│   ├── database.py          # SQLAlchemy engine/session
│   ├── models.py            # SQLAlchemy models
│   └── schemas.py           # Pydantic schemas
├── tests/
│   ├── __init__.py
│   ├── conftest.py          # FastAPI TestClient + DB override
│   ├── unit/
│   │   └── __init__.py
│   ├── integration/
│   │   ├── __init__.py
│   │   └── test_api_flow.py # Basic healthcheck + CRUD flow
│   └── e2e/
│       └── __init__.py
└── pyproject.toml           # Project configuration (format depends on --manager)

Environment Configuration

The init command creates a .env.example file with sensible defaults:

# Environment variables template
# Copy this file to .env and fill in your actual values

# Python Configuration
PYTHONDONTWRITEBYTECODE=1  # Prevents creation of __pycache__ and .pyc files

# Add your project-specific environment variables below
DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/app_db
# SECRET_KEY=your-secret-key-here
# DEBUG=False

Behavior:

  • If .env.example, .env.local, or .env.testing already exist → adds PYTHONDONTWRITEBYTECODE=1 if missing
  • If none exist → creates .env.example with the template above
  • If .gitignore exists → adds rules to exclude .env and .env.local (but allows .env.example)
  • If .gitignore doesn't exist → only creates .env.example (doesn't create .gitignore)

Generated pyproject.toml — pyenv + Poetry backend (--manager pyenv)

If no pyproject.toml exists, a minimal one is created:

[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = []
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"  # Example with --python 3.12.12 (always follows --python)

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Generated pyproject.toml — uv backend (--manager uv)

[project]
name = "my-project"
version = "0.1.0"
description = ""
readme = "README.md"
requires-python = ">=3.12"  # Example with --python 3.12.12
dependencies = []

Important:

  • Python version constraint automatically matches your specified --python version
  • Poetry backend uses [tool.poetry] section with caret constraint (^X.Y)
  • uv backend uses [project] section (PEP 621) with floor constraint (>=X.Y)
  • Neither file is ever overwritten if pyproject.toml already exists
  • When bootstrapping a brand-new project with --install, the CLI runs poetry add/uv add for: fastapi, uvicorn, sqlalchemy, psycopg[binary], alembic, pytest, httpx

Generated Dockerfile

The init command (and add-docker command) creates a production-ready multi-stage Dockerfile:

FROM python:3.12-slim-bookworm as builder

RUN apt-get update && apt-get install -y --no-install-recommends \
	build-essential && \
    rm -rf /var/lib/apt/lists/*

RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.12-slim-bookworm

WORKDIR /app
ENV PATH="/opt/venv/bin:$PATH"

CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8080"]

COPY --from=builder /opt/venv /opt/venv
COPY ./src ./src

Key features:

  • Version matching: Python version in Dockerfile automatically matches --python flag (e.g., --python 3.12.12python:3.12-slim-bookworm)
  • Multi-stage build: Separates build dependencies from runtime image (smaller final image)
  • In-project virtualenv: Installs dependencies in /opt/venv and reuses it in runtime stage
  • FastAPI-ready command: Runs uvicorn src.main:app on port 8080
  • Optimized layers: Installs dependencies before app source for better caching

Version extraction:

  • Full version 3.12.12 → Docker tag 3.12
  • Full version 3.11.5 → Docker tag 3.11
  • Ensures consistency between .python-version, pyproject.toml, and Dockerfile

Generated docker-compose.yml

The init command creates a docker-compose.yml with PostgreSQL ready for local development:

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: app_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - "5432:5432"

Start local database:

docker compose up -d db

🎯 Philosophy

api-bootstrapper-cli gives you a professional, runnable baseline while keeping setup deterministic:

  • ✅ Initialize a working API scaffold (healthcheck + CRUD + tests)
  • ✅ Add platform features incrementally
  • ✅ Maintain idempotency (safe to run multiple times)
  • ✅ Avoid breaking existing setups

Designed for teams that want consistent environments and deterministic setup without the complexity of cookiecutter templates.


Troubleshooting

pyenv not found

Symptom: Error: pyenv not found in PATH. Install pyenv first.

# Install pyenv (Linux)
curl https://pyenv.run | bash

# Add to ~/.bashrc or ~/.zshrc:
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

# Then reload your shell:
source ~/.bashrc  # or ~/.zshrc

pyenv: command not found (pip/python/pip3)

Symptom: pyenv: pip: command not found or pyenv: python: command not found

This happens when no Python version is set as global or local in pyenv. Even though you have Python versions installed via pyenv, none of them is active.

Solution:

# Set a global Python version
pyenv global 3.12.12

# Or set a local version for the current directory
pyenv local 3.12.12

# Verify it worked
python --version
pip --version

After setting the version, you can install packages:

pip install uv

Alternative: Install uv without pip (recommended)

# Using the official installer (works without pip)
curl -LsSf https://astral.sh/uv/install.sh | sh

Tip: If you frequently switch between projects, use pyenv local instead of pyenv global to set different Python versions per directory.

uv not found

Symptom: Error: uv not found in PATH. Install uv first.

# Install uv (Linux/macOS)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Or with pip
pip install uv

# Or with pipx
pipx install uv

# Make sure ~/.cargo/bin or ~/.local/bin is in PATH:
source ~/.bashrc  # or ~/.zshrc

pyenv: uv: command not found (when using --manager uv)

Symptom: pyenv: uv: command not found. The 'uv' command exists in these Python versions: X.Y.Z

This happens when uv was installed with pip install uv inside a specific pyenv Python version, making it unavailable when the project switches to a different Python version.

Problem:

# uv installed via pip in Python 3.13.9
pyenv global 3.13.9
pip install uv  # ❌ uv only available in 3.13.9

# When project uses Python 3.12.1, uv is not found
api-bootstrapper bootstrap-env --python 3.12.1 --manager uv
# Error: pyenv: uv: command not found

Solution: Install uv globally (outside pyenv)

# Option 1: Official installer (recommended)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Option 2: pipx (installs in isolated environment)
pipx install uv

# Option 3: Install in ALL pyenv versions
pyenv global <your-version>
pip install uv
# Then add uv to each version you use

After installing globally:

# Verify uv is accessible regardless of Python version
which uv  # Should show ~/.cargo/bin/uv or ~/.local/bin/uv (not a pyenv path)

# Now try again
api-bootstrapper bootstrap-env --python 3.12.1 --manager uv --path foo/

Key difference:

  • pip install uv → installs in current Python version only
  • curl ... | sh or pipx install uv → installs globally, works with any Python version

uv SSL certificate error (invalid peer certificate: UnknownIssuer)

Symptom: error: Failed to install cpython-X.Y.Z ... invalid peer certificate: UnknownIssuer

This happens when uv can't verify GitHub's SSL certificate, commonly caused by:

  • Corporate proxy with SSL inspection
  • Outdated CA certificates on your system
  • Network firewalls intercepting HTTPS

Solution 1: Update CA certificates (recommended)

# Debian/Ubuntu
sudo apt update && sudo apt install --reinstall ca-certificates

# Fedora/RHEL/CentOS
sudo dnf reinstall ca-certificates

# After updating, test:
curl -I https://github.com

Solution 2: Configure corporate proxy certificates

If behind a corporate proxy, you need to trust its certificate:

# Get your corporate CA certificate (usually provided by IT)
# Then add it to the system trust store

# Debian/Ubuntu
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# Fedora/RHEL/CentOS
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

Solution 3: Use pyenv backend instead

If SSL issues persist, use pyenv which builds Python from source:

# Use pyenv instead of uv
api-bootstrapper bootstrap-env --python 3.12.1 --manager pyenv --path foo/

Temporary workaround (NOT recommended for production):

# Skip SSL verification (security risk!)
export UV_NO_VERIFY_SSL=1
api-bootstrapper bootstrap-env --python 3.12.1 --manager uv --path foo/

Security warning: Only use UV_NO_VERIFY_SSL=1 in trusted networks for testing. Never use in production or untrusted networks.

Python build dependencies (Linux)

When pyenv install fails with compilation errors, install the required system libraries:

# Debian / Ubuntu
sudo apt install -y build-essential libssl-dev zlib1g-dev \
  libbz2-dev libreadline-dev libsqlite3-dev libffi-dev \
  liblzma-dev tk-dev

# Fedora / RHEL / CentOS
sudo dnf install -y gcc zlib-devel bzip2 bzip2-devel readline-devel \
  sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel

Poetry not found

Symptom: The CLI can't locate poetry after installation.

# Check if Poetry is installed
poetry --version

# Install Poetry via pipx (recommended)
pipx install poetry

# Or install via the official installer
curl -sSL https://install.python-poetry.org | python3 -

# Make sure $HOME/.local/bin is in PATH:
export PATH="$HOME/.local/bin:$PATH"

Permission error when removing poetry.lock

If you see a warning about poetry.lock not being removable:

rm poetry.lock
api-bootstrapper bootstrap-env --python <version> --path .

SSL errors when installing packages

# Test connectivity
python -m pip install --upgrade pip

# If behind a corporate proxy, configure pip:
pip config set global.proxy http://proxy.example.com:8080

# Or set pip trusted hosts:
pip config set global.trusted-host "pypi.org files.pythonhosted.org pypi.python.org"

bootstrap-env re-runs even though environment exists

This happens when the venv Python major.minor doesn't match .python-version. Delete the venv and let the CLI recreate it:

# pyenv + Poetry backend
rm -rf .venv poetry.lock
api-bootstrapper bootstrap-env --python <version> --path .

# uv backend
rm -rf .venv uv.lock
api-bootstrapper bootstrap-env --python <version> --path . --manager uv

📋 Compatibility Matrix

Component Supported versions Notes
Python (CLI requires) 3.12+ Runtime to run the CLI itself
Python (target project) 3.10+ The version you pass via --python
pyenv 2.3+ Earlier versions may lack pyenv prefix
Poetry 1.8+ Uses poetry install --no-root
uv 0.4+ Uses uv python install + uv sync
macOS 12 Monterey+ Intel & Apple Silicon tested
Linux Ubuntu 22.04+, Fedora 38+ Any modern distro should work
Windows Partial Activation instructions adapted; pyenv-win needed

Note: Windows support is experimental. Use pyenv-win and run commands in PowerShell or Git Bash.


Roadmap

  • bootstrap-env - pyenv + Poetry + VSCode
  • bootstrap-env --manager uv - uv + VSCode
  • add-pre-commit - Git hooks with Ruff and Commitizen
  • add-docker - Dockerfile for Python applications
  • ✅ Environment variables - .env.example template with PYTHONDONTWRITEBYTECODE=1
  • ✅ Project scaffold - FastAPI app + tests + Makefile
  • ✅ Local PostgreSQL - docker-compose.yml created by init
  • add-alembic - Database migrations
  • add-mypy - Type checking
  • ⬜ Profiles - fastapi-postgres-clean-arch

🧪 Development

Setup development environment

# Clone and install
git clone https://github.com/ranog/api-bootstrapper-cli.git
cd api-bootstrapper-cli
poetry install

Running tests

# All tests
poetry run pytest

# With coverage
poetry run pytest --cov=api_bootstrapper_cli

# By type
poetry run pytest -m unit
poetry run pytest -m integration
poetry run pytest -m e2e

Code quality

# Linting & formatting (auto-fix)
poetry run ruff check . --fix
poetry run ruff format .

🤝 Contributing

Contributions are welcome! To contribute:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Install dependencies (poetry install)
  4. Make your changes with tests
  5. Run tests and formatting (poetry run pytest, poetry run ruff format .)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to your fork (git push origin feature/amazing-feature)
  8. Open a Pull Request

📄 License

MIT License © 2026 João Paulo Ramos Nogueira

See LICENSE file for details.


🙏 Acknowledgments

  • Built with Typer for the CLI framework
  • Styled with Rich for beautiful terminal output
  • Tested with pytest for reliability

Made with ❤️ for Python developers who value automation and consistency

Releases

No releases published

Packages

 
 
 

Contributors