Skip to main content

Scaffolding engine for Create Awesome Python App

Project description

create-python-app-core

Programmatic scaffolding engine behind Create Awesome Python App. Import the scaffolding pipeline -- composable, headless, and CI-ready.

Requires Python >= 3.12.

This is the engine package. For the interactive CLI, use create-awesome-python-app instead.


Installation

pip install create-python-app-core

Or with uv:

uv add create-python-app-core

Usage

Scaffold a project programmatically

import asyncio
from create_python_app_core import create_python_app


async def main() -> None:
    await create_python_app(
        "my-app",
        {
            "projectName": "my-app",
            "template": "file:///path/to/template",
            "install": True,
        },
        transform_options=lambda opts: asyncio.sleep(0, result=opts),
    )


asyncio.run(main())

Scaffold with the installer API

from create_python_app_core import scaffold_project

scaffold_project(
    "my-app",
    template="file:///path/to/template",
    addons=[],
    extend=[],
    install=True,
    force=False,
    offline=False,
)

Resolve a template source

from create_python_app_core import resolve_source, get_template_dir_path

source = resolve_source(
    "https://github.com/Create-Python-App/cpa-templates?ref=main&subdir=fastapi"
)
print(source.kind)   # github
print(source.ref)    # main
print(source.subdir) # fastapi

Download a repository into the cache

from create_python_app_core import resolve_source, download_repository

source = resolve_source("https://github.com/org/my-template")
root = download_repository(source, refresh="stale", offline=False)
template_dir = get_template_dir_path(source, root)

Load template configuration

from pathlib import Path

from create_python_app_core import load_cpa_config

cfg = load_cpa_config(Path("/path/to/template/cpa.config.json"))
for opt in cfg.custom_options:
    print(opt.key, opt.default)

Check environment info

from create_python_app_core import print_env_info

print_env_info()
# Prints Python, platform, uv, and git info. Then exits.

Validate the Python version

from create_python_app_core import check_python_version

check_python_version(">=3.12", "my-tool")
# Exits with code 1 if the interpreter does not match.

API Reference

All public exports from create_python_app_core:

Functions

