pypi-simple
Advanced tools
| from enum import Enum | ||
| class ProjectStatus(str, Enum): | ||
| """ | ||
| .. versionadded:: 1.7.0 | ||
| Enum of project status markers as defined by :pep:`792` | ||
| """ | ||
| #: The project is active. This is the default status for a project. | ||
| ACTIVE = "active" | ||
| #: The project does not expect to be updated in the future. | ||
| ARCHIVED = "archived" | ||
| #: The project is considered generally unsafe for use, e.g. due to malware. | ||
| QUARANTINED = "quarantined" | ||
| #: The project is considered obsolete, and may have been superseded by | ||
| #: another project. | ||
| DEPRECATED = "deprecated" | ||
| def __str__(self) -> str: | ||
| return self.value |
+10
-0
@@ -0,1 +1,11 @@ | ||
| v1.7.0 (2025-07-28) | ||
| ------------------- | ||
| - Support Python 3.13 | ||
| - **Bugfix**: Fix parsing of PEP 708 `alternate-locations` fields in JSON | ||
| project pages (Previous versions looked for the field in the wrong location) | ||
| - Support PEP 792 | ||
| - `status` and `status_reason` attributes added to `ProjectPage` and `RepositoryPage` | ||
| - `ProjectStatus` enum added | ||
| - `SUPPORTED_REPOSITORY_VERSION` increased to `"1.4"` | ||
| v1.6.1 (2024-10-23) | ||
@@ -2,0 +12,0 @@ ------------------- |
+1
-0
@@ -15,2 +15,3 @@ .. currentmodule:: pypi_simple | ||
| .. autoclass:: DistributionPackage() | ||
| .. autoclass:: ProjectStatus() | ||
@@ -17,0 +18,0 @@ Progress Trackers |
+14
-0
@@ -6,2 +6,16 @@ .. currentmodule:: pypi_simple | ||
| v1.7.0 (2025-07-28) | ||
| ------------------- | ||
| - Support Python 3.13 | ||
| - **Bugfix**: Fix parsing of :pep:`708` ``alternate-locations`` fields in JSON | ||
| project pages (Previous versions looked for the field in the wrong location) | ||
| - Support :pep:`792` | ||
| - ``status`` and ``status_reason`` attributes added to `ProjectPage` and `RepositoryPage` | ||
| - `ProjectStatus` enum added | ||
| - `SUPPORTED_REPOSITORY_VERSION` increased to `"1.4"` | ||
| v1.6.1 (2024-10-23) | ||
@@ -8,0 +22,0 @@ ------------------- |
+1
-1
@@ -5,3 +5,3 @@ from pypi_simple import __version__ | ||
| author = "John T. Wodder II" | ||
| copyright = "2018-2024 John T. Wodder II" # noqa: A001 | ||
| copyright = "2018-2025 John T. Wodder II" # noqa: A001 | ||
@@ -8,0 +8,0 @@ extensions = [ |
+7
-7
@@ -22,9 +22,9 @@ .. module:: pypi_simple | ||
| specified in :pep:`503` and updated by :pep:`592`, :pep:`629`, :pep:`658`, | ||
| :pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, and :pep:`740`. With it, you | ||
| can query `the Python Package Index (PyPI) <https://pypi.org>`_ and other `pip | ||
| <https://pip.pypa.io>`_-compatible repositories for a list of their available | ||
| projects and lists of each project's available package files. The library also | ||
| allows you to download package files and query them for their project version, | ||
| package type, file digests, ``requires_python`` string, PGP signature URL, and | ||
| metadata URL. | ||
| :pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, :pep:`740`, and :pep:`792`. | ||
| With it, you can query `the Python Package Index (PyPI) <https://pypi.org>`_ | ||
| and other `pip <https://pip.pypa.io>`_-compatible repositories for a list of | ||
| their available projects and lists of each project's available package files. | ||
| The library also allows you to download package files and query them for their | ||
| project version, package type, file digests, ``requires_python`` string, PGP | ||
| signature URL, and metadata URL. | ||
@@ -31,0 +31,0 @@ Installation |
+1
-1
| The MIT License (MIT) | ||
| Copyright (c) 2018-2024 John Thorvald Wodder II and contributors | ||
| Copyright (c) 2018-2025 John Thorvald Wodder II and contributors | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
+10
-10
@@ -1,4 +0,4 @@ | ||
| Metadata-Version: 2.3 | ||
| Metadata-Version: 2.4 | ||
| Name: pypi-simple | ||
| Version: 1.6.1 | ||
| Version: 1.7.0 | ||
| Summary: PyPI Simple Repository API client library | ||
@@ -12,3 +12,2 @@ Project-URL: Source Code, https://github.com/jwodder/pypi-simple | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: License :: OSI Approved :: MIT License | ||
| Classifier: Programming Language :: Python :: 3 | ||
@@ -21,2 +20,3 @@ Classifier: Programming Language :: Python :: 3 :: Only | ||
| Classifier: Programming Language :: Python :: 3.12 | ||
| Classifier: Programming Language :: Python :: 3.13 | ||
| Classifier: Programming Language :: Python :: Implementation :: CPython | ||
@@ -67,9 +67,9 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy | ||
| specified in :pep:`503` and updated by :pep:`592`, :pep:`629`, :pep:`658`, | ||
| :pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, and :pep:`740`. With it, you | ||
| can query `the Python Package Index (PyPI) <https://pypi.org>`_ and other `pip | ||
| <https://pip.pypa.io>`_-compatible repositories for a list of their available | ||
| projects and lists of each project's available package files. The library also | ||
| allows you to download package files and query them for their project version, | ||
| package type, file digests, ``requires_python`` string, PGP signature URL, and | ||
| metadata URL. | ||
| :pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, :pep:`740`, and :pep:`792`. | ||
| With it, you can query `the Python Package Index (PyPI) <https://pypi.org>`_ | ||
| and other `pip <https://pip.pypa.io>`_-compatible repositories for a list of | ||
| their available projects and lists of each project's available package files. | ||
| The library also allows you to download package files and query them for their | ||
| project version, package type, file digests, ``requires_python`` string, PGP | ||
| signature URL, and metadata URL. | ||
@@ -76,0 +76,0 @@ See `the documentation <https://pypi-simple.readthedocs.io>`_ for more |
+2
-2
@@ -12,3 +12,3 @@ [build-system] | ||
| license = "MIT" | ||
| license-files = { paths = ["LICENSE"] } | ||
| license-files = ["LICENSE"] | ||
| authors = [ | ||
@@ -35,5 +35,5 @@ { name = "John Thorvald Wodder II", email = "pypi-simple@varonathe.org" } | ||
| "Programming Language :: Python :: 3.12", | ||
| "Programming Language :: Python :: 3.13", | ||
| "Programming Language :: Python :: Implementation :: CPython", | ||
| "Programming Language :: Python :: Implementation :: PyPy", | ||
| "License :: OSI Approved :: MIT License", | ||
| "Topic :: Software Development :: Libraries :: Python Modules", | ||
@@ -40,0 +40,0 @@ "Topic :: System :: Software Distribution", |
+7
-7
@@ -30,9 +30,9 @@ |repostatus| |ci-status| |coverage| |pyversions| |license| | ||
| specified in :pep:`503` and updated by :pep:`592`, :pep:`629`, :pep:`658`, | ||
| :pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, and :pep:`740`. With it, you | ||
| can query `the Python Package Index (PyPI) <https://pypi.org>`_ and other `pip | ||
| <https://pip.pypa.io>`_-compatible repositories for a list of their available | ||
| projects and lists of each project's available package files. The library also | ||
| allows you to download package files and query them for their project version, | ||
| package type, file digests, ``requires_python`` string, PGP signature URL, and | ||
| metadata URL. | ||
| :pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, :pep:`740`, and :pep:`792`. | ||
| With it, you can query `the Python Package Index (PyPI) <https://pypi.org>`_ | ||
| and other `pip <https://pip.pypa.io>`_-compatible repositories for a list of | ||
| their available projects and lists of each project's available package files. | ||
| The library also allows you to download package files and query them for their | ||
| project version, package type, file digests, ``requires_python`` string, PGP | ||
| signature URL, and metadata URL. | ||
@@ -39,0 +39,0 @@ See `the documentation <https://pypi-simple.readthedocs.io>`_ for more |
@@ -17,3 +17,3 @@ """ | ||
| __version__ = "1.6.1" | ||
| __version__ = "1.7.0" | ||
| __author__ = "John Thorvald Wodder II" | ||
@@ -28,3 +28,3 @@ __author_email__ = "pypi-simple@varonathe.org" | ||
| #: The maximum supported simple repository version (See :pep:`629`) | ||
| SUPPORTED_REPOSITORY_VERSION: str = "1.3" | ||
| SUPPORTED_REPOSITORY_VERSION: str = "1.4" | ||
@@ -74,2 +74,3 @@ #: :mailheader:`Accept` header value for accepting either the HTML or JSON | ||
| from .client import PyPISimple | ||
| from .enums import ProjectStatus | ||
| from .errors import ( | ||
@@ -103,2 +104,3 @@ DigestMismatchError, | ||
| "ProjectPage", | ||
| "ProjectStatus", | ||
| "PyPISimple", | ||
@@ -105,0 +107,0 @@ "RepositoryPage", |
@@ -9,2 +9,3 @@ from __future__ import annotations | ||
| import requests | ||
| from .enums import ProjectStatus | ||
| from .errors import UnparsableFilenameError, UnsupportedContentTypeError | ||
@@ -281,2 +282,12 @@ from .filenames import parse_filename | ||
| #: .. versionadded:: 1.7.0 | ||
| #: | ||
| #: Project status marker, or `None` if not specified. See :pep:`792`. | ||
| status: ProjectStatus | None = None | ||
| #: .. versionadded:: 1.7.0 | ||
| #: | ||
| #: Freeform text contextualizing `status`, or `None` if not specified | ||
| status_reason: str | None = None | ||
| @classmethod | ||
@@ -322,2 +333,4 @@ def from_html( | ||
| alternate_locations=page.alternate_locations, | ||
| status=page.status, | ||
| status_reason=page.status_reason, | ||
| ) | ||
@@ -357,3 +370,5 @@ | ||
| tracks=project.meta.tracks, | ||
| alternate_locations=project.meta.alternate_locations, | ||
| alternate_locations=project.alternate_locations, | ||
| status=project.project_status.status, | ||
| status_reason=project.project_status.reason, | ||
| ) | ||
@@ -360,0 +375,0 @@ |
@@ -119,2 +119,8 @@ from __future__ import annotations | ||
| .. warning:: | ||
| PyPI's top-level simple HTML page is cached for 24 hours, meaning | ||
| that new projects won't show up on this page immediately. Access | ||
| the project page directly if you need immediate results. | ||
| .. versionchanged:: 1.0.0 | ||
@@ -121,0 +127,0 @@ |
@@ -7,2 +7,3 @@ from __future__ import annotations | ||
| from bs4 import BeautifulSoup, Tag | ||
| from .enums import ProjectStatus | ||
| from .util import basejoin, check_repo_version | ||
@@ -56,2 +57,24 @@ | ||
| @property | ||
| def status(self) -> ProjectStatus | None: | ||
| """ | ||
| .. versionadded:: 1.7.0 | ||
| Project status marker, or `None` if not specified. See :pep:`792`. | ||
| """ | ||
| if st := self.pypi_meta.get("project-status"): | ||
| return ProjectStatus(st[0]) | ||
| else: | ||
| return None | ||
| @property | ||
| def status_reason(self) -> str | None: | ||
| """ | ||
| .. versionadded:: 1.7.0 | ||
| Freeform text contextualizing `status`, or `None` if not specified. | ||
| See :pep:`792` for more information. | ||
| """ | ||
| return self.pypi_meta.get("project-status-reason", [None])[0] | ||
| @classmethod | ||
@@ -58,0 +81,0 @@ def from_html( |
@@ -5,2 +5,3 @@ from __future__ import annotations | ||
| from pydantic import BaseModel, Field, StrictBool, field_validator | ||
| from .enums import ProjectStatus | ||
@@ -27,5 +28,9 @@ | ||
| tracks: List[str] = Field(default_factory=list) | ||
| alternate_locations: List[str] = Field(default_factory=list) | ||
| class StatusData(BaseModel): | ||
| status: Optional[ProjectStatus] = None | ||
| reason: Optional[str] = None | ||
| class File(BaseModel, alias_generator=shishkebab, populate_by_name=True): | ||
@@ -74,6 +79,8 @@ filename: str | ||
| class Project(BaseModel): | ||
| class Project(BaseModel, alias_generator=shishkebab, populate_by_name=True): | ||
| name: str | ||
| files: List[File] | ||
| meta: ProjectMeta | ||
| alternate_locations: List[str] = Field(default_factory=list) | ||
| project_status: StatusData = Field(default_factory=StatusData) | ||
| versions: Optional[List[str]] = None | ||
@@ -80,0 +87,0 @@ |
@@ -29,7 +29,11 @@ { | ||
| "api-version": "1.2", | ||
| "tracks": ["https://tracks.package/pypi/argset/", "https://test.tracks.package/pypi/argset"], | ||
| "alternate-locations": ["https://alt.package/pypi/argset/", "https://test.alt.package/pypi/argset"] | ||
| "tracks": ["https://tracks.package/pypi/argset/", "https://test.tracks.package/pypi/argset"] | ||
| }, | ||
| "alternate-locations": ["https://alt.package/pypi/argset/", "https://test.alt.package/pypi/argset"], | ||
| "project-status": { | ||
| "status": "deprecated", | ||
| "reason": "Dev is tired of project" | ||
| }, | ||
| "name": "argset", | ||
| "versions": ["0.1.0"] | ||
| } |
@@ -10,2 +10,4 @@ <!DOCTYPE html> | ||
| <meta name="pypi:alternate-locations" content="https://test.alt.package/pypi/qypi/"/> | ||
| <meta name="pypi:project-status" content="deprecated"/> | ||
| <meta name="pypi:project-status-reason" content="Dev is tired of project"/> | ||
| </head> | ||
@@ -12,0 +14,0 @@ <body> |
@@ -10,2 +10,3 @@ from datetime import datetime, timezone | ||
| ProjectPage, | ||
| ProjectStatus, | ||
| UnsupportedRepoVersionError, | ||
@@ -500,2 +501,4 @@ ) | ||
| ], | ||
| status=ProjectStatus.DEPRECATED, | ||
| status_reason="Dev is tired of project", | ||
| ), | ||
@@ -797,2 +800,4 @@ ), | ||
| ], | ||
| status=ProjectStatus.DEPRECATED, | ||
| status_reason="Dev is tired of project", | ||
| ), | ||
@@ -799,0 +804,0 @@ ), |
+2
-2
| [tox] | ||
| envlist = lint,typing,py38,py39,py310,py311,py312,pypy3 | ||
| envlist = lint,typing,py38,py39,py310,py311,py312,py313,pypy3 | ||
| skip_missing_interpreters = True | ||
@@ -12,3 +12,3 @@ isolated_build = True | ||
| pytest-mock | ||
| responses!=0.24 | ||
| responses!=0.24,!=0.25.5 | ||
| commands = | ||
@@ -15,0 +15,0 @@ pytest {posargs} test README.rst docs/index.rst |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
302169
1.26%52
1.96%6119
1.14%