mirror of
https://github.com/zulip/zulip.git
synced 2025-11-18 04:43:58 +00:00
api_docs: Fix missing content from API documentation.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from typing import Any, List, Mapping, Sequence
|
from typing import Any, Dict, List, Mapping, Sequence
|
||||||
|
|
||||||
import markdown
|
import markdown
|
||||||
from django.utils.html import escape as escape_html
|
from django.utils.html import escape as escape_html
|
||||||
@@ -36,6 +36,13 @@ OBJECT_DETAILS_TEMPLATE = """
|
|||||||
</ul>
|
</ul>
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
|
ONEOF_OBJECT_DETAILS_TEMPLATE = """
|
||||||
|
<p>An object with the following fields:</p>
|
||||||
|
<ul>
|
||||||
|
{values}
|
||||||
|
</ul>
|
||||||
|
""".strip()
|
||||||
|
|
||||||
OBJECT_LIST_ITEM_TEMPLATE = """
|
OBJECT_LIST_ITEM_TEMPLATE = """
|
||||||
<li>
|
<li>
|
||||||
<code>{value}</code>: <span class=api-field-type>{data_type}</span> {required} {description}{object_details}
|
<code>{value}</code>: <span class=api-field-type>{data_type}</span> {required} {description}{object_details}
|
||||||
@@ -49,6 +56,17 @@ OBJECT_DESCRIPTION_TEMPLATE = """
|
|||||||
|
|
||||||
OBJECT_CODE_TEMPLATE = "<code>{value}</code>".strip()
|
OBJECT_CODE_TEMPLATE = "<code>{value}</code>".strip()
|
||||||
|
|
||||||
|
ONEOF_DETAILS_TEMPLATE = """
|
||||||
|
<p>This parameter must be one of the following:</p>
|
||||||
|
<ol>
|
||||||
|
{values}
|
||||||
|
</ol>
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
ONEOF_LIST_ITEM_TEMPLATE = """
|
||||||
|
<li>{item}</li>
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
|
||||||
class MarkdownArgumentsTableGenerator(Extension):
|
class MarkdownArgumentsTableGenerator(Extension):
|
||||||
@override
|
@override
|
||||||
@@ -100,6 +118,24 @@ class APIArgumentsTablePreprocessor(Preprocessor):
|
|||||||
done = True
|
done = True
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
def render_oneof_block(self, object_schema: Dict[str, Any], name: str) -> str:
|
||||||
|
md_engine = markdown.Markdown(extensions=[])
|
||||||
|
content = ""
|
||||||
|
for element in object_schema["oneOf"]:
|
||||||
|
if "items" in element and "properties" in element["items"]:
|
||||||
|
content += ONEOF_LIST_ITEM_TEMPLATE.format(
|
||||||
|
item=self.render_object_details(element["items"], str(name), True)
|
||||||
|
)
|
||||||
|
elif "properties" in element:
|
||||||
|
content += ONEOF_LIST_ITEM_TEMPLATE.format(
|
||||||
|
item=self.render_object_details(element, str(name), True)
|
||||||
|
)
|
||||||
|
elif "description" in element:
|
||||||
|
content += ONEOF_LIST_ITEM_TEMPLATE.format(
|
||||||
|
item=md_engine.convert(element["description"])
|
||||||
|
)
|
||||||
|
return ONEOF_DETAILS_TEMPLATE.format(values=content)
|
||||||
|
|
||||||
def render_parameters(self, parameters: Sequence[Parameter]) -> List[str]:
|
def render_parameters(self, parameters: Sequence[Parameter]) -> List[str]:
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
@@ -159,6 +195,8 @@ class APIArgumentsTablePreprocessor(Preprocessor):
|
|||||||
object_block = self.render_object_details(object_schema["items"], str(name))
|
object_block = self.render_object_details(object_schema["items"], str(name))
|
||||||
elif "properties" in object_schema:
|
elif "properties" in object_schema:
|
||||||
object_block = self.render_object_details(object_schema, str(name))
|
object_block = self.render_object_details(object_schema, str(name))
|
||||||
|
elif "oneOf" in object_schema:
|
||||||
|
object_block = self.render_oneof_block(object_schema, str(name))
|
||||||
|
|
||||||
lines.append(
|
lines.append(
|
||||||
API_PARAMETER_TEMPLATE.format(
|
API_PARAMETER_TEMPLATE.format(
|
||||||
@@ -174,7 +212,9 @@ class APIArgumentsTablePreprocessor(Preprocessor):
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def render_object_details(self, schema: Mapping[str, Any], name: str) -> str:
|
def render_object_details(
|
||||||
|
self, schema: Mapping[str, Any], name: str, oneof: bool = False
|
||||||
|
) -> str:
|
||||||
md_engine = markdown.Markdown(extensions=[])
|
md_engine = markdown.Markdown(extensions=[])
|
||||||
li_elements = []
|
li_elements = []
|
||||||
|
|
||||||
@@ -227,6 +267,8 @@ class APIArgumentsTablePreprocessor(Preprocessor):
|
|||||||
details = ""
|
details = ""
|
||||||
if "object" in data_type and "properties" in object_values[value]:
|
if "object" in data_type and "properties" in object_values[value]:
|
||||||
details += self.render_object_details(object_values[value], str(value))
|
details += self.render_object_details(object_values[value], str(value))
|
||||||
|
elif "oneOf" in object_values[value]:
|
||||||
|
details += self.render_oneof_block(object_values[value], str(value))
|
||||||
|
|
||||||
li = OBJECT_LIST_ITEM_TEMPLATE.format(
|
li = OBJECT_LIST_ITEM_TEMPLATE.format(
|
||||||
value=value,
|
value=value,
|
||||||
@@ -237,11 +279,15 @@ class APIArgumentsTablePreprocessor(Preprocessor):
|
|||||||
)
|
)
|
||||||
|
|
||||||
li_elements.append(li)
|
li_elements.append(li)
|
||||||
|
if oneof:
|
||||||
object_details = OBJECT_DETAILS_TEMPLATE.format(
|
object_details = ONEOF_OBJECT_DETAILS_TEMPLATE.format(
|
||||||
argument=name,
|
values="\n".join(li_elements),
|
||||||
values="\n".join(li_elements),
|
)
|
||||||
)
|
else:
|
||||||
|
object_details = OBJECT_DETAILS_TEMPLATE.format(
|
||||||
|
argument=name,
|
||||||
|
values="\n".join(li_elements),
|
||||||
|
)
|
||||||
return object_details
|
return object_details
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,39 @@ class APIReturnValuesTablePreprocessor(Preprocessor):
|
|||||||
+ description
|
+ description
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def render_oneof_block(self, object_schema: Dict[str, Any], spacing: int) -> List[str]:
|
||||||
|
ans = []
|
||||||
|
block_spacing = spacing
|
||||||
|
for element in object_schema["oneOf"]:
|
||||||
|
spacing = block_spacing
|
||||||
|
if "description" not in element:
|
||||||
|
# If the description is not present, we still need to render the rest
|
||||||
|
# of the documentation of the element shifted towards left of the page.
|
||||||
|
spacing -= 4
|
||||||
|
else:
|
||||||
|
# Add the specialized description of the oneOf element.
|
||||||
|
data_type = generate_data_type(element)
|
||||||
|
ans.append(self.render_desc(element["description"], spacing, data_type))
|
||||||
|
# If the oneOf element is an object schema then render the documentation
|
||||||
|
# of its keys.
|
||||||
|
if "properties" in element:
|
||||||
|
ans += self.render_table(element["properties"], spacing + 4)
|
||||||
|
if element.get("additionalProperties", False):
|
||||||
|
additional_properties = element["additionalProperties"]
|
||||||
|
if "description" in additional_properties:
|
||||||
|
data_type = generate_data_type(additional_properties)
|
||||||
|
ans.append(
|
||||||
|
self.render_desc(
|
||||||
|
additional_properties["description"], spacing + 4, data_type
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if "properties" in additional_properties:
|
||||||
|
ans += self.render_table(
|
||||||
|
additional_properties["properties"],
|
||||||
|
spacing + 8,
|
||||||
|
)
|
||||||
|
return ans
|
||||||
|
|
||||||
def render_table(self, return_values: Dict[str, Any], spacing: int) -> List[str]:
|
def render_table(self, return_values: Dict[str, Any], spacing: int) -> List[str]:
|
||||||
IGNORE = ["result", "msg", "ignored_parameters_unsupported"]
|
IGNORE = ["result", "msg", "ignored_parameters_unsupported"]
|
||||||
ans = []
|
ans = []
|
||||||
@@ -165,16 +198,7 @@ class APIReturnValuesTablePreprocessor(Preprocessor):
|
|||||||
return_values[return_value]["description"], spacing, data_type, return_value
|
return_values[return_value]["description"], spacing, data_type, return_value
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
for element in return_values[return_value]["oneOf"]:
|
ans += self.render_oneof_block(return_values[return_value], spacing + 4)
|
||||||
if "description" not in element:
|
|
||||||
continue
|
|
||||||
# Add the specialized description of the oneOf element.
|
|
||||||
data_type = generate_data_type(element)
|
|
||||||
ans.append(self.render_desc(element["description"], spacing + 4, data_type))
|
|
||||||
# If the oneOf element is an object schema then render the documentation
|
|
||||||
# of its keys.
|
|
||||||
if "properties" in element:
|
|
||||||
ans += self.render_table(element["properties"], spacing + 8)
|
|
||||||
continue
|
continue
|
||||||
description = return_values[return_value]["description"]
|
description = return_values[return_value]["description"]
|
||||||
data_type = generate_data_type(return_values[return_value])
|
data_type = generate_data_type(return_values[return_value])
|
||||||
@@ -198,6 +222,10 @@ class APIReturnValuesTablePreprocessor(Preprocessor):
|
|||||||
return_values[return_value]["additionalProperties"]["properties"],
|
return_values[return_value]["additionalProperties"]["properties"],
|
||||||
spacing + 8,
|
spacing + 8,
|
||||||
)
|
)
|
||||||
|
elif "oneOf" in return_values[return_value]["additionalProperties"]:
|
||||||
|
ans += self.render_oneof_block(
|
||||||
|
return_values[return_value]["additionalProperties"], spacing + 8
|
||||||
|
)
|
||||||
elif return_values[return_value]["additionalProperties"].get(
|
elif return_values[return_value]["additionalProperties"].get(
|
||||||
"additionalProperties", False
|
"additionalProperties", False
|
||||||
):
|
):
|
||||||
@@ -220,13 +248,15 @@ class APIReturnValuesTablePreprocessor(Preprocessor):
|
|||||||
],
|
],
|
||||||
spacing + 12,
|
spacing + 12,
|
||||||
)
|
)
|
||||||
if (
|
if "items" in return_values[return_value]:
|
||||||
"items" in return_values[return_value]
|
if "properties" in return_values[return_value]["items"]:
|
||||||
and "properties" in return_values[return_value]["items"]
|
ans += self.render_table(
|
||||||
):
|
return_values[return_value]["items"]["properties"], spacing + 4
|
||||||
ans += self.render_table(
|
)
|
||||||
return_values[return_value]["items"]["properties"], spacing + 4
|
elif "oneOf" in return_values[return_value]["items"]:
|
||||||
)
|
ans += self.render_oneof_block(
|
||||||
|
return_values[return_value]["items"], spacing + 4
|
||||||
|
)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def generate_event_strings(self, event_data: EventData) -> List[str]:
|
def generate_event_strings(self, event_data: EventData) -> List[str]:
|
||||||
|
|||||||
Reference in New Issue
Block a user