A requirements.txt that says flask>=2.0 is a promise to install whatever is newest on the day someone runs pip install. That is fine for a notebook and a risk for anything you deploy. Three changes make an install repeatable and much harder to tamper with.
--extra-index-url) that lets a same-named public package outrank yours.--trusted-host, which removes TLS protection.#sha256= hash.>=, ~=, < or wildcard range that lets the resolved version drift.--hash (only reported with the require-hashes option).-e install that cannot be reproduced from a registry.requirements.in (flask>=2.0) and generate the locked file: pip-compile --generate-hashes requirements.in or uv pip compile --generate-hashes requirements.in -o requirements.txt.pip install --require-hashes -r requirements.txt so any file that does not match its hash fails the build.--extra-index-url.node requirements-check.mjs --fail-on medium to CI so a loose line cannot be committed silently.It scans the text of the file. It does not run pip's resolver, read transitive dependencies, or check pinned versions against a vulnerability database, so a fully pinned file can still contain a vulnerable release. It is a heuristic and is not security advice.