{"id":17277894,"url":"https://github.com/abravalheri/validate-pyproject","last_synced_at":"2026-02-02T19:03:30.267Z","repository":{"id":37956501,"uuid":"419090643","full_name":"abravalheri/validate-pyproject","owner":"abravalheri","description":"Validation library for simple check on `pyproject.toml`","archived":false,"fork":false,"pushed_at":"2026-01-21T17:08:25.000Z","size":705,"stargazers_count":198,"open_issues_count":13,"forks_count":21,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-22T05:09:04.186Z","etag":null,"topics":["pep517","pep518","pep621","pyproject","toml"],"latest_commit_sha":null,"homepage":"https://validate-pyproject.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abravalheri.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.rst","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.txt","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-19T21:05:00.000Z","updated_at":"2026-01-21T17:08:32.000Z","dependencies_parsed_at":"2023-10-11T13:25:07.570Z","dependency_job_id":"68b069ff-14b6-416c-97f9-fd75cca01050","html_url":"https://github.com/abravalheri/validate-pyproject","commit_stats":{"total_commits":499,"total_committers":15,"mean_commits":"33.266666666666666","dds":0.2525050100200401,"last_synced_commit":"db197f4a7d76133e864a2a4d555642d231791caa"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/abravalheri/validate-pyproject","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abravalheri%2Fvalidate-pyproject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abravalheri%2Fvalidate-pyproject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abravalheri%2Fvalidate-pyproject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abravalheri%2Fvalidate-pyproject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abravalheri","download_url":"https://codeload.github.com/abravalheri/validate-pyproject/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abravalheri%2Fvalidate-pyproject/sbom","scorecard":{"id":161643,"data":{"date":"2025-08-11","repo":{"name":"github.com/abravalheri/validate-pyproject","commit":"861bf8e29e487baf23527fdcd3dab1355fe46ee5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.4,"checks":[{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":7,"reason":"Found 7/9 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:82: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:85: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:87: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:90: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:103: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:115: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:125: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:126: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:128: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:130: update your workflow using https://app.stepsecurity.io/secureworkflow/abravalheri/validate-pyproject/ci.yml/main?enable=pin","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T13:38:12.575Z","repository_id":37956501,"created_at":"2025-08-16T13:38:12.576Z","updated_at":"2025-08-16T13:38:12.576Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29017940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T18:51:31.335Z","status":"ssl_error","status_checked_at":"2026-02-02T18:49:20.777Z","response_time":58,"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":["pep517","pep518","pep621","pyproject","toml"],"created_at":"2024-10-15T09:10:19.313Z","updated_at":"2026-02-02T19:03:30.260Z","avatar_url":"https://github.com/abravalheri.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":".. These are examples of badges you might want to add to your README:\n   please update the URLs accordingly\n\n    .. image:: https://img.shields.io/conda/vn/conda-forge/validate-pyproject.svg\n        :alt: Conda-Forge\n        :target: https://anaconda.org/conda-forge/validate-pyproject\n    .. image:: https://pepy.tech/badge/validate-pyproject/month\n        :alt: Monthly Downloads\n        :target: https://pepy.tech/project/validate-pyproject\n    .. image:: https://img.shields.io/twitter/url/http/shields.io.svg?style=social\u0026label=Twitter\n        :alt: Twitter\n        :target: https://twitter.com/validate-pyproject\n\n.. image:: https://img.shields.io/badge/-PyScaffold-005CA0?logo=pyscaffold\n    :alt: Project generated with PyScaffold\n    :target: https://pyscaffold.org/\n.. image:: https://api.cirrus-ci.com/github/abravalheri/validate-pyproject.svg?branch=main\n    :alt: Built Status\n    :target: https://cirrus-ci.com/github/abravalheri/validate-pyproject\n.. image:: https://readthedocs.org/projects/validate-pyproject/badge/?version=latest\n    :alt: ReadTheDocs\n    :target: https://validate-pyproject.readthedocs.io\n.. image:: https://img.shields.io/coveralls/github/abravalheri/validate-pyproject/main.svg\n    :alt: Coveralls\n    :target: https://coveralls.io/r/abravalheri/validate-pyproject\n.. image:: https://img.shields.io/pypi/v/validate-pyproject.svg\n    :alt: PyPI-Server\n    :target: https://pypi.org/project/validate-pyproject/\n\n|\n\n==================\nvalidate-pyproject\n==================\n\n\n    Automated checks on ``pyproject.toml`` powered by JSON Schema definitions\n\n\n.. important:: This project is **experimental** and under active development.\n   Issue reports and contributions are very welcome.\n\n\nDescription\n===========\n\nWith the approval of `PEP 517`_ and `PEP 518`_, the Python community shifted\ntowards a strong focus on standardisation for packaging software, which allows\nmore freedom when choosing tools during development and make sure packages\ncreated using different technologies can interoperate without the need for\ncustom installation procedures.\n\nThis shift became even more clear when `PEP 621`_ was also approved, as a\nstandardised way of specifying project metadata and dependencies.\n\n``validate-pyproject`` was born in this context, with the mission of validating\n``pyproject.toml`` files, and make sure they are compliant with the standards\nand PEPs. Behind the scenes, ``validate-pyproject`` relies on `JSON Schema`_\nfiles, which, in turn, are also a standardised way of checking if a given data\nstructure complies with a certain specification.\n\n\n.. _installation:\n\nUsage\n=====\n\nThe easiest way of using ``validate-pyproject`` is via CLI.\nTo get started, you need to install the package, which can be easily done\nusing |pipx|_:\n\n.. code-block:: bash\n\n    $ pipx install 'validate-pyproject[all]'\n    # or to install and run in a single command\n    $ pipx run 'validate-pyproject[all]' --help\n\nNow you can use ``validate-pyproject`` as a command line tool:\n\n.. code-block:: bash\n\n    # in you terminal\n    $ validate-pyproject --help\n    $ validate-pyproject path/to/your/pyproject.toml\n\nYou can also use ``validate-pyproject`` in your Python scripts or projects:\n\n.. _example-api:\n\n.. code-block:: python\n\n    # in your python code\n    from validate_pyproject import api, errors\n\n    # let's assume that you have access to a `loads` function\n    # responsible for parsing a string representing the TOML file\n    # (you can check the `toml` or `tomli` projects for that)\n    pyproject_as_dict = loads(pyproject_toml_str)\n\n    # now we can use validate-pyproject\n    validator = api.Validator()\n\n    try:\n        validator(pyproject_as_dict)\n    except errors.ValidationError as ex:\n        print(f\"Invalid Document: {ex.message}\")\n\nTo do so, don't forget to add it to your `virtual environment`_ or specify it as a\n`project`_ or `library dependency`_.\n\n.. note::\n   When you install ``validate-pyproject[all]``, the packages ``tomli``,\n   ``packaging`` and ``trove-classifiers`` will be automatically pulled as\n   dependencies. ``tomli`` is a lightweight parser for TOML, while\n   ``packaging`` and ``trove-classifiers`` are used to validate aspects of `PEP\n   621`_.\n\n   If you are only interested in using the Python API and wants to keep the\n   dependencies minimal, you can also install ``validate-pyproject``\n   (without the ``[all]`` extra dependencies group).\n\n   If you don't install ``trove-classifiers``, ``validate-pyproject`` will\n   try to download a list of valid classifiers directly from PyPI\n   (to prevent that, set the environment variable\n   ``NO_NETWORK`` or ``VALIDATE_PYPROJECT_NO_NETWORK``).\n\n   On the other hand, if ``validate-pyproject`` cannot find a copy of\n   ``packaging`` in your environment, the validation will fail.\n\nMore details about ``validate-pyproject`` and its Python API can be found in\n`our docs`_, which includes a description of the `used JSON schemas`_,\ninstructions for using it in a |pre-compiled way|_ and information about\nextending the validation with your own plugins_.\n\n.. _pyscaffold-notes:\n\n.. tip::\n   If you consider contributing to this project, have a look on our\n   `contribution guides`_.\n\nPlugins\n=======\n\nThe `validate-pyproject-schema-store`_ plugin has a vendored copy of\npyproject.toml related `SchemaStore`_ entries.  You can even install this using\nthe ``[store]`` extra:\n\n    $ pipx install 'validate-pyproject[all,store]'\n\nSome of the tools in SchemaStore also have integrated validate-pyproject\nplugins, like ``cibuildwheel`` and ``scikit-build-core``. However, unless you\nwant to pin an exact version of those tools, the SchemaStore copy is lighter\nweight than installing the entire package.\n\nIf you want to write a custom plugin for your tool, please consider also contributing a copy to SchemaStore.\n\npre-commit\n==========\n\n``validate-pyproject`` can be installed as a pre-commit hook:\n\n.. code-block:: yaml\n\n    ---\n    repos:\n      - repo: https://github.com/abravalheri/validate-pyproject\n        rev: \u003cinsert current version here\u003e\n        hooks:\n          - id: validate-pyproject\n            # Optional extra validations from SchemaStore:\n            additional_dependencies: [\"validate-pyproject-schema-store[all]\"]\n\nBy default, this ``pre-commit`` hook will only validate the ``pyproject.toml``\nfile at the root of the project repository.\nYou can customize that by defining a `custom regular expression pattern`_ using\nthe ``files`` parameter.\n\nYou can also use ``pre-commit autoupdate`` to update to the latest stable\nversion of ``validate-pyproject`` (recommended).\n\nYou can also use `validate-pyproject-schema-store`_ as a pre-commit hook, which\nallows pre-commit to pin and update that instead of ``validate-pyproject`` itself.\n\nNote\n====\n\nThis project and its sister project ini2toml_ were initially created in the\ncontext of PyScaffold, with the purpose of helping migrating existing projects\nto `PEP 621`_-style configuration when it is made available on ``setuptools``.\nFor details and usage information on PyScaffold see https://pyscaffold.org/.\n\n\n.. |pipx| replace:: ``pipx``\n.. |pre-compiled way| replace:: *pre-compiled* way\n\n\n.. _contribution guides: https://validate-pyproject.readthedocs.io/en/latest/contributing.html\n.. _custom regular expression pattern: https://pre-commit.com/#regular-expressions\n.. _our docs: https://validate-pyproject.readthedocs.io\n.. _ini2toml: https://ini2toml.readthedocs.io\n.. _JSON Schema: https://json-schema.org/\n.. _library dependency: https://setuptools.pypa.io/en/latest/userguide/dependency_management.html\n.. _PEP 517: https://peps.python.org/pep-0517/\n.. _PEP 518: https://peps.python.org/pep-0518/\n.. _PEP 621: https://peps.python.org/pep-0621/\n.. _pipx: https://pipx.pypa.io/stable/\n.. _project: https://packaging.python.org/tutorials/managing-dependencies/\n.. _setuptools: https://setuptools.pypa.io/en/stable/\n.. _used JSON schemas: https://validate-pyproject.readthedocs.io/en/latest/schemas.html\n.. _pre-compiled way: https://validate-pyproject.readthedocs.io/en/latest/embedding.html\n.. _plugins: https://validate-pyproject.readthedocs.io/en/latest/dev-guide.html\n.. _virtual environment: https://realpython.com/python-virtual-environments-a-primer/\n.. _validate-pyproject-schema-store: https://github.com/henryiii/validate-pyproject-schema-store\n.. _SchemaStore: https://www.schemastore.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabravalheri%2Fvalidate-pyproject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabravalheri%2Fvalidate-pyproject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabravalheri%2Fvalidate-pyproject/lists"}