Skip to content

Commit da13103

Browse files
authored
PEP691: Switch to a List for Project, Address more Feedback (#2653)
1 parent 1cba25d commit da13103

File tree

1 file changed

+168
-12
lines changed

1 file changed

+168
-12
lines changed

pep-0691.rst

+168-12
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ There are two major issues with an HTML-based API:
3535
fully support HTML5.
3636

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

@@ -178,24 +178,41 @@ Project List
178178
~~~~~~~~~~~~
179179

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

186185
.. code-block:: json
187186
188187
{
189188
"meta": {
190189
"api-version": "1.0"
191190
},
192-
"projects": {
193-
"frob": {"url": "/frob/"},
194-
"spamspamspam": {"url": "/spamspamspam/"}
195-
}
191+
"projects": [
192+
{"name": "Frob"},
193+
{"name": "spamspamspam"},
194+
]
196195
}
197196
198197
198+
.. note::
199+
200+
The ``name`` field is the same as the one from :pep:`503`, which does not specify
201+
whether it is the non-normalized display name or the normalized name. In practice
202+
different implementations of these PEPs are choosing differently here, so relying
203+
on it being either non-normalized or normalized is relying on an implementation
204+
detail of the repository in question.
205+
206+
207+
.. note::
208+
209+
While the ``projects`` key is an array, and thus is required to be in some kind
210+
of an order, neither :pep:`503` nor this PEP requires any specific ordering nor
211+
that the ordering is consistent from one request to the next. Mentally this is
212+
best thought of as a set, but both JSON and HTML lack the functionality to have
213+
sets.
214+
215+
199216
Project Detail
200217
~~~~~~~~~~~~~~
201218

@@ -286,6 +303,15 @@ As an example:
286303
}
287304
288305
306+
.. note::
307+
308+
While the ``files`` key is an array, and thus is required to be in some kind
309+
of an order, neither :pep:`503` nor this PEP requires any specific ordering nor
310+
that the ordering is consistent from one request to the next. Mentally this is
311+
best thought of as a set, but both JSON and HTML lack the functionality to have
312+
sets.
313+
314+
289315
Content-Types
290316
-------------
291317

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

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

830857

858+
Why v1.0 and not v1.1 or v2.0?
859+
------------------------------
860+
861+
This PEP is still wholly backwards compatible with clients that could read the
862+
existing v1.0 API, can still continue to read the API after these changes have
863+
been made. In :pep:`629`, the qualification for a major version bump is:
864+
865+
Incrementing the major version is used to signal a backwards incompatible
866+
change such that existing clients would no longer be expected to be able to
867+
meaningfully use the API.
868+
869+
The changes in this PEP do not meet that bar, nothing has changed in a way that
870+
existing clients would no longer be expected to be able to meaningfully use the
871+
API.
872+
873+
That means we should still be within the v1.x version line.
874+
875+
The question of whether we should be v1.1 or v1.0 is a more interesting one, and
876+
there are a few ways of looking at it:
877+
878+
- We've exposed new features to the API (the project name on the project
879+
page, multiple hashes), which is a sign that we should increment the minor
880+
version.
881+
- The new features exist wholly within the JSON serialization, which means that
882+
no client that currently is requesting the HTML 1.0 page, would ever see any
883+
of the new features anyways, so for them it is effectively still v1.0.
884+
- No major client has implemented support for PEP 629 yet, which means that the
885+
minor version numbering is largely academic at this point anyways, since it
886+
exists to let clients provide feedback to end users.
887+
888+
The second and third points above end up making the first point kind of
889+
meaningless, and with that, it makes more sense to just call everything v1.0
890+
and be stricter about updating versions into the future.
891+
892+
831893
Appendix 1: Survey of use cases to cover
832894
========================================
833895

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

883945

946+
Appendix 2: Rough Underlying Data Models
947+
========================================
948+
949+
These are not intended to perfectly match the server, client, or wire
950+
formats. Rather, these are concpetual models, put to code to make them
951+
more explicit as to the abstract models underlining the repository API
952+
as it evolved through :pep:`503`, :pep:`529`, :pep:`629`, :pep:`658`,
953+
and now this PEP, :pep:`691`.
954+
955+
The existing HTML, and the new JSON serialization of these models then
956+
represent how these underlying concpetual models get mapped onto the
957+
actual wire formats.
958+
959+
How servers or clients choose to model this data is out of scope for
960+
this PEP.
961+
962+
.. code-block:: python
963+
964+
@dataclass
965+
class Meta:
966+
api_version: Literal["1.0"]
967+
968+
969+
@dataclass
970+
class Project:
971+
# Normalized or Non-Normalized Name
972+
name: str
973+
# Computed in JSON, Included in HTML
974+
url: str | None
975+
976+
977+
@dataclass
978+
class File:
979+
filename: str
980+
url: str
981+
# Limited to a len() of 1 in HTML
982+
hashes: dict[str, str]
983+
gpg_sig: bool | None
984+
requires_python: str | None
985+
986+
987+
@dataclass
988+
class PEP529File(File):
989+
yanked: bool | str
990+
991+
992+
# Simple Index page (/simple/)
993+
@dataclass
994+
class PEP503_Index:
995+
projects: set[Project]
996+
997+
998+
@dataclass
999+
class PEP629_Index(PEP503_Index):
1000+
meta: Meta
1001+
1002+
1003+
@dataclass
1004+
class Index(PEP629_Index):
1005+
pass
1006+
1007+
1008+
# Simple Detail page (/simple/$PROJECT/)
1009+
@dataclass
1010+
class PEP503_Detail:
1011+
files: set[File]
1012+
1013+
1014+
@dataclass
1015+
class PEP529_Detail(PEP503_Detail):
1016+
files: set[PEP529File]
1017+
1018+
1019+
@dataclass
1020+
class PEP629_Detail(PEP529_Detail):
1021+
meta: Meta
1022+
1023+
1024+
@dataclass
1025+
class PEP658_Detail(PEP629_Detail):
1026+
# Limited to a len() of 1 in HTML
1027+
dist_info_metadata: bool | dict[str, str]
1028+
1029+
1030+
@dataclass
1031+
class PEP691_Detail(PEP658_Detail):
1032+
name: str # Normalized Name
1033+
1034+
1035+
@dataclass
1036+
class Detail(PEP691_Detail):
1037+
pass
1038+
1039+
8841040
Copyright
8851041
=========
8861042

0 commit comments

Comments
 (0)