Skip to content

Instantly share code, notes, and snippets.

@samuelcolvin
Created October 20, 2025 17:30
Show Gist options
  • Select an option

  • Save samuelcolvin/c1fd35a477c0af3b25b28a93d75e9d89 to your computer and use it in GitHub Desktop.

Select an option

Save samuelcolvin/c1fd35a477c0af3b25b28a93d75e9d89 to your computer and use it in GitHub Desktop.
save this as "pypi" somewhere in your path to be able to query pypi versions from the terminal
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "pydantic",
# "pygments",
# ]
# ///
import argparse
from datetime import datetime, timezone
import httpx
from pydantic import AliasPath, BaseModel, Field
from pydantic.fields import computed_field
from pygments import highlight # type: ignore[reportUnknownVariableType]
from pygments.formatters import TerminalFormatter
from pygments.lexers.json5 import Json5Lexer # type: ignore[reportUnknownVariableType]
class PyPIReleaseFile(BaseModel):
upload_time_iso_8601: datetime
class PyPIResponse(BaseModel):
name: str = Field(validation_alias=AliasPath('info', 'name'))
version: str = Field(validation_alias=AliasPath('info', 'version'))
requires_python: str | None = Field(None, validation_alias=AliasPath('info', 'requires_python'))
license_expression: str | None = Field(None, validation_alias=AliasPath('info', 'license_expression'))
project_urls: dict[str, str] | None = Field(None, validation_alias=AliasPath('info', 'project_urls'))
releases: dict[str, list[PyPIReleaseFile]]
@computed_field
@property
def last_release(self) -> str | None:
if release := self.releases.get(self.version):
try:
last_release = release[0].upload_time_iso_8601
except IndexError:
return None
else:
ago = datetime.now(tz=timezone.utc) - last_release
return f'{last_release:%Y-%m-%d} ({ago.days} days ago)'
return None
@computed_field
@property
def release_count(self) -> int:
return len(self.releases)
def main():
parser = argparse.ArgumentParser(description='Fetch PyPI package information')
parser.add_argument('package_name', help='Name of the package to fetch')
args = parser.parse_args()
url = f'https://pypi.org/pypi/{args.package_name}/json'
response = httpx.get(url)
response.raise_for_status()
package_info = PyPIResponse.model_validate_json(response.content)
json = package_info.model_dump_json(indent=2, exclude_none=True, exclude={'releases'})
print(highlight(json, Json5Lexer(), TerminalFormatter())) # type: ignore[reportUnknownVariableType]
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment