| β | This is a mirror repository of Galactipy, which is currently being developed on GitLab. Take a look at our CONTRIBUTING.md to get more familiar with the project and understand how to contribute! |
|---|
cookiecutter gl:galactipy/galactipy --checkout v3.3.0All you need is the latest version of Cookiecutter! π
In this Cookiecutter πͺ template we combine state-of-the-art libraries and best development practices for Python.
- Supports Python
3.10and higher; - Provides
minimal boilerplate code
for CLI/TUI applications
with Typer and Textual
(or no code at all, you choose)!
With it, you have:
- Batteries-included configuration setup and management with Orbittings;
- Both beautiful logging on the terminal and easy-to-parse log files thanks to Nebulog;
- Preconfigured Noctis themes to make your application shine on the terminal;
- Uses Poetry
as the dependency manager
and extends functionality
with dynamic versioning,
virtual environment bundling,
dependency export
and update resolution;
see configuration
in
pyproject.toml; - Automatic code formatting with Ruff, with ready-to-use pre-commit hooks and several rules already selected for linting;
- Type checks with mypy, security checks with Bandit;
- Testing with Pytest and an option to use behaviour-driven development for managing scenarios; more details in How to Handle the Development Cycle with BDD;
- Code quality integrations with either Coveralls for more basic test coverage or Codacy for full code analysis, both integrated into your project's workflow via CI/CD;
- Everything is already set up for security checks, codestyle checks, code formatting, testing, linting, docker builds etc. with Invoke; more details in Invoke Usage;
- Predefined VS Code
settings.jsonwith quality-of-life configuration for editor, workbench, debugging and more; - Ready-to-use
.editorconfig,.dockerignoreand.gitignorefiles; you don't have to worry about those things.
- The boilerplate code provided with the template is already 100% covered by unit tests; you can dive in directly into your project's implementation without the hassle of handling test cases;
- Predefined CI/CD build workflows with GitLab CI and Github Actions;
- Automatic package uploads to PyPI test and production repositories;
- Automatic documentation deployment to GitLab Pages and GitHub Pages
- A
Dockerfilefor your package, with CI/CD workflows to publish your image to a container registry; - Automatic release cycles with GitLab Changelog or Release Drafter;
- Automatic dependency updates thanks to Renovate and Dependabot.
- Ready-to-use Merge Request templates and several Issue templates for easy integration with GitLab and GitHub;
- Workflows to mark and close abandoned issues after a period of inactivity for both GitLab with Triage Policies and GitHub with Stale Bot;
- Choose the versioning schema that best suits your project type and development style; from 7 different options (yes, you can even choose SemVer, if you wish :upside_down:);
- Option to choose between Gitmoji, Conventional Commits or a mix of both to standardise your commit titles.
- Provide your users with a polished documentation structure, complete with user guides, API reference and announcements powered by Zensical;
- With Galactipy templates,
you get more than a
CONTRIBUTING.mdfile; you have a comprehensive development philosophy, drawing inspiration from some of the most distinguished open source projects; we provide extensive yet user-friendly guidelines, enabling your project to onboard new contributors and scale effortlessly with minimal adjustments; - Files such as
LICENCE,CODE_OF_CONDUCT.md,CITATION.cff,ROADMAP.mdandSECURITY.mdare generated automatically; - Loads of predefined badges to make your project stand out; you can either keep them, remove as you wish or be welcome to add even more.
You are free to choose whichever platform works best for you and your project. The original template by TezRomacH was created with GitHub in mind, which prompted the creation of a similarly fully-featured template for GitLab users as well.
However, not everything that is available for GitHub users is available to GitLab users, and vice-versa. Please mind the differences between both options.
Below is a comparison between the features available in this package depending on which platform you choose to host your project:
| Feature | GitLab | GitHub | Observations |
|---|---|---|---|
| Issue templates | β | β | Both options feature automatic labels, but GitHub has an extra configuration to prevent the creation of empty issues. |
| Merge/pull requests templates | β | For GitHub, templates can only be accessed by applying custom query parameters during PR creation. | |
| Project conditions checks | β | β | A basic workflow to install the package and run tests, check codestyle and safety. |
| Publication to TestPyPI | β | β | For GitHub, the workflow uses the official PyPI Publish action, while GitLab CI uses the PyPI API. |
| Publication to PyPI | β | β | Both GitLab and GitHub projects use trusted publishing to upload packages to the canonical PyPI registry. Projects on both platforms will also publish the build files attestations. |
| Documentation publication | β | β | Both GitLab and GitHub projects allow developers to publish documentation to their respective Pages environment. However, publication is disabled by default and should be set up by the user. |
| SLSA Level 3 provenances | β | β | GitLab projects use the SLSA CI/CD component to sign the PyPI attestations and the metadata generated during package building to comply with level 3 standards. |
| Image publication | β | β | For GitHub, images are pushed to Docker Hub, while GitLab CI pushes images to the repository's Container Registry by default (and can be reconfigured). |
| Snapshot images | β | β | For GitLab, the Docker CI/CD component is used and allows for pushing snapshot images for testing when a Merge Request is open. |
| Dockerfile linting | β | β | The Docker GitLab CI/CD component includes a job for linting the Dockerfile with Hadolint. |
| Image vulnerability analysis | β | β | The Docker GitLab CI/CD component uses Trivy to scan the image for vulnerabilities. |
| Docker SBOM files | β | β | The Docker GitLab CI/CD component generates a bill of materials with CycloneDX. |
| Dependency scanning | β | β | For GitLab, the Dependency Scanning CI/CD component generates a bill of materials with CycloneDX. |
| SAST | β | β | For GitLab, the SAST CI/CD component performs a security analysis and provides a report with its results. |
| Secret detection | β | β | For GitLab, the Secret Detection CI/CD component performs an analysis on potential leaked secrets in tracked files and provides a report with its results. |
| Stale issues | β | β | GitLab rules are more flexible, marking stale issues only for those not opened by project members. |
| Greetings workflow | β | β | GitHub provides workflows to automatically reply to issues and merge requests with the First Interaction action. |
| Dependency updates | β | β | To reduce development overhead, GitLab projects use a Renovate configuration which should be paired with a separate repository implementing the Renovate CI/CD component, while GitHub projects use Dependabot out of the box. |
| Release drafter | β | β | Release Drafter is a custom workflow available on GitHub Marketplace. You may see the list of labels in release-drafter.yml. Works perfectly with any SemVer-compatible schema. |
| Changelog configuration | β | β | GitLab provides automatic changelog updates through their API. You may modify the template in changelog_config.yml. GitLab projects also leverage use of Galactic Releases to manage release cycles and release notes. |
| Test Reports | β | β | JUnit XML reports are supported by GitLab to allow test reports to be displayed in pipelines and merge requests. |
| CI control over pushed tags | β | GitLab provides full control for tags pushed to the repository using regex, while GitHub Actions is more restricted in how it filters workflows to run, and can only apply these filters at the top level, limiting workflow customization. |
To begin using the template consider updating Cookiecutter:
pipx upgrade cookiecutterthen go to a directory where you want to create your project and run:
cookiecutter gl:galactipy/galactipy --checkout v3.3.0Cookiecutter will ask you to fill some variables in order to generate the files with everything you need already set up.
The input variables are as follows:
| Variable | Type | Default value | Valid options | Observations |
|---|---|---|---|---|
project_name |
βοΈ | Python Project |
Any | A suitable name by which people will refer to. |
repo_name |
βοΈ | based on project_name |
GitLab-compliant values PyPA-compliant values |
Name of the repository to develop the project on. Check the availability of possible names before creating the project. |
package_name |
βοΈ | based on project_name |
Valid Python identifiers PyPA-compliant values |
Check the availability of possible names before creating the project. |
project_description |
βοΈ | based on project_name |
Any | A brief one-line description of your project. |
copyright |
βοΈ | The Galactipy Contributors |
Any | Name of the author or organisation which will hold the project's copyright. Used to specify code ownership in LICENCE. |
maintainer |
βοΈ | Manoel Pereira de Queiroz |
Any | Name of the primary maintainer of the project. Used to specify author data in pyproject.toml and CITATION.cff. |
scm_platform |
π | GitLab Free |
GitLab FreeGitLab PremiumGitLab UltimateGitHub |
Depending on the choice you will have different features to work with. |
scm_namespace |
βοΈ | galactipy |
GitLab-compliant values Between 2 and 255 characters |
GitHub or GitLab namespace for hosting. Also used to set up README.md, pyproject.toml and template files for either platform. Can be provided as a nested subgroup separated by slashes. |
email |
βοΈ | based on scm_namespace |
Values complying with RFC 5332 | Email for CODE_OF_CONDUCT.md, SECURITY.md files and to specify author data in pyproject.toml and CITATION.cff. |
licence |
π | MIT |
MITBSD-3GNU GPL v3.0GNU AGLP v3.0GNU LGPL v3.0Mozilla Public License 2.0Apache Software License 2.0Not open source |
The non-OSS licence option provides policy documents with different rules for project development. |
minimal_python_version |
π | 3.10 |
3.103.113.123.133.14 |
Used for builds, pipelines and formatters. |
line_length |
#οΈβ£ | 88 | Between 50 and 300 | The max line length to be validated by the formatter. |
docstring_style |
π | Numpydoc |
NumpydocGoogle Python StyleSphinxOther |
Other will only render the docstring short summaries, while all others will detail arguments and returns for public classes, methods and functions. |
docstring_length |
#οΈβ£ | based on line_length |
Between 50 and 300 Equal or lower than line_length |
The max line length for docstrings to be validated by the formatter. |
version_schema |
π | EffVer |
EffVerSemVerCalVer (automanaged)CalVer (explicit)RomVerSoloVerTrunkVer |
Automanaged CalVer provides a CI/CD configuration to automatically create tags and release the package on a weekly basis. The TrunkVer option sets up a new package release on each commit made to the default branch. Other options require a tag to be manually created to trigger releases. |
commit_convention |
π | Gitmoji |
GitmojiConventional CommitsConventional Commits with Gitmoji |
The Conventional Commits and Convetional Commits with Gitmoji options add a pre-commit hook for Commitizen to validate commit message title structure. |
use_bdd |
πΊ | True |
Option to use behaviour-driven development for managing tests. | |
coverage_service |
π | Codacy |
CodacyCoveralls |
Coveralls provide cove coverage only, while Codacy allows for code quality reports and static analysis. |
create_docker |
πΊ | True |
Option to create a Dockerfile and build an image for your project. Also configures CI jobs to publish the image to container registries. | |
create_docs |
πΊ | True |
Option to create documentation files using Zensical. | |
app_type |
π | Integrated CLI+TUI |
Integrated CLI+TUIHybrid CLI/TUICLI-only applicationMinimal CLI structureBare repository |
Depending on the chosen option, configures Typer and Textual as the core dependency libraries. |
[!NOTE] Legend
Icon Type βοΈ Free text #οΈβ£ Number π Option πΊ Boolean Boolean variables can be dismissed by typing either
0,false,f,no,noroff.
All input values will be saved in cookiecutter-config-file.yml
so that you won't lose them. π
The app_type Cookiecutter variable
is used to define the level
of sample files
provided by Galactipy
and how the project tree
is structured:
| Application Type | What's Included | Recommended Usage |
|---|---|---|
| Integrated CLI+TUI | A TUI-first application, where the top-level command launches the interface. It also includes configuration commands via CLI and allow for additional commands built by the user. | Projects designed to be interacted with mainly through a visual interface. |
| Hybrid CLI/TUI | Same as Integrated CLI+TUI, with the difference that the interface is launched via its own command. | Projects with many-yet-simple operations which can be mastered solely at the command-line, but also targeted at non-power-users who prefer a visual interface to interact with the API. |
| CLI-only application | Removes TUI-related features to solely rely on CLI commands. Still includes the configuration commands and config file management available in TUI options. | Projects with simpler interactions that do not require much cognitive load or a visual helper to navigate through operations. |
| Minimal CLI structure | Same as CLI-only application, but removes the API related to configuration management. | Projects that do not require stateful/persisted values to perform their operations from the command-line. |
| Bare repository | Removes sample code files altogether while keeping all other development features such as CI/CD configuration and pre-commit hooks. | General-purpose libraries and APIs. |
You must have Poetry installed to leverage the features provided with the Galactipy template.
After creating a project, ensure you have Invoke installed and run the following command to install dependencies and pre-commit hooks:
invoke installIf you don't have Invoke available in your system, run this instead:
poetry install
invoke hooksWant to know more about Poetry? Check its documentation. Poetry's commands are very intuitive and easy to learn, streamlining your development process.
Galactipy is best used
for terminal applications,
either a TUI
or a simple CLI interface.
If you choose any of the options for app_type
excluding Bare repository,
your project will embed Typer
as a dependency,
and Textual will be provided for
the Integrated CLI+TUI and Hybrid CLI/TUI options.
For any of the options providing an interface,
you can call the application
after setting up the virtual environment
via invoke install or poetry install:
poetry run <repo_name> --helppoetry run <repo_name> --versionThen you can use the structure provided with Galactipy to build your application upon the barebones codebase. π
To release a new version of the application, you must first have a PyPI account and set up Trusted Publishing for your project.
Then, when you push a tag to GitLab or GitHub, the preconfigured CI/CD pipeline will handle building, publishing and releasing automatically, with minimal configuration required! π₯³
Note
To allow releasing directly via CI/CD workflows, besides setting up a canonical PyPI token, you must also generate a API token for the TestPyPI repository.
If you have generated your project with the Docker option enabled, pushing a tag to your repository will also set up the automated workflows to build and publish your image to a container registry.
invoke is a library that
enables easy configuration of
shell-oriented subprocesses
as Python functions,
essentially organising a collection of aliases
for all project developers to use.
Below is a list
with the main task groups
and details when relevant.
Available tasks can be viewed
at anytime
with the invoke --list command.
| Command | Details |
|---|---|
invoke install |
πΊ Sets up the Poetry virtual environment, installs the dependencies, pre-commit hooks and runs a mypy check. |
invoke pyproject |
Checks pyproject.toml integrity. |
invoke update |
Updates dependencies to their latest compatible release requirements, with an option to update to the latest versions overall. |
Warning
πΊ Invoke must be installed and callable.
Otherwise, it is recommended to run poetry install
to set up the repository.
| Command | Details |
|---|---|
invoke codestyle |
Format files with Ruff, with an option to check files only. |
invoke lint |
Check compliance with linting rules, with an option to correct those considered fixable by Ruff. |
invoke mypy |
Run mypy to check for static typing. |
invoke test |
Run the test suite with Pytest. |
invoke report |
Run the test and mypy tasks and open their HTML coverage reports. |
invoke security |
Run security checks with Bandit and check pyproject.toml integrity. |
The invoke sweep task groups all tasks
except for report
into a single command.
invoke ruff can be used
to run the Ruff formatter and linter
with a single command.
| Command | Details |
|---|---|
invoke build |
Build the project wheels. |
invoke config |
πΊ Configure PyPI repositories, requiring at least an API token, with optional repository name and URL arguments. |
invoke publish |
Publish the project to a registry, defaulting to the canonical PyPI repository, with an option to build the project wheels. |
invoke docs |
Build the project documentation with Zensical. |
Note
πΊ When provided with no --repo option,
Invoke will configure the connection
to the canonical PyPI repository,
with only the API token being required.
When provided with the --repo testpypi option instead,
it will configure the connection
to TestPyPI
and no URL is needed.
Other --repo values must also
receive a --url argument
pointing to the desired custom registry.
| Command | Details |
|---|---|
invoke login |
Log in to a container registry. For GitHub users, points to Docker Hub. For GitLab users, points to the repository's integrated container registry. |
invoke container |
Build local container images, with the option to set multiple tags and an alternate repository to point. |
invoke push |
Push all project images to a container registry, with the option to set an alternate repository to push. |
invoke prune |
Remove all local images built for the project, with the option to set an alternate repository to point. |
| Command | Details |
|---|---|
invoke remove-cache |
Remove __pycache__ files from the local repository. |
invoke remove-dsstore |
Remove the .DS_Store directory from the local repository. |
invoke remove-mypy |
Remove the .mypy_cache directory from the local repository. |
invoke remove-ipynb |
Remove the .ipynb_checkpoints directory from the local repository. |
invoke remove-pytest |
Remove the .pytest_cache directory and the .coverage and test_report.xml files from the local repository. |
invoke remove-ruff |
Remove the .ruff_cache directory from the local repository. |
invoke remove-build |
Remove wheels built locally. |
The invoke cleanup task groups all tasks
except for remove-build
into a single command.
Behaviour-driven development is a software development paradigm in which domain language is used to describe the behaviour of the code. It emerged as a sophisticated evolution of test-driven development.
If you choose to use BDD for your project,
a features directory will be created under tests
and pytest-bdd will be added as a dependency.
You should place .feature files inside this folder
to describe real-life usage scenarios
using the Gherkin language:
# tests/features/root_command.feature
Feature: Command-line interface
Scenario: Check program version
When the root program receives the `--version` option
Then the terminal displays the program's version
And the program exits without errors
You would then use pytest-bdd to wrap each scenario referred in the feature file as a step-by-step validation:
from typer.testing import CliRunner
from pytest_bdd import scenario, when, then, parsers
from python_project.cli.commands.root_command import app
runner = CliRunner()
@scenario("root_command.feature", "Check program version")
def test_cli_with_version_arg():
pass
@when("the root program receives the `--version` option", target_fixture="cli_run")
def invoke_version_arg():
return runner.invoke(app, args=["--version"])
@then("the terminal displays the program's version")
def version_display(cli_run, version_string):
assert cli_run.stdout == version_string
@then("the program exits without errors")
def successful_termination(cli_run):
assert cli_run.exit_code == 0Once the tests are defined, you can simply use Pytest as you normally would to run the test suite and check the results.
For more information on behaviour-driven development and tools to handle more complex conditions, please check out the Cucumber documentation.
Well, that's up to you. πͺ
For further setting up your project:
- Look for files and sections
marked with special inline comment tags:
TODOcomments must be addressed in order for your project to run properly from end-to-end;UPDATEMEcomments point to additional settings or content you can provide, but are not necessary to enable development;DEFINEcomments mark sections in policy files for concepts and content specifically tailored to your project's context;- If you use VS Code,
install the Todo Tree extension
to easily locate and jump
to these marks,
they are already configured
in the
settings.jsonfile;
- Make sure to create your desired Issue labels (and GitLab statuses, if you're using GitLab Premium or Ultimate) on your repository before you start tracking issues;
- Make changes to your CI configuration to better suit your needs.
Important
In order to reduce user prompts and keep things effective, the template generates files with a few assumptions:
- It assumes your main Git branch is
master; if you wish to use another branch name for development, be aware of changes you will have to make in Markdown files so links won't break when you push them to your repo; - It defines the
namesetting inpyproject.tomlassuming you will be able to publish your project to PyPI underrepo_name, change it otherwise; - It specifies the
DEFAULT_DOCKER_REPOSITORYconstant intasks.pyassuming you also usescm_namespacefor Docker Hub and you will push your image underrepo_name, change it otherwise.
If you want to put your project on steroids, here are a few Python tools which can help you depending on what you want to achieve with your application:
- If you chose
to generate a TUI or CLI example
during the Cookiecutter setup,
these libraries will already be
among your dependencies:
- Rich makes it easy to add beautiful formatting in the terminal;
- Typer builds great Command-Line Interfaces (CLI) applications with an easy-to-code API based on type hints;
- Textual is a rapid application development framework to create Terminal User Interfaces (TUIs), made to be fun to build with;
- Orbittings is Galactipy's own utility to manage configuration files and settings for these CLI/TUI applications; π
- Nebulog makes logging stupidly simple (and beautiful), brought to you by The Galactipy Contributors; πΊ
- attrs and cattrs work together to make data structuring and validation your application's powerhouse, not its Achilles's heel;
- Trio is a friendly library for async concurrency and I/O;
- FastAPI is a web framework for high performance and easy learning;
- textX allows you to build your own Domain-Specific Languages (DSL) in plain Python;
- Returns makes you function's output meaningful, typed and safe;
- Hydra is a framework for elegantly configuring complex applications;
- Locust allows you to write scalable load tests in plain Python;
- orjson is an ultra fast JSON parsing library;
- Lark is a parsing toolkit for Python, built with a focus on ergonomics, performance and modularity.
For taking development and exposition of your project to the next level:
- Experiment with additional badges;
not only they enhance
your project's appearance
but also visually communicate key aspects,
helping visitors quickly grasp
important details about your work:
- You can look at dynamic badges available at Shields.io;
- There is a myriad of static badges for brands and services in general at Simple Badges;
- awesome-badges provides a lot of useful resources on this topic;
- Add your project
to the OpenSSF Best Practices and OSSRank indexes;
if you have ambitious goals
or expect significant growth,
these indexes provide
valuable visibility;
- There are already badges for them
in your
README.mdfile, just waiting for you to update their URLs with your project's index; π
- There are already badges for them
in your
- Create a sponsorship page
enabling users and organisations
to help fund your project's
growth and development;
popular plaforms include:
- Liberapay;
- Open Collective;
- Ko-fi;
- If you host your project on GitHub, you can set a Sponsors account directly integrated into the platform;
- If you are unsure about which versioning logic to use, check this list briefly explaining all available options with Galactipy (and some others more).
And here are a few articles which may help you:
- Open Source Guides;
- A handy guide to financial support for open source;
- GitLab CI Documentation;
- GitHub Actions Documentation;
- A Comprehensive Look at Testing in Software Development;
- Robust Exception Handling;
- Why Your Mock Doesn't Work;
- Managing TODOs in a codebase;
- The importance of layered thinking in data engineering.
You can see the list of available releases on the GitLab Releases page.
We follow the Romantic Versioning specification,
details can be found
in our CONTRIBUTING guide.
Galactipy's roadmap is managed
through our Epics page,
which lays out
the current development streams
mapped for delivery.
All official details on
development,
timeline
and deliverables
are found there.
The project's epics are also presented
in the ROADMAP file
purely for informational purposes.
This project is licenced
under the terms of the MIT licence.
See LICENCE for more details.
Firstly, there is no way this template would exist without the previous phenomenal work by Roman Tezikov and his rich python-package-template. If there is anyone more deserving of a π and acknowledgement, it's him! Please give a shoutout and support if possible.
The original template was inspired by several articles that might be helpful if you are starting out managing projects:
- Hypermodern Python;
- Ultimate Setup for Your Next Python Project;
- Nine simple steps for better-looking python code;
- Modern Python developer's toolkit.
Additionally, we would like to thank the teams of the following projects and individuals for either aiding us directly during our research of best practices and tools for Python development or whose documentation have inspired parts of the project:
Give them your β, these resources are amazing! π
Galactipy Bot avatar created by Smashicons.
We provide a CITATION.cff file
to make it easier
to cite this project
in your paper.
Add the badge
to your project!
It would be really appreciated
to spread the word of this template.
Here is the Markdown source for it:
[](https://kutt.it/7fYqQl)We would be equally grateful if you could also do any of the following:
- Set the notification level to "Watch" to receive our latest updates; π
- Star the project! π
- Share the project with colleagues; π£οΈ
- Write a short article on how you are using Galactipy on your projects; βοΈ
- Share best practices, references and tools for project management with us! π»