claude-code-commands/framework.md
2025-08-04 00:18:37 +01:00

13 KiB

Python Framework & Configuration Audit

Your primary task is to audit this project's configuration and ensure it aligns with modern Python development best practices. You should either create new configuration files for a new project or intelligently modify existing ones to meet these standards.

Do not blindly replace files. Your goal is to enforce a consistent, modern, and efficient development environment. Always explain the changes you are making and why they align with the framework principles outlined below.

Initial Project Analysis

Before making any changes, gather project information:

  1. Check if this is a Git repository and get remote URL:

    git remote -v
    

    Use this information to populate the [project.urls] section in pyproject.toml.

  2. Examine existing project structure:

    • Look for existing pyproject.toml, setup.py, requirements.txt, or poetry.lock
    • Check for existing source code to understand the project name and structure
    • Look for existing tests to understand testing framework (pytest, unittest, etc.)
    • Read README.md if it exists - this often contains the best description of what the project does and can inform the name, description, and classifiers in pyproject.toml
  3. Identify the project type:

    • Is it a library (should be installable)?
    • Is it an application (needs entry points)?
    • Does it need containerisation?

Guiding Principles

Before looking at the specific files, understand the philosophy behind this framework:

  • Speed & Efficiency: We prioritise fast dependency management, builds, and CI/CD pipelines. Tools like uv and multi-stage Docker builds are central to this.
  • Consolidation: We use pyproject.toml as the single source of truth for project metadata, dependencies, and tool configuration (linting, formatting, etc.).
  • Clarity & Consistency: Code and configuration should be easy to read and maintain. Comments in configuration files should explain non-obvious choices.
  • Automation: The CI/CD workflow automates quality assurance and should be reliable whilst providing fast feedback.

1. Project & Tooling Configuration (pyproject.toml)

The pyproject.toml file is the backbone of the project's structure.

Your Task:

  • If no pyproject.toml exists, create one based on the template below.
  • If one exists, audit it. Ensure it uses ruff for both linting and formatting, configures project metadata under the [project] table, and uses the [tool.uv] section for dependency management.
  • Pay close attention to the ruff linting codes. The template contains comments explaining the currently selected ruleset. If the project's file has outdated or conflicting codes, update them and explain the change.
  • IMPORTANT: Replace placeholder values with actual project information gathered from your initial analysis.
[project]
# Replace with actual project name (use directory name if unclear)
name = "your-project-name"
version = "0.1.0"
# Replace with appropriate description based on project contents
description = "A brief description of what this project does."
readme = "README.md"
# Choose appropriate licence (MIT, Apache-2.0, GPL-3.0, etc.)
license = { text = "MIT" }
# Replace with actual author information
authors = [{ name = "Your Name", email = "your.email@example.com" }]
maintainers = [{ name = "Your Name", email = "your.email@example.com" }]
# Adjust Python version based on project requirements
requires-python = ">=3.11"
classifiers = [
    "Development Status :: 3 - Alpha",  # Or 4 - Beta, 5 - Production/Stable
    "License :: OSI Approved :: MIT License",  # Match your chosen licence
    "Programming Language :: Python",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
]
# Adjust dependencies based on actual project requirements
dependencies = [
    # Example common dependencies - replace with actual needs:
    # "fastapi>=0",
    # "requests>=2",
    # "pydantic>=2",
    # "pytz>=2025",
    "uvicorn[standard]>=0",
]

[project.urls]
# Replace with actual repository URL from `git remote -v`
Homepage = "https://github.com/username/repository-name"
# Add additional URLs as appropriate:
# "Bug Reports" = "https://github.com/username/repository-name/issues"
# "Source" = "https://github.com/username/repository-name"
# "Documentation" = "https://your-project-docs.readthedocs.io/"

[dependency-groups]
dev = ["ruff>=0", "uv>=0"]

[tool.uv]
package = true

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

# Only include if this is an application with CLI entry points
[project.scripts]
# Replace with actual script name and module path
your-cli-command = "your_package.__main__:main"

[tool.setuptools]
packages = { find = {} }

[tool.ruff]
cache-dir = "/tmp/.ruff_cache"
fix = true
line-length = 100
preview = true
show-fixes = false
# Adjust target version to match requires-python
target-version = "py311"
unsafe-fixes = true

[tool.ruff.format]
line-ending = "auto"
skip-magic-trailing-comma = false

[tool.ruff.lint]
fixable = ["ALL"]
ignore = [
    "ANN401",  # use of Any type
    "BLE001",  # blind Exception usage
    "COM812",  # missing trailing comma
    "CPY",     # flake8-copyright
    "FBT",     # boolean arguments
    "PLR0912", # too many branches
    "PLR0913", # too many arguments
    "PLR0915", # too many statements
    "PLR0917", # too many positional arguments
    "PLR6301", # method could be static
    "RUF029",  # async methods that don't await
    "S104",    # binding to all interfaces
    "S110",    # passed exceptions
    "TRY301",  # raise inside try block
]
select = ["ALL"]
unfixable = [
    "F841",   # local variable assigned but never used
    "RUF100", # unused noqa comments
    "T201",   # don't strip print statement
]

[tool.ruff.lint.isort]
combine-as-imports = true
required-imports = ["from __future__ import annotations"]

