{"id":48890639,"url":"https://github.com/mendix/python-project-template","last_synced_at":"2026-04-16T07:36:28.070Z","repository":{"id":136895697,"uuid":"379269691","full_name":"mendix/python-project-template","owner":"mendix","description":"An opinionated template for creating Python microservices, with sane defaults.","archived":false,"fork":false,"pushed_at":"2024-04-04T12:27:23.000Z","size":41,"stargazers_count":3,"open_issues_count":5,"forks_count":2,"subscribers_count":9,"default_branch":"main","last_synced_at":"2024-04-14T11:54:07.545Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/mendix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-06-22T12:56:12.000Z","updated_at":"2024-04-14T11:54:07.545Z","dependencies_parsed_at":"2023-04-14T01:31:15.583Z","dependency_job_id":null,"html_url":"https://github.com/mendix/python-project-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mendix/python-project-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendix%2Fpython-project-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendix%2Fpython-project-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendix%2Fpython-project-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendix%2Fpython-project-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mendix","download_url":"https://codeload.github.com/mendix/python-project-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendix%2Fpython-project-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31876798,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T07:36:03.521Z","status":"ssl_error","status_checked_at":"2026-04-16T07:35:53.576Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-04-16T07:36:27.218Z","updated_at":"2026-04-16T07:36:28.060Z","avatar_url":"https://github.com/mendix.png","language":"Python","readme":"# python-project-template\n\n![Test status](https://github.com/matyaskuti/python-project-template/actions/workflows/python-app.yml/badge.svg\n)\n\nA [`cookiecutter`](https://github.com/audreyr/cookiecutter) based Python\nproject template.\n\nThis is an opinionated template, based on useful defaults that we like to have\nwhen creating new projects. We include a pre-built makefile, with rules for\nlinting and test, scaffolded unit tests, and tools for building wheels,\namongst other things. \n\nThis project is open source because we think it might be useful to other\nengineers. However, Mendix does not officially support this project.\n\n## License\n\nThis project is licensed under the MIT license.\n\n## Usage - new project\n\nIn the below sections it is explained how to generate a new Python package with\nthis project. When generating a new package, the tool will request a series of\ninputs, such as the package name, description, author, whether to include\ncertain tooling, etc.\n\n### By cloning this repo\n\n1. Clone this repository on your local machine\n2. In the local repository root, run `make generate`\n    This will create the new project in the repo root, in order to specify a\n    target directory, run with `make generate TARGET_DIR=\"/path/to/dir\"`\n\n_Note: using the above `make generate` target, the `cookiecutter` package will\nbe installed automatically._\n\n### By manually installing `cookiecutter`\n\n1. Install `cookiecutter` with `pip install cookiecutter`\n2. Run `cookiecutter \u003crepository URL\u003e`\n\nTo see what options `cookiecutter` offers (eg. output/target directory,\nverbosit, etc.), run `cookiecutter --help`.\n\n### Remove clutter\n\nIn order to be able to test that the package is generated correctly and linting\nand tests can be run, there is a `dummy.py` and a corresponding `test_dummy.py`\nfile generated. This is exactly what the name suggests and should be removed.\n\n### Pushing to Git\n\nMake sure you have created a new repository in GitLab/GitHub/etc. already.\n\nAfter having the desired package generated you can\n* Run `git init` in the new project root and add the existing remote repository\nwith `git remote add origin \u003crepository URL\u003e`\n* Or if you have the empty repository already cloned on your machine, copy the\ngenerated files to the cloned local repository\n* Then all you have to do is push\n\n## Usage - existing project\n\nSince many times we want to improve existing projects instead of generating a\nnew one, this tool can also be used to do so, with some extra manual steps\nalong the way.\n\nSo in case you wish to migrate an existing Python project to comply with this\ntemplate, do the following steps\n\n1. Clone the existing repository\n2. Make sure you are able to use this project on your machine (see the usage\nfor a new project above: clone/install cookiecutter)\n3. Generate a new empty project, with the same name as your existing one\n(this is an important step, since later you don't want to manually modify the\n``Makefile`` and ``setup.py`` too much)\n4. From the generated project, move the following files, as-is to your existing\nlocal repository\n    * ``.gitignore`` (just to be sure, diff it in case your project contains\n    more ignored patterns than the new one)\n    * ``Makefile``\n    * ``pylintrc`` (if applicable)\n    * ``tests`` (if it doesn't exist yet)\n5. Rename the existing ``setup.py`` to ``setup.py.bak``\n6. Move the generated ``setup.py`` to the existing local repository\n7. Merge ``setup.py.bak`` into ``setup.py``\n    * Move entry points\n    * Change description if needed\n    * Adjust the `packages` parameter of the `setup(...)` call if needed,\n    although `find_packages()` should suffice in 99% of cases\n    * Update the `install_requires` parameter with the requirements of the\n    existing package\n    * Create a ``metadata.py`` within the new project's main Python package and\n    make sure the version is correct (`VERSION` and `__version__` parameters)\n    * Make sure you don't lose any extras that are in the setup file, such as\n    extra package data, reference to ``MANIFEST.in``, etc.\n8. Remove ``setup.py.bak``\n9. Remove ``tests/test_dummy.py`` and make there is at least one test to be run\n10. Do a sanity check on the make targets\n    * format\n    * lint\n    * test\n    * build\n    * clean\n11. Make sure tests and linting are green - it could be that making linting\npass requires a bit of manual work in the code\n    * `flake8`, `pylint`, `black` errors should be easy to fix or explicitly\n    ignore (note that `pylint` errors/warnings that cannot be immediately fixed\n    are usually caused by some deeper design smell in the code, maybe just\n    ignore these at first and come back to fixing them later)\n    * `mypy` can break if some dependencies are not implementing type hinting\n    in this case check out the\n    [documentation](https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports)\n    to explicitly ignore import problems related to this\n12. Remove the newly generated project\n\n## About the contents of this repository\n\nThis project makes use of the following tools (similarly to the generated\nPython package - see below):\n* `make`\n* `cookiecutter`\n* `pytest`\n* `pytest-cookies`\n* `pylint`\n* `black`\n* `flake8`\n* `mypy`\n\nThese are the most notable components:\n* `{{cookiecutter.package_name}}` - the directory containing the actual\nblueprint of the project to be generated, file names and contents are\nessentially Jinja2 templates, which are filled in by `cookiecutter`\n* `hooks` - contains pre-generation and post-generation Python scripts to\nensure the new project contains what it needs to contain\n* `tests` - contains a set of automated tests that ensure project generation is\ncorrect\n* `cookiecutter.json` - configuration file for `cookiecutter` with default\nvalues of project parameters\n\nIn order to easily test proper generation of a Python project, a `pytest`\nplugin, `pytest-cookies` is used. This provides a `cookies` fixture, which is\ninjected into the test cases during runtime, making it really easy to test-run\nthe `cookiecutter` template in an auto-generated location.\n\n## About the generated Python project\n\nOne of the goals of this, besides providing uniform tooling to all new Python\npackages is to define and create a common interface for all projects so they\ncan be plugged in to the same CI/CD pipeline (template).\n\nBelow are the main `make` targets and the tools used within:\n\n* `lint` - to ensure compliance to coding standards\n    * `flake8` - PEP8 style checker, to ensure a standard code format that is\n    familiar to all Python developers and easy to read\n    * `black` - also a PEP8 checker and autoformatter; because PEP8 compliance\n    still leaves a lot of flexibility and there are as many preferences as\n    developers, we use this tool because it is already opinionated so you don't\n    have to be\n    * `pylint` - linting, error and duplication detection and very much\n    customizable; the generated project contains a minimal, but decent\n    `pylintrc` configuration file; its usage is optional, can be decided upon\n    project generation, however highly recommended and turned on by default\n    * `mypy` - type checker, the de facto standard at the moment\n* `format` - to easily comply with the above standards at the push of a button\n    * `black` - because of the reasons mentioned above\n* `test` - to verify functionality at the smallest level of granularity (unit)\n    * `pytest` - at the moment this is one of the best test-runner tools\n    available; besides that it provides a powerful test fixture mechanism\n    (this should be used sparingly though, if the builtin `unittest` library\n    doesn't suffice - although this is a matter of taste to some extent)\n    * `pytest-cov` - plugin of `pytest` to provide coverage metrics\n* `clean` - to clean the working directory by removing generated files,\nreports, etc.\n* `build` - to create a standard, distributable Python package\n    * `wheel` - this is the current standard for creating distributables\n\n_Note: the targets `lint`, `test` and `build` have a corresponding\n`install_\u003ctarget\u003e_requirements` target to install extra dependencies. These are\nindividually defined in the generated project's `setup.py` as well as extra\nrequirements. There is no need to call the install targets on their own, they\nare called automatically in their related main target._\n\n### Future extension\n\nNew linters can be easily added by extending the `Makefile`, potentially made\noptional (just as with `pylint`).\n\nCurrently in the created project there is only one `test` target which is\nintendet to be used to run a set of automated tests in the \"commit phase\".\nHowever eventually there should be more testing targets created, thus\nseparating different levels of automated tests, such as\n* Integration tests (`test-integration`) - automatically verifying the\napplication is piped correctly to other system components\n* Acceptance tests (`test-acceptance` target) - automatically verifying\nfunctional and non-functional requirements, potentially in a BDD style\n* Capacity tests (`test-capacity` target) - automatically verifying that an\napplication is able to handle load according to requirements\n* Security (`security` target), to run some automated security tooling\n(eg. Snyk or BlackDuck) to reveal potential vurnelabilities in the application\ncode itself or introduced by dependencies\n\nIn addition to this we could introduce automated documentation generation in\nthe created project, using [Sphinx](http://www.sphinx-doc.org/en/master/) via\na `make docs` target. For this we will need some storage to be able to host the\ngenerated docs and push to it from Python projects upon a successful master\nbuild.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmendix%2Fpython-project-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmendix%2Fpython-project-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmendix%2Fpython-project-template/lists"}