Agent Skills: Python Project Scaffold

Scaffold a multi-repo Python workspace with models library, core library, Flask backend, and optional sub-projects. Creates directory structure and root CLAUDE.md describing each sub-project and which skills to use next. Use when starting a new Python project, setting up a multi-repo workspace, or scaffolding a project skeleton.

UncategorizedID: jmazzahacks/byteforge-claude-skills/python-project-scaffold

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jmazzahacks/byteforge-claude-skills/tree/HEAD/skills/python-project-scaffold

Skill Files

Browse the full folder contents for python-project-scaffold.

Download Skill

Loading file tree…

skills/python-project-scaffold/SKILL.md

Skill Metadata

Name
python-project-scaffold
Description
Scaffold a multi-repo Python workspace with models library, core library, Flask backend, and optional sub-projects. Creates directory structure and root CLAUDE.md describing each sub-project and which skills to use next. Use when starting a new Python project, setting up a multi-repo workspace, or scaffolding a project skeleton.

Python Project Scaffold

This skill creates a multi-repo workspace skeleton for a new Python project. It sets up the directory structure and a root CLAUDE.md that describes each sub-project's purpose, how they connect, and which existing skills to run next. No application code is generated — actual code generation is deferred to existing skills.

When to Use This Skill

Use this skill when:

  • Starting a brand-new Python project from scratch
  • You want the standard multi-repo workspace layout (models lib, core lib, Flask backend)
  • You want a root CLAUDE.md that guides future development with existing skills

What This Skill Creates

  1. Directory skeleton — empty sub-project directories under {project}/
  2. {project}/CLAUDE.md — root development guide describing each sub-project and which skills to use
  3. {project}/.gitignore — workspace-level gitignore for Python projects
  4. Next-steps documentation — tells the user which skills to run in each sub-project

Step 1: Gather Project Information

IMPORTANT: Before creating anything, ask the user these questions using AskUserQuestion:

  1. "What is your project name?" (e.g., "arcana", "trading-bot", "my-app")

    • Derive naming variants:
      • {project} — kebab-case (e.g., arcana, trading-bot)
      • {project_name} — snake_case (e.g., arcana, trading_bot)
      • {ProjectName} — PascalCase (e.g., Arcana, TradingBot)
      • {PROJECT_NAME} — UPPER_SNAKE (e.g., ARCANA, TRADING_BOT)
  2. "Brief project description?" (one or two sentences for the CLAUDE.md header)

  3. "What is the GitHub org or owner?" (e.g., jmazzahacks)

  4. "Which optional sub-projects do you need?" (multi-select)

    • python-scripts — standalone utility scripts
    • {project}-api-python — Python API client library
    • {project}-api-js — TypeScript API client library
    • {project}-frontend — Next.js frontend
  5. "Does the backend need Celery + Redis for background tasks?" (yes/no)

  6. "Which license?"

    • Proprietary
    • MIT
    • O'Saasy (https://osaasy.dev/)

Step 2: Create Directory Structure

Create empty directories under {project}/. Use mkdir -p to create each directory with a .gitkeep file so they are tracked by git.

Always created:

{project}/
├── {project}-models/
├── {project}-core/
└── {project}-backend/

Conditionally created based on Step 1 answers:

├── python-scripts/          # if "python-scripts" selected
├── {project}-api-python/    # if Python API client selected
├── {project}-api-js/        # if TypeScript API client selected
└── {project}-frontend/         # if Next.js frontend selected

Step 3: Create Root CLAUDE.md

Create {project}/CLAUDE.md with the following structure. Replace all {project}, {project_name}, {ProjectName}, and {PROJECT_NAME} placeholders with actual values.

# {ProjectName} — Development Guide

{description}

## Project Structure

This is a multi-repo workspace. Each sub-directory is an independent project with its own virtual environment, git history, and dependencies.

