@@ -35,7 +35,7 @@ There are two major issues with an HTML-based API:
35
35
fully support HTML5.
36
36
37
37
- 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
39
39
reasons, and it's unlikely anyone would design an API that relied on it if
40
40
they were starting from scratch.
41
41
@@ -178,24 +178,41 @@ Project List
178
178
~~~~~~~~~~~~
179
179
180
180
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:
185
184
186
185
.. code-block :: json
187
186
188
187
{
189
188
"meta" : {
190
189
"api-version" : " 1.0"
191
190
},
192
- "projects" : {
193
- "frob" : { "url " : " /frob/ " },
194
- "spamspamspam" : { "url " : " / spamspamspam/ " }
195
- }
191
+ "projects" : [
192
+ { "name " : " Frob " },
193
+ { "name " : " spamspamspam" },
194
+ ]
196
195
}
197
196
198
197
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
+
199
216
Project Detail
200
217
~~~~~~~~~~~~~~
201
218
@@ -286,6 +303,15 @@ As an example:
286
303
}
287
304
288
305
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
+
289
315
Content-Types
290
316
-------------
291
317
@@ -336,10 +362,11 @@ negotiation, the flow is roughly:
336
362
1. The client makes an HTTP request containing an ``Accept `` header listing all
337
363
of the version+format content types that they are able to understand.
338
364
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: */* ``).
340
367
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:
343
370
344
371
a. Select a default content type other than what the client has requested
345
372
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
828
855
exist.
829
856
830
857
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
+
831
893
Appendix 1: Survey of use cases to cover
832
894
========================================
833
895
@@ -881,6 +943,100 @@ how they use the Simple + JSON APIs today or how they currently plan to use it:
881
943
- XML-RPC Call: ``list_packages_with_serial ``
882
944
883
945
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
+
884
1040
Copyright
885
1041
=========
886
1042
0 commit comments