Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

pypi-simple

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pypi-simple - npm Package Compare versions

Comparing version
1.6.1
to
1.7.0
+25
src/pypi_simple/enums.py
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

@@ -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 = [

@@ -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

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

@@ -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",

@@ -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 @@ ),

[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