Python Project Scaffolding
Overview
Use this skill when the user wants a Python project scaffold that should be workable immediately, not just sketched at a high level.
This skill preserves the upstream intent: act as a Python project architecture expert and generate complete project structures with modern tooling, typed code, testing, and current best practices. The enhanced version adds clearer project-type branching, stronger packaging defaults, uv-first workflows, validation gates, and safer troubleshooting.
Primary defaults in this skill:
- Use
uv for project lifecycle commands unless the user explicitly needs compatibility-first tooling.
- Use
pyproject.toml as the primary project configuration file.
- Include typed code, linting, formatting, and tests in the initial scaffold.
- Choose structure based on project type instead of forcing one tree onto every Python repo.
- Prefer reversible inspection and validation before destructive cleanup.
Open these support files when needed:
references/runtime-practices.md for decision guidance on layout, metadata, dependency groups, and framework-specific structure.
examples/implementation-example.md for copyable library and FastAPI scaffold examples.
scripts/validate-runtime.py to inspect a generated scaffold for common structural errors.
When to Use
Use this skill when:
- The user asks to create or reshape a Python repository skeleton.
- The request involves a library, CLI, FastAPI service, Django project, or a general Python application that needs modern packaging.
- The user wants
uv, pyproject.toml, Ruff, mypy, pytest, or a typed project baseline.
- You need to generate a concrete file tree, starter files, dependency groups, and validation commands.
- You need to review whether an existing scaffold is missing packaging, layout, or validation essentials.
Do not use this skill as the primary tool when:
- The task is mainly feature implementation inside an already-established project.
- The project is intentionally non-packaged and the user only wants a one-off script.
- The user needs framework-internal design beyond scaffolding, such as deep Django domain modeling or production deployment architecture.
- The language or runtime is not Python.
Operating Table
| Situation |
Start here |
Why it matters |
| User has not chosen project type |
## Project-Type Analysis |
Prevents generating the wrong tree or layout |
| Need authoritative defaults |
references/runtime-practices.md |
Summarizes layout, metadata, dependency, and framework decisions |
| Need a concrete starting point |
examples/implementation-example.md |
Provides copyable trees, pyproject.toml snippets, and command sequences |
| Scaffold already generated and needs checking |
scripts/validate-runtime.py |
Catches missing metadata, layout, package, and test structure issues |
| Final handoff |
## Validation |
Ensures the scaffold actually installs, imports, lints, type-checks, and tests |
Workflow
Classify the target project
- Decide whether the scaffold is for a library, CLI, FastAPI service, Django project, or a generic application.
- If the user request is vague, ask for intended distribution model, runtime entrypoint, packaging expectations, and Python version target.
Confirm core decisions before writing files
- Target Python version or minimum supported range.
- Whether the project is distributable or application-only.
- Whether
src/ layout is appropriate.
- Required frameworks and runtime dependencies.
- Required dev tooling: Ruff, mypy, pytest, docs, CI conventions.
Initialize using a uv-first workflow
- Prefer
uv init for new projects.
- Add dependencies with
uv add.
- Add development tools with dependency groups.
- Lock and sync before claiming the scaffold is ready.
- Run commands with
uv run so execution matches the managed environment.
Write the scaffold around the chosen project type
- Use
src/ layout by default for libraries and packaged CLIs.
- Use an application package layout for FastAPI services unless packaging requirements suggest otherwise.
- Preserve Django's canonical
manage.py + project package + app package structure.
Include the minimum production-ready baseline
pyproject.toml with [build-system] and [project] metadata.
- Package or application directory with typed starter code.
tests/ directory.
- Lint, format, type-check, and test configuration.
.python-version when version pinning is part of the scaffold workflow.
.gitignore appropriate for Python build, cache, virtual environment, and tool artifacts.
Validate immediately after generation
- Run the local structural validator in
scripts/validate-runtime.py.
- Run lint, format check, type-check, and tests through
uv run.
- Confirm the main entrypoint or framework startup command works.
Handoff with explicit assumptions
- State which project type branch was used.
- State Python version assumptions.
- State whether the scaffold is intended for packaging, internal-only use, or service deployment.
- Note any deferred choices such as CI, containerization, settings management, or database setup.
Project-Type Analysis
1. Library
Use when the project is meant to be imported by other Python code or distributed as a package.
Default choices:
- Prefer
src/ layout.
- Include
py.typed if the distributed package is intended to advertise inline typing support.
- Keep runtime dependencies minimal.
- Separate dev and optional dependencies cleanly.
Good fit signals:
- Reusable utilities.
- SDKs or client libraries.
- Internal shared packages.
2. CLI
Use when the project is mainly a command-line tool.
Default choices:
- Usually use
src/ layout if distributed as an installable package.
- Add a console entry point in
pyproject.toml.
- Include a small
main.py or cli.py with typed argument handling.
Good fit signals:
- Automation tools.
- Developer utilities.
- User-invoked terminal commands.
3. FastAPI Service
Use when the project exposes HTTP endpoints and is application-centric.
Default choices:
- Organize as an app package with routers, schemas, and dependencies separated once the service is more than trivial.
- Keep server startup explicit.
- Include tests for at least one health or example route.
- Avoid over-packaging service-only code unless distribution is a stated goal.
Good fit signals:
- REST APIs.
- Async services.
- Internal microservices.
4. Django Project
Use when the project needs Django's project/app model, ORM, admin, and batteries-included workflow.
Default choices:
- Preserve Django's canonical project structure.
- Separate project configuration from reusable apps.
- Keep settings handling explicit and environment-sensitive.
- Validate with Django-native commands, not just generic Python checks.
Good fit signals:
- Admin-backed systems.
- ORM-heavy applications.
- Full-stack web apps using Django conventions.
5. Generic Application
Use when the project is Python-based but not clearly a package, CLI, or framework app.
Default choices:
- Use a simple application package or module layout.
- Avoid claiming the scaffold is packaging-ready unless build metadata and install paths are deliberately included.
- Still include tests, linting, and typing.
Scaffold Recipes
Common baseline
Every scaffold should usually include:
pyproject.toml
README.md
tests/
- package or app code directory
- Ruff configuration
- mypy configuration
- pytest configuration or sensible defaults
.gitignore
uv-first command sequence
Use a narrow, modern workflow unless the user requested a fallback:
uv init
uv add --group dev ruff mypy pytest
uv lock
uv sync
Add framework dependencies only after the project type is confirmed, for example:
uv add fastapi uvicorn
or
uv add django
pyproject.toml minimum expectations
At minimum, expect:
[build-system]
[project]
- project name
- version or explicit dynamic versioning choice
requires-python
- runtime dependencies
- grouped development dependencies where supported by the selected workflow
- tool configuration for Ruff, mypy, and pytest when non-default behavior matters
Do not default to legacy-only scaffolding such as setup.py without pyproject.toml unless the user explicitly requests backward compatibility.
Layout guidance
Choose layout deliberately:
- Prefer
src/ layout for reusable libraries and packaged CLIs because it helps catch accidental imports from the repository root.
- Flat or app-package layout can be acceptable for application-only repositories such as many FastAPI services.
- Do not force
src/ into Django if it complicates canonical Django expectations without a clear benefit.
For detailed selection guidance, see references/runtime-practices.md.
Validation
A scaffold is not done when the tree exists. It is done when the basic workflow works.
Structural validation
Run:
python scripts/validate-runtime.py .
Expected result:
- exit code
0 for a structurally valid scaffold
- clear diagnostics for missing or inconsistent files
Environment and dependency validation
Run:
uv lock
uv sync
Expected result:
- lockfile resolves successfully
- local environment sync completes without dependency drift
Quality gate
Run the checks through uv run:
uv run ruff check .
uv run ruff format --check .
uv run mypy .
uv run pytest
Expected result:
- no lint errors
- formatting check passes
- mypy completes without unresolved package-path mistakes
- tests are discovered and pass
Entry-point validation
Choose the command that matches the project type:
Library or package import smoke test:
uv run python -c "import your_package_name"
CLI:
uv run your-command --help
FastAPI:
uv run python -c "from app.main import app; print(app.title if hasattr(app, 'title') else 'ok')"
Django:
uv run python manage.py check
Troubleshooting
Imports work in the repo but fail after installation
Likely cause:
- flat layout masked a packaging error, or package discovery is wrong.
Inspect safely:
- verify package path matches the intended import name
- confirm
pyproject.toml build metadata exists
- compare repository layout against
references/runtime-practices.md
- run
python scripts/validate-runtime.py .
Fix direction:
- move distributable package code under
src/ for libraries and packaged CLIs, or correct package discovery settings.
uv sync or lock resolution does not match expectations
Likely cause:
- dependency groups were not added consistently, or metadata changed without lock refresh.
Inspect safely:
- review
pyproject.toml
- rerun
uv lock
- verify whether the requested dependency belongs in runtime or dev/test groups
Fix direction:
- update dependencies through
uv add rather than editing only part of the configuration by hand.
mypy cannot resolve modules
Likely cause:
- package layout and import paths disagree, or the scaffold mixes application and package assumptions.
Inspect safely:
- check actual package directory names
- verify test imports are not relying on repository-root leakage
- confirm the project type branch used during scaffold creation
Fix direction:
- correct package paths first; only then adjust mypy settings if needed.
pytest discovers no tests
Likely cause:
tests/ is missing, names do not match pytest discovery conventions, or framework-specific setup is incomplete.
Inspect safely:
- confirm the
tests/ directory exists
- confirm at least one
test_*.py file exists
- run
uv run pytest -q
Fix direction:
- add an initial smoke test and keep test layout straightforward before adding custom discovery rules.
Django scaffold behaves like a generic Python app
Likely cause:
- canonical Django project/app separation was skipped.
Inspect safely:
- confirm
manage.py exists
- confirm the project package contains
settings.py, urls.py, and wsgi.py or asgi.py
- run
uv run python manage.py check
Fix direction:
- regenerate or normalize to standard Django structure instead of patching a generic scaffold incrementally.
Additional Resources
references/runtime-practices.md
examples/implementation-example.md
scripts/validate-runtime.py
Related Skills
Switch to a more specialized skill if the work moves beyond scaffolding into:
- framework-specific feature implementation
- CI/CD pipeline design
- production containerization and deployment
- deep package publishing and release automation
Output Expectations
When using this skill to answer a user request, return:
- the chosen project type
- the generated file tree
- the key
pyproject.toml sections
- the dependency groups and why they exist
- the validation commands
- any assumptions or unresolved decisions
Keep generated commands narrow, local, and reversible.
1---2name: python-development-python-scaffold-23description: Python Project Scaffolding workflow skill. Use this skill when the user needs a production-ready Python project scaffold with modern packaging, uv-based environment management, typed code, testing, and project-type-specific structure for libraries, CLIs, FastAPI services, or Django applications.4---56# Python Project Scaffolding78## Overview910Use this skill when the user wants a Python project scaffold that should be workable immediately, not just sketched at a high level.1112This skill preserves the upstream intent: act as a Python project architecture expert and generate complete project structures with modern tooling, typed code, testing, and current best practices. The enhanced version adds clearer project-type branching, stronger packaging defaults, uv-first workflows, validation gates, and safer troubleshooting.1314Primary defaults in this skill:15- Use `uv` for project lifecycle commands unless the user explicitly needs compatibility-first tooling.16- Use `pyproject.toml` as the primary project configuration file.17- Include typed code, linting, formatting, and tests in the initial scaffold.18- Choose structure based on project type instead of forcing one tree onto every Python repo.19- Prefer reversible inspection and validation before destructive cleanup.2021Open these support files when needed:22- `references/runtime-practices.md` for decision guidance on layout, metadata, dependency groups, and framework-specific structure.23- `examples/implementation-example.md` for copyable library and FastAPI scaffold examples.24- `scripts/validate-runtime.py` to inspect a generated scaffold for common structural errors.2526## When to Use2728Use this skill when:29- The user asks to create or reshape a Python repository skeleton.30- The request involves a library, CLI, FastAPI service, Django project, or a general Python application that needs modern packaging.31- The user wants `uv`, `pyproject.toml`, Ruff, mypy, pytest, or a typed project baseline.32- You need to generate a concrete file tree, starter files, dependency groups, and validation commands.33- You need to review whether an existing scaffold is missing packaging, layout, or validation essentials.3435Do not use this skill as the primary tool when:36- The task is mainly feature implementation inside an already-established project.37- The project is intentionally non-packaged and the user only wants a one-off script.38- The user needs framework-internal design beyond scaffolding, such as deep Django domain modeling or production deployment architecture.39- The language or runtime is not Python.4041## Operating Table4243| Situation | Start here | Why it matters |44| --- | --- | --- |45| User has not chosen project type | `## Project-Type Analysis` | Prevents generating the wrong tree or layout |46| Need authoritative defaults | `references/runtime-practices.md` | Summarizes layout, metadata, dependency, and framework decisions |47| Need a concrete starting point | `examples/implementation-example.md` | Provides copyable trees, `pyproject.toml` snippets, and command sequences |48| Scaffold already generated and needs checking | `scripts/validate-runtime.py` | Catches missing metadata, layout, package, and test structure issues |49| Final handoff | `## Validation` | Ensures the scaffold actually installs, imports, lints, type-checks, and tests |5051## Workflow52531. **Classify the target project**54 - Decide whether the scaffold is for a library, CLI, FastAPI service, Django project, or a generic application.55 - If the user request is vague, ask for intended distribution model, runtime entrypoint, packaging expectations, and Python version target.56572. **Confirm core decisions before writing files**58 - Target Python version or minimum supported range.59 - Whether the project is distributable or application-only.60 - Whether `src/` layout is appropriate.61 - Required frameworks and runtime dependencies.62 - Required dev tooling: Ruff, mypy, pytest, docs, CI conventions.63643. **Initialize using a uv-first workflow**65 - Prefer `uv init` for new projects.66 - Add dependencies with `uv add`.67 - Add development tools with dependency groups.68 - Lock and sync before claiming the scaffold is ready.69 - Run commands with `uv run` so execution matches the managed environment.70714. **Write the scaffold around the chosen project type**72 - Use `src/` layout by default for libraries and packaged CLIs.73 - Use an application package layout for FastAPI services unless packaging requirements suggest otherwise.74 - Preserve Django's canonical `manage.py` + project package + app package structure.75765. **Include the minimum production-ready baseline**77 - `pyproject.toml` with `[build-system]` and `[project]` metadata.78 - Package or application directory with typed starter code.79 - `tests/` directory.80 - Lint, format, type-check, and test configuration.81 - `.python-version` when version pinning is part of the scaffold workflow.82 - `.gitignore` appropriate for Python build, cache, virtual environment, and tool artifacts.83846. **Validate immediately after generation**85 - Run the local structural validator in `scripts/validate-runtime.py`.86 - Run lint, format check, type-check, and tests through `uv run`.87 - Confirm the main entrypoint or framework startup command works.88897. **Handoff with explicit assumptions**90 - State which project type branch was used.91 - State Python version assumptions.92 - State whether the scaffold is intended for packaging, internal-only use, or service deployment.93 - Note any deferred choices such as CI, containerization, settings management, or database setup.9495## Project-Type Analysis9697### 1. Library9899Use when the project is meant to be imported by other Python code or distributed as a package.100101Default choices:102- Prefer `src/` layout.103- Include `py.typed` if the distributed package is intended to advertise inline typing support.104- Keep runtime dependencies minimal.105- Separate dev and optional dependencies cleanly.106107Good fit signals:108- Reusable utilities.109- SDKs or client libraries.110- Internal shared packages.111112### 2. CLI113114Use when the project is mainly a command-line tool.115116Default choices:117- Usually use `src/` layout if distributed as an installable package.118- Add a console entry point in `pyproject.toml`.119- Include a small `main.py` or `cli.py` with typed argument handling.120121Good fit signals:122- Automation tools.123- Developer utilities.124- User-invoked terminal commands.125126### 3. FastAPI Service127128Use when the project exposes HTTP endpoints and is application-centric.129130Default choices:131- Organize as an app package with routers, schemas, and dependencies separated once the service is more than trivial.132- Keep server startup explicit.133- Include tests for at least one health or example route.134- Avoid over-packaging service-only code unless distribution is a stated goal.135136Good fit signals:137- REST APIs.138- Async services.139- Internal microservices.140141### 4. Django Project142143Use when the project needs Django's project/app model, ORM, admin, and batteries-included workflow.144145Default choices:146- Preserve Django's canonical project structure.147- Separate project configuration from reusable apps.148- Keep settings handling explicit and environment-sensitive.149- Validate with Django-native commands, not just generic Python checks.150151Good fit signals:152- Admin-backed systems.153- ORM-heavy applications.154- Full-stack web apps using Django conventions.155156### 5. Generic Application157158Use when the project is Python-based but not clearly a package, CLI, or framework app.159160Default choices:161- Use a simple application package or module layout.162- Avoid claiming the scaffold is packaging-ready unless build metadata and install paths are deliberately included.163- Still include tests, linting, and typing.164165## Scaffold Recipes166167### Common baseline168169Every scaffold should usually include:170- `pyproject.toml`171- `README.md`172- `tests/`173- package or app code directory174- Ruff configuration175- mypy configuration176- pytest configuration or sensible defaults177- `.gitignore`178179### uv-first command sequence180181Use a narrow, modern workflow unless the user requested a fallback:182183```bash184uv init185uv add --group dev ruff mypy pytest186uv lock187uv sync188```189190Add framework dependencies only after the project type is confirmed, for example:191192```bash193uv add fastapi uvicorn194```195196or197198```bash199uv add django200```201202### `pyproject.toml` minimum expectations203204At minimum, expect:205- `[build-system]`206- `[project]`207- project name208- version or explicit dynamic versioning choice209- `requires-python`210- runtime dependencies211- grouped development dependencies where supported by the selected workflow212- tool configuration for Ruff, mypy, and pytest when non-default behavior matters213214Do not default to legacy-only scaffolding such as `setup.py` without `pyproject.toml` unless the user explicitly requests backward compatibility.215216### Layout guidance217218Choose layout deliberately:219- **Prefer `src/` layout** for reusable libraries and packaged CLIs because it helps catch accidental imports from the repository root.220- **Flat or app-package layout can be acceptable** for application-only repositories such as many FastAPI services.221- **Do not force `src/` into Django** if it complicates canonical Django expectations without a clear benefit.222223For detailed selection guidance, see `references/runtime-practices.md`.224225## Validation226227A scaffold is not done when the tree exists. It is done when the basic workflow works.228229### Structural validation230231Run:232233```bash234python scripts/validate-runtime.py .235```236237Expected result:238- exit code `0` for a structurally valid scaffold239- clear diagnostics for missing or inconsistent files240241### Environment and dependency validation242243Run:244245```bash246uv lock247uv sync248```249250Expected result:251- lockfile resolves successfully252- local environment sync completes without dependency drift253254### Quality gate255256Run the checks through `uv run`:257258```bash259uv run ruff check .260uv run ruff format --check .261uv run mypy .262uv run pytest263```264265Expected result:266- no lint errors267- formatting check passes268- mypy completes without unresolved package-path mistakes269- tests are discovered and pass270271### Entry-point validation272273Choose the command that matches the project type:274275Library or package import smoke test:276277```bash278uv run python -c "import your_package_name"279```280281CLI:282283```bash284uv run your-command --help285```286287FastAPI:288289```bash290uv run python -c "from app.main import app; print(app.title if hasattr(app, 'title') else 'ok')"291```292293Django:294295```bash296uv run python manage.py check297```298299## Troubleshooting300301### Imports work in the repo but fail after installation302303Likely cause:304- flat layout masked a packaging error, or package discovery is wrong.305306Inspect safely:307- verify package path matches the intended import name308- confirm `pyproject.toml` build metadata exists309- compare repository layout against `references/runtime-practices.md`310- run `python scripts/validate-runtime.py .`311312Fix direction:313- move distributable package code under `src/` for libraries and packaged CLIs, or correct package discovery settings.314315### `uv sync` or lock resolution does not match expectations316317Likely cause:318- dependency groups were not added consistently, or metadata changed without lock refresh.319320Inspect safely:321- review `pyproject.toml`322- rerun `uv lock`323- verify whether the requested dependency belongs in runtime or dev/test groups324325Fix direction:326- update dependencies through `uv add` rather than editing only part of the configuration by hand.327328### mypy cannot resolve modules329330Likely cause:331- package layout and import paths disagree, or the scaffold mixes application and package assumptions.332333Inspect safely:334- check actual package directory names335- verify test imports are not relying on repository-root leakage336- confirm the project type branch used during scaffold creation337338Fix direction:339- correct package paths first; only then adjust mypy settings if needed.340341### pytest discovers no tests342343Likely cause:344- `tests/` is missing, names do not match pytest discovery conventions, or framework-specific setup is incomplete.345346Inspect safely:347- confirm the `tests/` directory exists348- confirm at least one `test_*.py` file exists349- run `uv run pytest -q`350351Fix direction:352- add an initial smoke test and keep test layout straightforward before adding custom discovery rules.353354### Django scaffold behaves like a generic Python app355356Likely cause:357- canonical Django project/app separation was skipped.358359Inspect safely:360- confirm `manage.py` exists361- confirm the project package contains `settings.py`, `urls.py`, and `wsgi.py` or `asgi.py`362- run `uv run python manage.py check`363364Fix direction:365- regenerate or normalize to standard Django structure instead of patching a generic scaffold incrementally.366367## Additional Resources368369- `references/runtime-practices.md`370- `examples/implementation-example.md`371- `scripts/validate-runtime.py`372373## Related Skills374375Switch to a more specialized skill if the work moves beyond scaffolding into:376- framework-specific feature implementation377- CI/CD pipeline design378- production containerization and deployment379- deep package publishing and release automation380381## Output Expectations382383When using this skill to answer a user request, return:3841. the chosen project type3852. the generated file tree3863. the key `pyproject.toml` sections3874. the dependency groups and why they exist3885. the validation commands3896. any assumptions or unresolved decisions390391Keep generated commands narrow, local, and reversible.