| Directory | Purpose | Type |
|-----------|---------|------|
| `{project}-models/` | Shared data models and schemas | pip package (library) |
| `{project}-core/` | Business logic and service layer | pip package (library) |
| `{project}-backend/` | Flask REST API server | Docker service |
{# Include rows for optional sub-projects only if selected: }
{# | `python-scripts/` | Standalone utility scripts | Scripts | }
{# | `{project}-api-python/` | Python API client library | pip package (library) | }
{# | `{project}-api-js/` | TypeScript API client library | npm package | }
{# | `{project}-frontend/` | Next.js frontend application | Docker service | }

## Dependency Chain

{project}-models → {project}-core → {project}-backend


- **{project}-models** has no internal dependencies. It defines shared data models.
- **{project}-core** depends on `{project}-models`. It contains business logic.
- **{project}-backend** depends on both `{project}-models` and `{project}-core`.

## Setting Up Each Sub-Project

### {project}-models (shared models library)

Use the `python-lib-setup` skill to initialize this as a pip package:

cd {project}-models

Invoke python-lib-setup skill


### {project}-core (business logic library)

Use the `python-lib-setup` skill to initialize this as a pip package:

cd {project}-core

Invoke python-lib-setup skill


Add `{project}-models` as a GitHub dependency in `pyproject.toml` — **TOKEN-FREE
URL regardless of public/private.** Never embed `{env:CR_PAT}` (or any auth) in
`pyproject.toml`: hatchling expands it at wheel build time and bakes the live
PAT into the wheel's `.dist-info/METADATA` `Requires-Dist`, so every published
image carries a valid credential invisible to `docker inspect`. Auth for
private repos is supplied at INSTALL time (a `${CR_PAT}` line in the consuming
app's `requirements.txt`, or git `url.insteadOf` config — see the
`uv-supply-chain-hardening` skill for the full pattern).

```toml
dependencies = [
    # Public OR private — always token-free here. Install-time auth handles
    # private access; see uv-supply-chain-hardening Step 1 for the callout.
    "{project}-models @ git+https://github.com/{github_org}/{project}-models.git",
]

{project}-backend (Flask API server)

Set up in this order:

  1. flask-smorest-api — Flask app factory, blueprints, Marshmallow schemas
  2. postgres-setup — Database schema and setup script. Run its Step 7 to scaffold the resilient Database driver at src/{project_name}/database.py — required for the Flask process to survive Postgres restarts; skipping it leads to a wedged pool on the next upstream PG restart.
  3. flask-docker-deployment — Dockerfile, build script, versioning
  4. byteforge-loki-logging — Structured logging to Grafana Loki
  5. uv-supply-chain-hardening — Lock the dependency install: pin every third-party dep with hashes, gate on release age, pin the uv binary by digest, and route the private-dep token through a build-time secret so it never enters pyproject.toml or the running image. Run this AFTER 1–4 — it hardens what's already there rather than emitting new app code. Not optional: every scaffold that skipped this ended up in a downstream ticket for a leaked CR_PAT in the wheel Requires-Dist metadata.

Add model and core libraries as GitHub dependencies in requirements.txt:

# Public repos:
{project}-models @ git+https://github.com/{github_org}/{project}-models.git
{project}-core @ git+https://github.com/{github_org}/{project}-core.git
# Private repos (requires CR_PAT environment variable):
# {project}-models @ git+https://${CR_PAT}@github.com/{github_org}/{project}-models.git
# {project}-core @ git+https://${CR_PAT}@github.com/{github_org}/{project}-core.git

{# Include this section only if Celery + Redis was selected: }

Celery + Redis

This backend uses Celery for background task processing with Redis as the broker. Environment variables:

  • {PROJECT_NAME}_REDIS_URL — Redis connection URL (e.g., redis://localhost:6379/0)

{# Include this section only if {project}-frontend was selected: }

{project}-frontend (Next.js frontend)

Use the aegis-nextjs-frontend skill to scaffold the frontend:

cd {project}-frontend
# Invoke aegis-nextjs-frontend skill

{# Include this section only if python-scripts was selected: }

python-scripts (utility scripts)

Standalone scripts for development, data migration, or maintenance tasks. Each script should:

  • Have its own #!/usr/bin/env python shebang
  • Use python-dotenv to load .env
  • Import from {project}-models and {project}-core as needed

{# Include this section only if {project}-api-python was selected: }

{project}-api-python (Python API client)

Use the python-lib-setup skill to initialize this as a pip package:

cd {project}-api-python
# Invoke python-lib-setup skill

{# Include this section only if {project}-api-js was selected: }

{project}-api-js (TypeScript API client)

Initialize as a TypeScript npm package. Publish to GitHub Packages or npm.

Development Commands

Each sub-project with Python uses its own virtual environment:

cd {project}-models/
python -m venv bin
source bin/activate
pip install -r dev-requirements.txt

Run tests:

source bin/activate && pytest

Start the backend locally:

cd {project}-backend/
source bin/activate && python {project_name}.py

Conventions

  • Unix timestamps only — All date/time fields use BIGINT (epoch seconds), never TIMESTAMP or DATETIME
  • UUID primary keys — Use gen_random_uuid() in PostgreSQL
  • RealDictCursor — Always use psycopg2.extras.RealDictCursor for queries
  • Environment variables — Project-specific prefix: {PROJECT_NAME}_ (e.g., {PROJECT_NAME}_DB_HOST)
  • Type hints — All function parameters and return types must have type annotations
  • No lambdas — Use named functions or loops instead
  • Virtual environments — Always source bin/activate before running Python
  • No local path dependencies — NEVER use pip install -e ../sibling-project or file: references. Cross-repo dependencies MUST use GitHub URLs.
    • pyproject.toml — always TOKEN-FREE, public OR private: git+https://github.com/{github_org}/pkg.git. Never embed {env:CR_PAT} here — hatchling expands it at wheel build time and bakes the live PAT into Requires-Dist metadata, leaking a credential into every published image.
    • requirements.txt — token inline is safe (requirements files are never packaged): git+https://${CR_PAT}@github.com/{github_org}/pkg.git.
    • Auth for private deps declared in a pyproject.toml is supplied at INSTALL time — via a ${CR_PAT} line in the consuming app's requirements.txt, or git url.insteadOf config. The uv-supply-chain-hardening skill wires this end-to-end for the backend.

**IMPORTANT**: When generating the actual CLAUDE.md file:
- Remove all `{# ... }` comment lines
- Only include sections for sub-projects that were selected in Step 1
- Replace all placeholders with actual values
- Do NOT wrap the entire file in a code fence — write it as a real markdown file

## Step 4: Create Root .gitignore

Create `{project}/.gitignore`:

```gitignore
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
*.egg-info/
*.egg
dist/
build/
*.whl

# Virtual environments
bin/
lib/
lib64/
pyvenv.cfg
include/
share/

# Environment
.env
*.env.local

# IDE
.idea/
.vscode/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Docker
VERSION

# Node (if frontend selected)
node_modules/
.next/
out/

Step 5: Document Next Steps

After creating all files, tell the user:

  1. Initialize git in the root {project}/ directory
  2. Run skills in order for each sub-project:
    • cd {project}-models/ → run python-lib-setup
    • cd {project}-core/ → run python-lib-setup
    • cd {project}-backend/ → run flask-smorest-api, then postgres-setup, then flask-docker-deployment, then byteforge-loki-logging, then uv-supply-chain-hardening (locks + hashes the dep install, gates release-age, and routes the private-dep token as a build secret so it never lands in pyproject.toml or the image — the default for new Python projects)
    • (If frontend selected) cd {project}-frontend/ → run aegis-nextjs-frontend
    • (If Python API client selected) cd {project}-api-python/ → run python-lib-setup
  3. Create GitHub repos for each sub-project under {github_org}/
  4. Set up .env files with required environment variables