Add RFC 9457 Problem Details support for Simple API errors #19371
Add RFC 9457 Problem Details support for Simple API errors #19371luisgcoding wants to merge 8 commits intopypi:mainfrom
Conversation
warehouse/rfc9457.py
Outdated
| detail: str | None = None | ||
| type: str = "about:blank" | ||
| instance: str | None = None | ||
| extensions: dict[str, Any] = field(default_factory=dict) |
There was a problem hiding this comment.
When I was looking at the test, it seemed odd that extensions were passed in as a dictionary, but got flattened in the JSON result. I was put off by the different shape, but now I see why; it's because ProblemDetails is a dataclass, which doesn't have a way to specify **kws. I think that's okay, except that the way it's written, it's possible for keys in extensions to override the required arguments, e.g.
pd = ProblemDetails(400, "Bad request", extensions={"status": 200})Maybe that's not terrible, but maybe it makes sense to do some extra checking before the result.update() on line 66?
I also wonder is whether extensions should be a kw_only field?
| "title": self.title, | ||
| } | ||
|
|
||
| if self.type != "about:blank": |
There was a problem hiding this comment.
My reading of about:blank says it can be implicit but doesn't need to be. Should we default to explicit?
Also should we support the SHOULD "the title SHOULD be the same as the recommended HTTP status phrase for that code"?
There was a problem hiding this comment.
I added the SHOULD here in method problem_details_from_exception. I think is better to be implicit but happy to change it otherwise.
warehouse/rfc9457.py
Outdated
| def problem_details_from_exception( | ||
| exc: HTTPException, detail: str | None = None, **extensions: Any | ||
| ) -> ProblemDetails: | ||
| problem_detail = detail |
There was a problem hiding this comment.
Could be:
if detail is None:
problem_detail = getattr(...
else:
problem_detail = detailor a ternary expression, but I don't think that would make things more readable.
warehouse/rfc9457.py
Outdated
|
|
||
|
|
||
| def accepts_problem_json(request) -> bool: | ||
| acceptable = request.accept.acceptable_offers([RFC9457_CONTENT_TYPE]) |
There was a problem hiding this comment.
There was some question on DPO whether we wanted to limit this response to only requests that explicitly accept application/problem+json, although now that I'm looking I don't see accepts_problem_json() called anywhere.
I'm unsure so maybe @woodruffw can chime in?
There was a problem hiding this comment.
I removed the accepts_problem_json for the moment. We can add it back if we decide to use it for backwards compatibility.
ebcbecd to
7bcb466
Compare
This PR implements RFC9457 support for PyPI's Simple API error responses, replacing plain text error messages with standardized, machine-readable JSON error responses.
This is part of a Pre-PEP work discussed here.
Current PyPi behaviour when executing command

curl -i http://localhost:80/simple/nonexistent-package/:Now with the change proposed here:
