Skip to content

Serve the v1 API index as JSON only - #3208

Open
Alc-Alc wants to merge 2 commits into
python:mainfrom
Alc-Alc:api-v1-root-xml-500
Open

Alc-Alc wants to merge 2 commits into
python:mainfrom
Alc-Alc:api-v1-root-xml-500

Conversation

@Alc-Alc

@Alc-Alc Alc-Alc commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Description

While checking #3207 I found this sentry issue.

  • GET /api/v1/ returns a 500 to browsers.
    • Browsers send Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 when opening a page.
    • That header ranks application/xml above */*, so tastypie serializes the index as XML.
    • The index is keyed by resource names like pages/page, and / is not valid in an XML tag name, which fails.

Fix

  • Give the v1 Api a JSON-only serializer for the index.
    • Resource endpoints keep their own serializer, so ?format=xml on them is unchanged (XML is in use there).
    • ?format=yaml on the index now returns JSON instead of YAML, this shouldn't affect anyone (no yaml requests).

Closes

  • Fixes PYDOTORG-PROD-1JW (issue)
Before / After (DEBUG=False), traceback and body trimmed for brevity
curl -i http://localhost:8000/api/v1/ -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'

Before (500 status code; server log has a 500 with a traceback)

HTTP/1.1 500 Internal Server Error
Content-Type: text/html; charset=utf-8
[error] request_failed [django_structlog.middlewares.request] code=500 request='GET /api/v1/' user_id=None
Traceback (most recent call last):
  ...
  File "<site-packages>/tastypie/api.py", line 164, in top_level
    serialized = self.serializer.serialize(available_resources, desired_format, options)
  ...
  File "<site-packages>/tastypie/serializers.py", line 346, in to_etree
    element = Element(name or 'object')
  ...
ValueError: Invalid tag name 'pages/page'
[error] "GET /api/v1/ HTTP/1.1" 500 13602 [django.server] status_code=500

After (200 status code; server log has only the 200 info line)

HTTP/1.1 200 OK
Content-Type: application/json

{"downloads/os": {"list_endpoint": "/api/v1/downloads/os/", "schema": "/api/v1/downloads/os/schema/"}, "downloads/release": {...}, "downloads/release_file": {...}, "pages/page": {...}}
[info] "GET /api/v1/ HTTP/1.1" 200 447 [django.server] status_code=200

@Alc-Alc
Alc-Alc requested a review from JacobCoffee as a code owner November 4, 2026 11:55

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant