Package: hashin
Helps you write yourrequirements.txtwith hashes so you can
install withpip install--require-hashes-r...If you want to add a package or edit the version of one you’re currently
using you have to do the following steps:Go to pypi for that packageDownload the.tgzfilePossibly download the.whlfileRunpip hashdownloadedpackage-1.2.3.tgzRunpip hashdownloadedpackage-1.2.3.whlEditrequirements.txtThis script does all those things.
Hackishly wonderfully so.A Word of Warning!The whole point of hashing is that youvet the packagesthat you use
on your laptop and that they haven’t been tampered with. Then you
can confidently install them on a server.This tool downloads from PyPI (over HTTPS) and runspip hashon the downloaded files.You should check that the packages that are downloaded
are sane and not tampered with. The way you do that is to runhashinas normal but with the--verboseflag. When you do that
it will print where it downloaded the relevant files and those
files are not deleted. For example:$ hashin --verbose bgg /tmp/reqs.txt
https://pypi.python.org/pypi/bgg/json
* Latest version for 0.22.1
* Found URL https://pypi.python.org/packages/2.7/b/bgg/bgg-0.22.1-py2-none-any.whl
*   Re-using /var/folders/1x/2hf5hbs902q54g3bgby5bzt40000gn/T/bgg-0.22.1-py2-none-any.whl
*   Hash e5172c3fda0e8a42d1797fd1ff75245c3953d7c8574089a41a219204dbaad83d
* Found URL https://pypi.python.org/packages/source/b/bgg/bgg-0.22.1.tar.gz
*   Re-using /var/folders/1x/2hf5hbs902q54g3bgby5bzt40000gn/T/bgg-0.22.1.tar.gz
*   Hash aaa53aea1cecb8a6e1288d6bfe52a51408a264a97d5c865c38b34ae16c9bff88
* Editing /tmp/reqs.txtYou might not have time to go through the lines one by one
but you should be aware that the vetting process is your
responsibility.InstallationThis is something you only do or ever need in a development
environment. Ie. your laptop:pip install hashinHow to use itSuppose you want to installfutures. You can either do this:hashin futuresWhich will download the latest version tarball (and wheel) and
calculate their pip hash and edit yourrequirements.txtfile.Or you can be specific about exactly which version you want:hashin "futures==2.1.3"You can also specify more than one package at a time:hashin "futures==2.1.3" requestsSuppose you don’t have arequirements.txtright there in the same
directory you can specify--requirements-file:hashin futures --requirements-file=stuff/requirements/prod.txtBy defaultsha256hashes are used, but this can be overridden using the--algorithmargument:hashin futures --algorithm=sha512If there’s no output, it worked. Check how it edited your
requirements file.Filtering releases by Python versionSome requirements have many releases built for different versions of Python and
different architectures. These hashes aren’t useful in some cases, if those
wheels don’t work with your project.hashincan filter on the Python
version to skip these extraneous hashes.For example, thecffipackage offers wheels built for many versions of
CPython from 2.6 to 3.5. To select only one of them, you can use the--python-versionoption:hashin "cffi==1.5.2" --python-version 3.5If you need to support multiple versions, you can pass this option multiple
times:hashin "cffi==1.5.2" --python-version 2.7 --python-version 3.5hashinwill expand these Python versions to a full list of identifers that
could be found on PyPI. For example,3.5will expand to match any of3.5,py3,py3.5,py2.py3, orcp3.5. You can also specify
these exact identifiers directly, if you need something specific.Thesourcerelease is always automatically included.pipwill use
this as a fallback in the case a suitable wheel cannot be found.Dry run modeThere are some use cases, when you maybe don’t want to edit yourrequirements.txtright away. You can use the--dry-runargument to show the diff, so you
can preview the changes to yourrequirements.txtfile.Example:hashin --dry-run requests==2.19.1Would result in a printout on the command line:--- Old
+++ New
@@ -0,0 +1,3 @@
+requests==2.19.1 \
+    --hash=sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1 \
+    --hash=sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6aPEP-0496 Environment MarkersRequirements can usePEP-0496style specifiers (e.g. likecffi==1.5.2;python_version >= '3.4') and these will be passed
through when re-writing therequirements.txtfile.hashindoesn’t
parse the specifiers themselves and will take anything after the
semicolon. If you are usingpython_versionyou will still need to
pass appropriate options if you don’t want every available hash.An example of this might be:hashin "pywin32-ctypes ; sys_platform == 'win32'"which will result it something like this in therequirements.txtfile:pywin32-ctypes==0.1.2; sys_platform == 'win32' \
    --hash=sha256:4820b830f42e6889d34142bcd07b3896018c3620d8c31f5e13b72caf1f4d1d0fAnd if you want to limit it to certain Python versions, here’s an example:hashin "cffi==1.5.2; python_version >= '3.4'" -p 3.4 -p 3.5Using as a Python libraryEverything you can do withhashinon the command line you can do
