Skip to content

manoelpqueiroz/galactipy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
❗ 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!

Galactipy

Python support Repository Releases Licence Cookiecutter template

Project type Contributions Welcome Open issues Merge Requests

Code style: Ruff Docstrings: numpydoc Gitmoji Semantic Line Breaks

Poetry Pre-commit Editorconfig

Intended Effort versioning Code Quality Coverage GitLab Pipelines

Expand your project structure from atoms of code to galactic dimensions. 🌌

TL;DR

cookiecutter gl:galactipy/galactipy --checkout v0.18.0

All you need is the latest version of cookiecutter! πŸ˜‰

πŸš€ Features

In this cookiecutter πŸͺ template we combine state-of-the-art libraries and best development practices for Python.

Development features

Deployment features

Project management features

Open source community features

  • Files such as: LICENCE, CONTRIBUTING.md, CODE_OF_CONDUCT.md, CITATION.cff and SECURITY.md are generated automatically;
  • Loads of predefined badges to make your project stand out: project info, contributions, development practices, development tools and QA status; you can either keep them, remove as you wish or be welcome to add even more.

GitLab vs. GitHub feature comparison chart

You are free to choose whichever platform works best for you and your project. The original template by TezRomacH was created originally 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 βœ… βœ…
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 βœ… βœ… For GitHub, trusted publishing is used with the PyPI Publish action, while GitLab CI uses the PyPI API.
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.
SBOM files βœ… ❌ The Docker GitLab CI/CD component generates a bill of materials with CycloneDX.
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.
Dependabot ❌ βœ… Dependabot is a feature now incorporated into GitHub Security. See here how to enable it.
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 Semantic Versions specification.
Changelog configuration βœ… ❌ GitLab provides automatic changelog updates through their API. You may modify the template in changelog_config.yml.
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.

🀯 How to use it

Installation

To begin using the template consider updating cookiecutter:

pip install -U cookiecutter

then go to a directory where you want to create your project and run:

cookiecutter gl:galactipy/galactipy --checkout v0.18.0

Input variables

Cookiecutter will ask you to fill some variables in order to generate the files with everything you need already set up.

The input variables, with their default values, are as follows:

Parameter Default value Description
project_name Python Project A suitable name by which people will refer to, you are free to name it however you wish to.
repo_name based on project_name 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 PyPI-compliant Python package name. Check the availability of possible names before creating the project.
project_description based on project_name A brief description of your project.
author The Galactipy Contributors Name of the author or organisation. Used to generate LICENCE and to specify ownership in pyproject.toml.
scm_platform GitLab Free One of GitLab Free, GitLab Premium/Ultimate and GitHub. Depending on the choice you will have different features to work with.
scm_namespace galactipy GitHub or GitLab namespace for hosting. Also used to set up README.md, pyproject.toml and template files for either platform.
email based on scm_namespace Email for CODE_OF_CONDUCT.md, SECURITY.md files and to specify the ownership of the project in pyproject.toml.
licence MIT One of MIT, BSD-3, GNU GPL v3.0, GNU AGLP v3.0, GNU LGPL v3.0, Mozilla Public License 2.0 and Apache Software License 2.0, or Not open source.
minimal_python_version 3.9 Minimal Python version. All versions since 3.9 are available to choose. It is used for builds, pipelines and formatters.
line_length 88 The max length per line. NOTE: This value must be between 50 and 300.
docstring_style numpy One of numpy, pep257 or google. You can choose other to disable checks on your docstrings.
docstring_length based on line_lenght The max length for docstrings. NOTE: This value must be between 50 and 300 and lower of equal to line_lenght.
use_bdd True πŸ”Ί Option to use behaviour-driven development for managing tests.
coverage_service Coveralls One of Coveralls for code coverage and Codacy for code quality and static analysis.
app_type Integrated CLI+TUI One of Integrated CLI+TUI for a straight TUI application, Hybrid CLI/TUI for a CLI application with a preset TUI command, CLI-only application with minimal app configuration and Bare repository for no sample files at all. Employs Typer and Textual as libraries.
create_docker True πŸ”Ί Option to create a Dockerfile to build an image for your project.

Note

Input variables marked with πŸ”Ί are boolean variables, you can dismiss those by typing either 0, false, f, no, n or off.

All input values will be saved in the cookiecutter-config-file.yml file so that you won't lose them. πŸ˜‰

Initial set up

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 install

If you don't have Invoke available in your system, run this instead:

poetry install
invoke hooks

Want to know more about Poetry? Check its documentation. Poetry's commands are very intuitive and easy to learn, streamlining your development process.

Sample Application

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> --help
poetry run <repo_name> --version

Then you can use the structure provided with Galactipy to build your application upon the barebones codebase. πŸ˜„

Building and releasing your package

To release a new version of the application, you must first have a PyPI account and generate an API token.

Then, add the registry to the Poetry configuration with

invoke config <API_token>

You'll be all set to build and publish your package in one go!

