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.
- 🐍 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.exampletemplate withPYTHONDONTWRITEBYTECODE=1 - 🚀 Smart Detection - Skips setup if environment already exists
- 🎯 Zero Configuration - Creates minimal
pyproject.tomland 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
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 ensurepathThen install the CLI:
pipx install git+https://github.com/ranog/api-bootstrapper-cli.gitAfter installation, reload your shell:
source ~/.bashrc # or ~/.zshrc if using zshWhy 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
git clone https://github.com/ranog/api-bootstrapper-cli
cd api-bootstrapper-cli
poetry installTo update to the latest version:
If installed via pipx from git:
pipx install git+https://github.com/ranog/api-bootstrapper-cli.git --forceThen install/update bundled Codex skills:
api-bootstrapper install-skillsThen install/update bundled Agent Skills (open format):
api-bootstrapper install-agent-skillsEnable tab completion for commands and options:
# Install completion for your shell
api-bootstrapper --install-completion
# Restart your shell or run:
source ~/.bashrc # or ~/.zshrcNow 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, --installInitialize 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.xFor 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/activateNote: The CLI automatically detects paths with spaces or accents (e.g.,
/Área de Trabalho/project) and showssource $(poetry env info --path)/bin/activatewhich handles special characters reliably.
You can run the same bootstrap engine through an HTTP API (FastAPI), not only via CLI.
# From source checkout
make run-api
# Equivalent command
poetry run api-bootstrapper-apiServer default:
- Base URL:
http://localhost:8000 - OpenAPI docs:
http://localhost:8000/docs
curl -s http://localhost:8000/healthExpected response:
{"status":"ok"}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
}400: invalid bootstrap preconditions (for example, manager not installed)500: execution failed while running bootstrap operations
This repository now includes a dual skill distribution for agent runtimes:
skills/agentskills- canonical open-format Agent Skills sourceskills/codex- Codex-compatible mirror withagents/openai.yaml
Available skills:
api-bootstrapper-initapi-bootstrapper-bootstrap-envapi-bootstrapper-add-pre-commitapi-bootstrapper-add-dockerapi-bootstrapper-add-alembicapi-bootstrapper-bootstrap-flow(orchestrator)api-bootstrapper-sync-branchapi-bootstrapper-generate-commit-messageapi-bootstrapper-create-testsapi-bootstrapper-debug-issueapi-bootstrapper-review-codeapi-bootstrapper-prepare-taskapi-bootstrapper-staff-reviewapi-bootstrapper-understand-systemapi-bootstrapper-implement-feature-tddapi-bootstrapper-refactor-safelyapi-bootstrapper-add-tool-supportapi-bootstrapper-prepare-prapi-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-skillsKeep both trees in sync with:
make sync-skills
make validate-skills🎯 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
For using the CLI:
- pipx (recommended) or pip
- macOS or Linux
- Backend: pyenv (default) — pyenv installed
Backend: uv — uv installed (pip install uvorcurl -LsSf https://astral.sh/uv/install.sh | sh)
Target project can be:
- Empty directory - Will create a minimal
pyproject.tomland setup full environment - Existing project - With
pyproject.tomlalready present
Default behavior:
bootstrap-envuses3.12.12when--pythonis omittedinitrequires an explicit--pythonvaluepyproject.tomlconstraints 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.2The 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+.
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-installWhat it does:
- ✅ Creates a runnable FastAPI scaffold (
src/main.py,database.py,models.py,schemas.py) and test folders (unit/,integration/,e2e/) - ✅ Sets up Python environment (pyenv or uv + VSCode)
- ✅ Creates
Dockerfileanddocker-compose.yml(PostgreSQL service) - ✅ Creates
.env.examplewithPYTHONDONTWRITEBYTECODE=1 - ✅ Updates
.gitignoreto exclude.envfiles (if.gitignoreexists) - ✅ Adds default API dependencies on new projects (
fastapi,uvicorn,sqlalchemy,psycopg[binary],alembic,pytest,httpx) - ✅ Configures pre-commit hooks
- ✅ Shows clear next steps
This is the recommended command for new projects!
See --manager option below for choosing between pyenv+Poetry and uv.
Sets up a complete Python development environment and VSCode configuration.
Supports two backends via --manager:
pyenv(default) — uses pyenv for Python installation + Poetry for dependenciesuv— uses uv for both Python installation and dependency management (faster)
💡 Tip: If you want environment + pre-commit in one command, use
initinstead.
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 uvWhat it does (pyenv + Poetry backend):
- ✅ Installs Python version via pyenv (if not installed)
- ✅ Creates
.python-versionfile - ✅ Installs
pip,setuptools,wheel, andpoetryin project's Python - ✅ Creates minimal
pyproject.tomlif missing (Poetry format, never overwrites) - ✅ Configures Poetry with in-project virtualenv (
.venv) - ✅ Creates Poetry environment
- ✅ Installs dependencies (unless
--no-install) - ✅ Generates VSCode
settings.jsonwith Python interpreter
What it does (uv backend):
- ✅ Installs Python version via
uv python install(if not installed) - ✅ Creates
.python-versionfile viauv python pin - ✅ Creates minimal
pyproject.tomlif missing (PEP 621 format, never overwrites) - ✅ Creates in-project virtualenv (
.venv) viauv venv - ✅ Installs/syncs dependencies via
uv sync(unless--no-install) - ✅ Generates VSCode
settings.jsonwith 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 ✓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
pyenvwhen the project already uses Poetry or requires a specific pyenv workflow.
Configures pre-commit hooks with Ruff (linter/formatter) and Commitizen (conventional commits).
💡 Tip: If you're starting a new project, use
initwhich includes this automatically.
Basic usage:
# In current directory
api-bootstrapper add-pre-commit
# In a specific directory
api-bootstrapper add-pre-commit --path ./my-projectWhat it does:
- ✅ Creates
.pre-commit-config.yamlwith Ruff and Commitizen hooks - ✅ Adds
pre-commit,ruff, andcommitizento dev dependencies via Poetry or uv (based on selected manager) - ✅ Updates hook versions in config to match installed packages
- ✅ 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 messageRequires:
- Git repository initialized (
.git/directory) - Poetry or uv environment configured
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 uvWhat it does:
- ✅ Adds
mypyto dev dependencies (Poetry or uv format) - ✅ Creates
[tool.mypy]config inpyproject.tomlwhen missing - ✅ Preserves existing mypy config if already present
- ✅ Syncs dependencies (
poetry lock/installoruv sync)
Next step:
- Run
poetry run mypy src(pyenv/Poetry) oruv run mypy src(uv)
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.13What it does:
- ✅ Creates
Dockerfilewith multi-stage build - ✅ Uses Python slim image for smaller size
- ✅ Configures uvicorn to run FastAPI app on port 8080
- ✅ Optimizes for production with proper dependency caching
Generated Dockerfile features:
- Multi-stage build - Separates build dependencies from runtime
- Virtual environment - Uses
/opt/venvfor isolated dependencies - Minimal size - Based on
python:X.Y-slim-bookwormimage - FastAPI ready - Configured for
src.main:appwith 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:8080Requires:
requirements.txtwith dependenciessrc/main.pywith FastAPI app
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-headWhat it does:
- ✅ Initializes Alembic when missing
- ✅ Rewrites
alembic/env.pyto use projectBase.metadata - ✅ Can start
dbservice with Docker Compose (--with-db) - ✅ Can generate initial
itemsmigration (--create-initial-items) - ✅ Can apply migrations (
--upgrade-head)
Notes:
- When
--create-initial-itemsor--upgrade-headis used, the command automatically starts the local DB service (db) before running migrations. - The generated revision message is
create items table.
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-overwriteWhat it does:
- ✅ Loads embedded skill files bundled in the CLI package
- ✅ Copies all
api-bootstrapper-*skills to your Codex skills directory - ✅ Overwrites existing skill folders by default (or skips with
--no-overwrite)
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-overwriteWhat it does:
- ✅ Loads embedded open-format Agent Skills from the packaged CLI
- ✅ Copies all
api-bootstrapper-*skills to your Agent Skills directory - ✅ Overwrites existing skill folders by default (or skips with
--no-overwrite)
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)
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=FalseBehavior:
- If
.env.example,.env.local, or.env.testingalready exist → addsPYTHONDONTWRITEBYTECODE=1if missing - If none exist → creates
.env.examplewith the template above - If
.gitignoreexists → adds rules to exclude.envand.env.local(but allows.env.example) - If
.gitignoredoesn't exist → only creates.env.example(doesn't create.gitignore)
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"[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
--pythonversion - 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.tomlalready exists - When bootstrapping a brand-new project with
--install, the CLI runspoetry add/uv addfor:fastapi,uvicorn,sqlalchemy,psycopg[binary],alembic,pytest,httpx
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 ./srcKey features:
- Version matching: Python version in Dockerfile automatically matches
--pythonflag (e.g.,--python 3.12.12→python:3.12-slim-bookworm) - Multi-stage build: Separates build dependencies from runtime image (smaller final image)
- In-project virtualenv: Installs dependencies in
/opt/venvand reuses it in runtime stage - FastAPI-ready command: Runs
uvicorn src.main:appon port8080 - Optimized layers: Installs dependencies before app source for better caching
Version extraction:
- Full version
3.12.12→ Docker tag3.12 - Full version
3.11.5→ Docker tag3.11 - Ensures consistency between
.python-version,pyproject.toml, andDockerfile
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 dbapi-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.
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 ~/.zshrcSymptom: 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 --versionAfter setting the version, you can install packages:
pip install uvAlternative: Install uv without pip (recommended)
# Using the official installer (works without pip)
curl -LsSf https://astral.sh/uv/install.sh | shTip: If you frequently switch between projects, use
pyenv localinstead ofpyenv globalto set different Python versions per directory.
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 ~/.zshrcSymptom: 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 foundSolution: 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 useAfter 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 onlycurl ... | shorpipx install uv→ installs globally, works with any Python version
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.comSolution 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-trustSolution 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=1in trusted networks for testing. Never use in production or untrusted networks.
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-develSymptom: 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"If you see a warning about poetry.lock not being removable:
rm poetry.lock
api-bootstrapper bootstrap-env --python <version> --path .# 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"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| 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.
- ✅
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.exampletemplate withPYTHONDONTWRITEBYTECODE=1 - ✅ Project scaffold - FastAPI app + tests + Makefile
- ✅ Local PostgreSQL -
docker-compose.ymlcreated byinit - ✅
add-alembic- Database migrations - ✅
add-mypy- Type checking - ⬜ Profiles - fastapi-postgres-clean-arch
# Clone and install
git clone https://github.com/ranog/api-bootstrapper-cli.git
cd api-bootstrapper-cli
poetry install# 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# Linting & formatting (auto-fix)
poetry run ruff check . --fix
poetry run ruff format .Contributions are welcome! To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Install dependencies (
poetry install) - Make your changes with tests
- Run tests and formatting (
poetry run pytest,poetry run ruff format .) - Commit your changes (
git commit -m 'Add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License © 2026 João Paulo Ramos Nogueira
See LICENSE file for details.
- 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