{"id":16390604,"url":"https://github.com/marvinfriede/template-python-project","last_synced_at":"2025-03-23T04:31:40.600Z","repository":{"id":130376259,"uuid":"565086223","full_name":"marvinfriede/template-python-project","owner":"marvinfriede","description":"Template for a Python project.","archived":false,"fork":false,"pushed_at":"2025-03-03T17:36:04.000Z","size":63,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-18T17:51:22.132Z","etag":null,"topics":["python","python-project-template","python-template"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marvinfriede.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-12T09:49:19.000Z","updated_at":"2023-06-20T08:16:41.000Z","dependencies_parsed_at":"2023-07-11T14:35:38.986Z","dependency_job_id":"2ce7c081-c018-40df-a527-983f55786625","html_url":"https://github.com/marvinfriede/template-python-project","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvinfriede%2Ftemplate-python-project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvinfriede%2Ftemplate-python-project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvinfriede%2Ftemplate-python-project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvinfriede%2Ftemplate-python-project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marvinfriede","download_url":"https://codeload.github.com/marvinfriede/template-python-project/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245056889,"owners_count":20553855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","python-project-template","python-template"],"created_at":"2024-10-11T04:43:48.687Z","updated_at":"2025-03-23T04:31:40.321Z","avatar_url":"https://github.com/marvinfriede.png","language":"Python","readme":"# Template for open-source Python projects\n\n![Python versions](https://img.shields.io/badge/python-3.7%20%7C%203.8%20%7C%203.9%20%7C%203.10%20%7C%203.11-blue)\n![Tests](https://github.com/marvinfriede/python-project/actions/workflows/test.yml/badge.svg)\n[![codecov](https://codecov.io/gh/marvinfriede/python-project/branch/master/graph/badge.svg?token=UEKDZY459S)](https://codecov.io/gh/marvinfriede/python-project)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/marvinfriede/python-project/master.svg)](https://results.pre-commit.ci/latest/github/marvinfriede/python-project/master)\n[![code style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nThis repository aims to provide a starting template for Python projects containing the most important configuration files\n(which have to be tailored for your project!) and an initial directory structure separating source code and tests.\n\nI tried to incorporate most \"best practices\" but in the end, most of the design choices and tools are just personal preferences.\n\nThe following tools are used: black, covdefaults, coverage, pre-commit, pylint, pytest, tox\n\n\u003cbr\u003e\n\n## Source code\n\nAll of the source code goes into the [src/\\\u003cproject-name\\\u003e](src/squarer) directory. Here, some _dunder_ files can be found:\n\n- [\\_\\_version\\_\\_.py](src/squarer/__version__.py): just the version number as string, used by config files\n- [\\_\\_init\\_\\_.py](src/squarer/__init__.py): entry point for program/library\n- [\\_\\_main\\_\\_.py](src/squarer/__main__.py): same as `__init__.py` allowing calls via `python -m \u003cprog\u003e`\n\n\u003cbr\u003e\n\n## Tests (pytest/tox)\n\nTesting is done with `pytest` and `tox`. All tests go into the [test](test/) directory. Pytest automatically finds all directories\nand modules as well as functions and classes within these matching `test_*.py`/`*_test.py` files, `Test*` classes, and `test_*`\nfunctions and methods (automatic test discovery).\n\nThe [conftest.py](test/conftest.py) file is sort of a setup file that can be used to create additional configurations/hooks\n([small example](https://github.com/tbmalt/tbmalt/blob/main/tests/conftest.py)) and setup code (fixtures) for all tests.\n\nThe test environment for pytest is setup with the `setup.cfg` and/or `pyproject.toml` file. `tox` needs extra configuration\nwhich can be found in the _deps_ section of [tox.ini](tox.ini). Some projects also use a `requirements-tests.txt` file that lists\nall test dependencies and is also given in the _deps_ section with `deps = -rrequirements-tests.txt`.\nFurthermore, to run pytest from tox, the `commands` section must be given. Here, additional options for the code coverage report\nfrom the `coverage` tool are given.\n\n\u003cbr\u003e\n\n_When to use pytest, coverage and tox?_\n\nPersonally, I mostly use just pytest without coverage to test in my working environment with `pytest -svv test` or a specific\ntest module. Before committing, however, it is a good idea to check if your code also runs in different environments, which is where\n`tox` comes in. Running just `tox`, will test in all environments specified in [tox.ini](tox.ini)'s envlist and may take some\ntime. Certain environments can be selected with `tox -e py37`. Note that `tox` must be able to find a Python interpreter for\neach version given in the envlist.\n\n\u003cdetails\u003e\n\u003csummary\u003eHow to provide the Python interpreters for tox.\u003c/summary\u003e\n\nUnfortunately, this does not directly work with something like a conda environment but you can setup the environments and provide\na symlink to a directory which is in your path.\n\n```console\nmamba create --name \"py311\" python=3.11 -y\nln -s /opt/miniforge3/envs/py311/bin/python3.11 ~/bin/python3.11\n```\n\n\u003c/details\u003e\n\n\u003cbr\u003e\n\nFinally, some handy features of pytest you should be aware of:\n\n- fixtures: common setup for multiple tests (e.g., reading file or database connection)\n- parametrize: multiple test cases for single function\n- expected fails: testing if the code handles wrong inputs (`with pytest.raises(Exception): ...` or `@pytest.mark.xfail`)\n- check for [test pollution](https://github.com/asottile/detect-test-pollution) by randomizing the order of tests ([pytest-plugin](https://pypi.org/project/pytest-random-order/))\n\n\u003cbr\u003e\n\n## Setup files and Packaging\n\nPackaging is done with [`setuptools`](https://setuptools.pypa.io/en/latest/index.html), which is configured through the `pyproject.toml` and/or `setup.cfg`/`setup.py` files.\n\n\u003cdetails\u003e\n\u003csummary\u003e\n  \u003ccode\u003epyproject.toml\u003c/code\u003e vs.\n  \u003ccode\u003esetup.cfg\u003c/code\u003e vs\n  \u003ccode\u003esetup.py\u003c/code\u003e\n\u003c/summary\u003e\n\nThe `setup.py` file is a Python script and configuration is passed through keyword arguments of `setuptools.setup()`. This is not recommended due to possible security and parsing issues. The same setup can be accomplished in a declarative style within `setup.cfg` and `setup.py` remains mostly empty only calling `setuptools.setup()`.\nThe `pyproject.toml` file aims to unify configuration files including various tools like black or pytest. For packaging, it is very similar to `setup.cfg`. However, `pyproject.toml` has not been adopted as the default yet and many projects still use `setup.cfg` to declare the packaging setup. Note that `setup.py` is not necessary if a `pyproject.toml` is present.\n\n\u003c/details\u003e\n\n#### `pyproject.toml`\n\n- minimal build specification to use with setuptools\n- configuration of other tools (black, pytest, mypy, ...)\n\n[](https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#using-a-src-layout)\n\n#### `setup.cfg`\n\n- declarative configuration for setuptools\n- [_metadata_](https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#metadata): must at least contain _name_ and _version_\n- [_options_](https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#options): package discovery, dependencies\n  - [additional setup](https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#using-a-src-layout) required for `src/` layout\n- [_options.extras_require_](https://setuptools.pypa.io/en/latest/userguide/dependency_management.html#optional-dependencies): optional dependencies (dev tools, docs, ...)\n- [_options.package_data_](https://setuptools.pypa.io/en/latest/userguide/datafiles.html#package-data): inclusion of other, non-Python files (marker files, data, ...)\n  - alternative: `MANIFEST.in`\n- [_options.entry_points_](https://setuptools.pypa.io/en/latest/userguide/entry_point.html): entry point for command line interface\n- can also hold configuration of other tools\n\n\u003cbr\u003e\n\nThe package can be installed with `pip install .` or something like `pip install .[dev]` to also install additional dependencies specified in `setup.cfg`'s _options.extras_require_. Pass the `-e` flag for editable mode, which loads the package from the source directory, i.e., changing the source code does not require a new installation.\n\n\u003cbr\u003e\n\n## CI - Continuous Integration (with GitHub Actions)\n\n**Important!** CI in private repositories is generally limited (to _x_ minutes of execution time).\n\n...\n\n\u003cbr\u003e\n\n## More\n\nTools\n- [pre-commit.ci](https://github.com/apps/pre-commit-ci/)\n- [codecov](https://github.com/apps/codecov/)\n\nWebsites\n- [create .gitignore](https://www.toptal.com/developers/gitignore)\n- [choose license](https://choosealicense.com/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarvinfriede%2Ftemplate-python-project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarvinfriede%2Ftemplate-python-project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarvinfriede%2Ftemplate-python-project/lists"}