Skip to content

Commit

Permalink
PEP691: Switch to a List for Project, Address more Feedback (#2653)
Browse files Browse the repository at this point in the history
  • Loading branch information
dstufft authored Jun 17, 2022
1 parent 1cba25d commit da13103
Showing 1 changed file with 168 additions and 12 deletions.
180 changes: 168 additions & 12 deletions pep-0691.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ There are two major issues with an HTML-based API:
fully support HTML5.

- HTML5 is primarily designed as a markup language to present documents for human
consumption. Our use of it is driven largely for historical reasons and accidental
consumption. Our use of it is driven largely for historical and accidental
reasons, and it's unlikely anyone would design an API that relied on it if
they were starting from scratch.

Expand Down Expand Up @@ -178,24 +178,41 @@ Project List
~~~~~~~~~~~~

The root URL ``/`` for this PEP (which represents the base URL) will be a JSON encoded
dictionary which has a single key, ``projects``, which is itself a dictionary where each
key is a string of the normalized project name, and the value is a dictionary with a
single key, ``url``, which represents the URL that the project can be fetched from. As
an example:
dictionary which has a single key, ``projects``, which is an array where each entry
is a dictionary with a single key, ``name``, which represents string of the project
name. As an example:

.. code-block:: json
{
"meta": {
"api-version": "1.0"
},
"projects": {
"frob": {"url": "/frob/"},
"spamspamspam": {"url": "/spamspamspam/"}
}
"projects": [
{"name": "Frob"},
{"name": "spamspamspam"},
]
}
.. note::

The ``name`` field is the same as the one from :pep:`503`, which does not specify
whether it is the non-normalized display name or the normalized name. In practice
different implementations of these PEPs are choosing differently here, so relying
on it being either non-normalized or normalized is relying on an implementation
detail of the repository in question.


.. note::

While the ``projects`` key is an array, and thus is required to be in some kind
of an order, neither :pep:`503` nor this PEP requires any specific ordering nor
that the ordering is consistent from one request to the next. Mentally this is
best thought of as a set, but both JSON and HTML lack the functionality to have
sets.


Project Detail
~~~~~~~~~~~~~~

Expand Down Expand Up @@ -286,6 +303,15 @@ As an example:
}
.. note::

While the ``files`` key is an array, and thus is required to be in some kind
of an order, neither :pep:`503` nor this PEP requires any specific ordering nor
that the ordering is consistent from one request to the next. Mentally this is
best thought of as a set, but both JSON and HTML lack the functionality to have
sets.


Content-Types
-------------

Expand Down Expand Up @@ -336,10 +362,11 @@ negotiation, the flow is roughly:
1. The client makes an HTTP request containing an ``Accept`` header listing all
of the version+format content types that they are able to understand.
2. The server inspects that header, selects one of the listed content types,
then returns a response using that content type.
then returns a response using that content type (treating the absence of
an ``Accept`` header as ``Accept: */*``).
3. If the server does not support any of the content types in the ``Accept``
header or if the client did not provide an ``Accept`` header at all, then
they are able to choose between 3 different options for how to respond:
header then they are able to choose between 3 different options for how to
respond:

a. Select a default content type other than what the client has requested
and return a response with that.
Expand Down Expand Up @@ -828,6 +855,41 @@ with each other. Overall I think it's more confusing if the ``+html`` version do
exist.


Why v1.0 and not v1.1 or v2.0?
------------------------------

This PEP is still wholly backwards compatible with clients that could read the
existing v1.0 API, can still continue to read the API after these changes have
been made. In :pep:`629`, the qualification for a major version bump is:

Incrementing the major version is used to signal a backwards incompatible
change such that existing clients would no longer be expected to be able to
meaningfully use the API.

The changes in this PEP do not meet that bar, nothing has changed in a way that
existing clients would no longer be expected to be able to meaningfully use the
API.

That means we should still be within the v1.x version line.

The question of whether we should be v1.1 or v1.0 is a more interesting one, and
there are a few ways of looking at it:

- We've exposed new features to the API (the project name on the project
page, multiple hashes), which is a sign that we should increment the minor
version.
- The new features exist wholly within the JSON serialization, which means that
no client that currently is requesting the HTML 1.0 page, would ever see any
of the new features anyways, so for them it is effectively still v1.0.
- No major client has implemented support for PEP 629 yet, which means that the
minor version numbering is largely academic at this point anyways, since it
exists to let clients provide feedback to end users.

The second and third points above end up making the first point kind of
meaningless, and with that, it makes more sense to just call everything v1.0
and be stricter about updating versions into the future.


Appendix 1: Survey of use cases to cover
========================================

Expand Down Expand Up @@ -881,6 +943,100 @@ how they use the Simple + JSON APIs today or how they currently plan to use it:
- XML-RPC Call: ``list_packages_with_serial``


Appendix 2: Rough Underlying Data Models
========================================

These are not intended to perfectly match the server, client, or wire
formats. Rather, these are concpetual models, put to code to make them
more explicit as to the abstract models underlining the repository API
as it evolved through :pep:`503`, :pep:`529`, :pep:`629`, :pep:`658`,
and now this PEP, :pep:`691`.

The existing HTML, and the new JSON serialization of these models then
represent how these underlying concpetual models get mapped onto the
actual wire formats.

How servers or clients choose to model this data is out of scope for
this PEP.

.. code-block:: python
@dataclass
class Meta:
api_version: Literal["1.0"]
@dataclass
class Project:
# Normalized or Non-Normalized Name
name: str
# Computed in JSON, Included in HTML
url: str | None
@dataclass
class File:
filename: str
url: str
# Limited to a len() of 1 in HTML
hashes: dict[str, str]
gpg_sig: bool | None
requires_python: str | None
@dataclass
class PEP529File(File):
yanked: bool | str
# Simple Index page (/simple/)
@dataclass
class PEP503_Index:
projects: set[Project]
@dataclass
class PEP629_Index(PEP503_Index):
meta: Meta
@dataclass
class Index(PEP629_Index):
pass
# Simple Detail page (/simple/$PROJECT/)
@dataclass
class PEP503_Detail:
files: set[File]
@dataclass
class PEP529_Detail(PEP503_Detail):
files: set[PEP529File]
@dataclass
class PEP629_Detail(PEP529_Detail):
meta: Meta
@dataclass
class PEP658_Detail(PEP629_Detail):
# Limited to a len() of 1 in HTML
dist_info_metadata: bool | dict[str, str]
@dataclass
class PEP691_Detail(PEP658_Detail):
name: str # Normalized Name
@dataclass
class Detail(PEP691_Detail):
pass
Copyright
=========

Expand Down

0 comments on commit da13103

Please sign in to comment.