[tool.ruff.lint.pydocstyle]
convention = "google"

2. Development Environment Setup

Essential Commands for Project Setup:

  1. Install uv (if not already installed):

    curl -LsSf https://astral.sh/uv/install.sh | sh
    
  2. Initialise virtual environment and install dependencies:

    uv sync --all-groups
    

3. Containerisation (Dockerfile)

Create this file only if the project needs containerisation (web services, deployable applications).

Our containerisation strategy focuses on creating minimal, secure, and efficient runtime images.

Your Task:

  • Audit or create a Dockerfile that follows a multi-stage build process.
  • The fundamental pattern is:
    1. A build stage, based on a full Python image, where dependencies are compiled using uv.
    2. A final, minimal runtime stage (e.g., python-slim) where the virtual environment from the build stage is copied over.
  • Ensure the PATH environment variable in the final stage is correctly prepended with the virtual environment's bin directory. This ensures that python commands execute from within the virtual environment by default.
  • Replace project-specific details with actual project information.
# Build stage using uv with a frozen lockfile and dependency caching
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS uv
WORKDIR /app

# Enable bytecode compilation and copy mode
ENV UV_COMPILE_BYTECODE=1 \
  UV_LINK_MODE=copy

# Install dependencies using the lockfile
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv \
  uv sync --frozen --no-dev --no-editable --no-install-project

# Install the project in a second layer
COPY . .
RUN --mount=type=cache,target=/root/.cache/uv \
  uv sync --frozen --no-dev --no-editable

# Prepare runtime image
FROM python:3.13-slim-bookworm AS runtime
WORKDIR /app

# Install minimal system dependencies and create runtime user
# Adjust system packages based on your project's needs
RUN apt-get update && apt-get install -y curl \
  && rm -rf /var/lib/apt/lists/* \
  && groupadd -g 1000 appuser \
  && useradd -u 1000 -g 1000 -m appuser

# Copy only the virtual environment from the build stage
COPY --from=uv /app/.venv /app/.venv

# Switch to non-root user
USER appuser

# Set environment variables for runtime
ENV PATH="/app/.venv/bin:$PATH" \
  PYTHONDONTWRITEBYTECODE=1 \
  PYTHONUNBUFFERED=1

# Replace with appropriate startup command for your application
ENTRYPOINT ["uvicorn", "your_package", "--host", "0.0.0.0", "--port", "80"]

# Add health check for web services
# HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -f http://localhost:80/health || exit 1

4. Continuous Integration

The CI workflow automates our quality checks. The goal is fast, parallel execution.

For Forgejo (.forgejo/workflows/docker-build.yml)

  • Audit or create a CI file that defines jobs for linting, testing, and building.
  • Ensure the jobs are configured to run in parallel where possible.
  • The workflow should leverage caching mechanisms for dependencies to speed up subsequent runs.
  • The "lint" stage should simply run ruff check . and ruff format --check ..
  • The "test" stage should run the project's test suite, likely using pytest.
name: Docker Build

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  REGISTRY: git.tomfos.tr  # Replace with your registry URL

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install uv
        run: curl -LsSf https://astral.sh/uv/install.sh | sh
      - name: Add uv to PATH
        run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - name: Set up Python
        run: uv python install
      - name: Install dependencies
        run: uv sync
      - name: Run ruff check
        run: uv run ruff check .
      - name: Run ruff format
        run: uv run ruff format --check .

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install uv
        run: curl -LsSf https://astral.sh/uv/install.sh | sh
      - name: Add uv to PATH
        run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - name: Set up Python
        run: uv python install
      - name: Install dependencies
        run: uv sync
      - name: Run tests
        run: uv run pytest --cov

  build-and-push:
    name: Build and Push
    runs-on: ubuntu-latest
    needs: [lint, test]
    if: github.event_name == 'push'
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: https://github.com/docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: https://github.com/docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ gitea.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Determine image metadata
        id: meta
        uses: https://github.com/docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ gitea.repository }}
          tags: |
            type=ref,event=branch
            type=ref,event=branch,suffix=-{{sha}}
            type=raw,value=latest,enable={{is_default_branch}}

      - name: Build and push Docker image
        uses: https://github.com/docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ gitea.repository }}:build-cache
          cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ gitea.repository }}:build-cache,mode=max

How to Apply These Instructions

For a New Project

  1. Gather Information: Run git remote -v to get repository URL, examine directory structure
  2. Create Configuration: Use the templates above, replacing placeholders with actual project details
  3. Setup Environment: Run uv sync to create virtual environment and install dependencies
  4. Announce: "Setting up the project with modern Python development framework"

For an Existing Project

  1. Audit Current Setup: Compare existing files against framework guidelines
  2. Preserve Valid Configuration: Don't discard project-specific settings that don't conflict
  3. Migrate Dependencies: If requirements.txt exists, migrate to pyproject.toml dependency groups
  4. Update Tools: Ensure ruff is used for both linting and formatting
  5. Explain Changes: Clearly list proposed changes and justification for each

Migration from Legacy Tools

  • From setup.py: Move metadata to [project] table in pyproject.toml
  • From requirements.txt: Move to dependencies and [dependency-groups] in pyproject.toml
  • From black + flake8/pylint: Replace with ruff for unified linting and formatting
  • From pip: Migrate to uv for faster dependency management