Changeset View
Changeset View
Standalone View
Standalone View
swh/web/api/apidoc.py
Show All 13 Lines | |||||
import docutils.nodes | import docutils.nodes | ||||
import docutils.parsers.rst | import docutils.parsers.rst | ||||
import docutils.utils | import docutils.utils | ||||
from django.shortcuts import redirect | from django.shortcuts import redirect | ||||
from rest_framework.decorators import api_view | from rest_framework.decorators import api_view | ||||
from swh.web.api.apiresponse import make_api_response | from swh.web.api.apiresponse import make_api_response | ||||
from swh.web.api.apiurls import APIUrls, CategoryId | from swh.web.api.apiurls import CategoryId, api_urls | ||||
from swh.web.utils import parse_rst, reverse | from swh.web.utils import parse_rst, reverse | ||||
class _HTTPDomainDocVisitor(docutils.nodes.NodeVisitor): | class _HTTPDomainDocVisitor(docutils.nodes.NodeVisitor): | ||||
""" | """ | ||||
docutils visitor for walking on a parsed docutils document containing sphinx | docutils visitor for walking on a parsed docutils document containing sphinx | ||||
httpdomain roles. Its purpose is to extract relevant info regarding swh | httpdomain roles. Its purpose is to extract relevant info regarding swh | ||||
api endpoints (for instance url arguments) from their docstring written | api endpoints (for instance url arguments) from their docstring written | ||||
▲ Show 20 Lines • Show All 316 Lines • ▼ Show 20 Lines | ): | ||||
tags_set = set(tags) | tags_set = set(tags) | ||||
# @api_doc() Decorator call | # @api_doc() Decorator call | ||||
def decorator(f): | def decorator(f): | ||||
# if the route is not hidden, add it to the index | # if the route is not hidden, add it to the index | ||||
if "hidden" not in tags_set: | if "hidden" not in tags_set: | ||||
doc_data = get_doc_data(f, route, noargs) | doc_data = get_doc_data(f, route, noargs) | ||||
doc_desc = doc_data["description"] | doc_desc = doc_data["description"] | ||||
APIUrls.add_doc_route( | api_urls.add_doc_route( | ||||
route, | route, | ||||
category, | category, | ||||
re.split(r"\.\s", doc_desc)[0], | re.split(r"\.\s", doc_desc)[0], | ||||
noargs=noargs, | noargs=noargs, | ||||
api_version=api_version, | api_version=api_version, | ||||
tags=tags_set, | tags=tags_set, | ||||
) | ) | ||||
# create a dedicated view to display endpoint HTML doc | # create a dedicated view to display endpoint HTML doc | ||||
@api_view(["GET", "HEAD"]) | @api_view(["GET", "HEAD"]) | ||||
@wraps(f) | @wraps(f) | ||||
def doc_view(request): | def doc_view(request): | ||||
doc_data = get_doc_data(f, route, noargs) | doc_data = get_doc_data(f, route, noargs) | ||||
return make_api_response(request, None, doc_data) | return make_api_response(request, None, doc_data) | ||||
route_name = "%s-doc" % route[1:-1].replace("/", "-") | route_name = "%s-doc" % route[1:-1].replace("/", "-") | ||||
urlpattern = f"^api/{api_version}{route}doc/$" | urlpattern = f"^api/{api_version}{route}doc/$" | ||||
view_name = "api-%s-%s" % (api_version, route_name) | view_name = "api-%s-%s" % (api_version, route_name) | ||||
APIUrls.add_url_pattern(urlpattern, doc_view, view_name) | api_urls.add_url_pattern(urlpattern, doc_view, view_name) | ||||
# for backward compatibility as previous apidoc URLs were missing | # for backward compatibility as previous apidoc URLs were missing | ||||
# the /api prefix | # the /api prefix | ||||
old_view_name = view_name.replace("api-", "") | old_view_name = view_name.replace("api-", "") | ||||
old_urlpattern = f"^{api_version}{route}doc/$" | old_urlpattern = f"^{api_version}{route}doc/$" | ||||
@api_view(["GET", "HEAD"]) | @api_view(["GET", "HEAD"]) | ||||
def old_doc_view(request): | def old_doc_view(request): | ||||
return redirect(reverse(view_name)) | return redirect(reverse(view_name)) | ||||
APIUrls.add_url_pattern(old_urlpattern, old_doc_view, old_view_name) | api_urls.add_url_pattern(old_urlpattern, old_doc_view, old_view_name) | ||||
@wraps(f) | @wraps(f) | ||||
def documented_view(request, **kwargs): | def documented_view(request, **kwargs): | ||||
doc_data = get_doc_data(f, route, noargs) | doc_data = get_doc_data(f, route, noargs) | ||||
try: | try: | ||||
return {"data": f(request, **kwargs), "doc_data": doc_data} | return {"data": f(request, **kwargs), "doc_data": doc_data} | ||||
except Exception as exc: | except Exception as exc: | ||||
exc.doc_data = doc_data | exc.doc_data = doc_data | ||||
▲ Show 20 Lines • Show All 93 Lines • Show Last 20 Lines |