Search code examples
pythonpypisoftware-distributiondeb

How to find existing deb package corresponding to PyPI entry?


PyPI has a lot of packages, and many of them do have deb-equivalents for specific Debian distributions. It usually happens by prepending python- or python3- to the name of the original package, possibly with some other changes like lowercasing, etc, but not always.

Is there are good way to establish PyPI -> Debian version X correspondence in an automatic way?

For example, given a requirements.txt file (or a result of running pip freeze), are there any tools to list Debian packages?

Maybe, there is some service, which can, given "PyPI name", returns search result for Debian? I am not that familiar with Debian tools, but maybe there is a tool, which automates it as part of some process Debian uses?

For example: alembic package. Source package is a basis to create python-prefixed packages. And description points to where it was taken from. Then on PyPI there is a page for specific version files (and maybe a metadata description somewhere).

Can't find it with googling as search results turn out a lot of how to do your very own package, which is a different topic.

The process so far is time-consuming and heavily manual, using apt-file search -l to query for packages containing certain files.


Solution

  • Inspired by this answer: https://askubuntu.com/a/1912

    $ apt-file --package-only --regex search 'alembic\-.*\.egg\-info'
    python-alembic
    python3-alembic
    $ apt-file --package-only --regex search 'setuptools\-.*\.egg\-info'
    pypy-setuptools
    python-setuptools
    python3-setuptools
    

    Not sure about the regular expression, most likely it can be improved a lot.


    Short Python wrapper script as an example:

    import argparse
    import subprocess
    
    import pkg_resources  # from 'setuptools'
    
    
    def _main():
        parser = argparse.ArgumentParser(allow_abbrev=False)
        parser.add_argument(
            'requirements',
            metavar='requirements.txt',
            type=argparse.FileType('r'),
        )
        args = parser.parse_args()
        #
        requirements = [
            requirement.project_name
            for requirement
            in pkg_resources.parse_requirements(args.requirements)
        ]
        print(requirements)
        #
        regex = r'({})\-.*\.egg\-info'.format(
            '|'.join(
                [
                    requirement.replace('-', '_')
                    for requirement
                    in requirements
                ],
            ),
        )
        #
        output = subprocess.check_output(
            [
                'apt-file',
                '--package-only',
                '--regex',
                'search',
                regex,
            ],
        )
        print(output.decode())
    
    
    if __name__ == '__main__':
        _main()