Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPP-3799: Set tag group order in browsable API #4685

Merged
merged 1 commit into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions api/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from drf_spectacular.extensions import OpenApiAuthenticationExtension
from drf_spectacular.openapi import AutoSchema
from drf_spectacular.plumbing import alpha_operation_sorter
from rest_framework.response import Response


Expand Down Expand Up @@ -37,3 +38,52 @@ def preprocess_ignore_deprecated_paths(endpoints: list[ENDPOINT]) -> list[ENDPOI
for path, path_regex, method, callback in endpoints
if path not in IGNORED_PATHS
]


# Organize partial paths by tags
# The partial path is the part after /api/v1/, like /api/v1/{partial_path}/
# The tag is set with the @extend_schema decorator
_TAG_TO_PARTIAL_PATH = {
"email": {"domainaddresses", "first-forwarded-email", "relayaddresses"},
"privaterelay": {
"flags",
"profiles",
"report_webcompat_issue",
"runtime_data",
"terms-accepted-user",
"users",
},
"phones": {"inboundcontact", "realphone", "relaynumber", "vCard"},
"phones: Twilio": {"inbound_call", "inbound_sms", "sms_status", "voice_status"},
"phones: Outbound": {"call", "message", "messages"},
"phones: Inteliquent": {"inbound_sms_iq"},
}

# Reverse the dictionary to be partial paths to their tag
_PARTIAL_PATH_TO_TAG: dict[str, str] = {}
for _tag, _paths in _TAG_TO_PARTIAL_PATH.items():
for _path in _paths:
_PARTIAL_PATH_TO_TAG[_path] = _tag

# The order to display tag groups in the browsable API
_TAG_ORDER = {
"UNKNOWN": 0,
"privaterelay": 10,
"email": 20,
"phones": 30,
"phones: Twilio": 31,
"phones: Inteliquent": 32,
"phones: Outbound": 33,
}


def sort_by_tag(endpoint: ENDPOINT) -> tuple[int, str, int]:
"""
Sort paths by their tag, then name, then method.

The browseable APIs will sort by tag, but in the order returned by this sort key.
"""
drf_order = alpha_operation_sorter(endpoint)
partial_path = endpoint[0].split("/")[3]
tag = _PARTIAL_PATH_TO_TAG.get(partial_path, "UNKNOWN")
return (_TAG_ORDER[tag], drf_order[0], drf_order[1])
1 change: 1 addition & 0 deletions privaterelay/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ def set_index_cache_control_headers(
"VERSION": "1.0",
"SERVE_INCLUDE_SCHEMA": False,
"PREPROCESSING_HOOKS": ["api.schema.preprocess_ignore_deprecated_paths"],
"SORT_OPERATIONS": "api.schema.sort_by_tag",
}

if IN_PYTEST or RELAY_CHANNEL in ["local", "dev"]:
Expand Down