invoke publish

You should also push a tag to GitLab or GitHub and create a Release for your application, enabling users to download, track and inspect the changes made to the API.

Of course, you can also rely solely on the CI tools provided by Galactipy to 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 toke 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 Usage

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.

Environment Setup

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] :small_red_triangle: Invoke must be installed and callable. Otherwise, it is recommended to run poetry install to set up the repository.

Quality Assurance Tasks

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 coverage Generate the coverage file for upload to Coveralls or Codacy.
invoke security Run security checks with Bandit and check pyproject.toml integrity.

The invoke sweep task groups all tasks except for coverage into a single command.

Project Building & Publishing

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.

[!note] :small_red_triangle: 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.

Docker Operations

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.

Cleanup Tasks

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.

Use BDD for handling the development cycle

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: Invoke with version argument
    When the program is called with the `--version` argument
    Then the program's version is displayed
    And the program is terminated 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 python_project.cli.root_command import app
from pytest_bdd import scenario, when, then, parsers

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 == 0

Once 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.

🎯 What's next

Well, that's up to you. πŸ’ͺ

For further setting up your project:

  • Look for files and sections marked with TODO (which must be addressed in order for your project to run properly) and UPDATEME (optional settings if you feel inclined to);

    • 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.json file;
  • Make sure to create your desired Issue labels on your platform before you start tracking them so it ensures you will be able to filter them from the get-go;

  • Make changes to your CI configurations to better suit your needs.

  • 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 the Issue and Merge Request templates and README.md file so links won't break when you push them to your repo;
    • It generates a PyPI badge assuming you will be able to publish your project under repo_name, change it otherwise;
    • It generates a Docker badge assuming you also use scm_namespace for Docker Hub and you will push your image under repo_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:

  • Rich makes it easy to add beautiful formatting in the terminal. If you chose to generate a TUI or CLI example during the Cookiecutter setup, Rich will already be among your dependencies;
  • tqdm is a fast, extensible progress bar for Python and CLI;
  • orjson, an ultra fast JSON parsing library;
  • Pydantic is data validation and settings management using Python type hinting;
  • Returns makes you function's output meaningful, typed, and safe;
  • Loguru makes logging (stupidly) simple;
  • IceCream is a little library for sweet and creamy debugging;
  • Hydra is a framework for elegantly configuring complex applications;
  • FastAPI is a type-driven asynchronous web framework.

For taking development and exposition of your project to the next level:

  • Try out some more badges, not only it looks good, but it also helps people better understand some intricate details on how your project works:
    • You can look at dynamic badges available at Shields.io;
    • There is a myriad of standardised static badges at Simple Badges;
    • awesome-badges provides a lot of useful resources to help you deal with badges;
  • Add your project to OpenSSF Best Practices and OSSRank indexes. If you have greater ambitions for your project and/or expects it to scale at some point, it's worth considering adding it to these trackers;
    • There are already badges for those set up in your README.md file, just waiting for you to update their URLs with your project's index in both services; πŸ˜€
  • Setup a sponsorship page and allow users and organisations who appreciate your project to help raise for its development (and add a badge in the process! 😎). Popular platforms are:
    • Liberapay;
    • Open Collective;
    • Ko-fi;
    • If you host on GitHub, you can set a Sponsors account directly integrated into the platform;
    • Of course, you can also set any kind of gateway you wish, what works best for you and your project!
  • If you are unsure about the versioning logic to use, check this list with a plethora of options to choose from.

And here are a few articles which may help you:

πŸ“ˆ Galactipy Releases

You can see the list of available releases on the GitLab Releases page.

We follow Intended Effort Versioning specification, details can be found in our CONTRIBUTING guide.

:map: Roadmap

Galactipy's roadmap is managed through our Milestones page, which lays out the current development streams mapped for delivery. All official details on development, timeline and deliverables are found through those pages. The project's milestones are also presented in the ROADMAP file purely for informational purposes.

πŸ›‘οΈ Licence

Licence

This project is licenced under the terms of the MIT licence. See LICENCE for more details.

:sports_medal: Acknowledgements

Firstly, there is no way this template would exist without the previous phenomenal work by Roman Tezikov and his fully-featured 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:

And also there are some projects which can be studied as references in project management and template design:

Additionally, we would like to thank the teams of the following projects 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.

πŸ“ƒ Citation

We provide a CITATION.cff file to make it easier to cite this project in your paper.

πŸ“£ Spread the Word

Add the badge Expand your project structure from atoms of code to galactic dimensions. to your project! It would be really appreciated to spread the word of this template.

Here is the Markdown source for it:

[![Expand your project structure from atoms of code to galactic dimensions.](https://img.shields.io/badge/made%20with-galactipy%20%F0%9F%8C%8C-179287?style=for-the-badge&labelColor=193A3E)](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! 🍻

About

Expand your project structure from atoms of code to galactic dimensions. 🌌

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Contributors 13