Bootstrapping of Python projects
Provides functionality for generating skeletons for Python projects.
For Consumers
Installation
Create and activate a virtual environment if missed:
python3.13 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
Install the package:
pip install -i https://test.pypi.org/simple/ ak-py-bootstrap
During installing the package creates an entry-point bootstrap.
Using
Getting help
Call the tool with -h/-help argument:
bootstrap --help
It shows the following text:
usage: bootstrap [-h] {list,build,export,register} ...
...
Bootstraps management operations:
{list,build,export,register}
list Finds and prints the list of available bootstraps with brief description.
build Generates a skeleton of something from given bootstrap.
export Exports a bootstrap by given name.
register Registers a new bootstrap.
Getting a list of enabled / registered bootstraps
Call the following command:
bootstrap list
It should show something like:
...
application: Provides bootstrapping for Python Applications
package: Provides bootstrapping for Python Packages
...
Both of these subcommands provide a minimal skeleton of Python Project based on black, isort, flake, mypy and tox automation tool.
Application is a "final" project in bootstrap terms.
Package is an "intermediate" project in bootstrap terms.
The difference between them is the following: no need to build some package(s) from applications but it's important to do for packages.
So, tox tool provides for applications a minimal set of predefined commands:
- reformatting using
blackandisorttools. - check code style using
blackandflaketools. - check annotations using
mypy tool. - running tests based on
unittestsframework and calculating a level of coverage usingcoveragetool.
tox tool provides several additional commands for `packages:
- generating documentation based on
sphinxframework. - building versions of packages.
- publishing prepared archives in PyPI or Test PyPI.
You can prepare and register your own bootstraps for speeding up your work. See topics below how to do it.
Generating a skeleton of something
The main feature of the tool.
First of all, let's show on the help text of build command:
bootstrap build --help
You should see something like:
usage: bootstrap build [-h] [--dest DESTINATION_DIR] {application,package} ...
...
options:
...
--dest DESTINATION_DIR
Specifies the destination directory for generating. Current directory by default.
Found bootstraps:
{application,package}
application Generates a skeleton of a Python Application
package Generates a skeleton of a Python Package
The important here is the following:
--destargument. It's a common argument for all bootstraps. It specifies a target directory on a file system. Current directory by default.
Getting help for every bootstrap
Every bootstrap can provide own CLI interface. So, it's important to examine them before using.
Call the following command:
bootstrap build application --help
It should render something like:
usage: bootstrap build application [-h] --name NAME --description DESCRIPTION [--repo REPO]
...
options:
...
--name NAME Specifies name of the application
--description DESCRIPTIORepositoryN
Specifies description of the application.
As you can see, the required arguments are:
name. it specifies a name of the application. It should be python-compatible.description. it specifies a brief description of a generated application.
Generating a skeleton of a python application
After working with help text, we are ready to generate something. Call the following command:
bootstrap build application --name=demo-app --description="The Demo python Application"
Check the file system:
tree -L2
You should see something like:
├── CHANGELOG.md
├── pyproject.toml
├── README.md
├── requirements-dev.txt
├── requirements.txt
└── tests
└── __init__.py
So, you have got:
- prepared
pyproject.tomlfile with minimal configuration for the mentioned above tools. - minimal
README.mdfile. demo_appdirectory where you will place code of your application in the future.testsdirectory where you will place future unit tests for testing you application.
Congratulations! Now you are ready to make the first commit in your new application.
Generating a skeleton of python package is similar.
Preparing your own bootstraps
Bootstrap is a directory of the following structure:
__entry_point__.pyfile. It's an entry point into every bootstrap. It provides logic for generating bootstraps.- any set of any files or directories that provide content for the bootstrap.
There are two ways how to prepare a new custom bootstrap:
- from scratches.
- based on existed one.
Preparing new bootstrap from scratches
Working with bootstrap list command you can mention that exist one more bootstrap: boostrap.
Yes, this bootstrap provides generating new ... bootstraps.
Call the following command:
bootstrap build --dest=demo-bootstrap bootstrap --name=demo-bs --description="The Demo bootstrap"
Examine a local file system:
tree -L2 demo-bootstrap/
You should see something like:
demo-bootstrap/
├── demo-file.txt.tmpl
└── __entry_point__.py
1 directory, 2 files
It's a skeleton of new bootstrap.
Now it's able to prepare any static files or templates for generating a dynamic content for the bootstrap.
In demo-file.txt.tmpl you can find placeholders that the tool provides by default.
Export existed bootstrap
Instead developing bootstraps from scratches, it's able to export one of existed bootstraps and modify it.
Call the following command:
bootstrap export --dest=bs-application-copy application
In bs-application-copy you can find:
- original
__entry_point__.pyfile. - a set of static files and templates that provide content of
applicationbootstrap.
Please examine these files. That's the best way to understand bootstrapping functionality in details.
Now it's able to modify a cloned bootstrap files for reaching your aims.
Register new bootstraps
After developing new bootstrap but before using need to register this one in the tool.
register command is responsible to do it.
Call the following command for getting help text:
bootstrap register --help
You can see something like:
usage: bootstrap register [-h] --name BOOTSTRAP_NAME --source SOURCE_PATH [-y]
...
options:
--name BOOTSTRAP_NAME
Specifies name of registered bootstrap template.
--source SOURCE_PATH Specifies the source directory with metadata and bootstrap templates. Current directory by default.
-y, --yes-upload Do not prompt for confirmation.
The required arguments are:
--name. It specifies the name of new bootstrap in the tool.--source. It specifies a directory with implemented bootstrap.-y/--yes-upload. The argument disables interactive mode. A system won't print a confirmation prompt with waiting an input from a developer.
So, let's register a prepared new bootstrap:
bootstrap register --name=demo --source=demo-bootstrap
Confirm uploading by typing y.
Check registering by calling bootstrap list. It should show new demo bootstrap in a list of enabled.
That's all. Now it's able to use a registered bootstrap in your work.
NB: the system is very straightforward, it doesn't make any conclusions instead of you. The system allows overriding bootstraps. That's pros and cons at the same time. On the one hand, it's very easy to test new bootstraps, just fix templates, upload changes and check a result of generating immediately. On the other hand, it's easy to break a current bootstrap in case you make a decision to REPLACE existed one. So, it's a developer's duty to care about what exactly they register.
Embed package bootstraps as plugins
Define in yours pyproject.toml file the following section:
[project.entry-points.py_bootstrap_templates]
<your-package-name> = "<package-root-dir>.py_bootstrap.templates"
Create the following files structure:
<package-root-dir>
└── py_bootstrap
└── templates
├── <your-bootstrap-dir>
│ ├── __entry_point__.py
│ ...
├── <your-another-bootstrap-dir>
│ ├── __entry_point__.py
│ ...
└── __init__.py
Put into <package-root-dir>/py_bootstraps/templates/__init__.py file the following content:
__all__ = ("ENABLED_TEMPLATES",)
ENABLED_TEMPLATES = [
"<your-bootstrap-dir>",
"your-another-bootstrap-dir",
]
That's all! Build a new version of the package, install it in some virtual environment together with ak-py-bootstrap package and enjoy of working with package's bootstraps.
Running bootstrap list you will see something like:
...
your-bootstrap-dir: Your bootstrap description.
your-another-bootstrap-dir: Your another bootstrap description.
...
For developers
Cloning the project
Run the following commands:
git clone https://github.com/ABKorotky/py-bootstrap.git
cd py_bootstrap
Prepare a virtual environment for developing
Run the following commands:
python3.13 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e . --group dev
Dev tooling is declared as PEP 735 dependency
groups in pyproject.toml (test, format, cs, ann, doc, changelog,
scm, dist, release, and the umbrella dev). The tool has no runtime
dependencies.
Using make in development
Development and release tasks run through make. Each target installs the
dependency group it needs into a single .venv on demand, so the toolchain is
provisioned lazily rather than duplicated per task:
deps. Installs every dev dependency into.venv.cs. Code Style. Checks project's code style usingisort,blackandflake8tools.ann. Annotation. Checks types annotations in the project usingmypytool.test. Unit Tests with Coverage. Checks thattox.ini, thepyproject.tomlclassifiers and theci.ymlmatrix agree on the supported interpreters, then runs the suite on each of them viatox.make test PY_ENV=py313runs just one.check. Runscs,annandtest.format. Formatting. Reformats code in the project usingblackandisorttools.doc. Documentation. Generates project's documentation usingsphinxtool.cl-preview VERSION=X.Y.Z. Changelog Draft. Previews the section thechangelog.d/fragments would produce.cl-check. Changelog Check. Fails if the branch adds no news fragment (CI runs this on every PR).cl-build VERSION=X.Y.Z. Changelog. Collateschangelog.d/fragments intoCHANGELOG.mdand removes them.cut-tag VERSION=X.Y.Z. Verifies the version is releasable and unused and the working tree is clean, writes the## [X.Y.Z]section, commits it asPrepare X.Y.Z versionand tagsvX.Y.Z.dist-build. Builds the sdist and wheel intodist/from a clean working tree, then installs the wheel into a throwaway virtualenv and checksbootstrap listworks.dist-upload. UploadsDIST(defaultdist/*) toPYPI(defaultpypi) aftertwine check --strict.release VERSION=X.Y.Z [PYPI=testpypi]. The whole flow:cut-tag,dist-build,dist-upload, stopping at the first failure.clean/venvclean. Removes build, test and doc artefacts / also removes the virtualenvs (.venvand.tox/).
Run make with no target for the full list.
Using tox in development
tox is kept for one job: running the test suite against every supported
interpreter. tox runs py313 and py314; tox -e py313 runs just one.
Everything else lives in the Makefile.
Development rules and agreements
Follow Python's principles PEP 20 – The Zen of Python:
- Simple is better than complex.
- Explicit is better than implicit. And so on...
Follow "SOLID" principles:
- Single responsibility principle.
- Open–closed principle.
- Liskov substitution principle.
- Interface segregation principle.
- Dependency inversion principle.
Branching model
Based on "GitHub-Flow", extended by release branches on demand.
Branches
mainis the default stable branch; stable distributions are released from it.- Develop on
<feature>branches — commit count and messages there are not limited. - Older lines live on
release/<major>.<minor>branches, cut from that line's last tag. A release branch carries its ownCHANGELOG.mdandchangelog.d/.
Merging — enforced by GitHub, not done by hand:
- The only enabled merge method is squash, so every PR lands as one commit.
- A ruleset on
mainandrelease/*requires a PR, passingcichecks (cs,ann,utc,doc), thechangelogcheck, linear history (no merge commits), and the merge queue. - The merge queue rebases the PR onto the current target, re-runs the checks, and fast-forwards it in — no manual squash, rebase, or
--ff-only. Enable auto-merge on the PR and leave it.
Tags & releases
- Tag per PEP 440,
v-prefixed:vX.Y.Z,vX.Y.ZrcN. Merging intomainis an intention to release, so almost every commit onmainis tagged. - Cut a release the same way on
mainor a release branch:make release VERSION=X.Y.Z(see Releasing new distributions flow). Thereleaseworkflow accepts anyv*tag whose commit is reachable frommainor arelease/*branch. - Tags on
mainmust increase monotonically. Do not tagv0.2.0 -> v0.2.1 -> v0.3.0 -> v0.2.2; instead branchrelease/0.2fromv0.2.1, fix there, and tagv0.2.2. - Move fixes between lines with
cherry-pick— e.g. cherry-pick thev0.2.2fix fromrelease/0.2intomainand ship it asv0.3.2.
Recap: history on main stays a straight line, with release branches forking off tag points.
Releasing new distributions flow
The project version comes from the git tag (setuptools-scm), CHANGELOG.md is
assembled by towncrier from news fragments in changelog.d/, and publishing is
done by the release GitHub Actions workflow through PyPI Trusted Publishing — no
version constant to bump, no tokens, no manual twine. Setup and details:
docs/releasing/. Tags are v-prefixed (v0.10.0);
setuptools-scm also reads the older bare tags.
- Create a
featurebranch frommainor a release one. - Make the changes. Run
make formatandmake checkduring development. - Add a news fragment under
changelog.d/describing the change (seechangelog.d/README.md);make cl-checkmirrors what CI enforces on the PR. - Run
make docand examine the generated documentation. - Squash to one commit, rebase on the target branch, clean the diff.
- Run
make format, thenmake check, on the final commit; ensure both pass. Runtoxtoo if the change could be interpreter-sensitive. - Merge the
featurebranch into the target (mainorrelease/<major>.<minor>). - On the merge commit, decide the version and cut the release:
make cl-preview VERSION=0.10.0 # read the section the fragments will produce make cut-tag VERSION=0.10.0 # verify, write CHANGELOG.md, commit, tag v0.10.0 make dist-build # build and check the wheel installs make dist-upload # -> PyPI; PYPI=testpypi to rehearse git push origin <branch> --follow-tagsmake release VERSION=0.10.0runs those three steps in one go. - Validate in a fresh environment:
pip install ak-py-bootstrap.
To rebuild an already released version, check out its tag and run
make dist-build dist-upload — dist-build derives the version from the tag,
so the artefacts are identical to the original.
Use the same flow for releasing distributions from release branches.
Metadata
Release files for ak-py-bootstrap 0.9.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ak_py_bootstrap-0.9.4.tar.gz | 79.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ak_py_bootstrap-0.9.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 127.1 kB
Release files / ak_py_bootstrap-0.9.4.tar.gz
| Download URL | ak_py_bootstrap-0.9.4.tar.gz |
|---|---|
| Size | 79.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
79917d3168d9362a68abbc6885c851b83df7e5c5e49a0bc683bd49a8d57627bf
|
|
BLAKE2b-256 checksum How to use checksums |
eb4b3c2d23875ff70f1c1cc03c462ce1bfd50e6e53f4026828a080f1129d54ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Release files / ak_py_bootstrap-0.9.4-py3-none-any.whl
| Download URL | ak_py_bootstrap-0.9.4-py3-none-any.whl |
|---|---|
| Size | 47.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a6624bd61a76f03a2da06672090ab930dfa99d8479cca5f8b989bbac2cfd6869
|
|
BLAKE2b-256 checksum How to use checksums |
6ee87139a9a72ad41ea0c98ca1896d3fa57e1026dd606a1b3b04a0f925e22713
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Security for ak-py-bootstrap 0.9.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.