No 3rd-party dependencies. It's Asynchronous and Fast.
import asyncio, argparse, json, re, io from collections import namedtuple from typing import Iterable import urllib.request Package = namedtuple("Package", ["name", "version", "raw"]) placeholder = "{name:<30} {old_ver:10} {new_ver:<10}" async def get_pypi_latest_version(package: Package) -> tuple[Package, Package]: base_package, *_ = package.name.split("[") with urllib.request.urlopen(f"https://pypi.org/pypi/{base_package}/json") as f: data = json.loads(f.read()) version = data["info"]["version"] latest_package = Package(package.name, version, f"{package.name}=={version}") return package, latest_package async def fetch_all_latest_packages( packages: Iterable[Package], ) -> list[tuple[Package, Package]]: coro = (get_pypi_latest_version(package) for package in packages) new_packages = await asyncio.gather(*coro) return [(old, new) for old, new in new_packages if old.version != new.version] def read_packages(requirements_io: io.TextIOWrapper): for line in requirements_io: raw, *_ = line.split("#") if not (raw := raw.strip()): continue package_name, *rest = re.split(r"<|=|>|\[\]", raw) if not rest: continue *_, version = rest yield Package(package_name, version, raw) requirements_io.close() if __name__ == "__main__": parser = argparse.ArgumentParser( description="Check for updated dependencies in requirements file." ) parser.add_argument( "filename", type=argparse.FileType("r"), help="requirements file", ) args = parser.parse_args() current_packages = list(read_packages(args.filename)) latest_packages = asyncio.run(fetch_all_latest_packages(current_packages)) if not latest_packages: print("Everything upto date.") exit(0) print(placeholder.format(name="NAME", old_ver="OLD_VER", new_ver="NEW_VER")) for old, new in latest_packages: print( placeholder.format(name=new.name, old_ver=old.version, new_ver=new.version) )
$ python check_updates.py requirements.txt NAME OLD_VER NEW_VER Django 4.2.1 4.2.2 django-filter 23.1 23.2 psycopg 3.1.1 3.1.9 $ python check_updates.py -h usage: check_updates.py [-h] filename Check for updated dependencies in requirements file. positional arguments: filename requirements file options: -h, --help show this help message and exit
pip-compile -U requirements.txt.pip install pip-review. pypi.org/project/pip-review