{"id":20325762,"url":"https://github.com/aboutcode-org/pip-requirements-parser","last_synced_at":"2026-03-11T03:02:48.066Z","repository":{"id":43261574,"uuid":"448383893","full_name":"aboutcode-org/pip-requirements-parser","owner":"aboutcode-org","description":"a mostly correct pip requirements parsing library","archived":false,"fork":false,"pushed_at":"2024-09-02T08:26:16.000Z","size":3411,"stargazers_count":20,"open_issues_count":18,"forks_count":13,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-06T12:07:03.414Z","etag":null,"topics":[],"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/aboutcode-org.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.rst","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}},"created_at":"2022-01-15T20:29:18.000Z","updated_at":"2026-02-24T18:55:49.000Z","dependencies_parsed_at":"2023-02-02T19:00:47.244Z","dependency_job_id":"60191c40-f335-4d73-8133-d5264cc9ded5","html_url":"https://github.com/aboutcode-org/pip-requirements-parser","commit_stats":{"total_commits":2005,"total_committers":231,"mean_commits":8.67965367965368,"dds":0.8962593516209476,"last_synced_commit":"c009a483a899f0b39b474be434ef5c9cf7fe0a41"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":"aboutcode-org/skeleton","purl":"pkg:github/aboutcode-org/pip-requirements-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutcode-org%2Fpip-requirements-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutcode-org%2Fpip-requirements-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutcode-org%2Fpip-requirements-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutcode-org%2Fpip-requirements-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aboutcode-org","download_url":"https://codeload.github.com/aboutcode-org/pip-requirements-parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutcode-org%2Fpip-requirements-parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30368572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"online","status_checked_at":"2026-03-11T02:00:07.027Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":"2024-11-14T19:41:32.311Z","updated_at":"2026-03-11T03:02:48.046Z","avatar_url":"https://github.com/aboutcode-org.png","language":"Python","readme":"pip-requirements-parser - a mostly correct pip requirements parsing library\n================================================================================\n\nCopyright (c) nexB Inc. and others.\nCopyright (c) The pip developers (see AUTHORS.rst file)\nSPDX-License-Identifier: MIT\nHomepage: https://github.com/aboutcode-org/pip-requirements and https://www.aboutcode.org/\n\n\n``pip-requirements-parser`` is a mostly correct pip requirements parsing\nlibrary ... because it uses pip's own code!\n\npip is the ``package installer`` for Python that is using \"requirements\" text\nfiles listing the packages to install.\n\nPer https://pip.pypa.io/en/stable/reference/requirements-file-format/ :\n\n    \"The requirements file format is closely tied to a number of internal\n    details of pip (e.g., pip’s command line options). The basic format is\n    relatively stable and portable but the full syntax, as described here,\n    is only intended for consumption by pip, and other tools should take\n    that into account before using it for their own purposes.\"\n\nAnd per https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program :\n\n    \"[..] pip is a command line program. While it is implemented in Python, and\n    so is available from your Python code via import pip, you must not use pip’s\n    internal APIs in this way.\"\n\n    \"What this means in practice is that everything inside of pip is considered\n    an implementation detail. Even the fact that the import name is pip is\n    subject to change without notice. While we do try not to break things as\n    much as possible, all the internal APIs can change at any time, for any\n    reason. It also means that we generally won’t fix issues that are a result\n    of using pip in an unsupported way.\"\n\n\nBecause of all this, pip requirements are notoriously difficult to parse right\nin all their diversity because:\n\n- pip does not have a public API and therefore cannot be reliably used as a\n  stable library. Some libraries attempt to do this though. (See Alternative)\n\n- The pip requirements file syntax is closely aligned with pip's command line\n  interface and command line options. In some ways a pip requirements file is a\n  list of pip command line options and arguments. Therefore, it is hard to parse\n  these short of reproducing the pip command line options parsing. At least one\n  other library is using a command line option parser to parse options correctly.\n\n\nThis ``pip-requirements-parser`` Python library is yet another pip requirements\nfiles parser, but this time doing it hopefully correctly and doing as well as\npip does it, because this is using pip's own code.\n\n\nThe ``pip-requirements-parser`` library offers these key advantages:\n\n- Other requirements parsers typically do not work in all the cases that ``pip``\n  supports: parsing any requirement as seen in the wild will fail parsing some\n  valid pip requirements. Since the ``pip-requirements-parser`` library is based\n  on pip's own code, it works **exactly** like pip and will parse all the\n  requirements files that pip can parse.\n\n- The ``pip-requirements-parser`` library offers a simple and stable code API\n  that will not change without notice.\n\n- The ``pip-requirements-parser`` library is designed to work offline without\n  making any external network call, while the original pip code needs network\n  access.\n\n- The ``pip-requirements-parser`` library is a single file that can easily be\n  copied around as needed for easy vendoring. This is useful as requirements\n  parsing is often needed to bootstrap in a constrained environment.\n\n- The ``pip-requirements-parser`` library has only one external dependency on\n  the common \"packaging\" package. Otherwise it uses only the standard library.\n  The benefits are the same as being a single file: fewer moving parts helps with\n  using it in more cases.\n\n- The ``pip-requirements-parser`` library reuses and passes the full subset of\n  the pip test suite that deals with requirements. This is a not really\n  surprising since this is pip's own code. The suite suite has been carefully\n  ported and adjusted to work with the updated code subset.\n\n- The standard pip requirements parser depends on the ``requests`` HTTP library\n  and makes network connection to PyPI and other referenced repositories when\n  parsing. The ``pip-requirements-parser`` library works entirely offline and the\n  requests dependency and calling has been entirely removed.\n\n- The ``pip-requirements-parser`` library has preserved the complete pip git\n  history for the subset of the code we kept. The original pip code was merged\n  from multiple modules keeping all the git history at the line/blame level using\n  some git fu and git filter repo. The benefit is that we will be able to more\n  easily track and merge future pip updates.\n\n- The ``pip-requirements-parser`` library has an extensive test suite  made of:\n\n  - pip's own tests\n  - new unit tests\n  - new requirements test files (over 40 new test files)\n  - the tests suite of some of the main other requirement parsers including:\n\n     - http://github.com/di/pip-api\n     - https://github.com/pyupio/dparse\n     - https://github.com/landscapeio/requirements-detector\n     - https://github.com/madpah/requirements-parser\n\nAs a result, it has likely the most comprehensive requiremente parsing test\nsuite around.\n\n\nUsage\n~~~~~~~~~~\n\nThe entry point is the ``RequirementsFile`` object::\n\n    \u003e\u003e\u003e from pip_requirements_parser import RequirementsFile\n    \u003e\u003e\u003e rf = RequirementsFile.from_file(\"requirements.txt\")\n\nFrom there, you can dump to a dict::\n    \u003e\u003e\u003e rf.to_dict()\n\nOr access the requirements (either InstallRequirement or EditableRequirement\nobjects)::\n\n    \u003e\u003e\u003e for req in rf.requirements:\n    ...    print(req.to_dict())\n    ...    print(req.dumps())\n\nAnd the various other parsed elements such as options, commenst and invalid lines\nthat have a parsing error::\n\n    \u003e\u003e\u003e rf.options\n    \u003e\u003e\u003e rf.comment_lines\n    \u003e\u003e\u003e rf.invalid_lines\n\nEach of these and the ``requirements`` hahve a \"requirement_line\" attribute\nwith the original text.\n\nFinally you can get a requirements file back as a string::\n\n    \u003e\u003e\u003e rf.dumps()\n\n\nAlternative\n------------------\n\nThere are several other parsers that either:\n\n- Implement their own parsing and can therefore miss some subtle differences\n- Or wrap and import pip as a library, working around the lack of pip API\n\nNone of these use the approach of reusing and forking the subset of pip that is\nneeded to parse requirements.  The ones that wrap pip require network access\nlike pip does. They potentially need updating each time there is a new pip\nrelease. The ones that reimplement pip parsing may not support all pip\nspecifics.\n\n\nImplement a new pip parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- pip-api https://github.com/di/pip-api does not support hashes and certain pip options.\n  It does however use argparse for parsing options and is therefore correctly\n  handling most options. The parser is a single script that only depends on\n  packaging (that is vendored). It is not designed to be used as a single script\n  though and ``pip`` is a dependency.\n\n- requirements-parser https://github.com/madpah/requirements-parse does not\n  support hashes and certain pip options\n\n- dparse https://github.com/pyupio/dparse\n\n- https://github.com/GoogleCloudPlatform/django-cloud-deploy/blob/d316b1e45357761e2b124143e6e12ce34ef6f975/django_cloud_deploy/skeleton/requirements_parser.py\n\n\nReuse and wrap pip's own parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- requirementslib https://github.com/sarugaku/requirementslib uses pip-shim\n  https://github.com/sarugaku/pip-shims which is a set of \"shims\" around each\n  pip versions in an attempt to offer an API to pip. Comes with 20+ dependencies,\n\n- micropipenv https://github.com/thoth-station/micropipenv/blob/d0c37c1bf0aadf5149aebe2df0bf1cb12ded4c40/micropipenv.py#L53\n\n- pip-tools https://github.com/jazzband/pip-tools/blob/9e1be05375104c56e07cdb0904e1b50b86f8b550/piptools/_compat/pip_compat.py\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboutcode-org%2Fpip-requirements-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faboutcode-org%2Fpip-requirements-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboutcode-org%2Fpip-requirements-parser/lists"}