Python project scaffold
Skill jmazzahacks/byteforge-claude-skills/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.From its SKILL.md
npx -y skills add jmazzahacks/byteforge-claude-skills --skill python-project-scaffoldAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
11.9 KB, as published. Nobody here has run it
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
- Directory skeleton — empty sub-project directories under
{project}/ {project}/CLAUDE.md— root development guide describing each sub-project and which skills to use{project}/.gitignore— workspace-level gitignore for Python projects- 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:
-
"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)
- Derive naming variants:
-
"Brief project description?" (one or two sentences for the CLAUDE.md header)
-
"What is the GitHub org or owner?" (e.g.,
jmazzahacks) -
"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
-
"Does the backend need Celery + Redis for background tasks?" (yes/no)
-
"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:
flask-smorest-api— Flask app factory, blueprints, Marshmallow schemaspostgres-setup— Database schema and setup script. Run its Step 7 to scaffold the resilientDatabasedriver atsrc/{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.flask-docker-deployment— Dockerfile, build script, versioningbyteforge-loki-logging— Structured logging to Grafana Lokiuv-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 enterspyproject.tomlor 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 leakedCR_PATin the wheelRequires-Distmetadata.
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 pythonshebang - Use
python-dotenvto load.env - Import from
{project}-modelsand{project}-coreas 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), neverTIMESTAMPorDATETIME - UUID primary keys — Use
gen_random_uuid()in PostgreSQL - RealDictCursor — Always use
psycopg2.extras.RealDictCursorfor 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/activatebefore running Python - No local path dependencies — NEVER use
pip install -e ../sibling-projectorfile: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 intoRequires-Distmetadata, 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.tomlis supplied at INSTALL time — via a${CR_PAT}line in the consuming app'srequirements.txt, or giturl.insteadOfconfig. Theuv-supply-chain-hardeningskill 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:
- Initialize git in the root
{project}/directory - Run skills in order for each sub-project:
cd {project}-models/→ runpython-lib-setupcd {project}-core/→ runpython-lib-setupcd {project}-backend/→ runflask-smorest-api, thenpostgres-setup, thenflask-docker-deployment, thenbyteforge-loki-logging, thenuv-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 inpyproject.tomlor the image — the default for new Python projects)- (If frontend selected)
cd {project}-frontend/→ runaegis-nextjs-frontend - (If Python API client selected)
cd {project}-api-python/→ runpython-lib-setup
- Create GitHub repos for each sub-project under
{github_org}/ - Set up
.envfiles with required environment variables