Signature Description
create_python_app(project_directory, options, transform_options=None) Async orchestrator. Applies transform_options, then delegates to scaffold_project.
scaffold_project(project_directory, *, template, addons=None, extend=None, force=False, install=True, offline=False, refresh=None, keep_on_failure=False, cache_dir=None, options=None) Main scaffolding pipeline. Resolves sources, downloads layers, merges files, runs uv sync, and initializes git.
resolve_source(spec, *, cache_dir=None) Parses a template/extension specifier (GitHub URL, file://, slug) into a ResolvedSource.
get_template_dir_path(source, root) Returns the template/ subdirectory when present, otherwise the resolved root.
default_cache_dir() Returns CPA_CACHE_DIR or ~/.cache/cpa.
download_repository(source, *, offline=False, refresh=None, cache_root=None) Clones or refreshes a Git repo into the cache. Returns the entry directory.
read_cache_meta(entry) Reads .cpa-cache.json metadata from a cache entry.
write_cache_meta(entry, meta) Writes .cpa-cache.json metadata for a cache entry.
load_cpa_config(path) Loads optional cpa.config.json (custom CLI prompts). Returns empty CpaConfig when missing.
assert_directory_is_empty(path, *, force=False) Raises NonEmptyTargetDirectoryError when the target exists and is non-empty.
load_layer(source, root, dest, *, overwrite=True, context=None) Copies one template/extension layer into dest.
merge_layers(layers, dest, *, context=None) Applies layers in order (template, addons, extend). Later layers win.
merge_pyproject_text(base_text, overlay_text) Deep-merges two pyproject.toml documents as TOML.
check_python_version(required, package_name) Compares sys.version_info against a PEP 440 specifier. Exits with code 1 if too old.
check_for_latest_version(package_name) Async. Fetches the latest version from PyPI. Returns None on failure.
print_env_info() Prints OS, Python, uv, and git info to stdout, then exits.

Constants

Name Description
__version__ Installed package version string.
CPA_USER_AGENT HTTP User-Agent sent to PyPI (create-python-app-core/<version>).
NON_EMPTY_DIR_ERROR_CODE Stable code for NonEmptyTargetDirectoryError (CPA_NON_EMPTY_TARGET_DIR).

Types

Type Shape
ResolvedSource kind (github | file | slug | git), url, ref, subdir, local_path
CacheMeta url, ref, fetched_at, commit
CpaConfig name, custom_options, raw
CpaCustomOption key, type, message, default
CpaError Base exception with .code attribute
ConfigParseError Invalid cpa.config.json (code: CPA_CONFIG_PARSE)
ManifestLoadError Missing template directory (code: CPA_MANIFEST_LOAD)
PackageManagerFallbackError Package manager fallback failure (code: CPA_PM_FALLBACK)
ScaffoldAbortedError Scaffold failed mid-run (code: CPA_ABORTED)
NonEmptyTargetDirectoryError Target directory not empty (code: CPA_NON_EMPTY_TARGET_DIR)

create_python_app options dict

Key Type Default Description
template str "" Primary template specifier (URL, file://, or slug).
addons list[str] [] Additional template layers applied after the base template.
extend list[str] [] Extension layers applied last (later wins on conflicts).
force bool False Allow scaffolding into a non-empty directory.
install bool True Run uv sync when pyproject.toml is present.
offline bool False Use cached repos only; raise on cache miss.
refresh str env / "stale" Cache refresh mode: always, stale, or manual.
keep_on_failure bool False Keep the partial project directory when scaffolding fails.
cache_dir str | Path None Override the default cache root.
set dict {} Jinja context overrides (merged into projectName and custom option defaults).

Environment Variables

All CPA_* variables read by the core engine:

Variable Default Description
CPA_CACHE_DIR ~/.cache/cpa Root directory for cloned repository cache entries.
CPA_REFRESH stale Default cache refresh mode: always, stale, or manual.
CPA_REFRESH_AFTER_HOURS 24 Hours before a stale cache entry is refreshed.
CPA_SKIP_GIT unset Set to 1 to skip git init and block all git subprocess calls.
CPA_STRICT_REPRO unset Set to 1 to require a full 40-character commit SHA in ?ref= query params.

Error Codes

Stable machine-readable codes on CpaError.code:

Code Exception class When raised
CPA_ERROR CpaError Generic base error (default).
CPA_CONFIG_PARSE ConfigParseError Malformed or invalid cpa.config.json.
CPA_MANIFEST_LOAD ManifestLoadError Template directory not found on disk.
CPA_PM_FALLBACK PackageManagerFallbackError Package manager fallback failure.
CPA_ABORTED ScaffoldAbortedError Scaffold failed (template render, unexpected error, etc.).
CPA_NON_EMPTY_TARGET_DIR NonEmptyTargetDirectoryError Target directory exists and is not empty.
CPA_GIT CpaError Git subprocess failed or git not found.
CPA_SKIP_GIT CpaError Git operation attempted while CPA_SKIP_GIT=1.
CPA_FILE CpaError file:// source path does not exist.
CPA_OFFLINE CpaError Offline mode with no cached copy of the repository.
CPA_STRICT_REPRO CpaError ?ref= is not a full SHA while CPA_STRICT_REPRO=1.

How It Works

create_python_app()
  |-- transform_options() (optional)
  |-- scaffold_project()
        |-- assert_directory_is_empty()
        |-- resolve_source() for each template / addon / extend
        |-- download_repository() (git clone or file://)
        |-- load_cpa_config() from cpa.config.json
        |-- build_scaffold_context() (projectName + custom options + --set)
        |-- merge_layers() (Jinja .template, .append, pyproject merge)
        |-- uv sync (when install=True and pyproject.toml exists)
        |-- git init (unless CPA_SKIP_GIT=1)
        +-- cleanup partial directory on failure (unless keep_on_failure)

Architecture

The package is organized into these modules:

Module Responsibility
__init__.py Barrel export and public API surface
api.py create_python_app, version checks, env info, PyPI lookup
installer.py scaffold_project orchestration, uv sync, git init
loaders.py File discovery, .template / .append processing, layer merge
pyproject_merge.py Deep-merge pyproject.toml across template layers
paths.py URL resolution (GitHub, file://, slugs, ?ref=, ?subdir=)
git_cache.py Clone/pull with cache, refresh modes, offline support
config.py Reads optional cpa.config.json for custom CLI prompts
errors.py Typed CpaError hierarchy with stable codes

Related


License

MIT (c) Create Python App Contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

create_python_app_core-0.2.2.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

create_python_app_core-0.2.2-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file create_python_app_core-0.2.2.tar.gz.

File metadata

  • Download URL: create_python_app_core-0.2.2.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for create_python_app_core-0.2.2.tar.gz
Algorithm Hash digest
SHA256 43049bb2327418b4e64f10aa8d4e2ec40d48ad3fc0e1c7e9a9ece8be751e3924
MD5 5f4c0b2ada3b856606ae3757e614080b
BLAKE2b-256 0bca473bf1ee5d0f69074cbc89faf0f9f330ba5e406733d39ea1fb54c5e053cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for create_python_app_core-0.2.2.tar.gz:

Publisher: publish.yml on Create-Python-App/create-python-app

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file create_python_app_core-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for create_python_app_core-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1ea6202375efe7a3dfc73324896e9f90b67bebee36fb893680ca4389897ce19a
MD5 0290989d2adb25571ceb9980126836f0
BLAKE2b-256 f15369a3d9037342878e338c4b6a1b4fa7a31de4c27ba3c8e3baf95c1d36e0d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for create_python_app_core-0.2.2-py3-none-any.whl:

Publisher: publish.yml on Create-Python-App/create-python-app

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page