in running Python too. For example:import hashin
from pprint import pprint
pprint(hashin.get_package_hashes('Django'))This will print out:{'hashes': [{'hash': 'fbc7ffaa45a4a67cb45f77dbd94e8eceecebe1d0959fe9c665dfbf28b41899e6',
         'url': 'https://pypi.python.org/packages/41/c1/68dd27946b03a3d756b0ff665baad25aee1f59918891d86ab76764209208/Django-1.11b1-py2.py3-none-any.whl'}],
'package': 'Django',
'version': '1.11b1'}Or with specific version, algorithm and certain Python versions:import hashin
from pprint import pprint
pprint(hashin.get_package_hashes(
    'Django',
    version='1.10',
    algorithm='sha512',
    python_versions=('3.5',)
))Local developmentAfter you have cloned the project, created a virtual environment and run:pip install -e “.[dev]”Now, to run it you can use the installed executablehashinand do things
like:touch /tmp/reqs.txt
hashin -r /tmp/reqs.txt DjangoRunning testsSimply run:python setup.py testWhen you usepip install".[dev]"it will installtoxwhich you can use
to run the full test suites (plus linting) in different Python environments:toxRunning tests with test coverageTo run the tests with test coverage, withpytestrun something like
this:$ pip install pytest-cover
$ pytest --cov=hashin --cov-report=html
$ open htmlcov/index.htmlDebuggingTo avoid having to installhashinjust to test it or debug a feature
you can simply just run it like this:touch /tmp/whatever.txt
python hashin.py --verbose Django /tmp/whatever.txtCode StyleAll Python code should be run throughBlack.
This is checked in CI and you can test it locally withtox.Also, this project usestherapistwhich helps with checking code style as a git pre-commit hook.therapistis used intox. To run all code style checks, usetox-elintbut
make sure your version oftoxis built on a Python 3.HistoryThis program is a “fork” ofhttps://pypi.python.org/pypi/peepinpeepinwas a companion to the programpeephttps://pypi.python.org/pypi/peep/but the functionality ofpeephas been put directly intopipas of version 8.FutureIf this script proves itself to work and be useful, I hope we can
put it directly intopip.Version History0.17.0Add python 3.9 and 3.10 to the test matrix.Preserve lexigraphical order of hashes for the output of theget_releases_hashesfunction.
Seehttps://github.com/peterbe/hashin/issues/1260.16.0Preserve indented comments when updating requirements files.
Seehttps://github.com/peterbe/hashin/issues/124Switch to GitHub Actions instead of TravisCI. And testtoxin
Python 3.7 and 3.8 additionally as well as upgrading lint requirements.
Seehttps://github.com/peterbe/hashin/pull/1180.15.0Use of underscore or hyphens in package names is corrected
Seehttps://github.com/peterbe/hashin/issues/116Thanks @caphrim0070.14.6Indentation in the requirements file is preserved.
Seehttps://github.com/peterbe/hashin/issues/112Thanks @techtonikIf you use--update-alland forget the-rwhen specifying your
requirements file, instead of complaining, it corrects the intentions.
Seehttps://github.com/peterbe/hashin/issues/1040.14.5When writing down hashes, they are now done in a lexigraphically ordered
way. This makes the writes to the requirements file more predictable.
Seehttps://github.com/peterbe/hashin/issues/1050.14.4Bugfix for new--index-urloption feature in version 0.14.3.
Seehttps://github.com/peterbe/hashin/issues/1080.14.3New parameter--index-urlwhich allows to override the default which
ishttps://pypi.org. Thanks @nmacinnis
Seehttps://github.com/peterbe/hashin/pull/1070.14.2When using--update-alland parsing requirements file it could be fooled
by comments that look like package specs (e.g# check outfoo==1.0)
Seehttps://github.com/peterbe/hashin/issues/1030.14.1All HTTP GET work to fetch information about packages from PyPI is done in
concurrent threads. Requires backport for Python 2.7.
Seehttps://github.com/peterbe/hashin/issues/1010.14.0--interactive(when you use--update-all) will iterate over all outdated
versions in your requirements file and ask, for each one, if you want to
updated it.
Seehttps://github.com/peterbe/hashin/issues/90Order of hashes should not affect if a package in the requirements file
should be replaced or not.
Seehttps://github.com/peterbe/hashin/issues/93(Internal) All tests have been rewritten as plain pytest functions.In Python 3, if the package can’t be found you get a more explicit exception
pointing out which package (URL) that failed.
Seehttps://github.com/peterbe/hashin/issues/87New flag--update-all(alias-u) will parse the requirements file,
ignore the version, and update all packages that have new versions.
Seehttps://github.com/peterbe/hashin/pull/88Support for “extras syntax”. E.g.hashin "requests[security]". Doesn’t
actually get hashes forsecurity(in this case, that’s not even a
package) but allows that syntax into yourrequirements.txtfile.
Seehttps://github.com/peterbe/hashin/issues/70All code is now formatted withBlack.0.13.4Ability to pass--dry-runwhich prints a diff of what itwoulddo to your requirements file. Seehttps://github.com/peterbe/hashin/pull/78Better error message when no versions, but some pre-releases found.
Seehttps://github.com/peterbe/hashin/issues/76Don’t show URLs when using--verboseif files don’t need to be
downloaded. Seehttps://github.com/peterbe/hashin/issues/730.13.3Makes it possible to installnltkon Windows.Thanks @chrispbailey!0.13.2Match Python versions aspy{major}{minor}additionally. Solves
problem with installing packages with files likePaste-2.0.3-py34-none-any.whl.Thanks @danfoster!0.13.1Ability to pass--include-prereleasesif you’re trying to add
a package thatonlyhas pre-releases.0.13.0Two new dependencies forhashin:pip-apiandpackaging.
This means we no longer need toimportpipand rely on private
APIs.Thanks @di!This also means you can no longer installhashinon Python 2.6 and
Python<=3.3.0.12.0Switch frompypi.python.org/pypi/<package>/jsontopypi.org/pypi/<package>/jsonwhich also means the sha256 hash is part
of the JSON payload immediately instead of having to download and runpipto get the hash.Testing no runs Python 2.6 and Python 3.3.All hashes, per package, are sorted (by the hash) to make it more
predictable.0.11.5You can now pass PEP-0496 Environment Markers together with the package
name, and they get passed into therequirements.txtfile.
Thanks @meejah0.11.4PackageErrors happening in CLI suppressed just the error message out on
stderr. No full traceback any more.0.11.3Better error if you typo the package name since it’ll 404 on PyPI.0.11.2Run continuous integration tests with Python 3.6 too.0.11.1Ability to runhashin--versionto see what version of hashin is
installed.
Seehttps://github.com/peterbe/hashin/issues/410.11.0Cope with leading zeros in version numbers when figuring out what
the latest version is.
Seehttps://github.com/peterbe/hashin/issues/390.10.0Latest version is now figured out by looking at all version numbers
in the list of releases from the JSON payload. The pre releases are
skipped.0.9.0Fixed a bug where it would fail to install a package whose name is
partially part of an existing (installed) package.
E.g. installingredis==x.y.zwhendjango-redis==a.b.cwas
already in the requirements file.0.8.0Ability to makehashinwork as a library. Thanks @jayfk !pep8 cleanups.0.7.2Fixes bug related to installing platform specific archives
Seehttps://github.com/peterbe/hashin/pull/33Thanks @mythmon0.7.1Package matching is now case insensitive. E.g.hashin dJaNgO0.7.0The requirements file and algorithm arguments are now keyword
arguments. Now, the second, third, nth positional argument are
additional arguments. Thanks @https://github.com/ahal0.6.1Support windows binaries packaged as a.msifile.0.6.0Fix compatibility issue with pip 8.1.2 and 8.1.1-2ubuntu0.1 and drop
support for Python 2.60.5.0Important bug fix. As an example, if you hadpytest-selenium==...already in yourrequirements.txtfile and addselenium==x.y.zit would touch the line withpytest-seleniumtoo.0.4.1Support for PyPI links that have a hash in the file URL.0.4.1Fix PackageError if no Python version is defined.0.4Add filtering of package releases by Python version.0.3Issue a warning for users of Python before version 2.7.9.0.2Last character asinglenewline. Not two.0.1First, hopefully, working version.