Claude Code-specific configuration and standards for the Python IPAM project.
IMPORTANT LANGUAGE REQUIREMENT:
- ALL documentation MUST be written in English
- This includes: README.md, API.md, FEATURES.md, REFACTORING.md, CLAUDE.md, code comments, commit messages
- German or other languages are NOT permitted in documentation
DOCUMENTATION UPDATE POLICY:
- Every code change MUST be evaluated for documentation impact
- Before committing ANY change, ask: "Does this require documentation updates?"
- Documentation files to check:
README.md- User-facing documentation, setup instructionsAPI.md- REST API endpoint documentationFEATURES.md- Feature tracking and roadmapREFACTORING.md- Architecture and refactoring notesCLAUDE.md- This file, project standards
- Documentation updates should be committed together with code changes
- Never commit code without updating related documentation
Python IPAM is a modern IP Address Management (IPAM) system based on:
- Flask 3.0 (Python Web Framework)
- SQLite/SQLAlchemy (Database)
- Bootstrap 5 + DataTables (Frontend)
- pytest (Testing Framework)
- Docker (Containerization)
Formatter: Black with 80 character line length
black . --line-length 80Linting: Pylint with Google configuration
pylint --rcfile=https://google.github.io/styleguide/pylintrc app.py tests/Naming Conventions:
- Modules/Packages:
lowercase_with_underscores - Classes:
CapWords(e.g.,NetworkForm,HostModel) - Functions/Variables:
lowercase_with_underscores - Constants:
CAPS_WITH_UNDERSCORES - Private:
_leading_underscore
Import Order (separated by blank lines):
from __future__ import annotations
import os
import ipaddress
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from ipam import db, Network, HostFollow security best practices:
FROM python:3.11-slim
# Security: Non-root user
RUN useradd -r -s /bin/false ipam
USER ipam
# Layer optimization
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# JSON notation for CMD
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]Format:
<type>(<scope>): <short summary>
<body>
<footer>
Types for this project:
feat: New IPAM features (Host/Network management)fix: Bug fixes in web UI or APItest: Unit tests for models/routes/formsdocker: Container configurationdocs: README or API documentation
Examples:
feat(networks): add VLAN ID support
fix(hosts): resolve auto-detection for overlapping subnets
test(models): add network cascade delete tests
docker: optimize layer caching in Dockerfile
docs: update pyenv setup instructionsIMPORTANT: Do not use AI signatures in commits!
For test scripts and setup automation:
#!/bin/bash
# Functions
function setup_venv() {
local python_version="$1"
echo "Setting up Python ${python_version}..."
}
# Prefer [[ ]]
if [[ -d "venv" ]]; then
source venv/bin/activate
fi
# Quote variables
echo "PATH: ${PATH}"Test Structure:
tests/
├── conftest.py # Pytest fixtures (Application Factory)
├── test_models.py # SQLAlchemy Model Tests
├── test_routes.py # Flask Route Tests
├── test_forms.py # WTForms Validation Tests
├── test_database.py # Database initialization tests
├── test_export_import.py # Export/Import plugin tests
└── test_crud_operations.py # CRUD operation tests
Test Commands:
# All tests
pytest -v
# With coverage
pytest --cov=ipam --cov-report=html
# Specific tests
pytest tests/test_models.py::TestNetworkModel::test_network_properties
# Database tests
pytest tests/test_database.py -vSQLAlchemy models in ipam/models.py:
from ipam.extensions import db
class Network(db.Model):
__tablename__ = 'networks' # Explicit table names
# Primary Keys as first column
id = db.Column(db.Integer, primary_key=True)
# Relationships with cascade definitions
hosts = db.relationship('Host', backref='network_ref',
cascade='all, delete-orphan')
# Properties for calculated values
@property
def total_hosts(self):
return len(list(ipaddress.IPv4Network(
f"{self.network}/{self.cidr}", strict=False
).hosts()))Application Factory Pattern in ipam/__init__.py:
from ipam.extensions import db
from ipam.config import config
def create_app(config_name='default'):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
from ipam.web import web_bp
from ipam.api import api_bp
app.register_blueprint(web_bp)
app.register_blueprint(api_bp)
return appWeb Routes in ipam/web/routes.py:
from ipam.web import web_bp
from ipam.extensions import db
from ipam.models import Network, Host
@web_bp.route('/')
def index():
"""Dashboard."""
networks = Network.query.all()
return render_template('index.html', networks=networks)API Routes in ipam/api/networks.py:
from flask_restx import Namespace, Resource
from ipam.extensions import db
from ipam.models import Network
api = Namespace('networks', description='Network operations')
@api.route('/')
class NetworkList(Resource):
def get(self):
"""List all networks."""
networks = Network.query.all()
return {'data': [network.to_dict() for network in networks]}HTML/Jinja2 template standards:
- Bootstrap 5 CSS classes
- Responsive design
- DataTables for tables
- Bootstrap Icons (
bi-*)
pyenv Setup:
pyenv install 3.13
pyenv local 3.13
python -m venv venv
source venv/bin/activate
pip install -r requirements.txtDatabase Initialization:
# Create database (on first start)
python3 -c "from ipam import create_app; from ipam.extensions import db; app = create_app(); app.app_context().push(); db.create_all()"Development Server:
python app.py # Flask dev server on :5000
# Available URLs:
# - Web Interface: http://localhost:5000
# - REST API: http://localhost:5000/api/v1
# - Swagger UI: http://localhost:5000/api/v1/docsDevelopment Container:
docker-compose --profile dev upProduction Container:
docker-compose up -dLinting/Formatting (local):
# Python Code
black . --line-length 80
pylint app.py tests/
# Dockerfile
hadolint Dockerfile
# Shell Scripts
shellcheck run_tests.shTesting:
./run_tests.sh # Complete test suite with coverage
make test # Makefile targetREST API Base URL: /api/v1
Swagger UI: http://localhost:5000/api/v1/docs
Main Endpoints:
Networks:
GET /api/v1/networks- List all networks (with filtering/pagination)POST /api/v1/networks- Create networkGET /api/v1/networks/{id}- Get networkPUT /api/v1/networks/{id}- Update networkDELETE /api/v1/networks/{id}- Delete network
Hosts:
GET /api/v1/hosts- List all hosts (with filtering/pagination)POST /api/v1/hosts- Create hostGET /api/v1/hosts/{id}- Get hostPUT /api/v1/hosts/{id}- Update hostDELETE /api/v1/hosts/{id}- Delete host
IP Management:
GET /api/v1/ip/networks/{id}/next-ip- Get next free IPGET /api/v1/ip/networks/{id}/available-ips- List all free IPsGET /api/v1/ip/{ip_address}- Query IP status
Response Format:
{
"data": [...],
"pagination": {
"page": 1,
"per_page": 50,
"total_items": 100,
"total_pages": 2
}
}Complete documentation: API.md
Production Images (Chainguard distroless):
- Registry: ghcr.io/tuxpeople/python-ipam
- Base: cgr.dev/chainguard/python:latest (distroless)
- Security: 0 CRITICAL/HIGH vulnerabilities (Trivy scanned)
- Size: ~50-100MB (multi-stage build)
- User: nonroot (UID 65532)
- Python: 3.13
Tags:
latest- Always points to latest stable release1.0.0- Specific patch version1.0- Minor version (updates with new patches)1- Major version (updates with new minors/patches)main-<sha>- Git commit SHA for main branch builds
Multi-stage Build:
# Stage 1: Build dependencies in -dev image
FROM cgr.dev/chainguard/python:latest-dev AS build
RUN python -m venv /home/nonroot/venv && \
/home/nonroot/venv/bin/pip install --upgrade 'pip<25.2' setuptools wheel
# Stage 2: Install Python packages
FROM build AS build-venv
COPY requirements.txt /tmp/requirements.txt
RUN /home/nonroot/venv/bin/pip install -r /tmp/requirements.txt
# Stage 3: Minimal runtime image (distroless)
FROM cgr.dev/chainguard/python:latest
COPY --from=build-venv /home/nonroot/venv /home/nonroot/venv
ENV PATH="/home/nonroot/venv/bin:$PATH"Kubernetes (if used):
# Follow Kubernetes best practices
metadata:
labels:
app.kubernetes.io/name: python-ipam
app.kubernetes.io/version: "1.0.0"
app.kubernetes.io/component: backend
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65532
fsGroup: 65532Common Issues:
-
SQLite Lock Issues:
# Use context manager with app.app_context(): db.session.commit()
-
pyenv Python not found:
pyenv rehash which python # Should show pyenv version -
Docker Build Failures:
docker system prune # Cleanup docker build --no-cache .
Dependencies Update:
pip list --outdated
pip install -U package_name
pip freeze > requirements.txtDatabase Migrations (on schema changes):
# In Python Console
from ipam import create_app
from ipam.extensions import db
app = create_app()
with app.app_context():
db.drop_all() # Caution in production!
db.create_all()Database Initialization (Command line):
python3 -c "from ipam import create_app; from ipam.extensions import db; app = create_app(); app.app_context().push(); db.create_all()"This project follows Semantic Versioning 2.0.0:
Version Format: MAJOR.MINOR.PATCH
- MAJOR: Breaking changes (API changes, database schema changes)
- MINOR: New features (backwards compatible)
- PATCH: Bug fixes (backwards compatible)
Examples:
v1.0.0- First production releasev1.1.0- New features (e.g., subnet calculator)v1.1.1- Bug fixesv2.0.0- Breaking changes (e.g., database schema migration)
IMPORTANT: Every version MUST have:
- Git tag (annotated)
- GitHub Release with changelog
- Docker image published to GHCR
Release Checklist:
-
Update Version (if not already done):
# Update version in relevant files if needed # (Currently no __version__ file, but could be added)
-
Run Full Test Suite:
pytest -v black . --check --line-length 80 hadolint Dockerfile -
Update Documentation:
- Check README.md, API.md, FEATURES.md for accuracy
- Update CLAUDE.md changelog (see below)
- Ensure all recent changes are documented
-
Create Git Tag:
# Create annotated tag with version (must start with 'v' for CI/CD) git tag -a v1.0.0 -m "v1.0.0" # Push tag to GitHub (triggers Docker build) git push origin v1.0.0
-
Create GitHub Release:
# Create release with changelog (title should be version only) gh release create v1.0.0 \ --title "v1.0.0" \ --notes-file /tmp/release-notes.md
Release Notes Template (
/tmp/release-notes.md):# Python IPAM v1.0.0 Brief description of the release. ## 🚀 Features - New feature 1 - New feature 2 ## 🐛 Bug Fixes - Fix for issue #123 ## 🔒 Security - Security improvements ## 📦 Container Image \`\`\`bash docker pull ghcr.io/tuxpeople/python-ipam:1.0.0 docker pull ghcr.io/tuxpeople/python-ipam:1.0 docker pull ghcr.io/tuxpeople/python-ipam:1 docker pull ghcr.io/tuxpeople/python-ipam:latest \`\`\` ## 🔄 Migration Notes - Breaking changes (if any) - Upgrade instructions ## 📝 Full Changelog https://github.com/tuxpeople/python-ipam/compare/v0.9.0...v1.0.0
-
Verify Docker Image:
# CI/CD automatically builds and pushes to GHCR on tag push # Verify all tags are available (wait ~5 minutes for build) docker pull ghcr.io/tuxpeople/python-ipam:1.0.0 docker pull ghcr.io/tuxpeople/python-ipam:1.0 docker pull ghcr.io/tuxpeople/python-ipam:1 docker pull ghcr.io/tuxpeople/python-ipam:latest
-
Update CLAUDE.md Changelog (after release):
### 2025-10-03 - v1.0.0 - ✅ First production release - ✅ Chainguard distroless migration (0 vulnerabilities) - ✅ Complete CI/CD pipeline
For urgent bug fixes:
-
Create branch from tag:
git checkout -b hotfix/v1.0.1 v1.0.0
-
Apply fix and test:
# Make changes pytest -v git commit -m "fix: critical bug in network calculation"
-
Tag and release:
git tag -a v1.0.1 -m "v1.0.1" git push origin v1.0.1 gh release create v1.0.1 --title "v1.0.1" --notes "Critical bug fix"
-
Merge back to main:
git checkout main git merge hotfix/v1.0.1 git push origin main
The GitHub Actions workflow automatically:
- Builds Docker image on tag push (tags starting with
v) - Generates SBOM with Anchore
- Scans with Trivy (fails on CRITICAL/HIGH)
- Pushes to GHCR with multiple version tags
- Creates tags:
1.0.0,1.0,1,latest(from Git tagv1.0.0)
Last Update: 2025-10-03 Maintainer: Python IPAM Team
- ✅ Security Hardening: Migrated to Chainguard distroless Python images
- ✅ Security Achievement: Reduced vulnerabilities from 275+ to 0 (100% reduction)
- ✅ Container Optimization: Multi-stage build, image size reduced to ~50-100MB
- ✅ CI/CD Pipeline: Automated testing, security scanning (Trivy), SBOM generation
- ✅ GitHub Infrastructure: Issue templates, project roadmap, automated workflows
- ✅ Extensible Export/Import: Plugin-based architecture (IPAM-004)
- ✅ Documentation: Complete English documentation, GitHub Pages deployment
- ✅ Test Suite: 96 tests passing, all SQLAlchemy 2.0 deprecations fixed
- ✅ Release Process: Established semantic versioning with Git tags and GitHub releases
- ✅ REST API: Flask-RESTX with Swagger UI at /api/v1/docs
- ✅ Application Factory Pattern: Modular Blueprint structure
- ✅ Python 3.13: Upgraded to latest Python version