openapi: Pass api_url to curl example generation.

Our new curl example generation logic was broken, in that it hardcoded
localhost:9991 (without an HTTP method or anything) as the API URL.

It requires a bit of plumbing to make this possible.
This commit is contained in:
Tim Abbott 2019-08-16 12:17:01 -07:00
parent e8b4e80d45
commit 2366490ffc
3 changed files with 57 additions and 31 deletions

View File

@ -34,7 +34,6 @@ client = zulip.Client(config_file="~/zuliprc-admin")
"""
DEFAULT_API_URL = "localhost:9991/api"
DEFAULT_AUTH_EMAIL = "BOT_EMAIL_ADDRESS"
DEFAULT_AUTH_API_KEY = "BOT_API_KEY"
DEFAULT_EXAMPLE = {
@ -80,7 +79,8 @@ def extract_python_code_example(source: List[str], snippet: List[str]) -> List[s
source = source[end + 1:]
return extract_python_code_example(source, snippet)
def render_python_code_example(function: str, admin_config: Optional[bool]=False) -> List[str]:
def render_python_code_example(function: str, admin_config: Optional[bool]=False,
**kwargs: Any) -> List[str]:
method = zerver.openapi.python_examples.TEST_FUNCTIONS[function]
function_source_lines = inspect.getsourcelines(method)[0]
@ -121,9 +121,9 @@ def curl_method_arguments(endpoint: str, method: str,
raise ValueError(msg)
def generate_curl_example(endpoint: str, method: str,
api_url: str,
auth_email: str=DEFAULT_AUTH_EMAIL,
auth_api_key: str=DEFAULT_AUTH_API_KEY,
api_url: str=DEFAULT_API_URL,
exclude: List[str]=[]) -> List[str]:
lines = ["```curl"]
openapi_entry = openapi_spec.spec()['paths'][endpoint][method.lower()]
@ -166,7 +166,8 @@ cURL example.""".format(endpoint, method, param_name)
return lines
def render_curl_example(function: str, exclude: List[str]=[]) -> List[str]:
def render_curl_example(function: str, api_url: str,
exclude: List[str]=[]) -> List[str]:
""" A simple wrapper around generate_curl_example. """
parts = function.split(":")
endpoint = parts[0]
@ -176,8 +177,7 @@ def render_curl_example(function: str, exclude: List[str]=[]) -> List[str]:
kwargs["auth_email"] = parts[2]
if len(parts) > 3:
kwargs["auth_api_key"] = parts[3]
if len(parts) > 4:
kwargs["api_url"] = parts[4]
kwargs["api_url"] = api_url
kwargs["exclude"] = exclude
return generate_curl_example(endpoint, method, **kwargs)
@ -193,6 +193,14 @@ SUPPORTED_LANGUAGES = {
} # type: Dict[str, Any]
class APICodeExamplesGenerator(Extension):
def __init__(self, api_url: Optional[str]) -> None:
self.config = {
'api_url': [
api_url,
'API URL to use when rendering curl examples'
]
}
def extendMarkdown(self, md: markdown.Markdown, md_globals: Dict[str, Any]) -> None:
md.preprocessors.add(
'generate_code_example', APICodeExamplesPreprocessor(md, self.getConfigs()), '_begin'
@ -201,6 +209,7 @@ class APICodeExamplesGenerator(Extension):
class APICodeExamplesPreprocessor(Preprocessor):
def __init__(self, md: markdown.Markdown, config: Dict[str, Any]) -> None:
super(APICodeExamplesPreprocessor, self).__init__(md)
self.api_url = config['api_url']
def run(self, lines: List[str]) -> List[str]:
done = False
@ -214,6 +223,9 @@ class APICodeExamplesPreprocessor(Preprocessor):
function = match.group(3)
key = match.group(4)
argument = match.group(6)
if self.api_url is None:
raise AssertionError("Cannot render curl API examples without API URL set.")
options['api_url'] = self.api_url
if key == 'fixture':
if argument:
@ -262,4 +274,4 @@ class APICodeExamplesPreprocessor(Preprocessor):
return fixture
def makeExtension(*args: Any, **kwargs: str) -> APICodeExamplesGenerator:
return APICodeExamplesGenerator(**kwargs)
return APICodeExamplesGenerator(*args, **kwargs)

View File

@ -107,7 +107,6 @@ def render_markdown_path(markdown_file_path: str,
),
zerver.lib.bugdown.api_arguments_table_generator.makeExtension(
base_path='templates/zerver/api/'),
zerver.lib.bugdown.api_code_examples.makeExtension(),
zerver.lib.bugdown.nested_code_blocks.makeExtension(),
zerver.lib.bugdown.tabbed_sections.makeExtension(),
zerver.lib.bugdown.help_settings_links.makeExtension(),
@ -117,11 +116,20 @@ def render_markdown_path(markdown_file_path: str,
if md_macro_extension is None:
md_macro_extension = zerver.lib.bugdown.include.makeExtension(
base_path='templates/zerver/help/include/')
extensions = md_extensions
if 'api_url' in context:
# We need to generate the API code examples extension each
# time so the `api_url` config parameter can be set dynamically.
#
# TODO: Convert this to something more efficient involving
# passing the API URL as a direct parameter.
extensions = extensions + [zerver.lib.bugdown.api_code_examples.makeExtension(
api_url=context["api_url"],
)]
if not any(doc in markdown_file_path for doc in docs_without_macros):
extensions = extensions + [md_macro_extension]
if any(doc in markdown_file_path for doc in docs_without_macros):
md_engine = markdown.Markdown(extensions=md_extensions)
else:
md_engine = markdown.Markdown(extensions=md_extensions + [md_macro_extension])
md_engine = markdown.Markdown(extensions=extensions)
md_engine.reset()
jinja = engines['Jinja2']

View File

@ -695,11 +695,15 @@ class TestCurlExampleGeneration(ZulipTestCase):
}
}
def curl_example(self, endpoint: str, method: str, *args: Any, **kwargs: Any) -> List[str]:
return generate_curl_example(endpoint, method,
"http://localhost:9991/api", *args, **kwargs)
def test_generate_and_render_curl_example(self) -> None:
generated_curl_example = generate_curl_example("/get_stream_id", "GET")
generated_curl_example = self.curl_example("/get_stream_id", "GET")
expected_curl_example = [
"```curl",
"curl -X GET -G localhost:9991/api/v1/get_stream_id \\",
"curl -X GET -G http://localhost:9991/api/v1/get_stream_id \\",
" -u BOT_EMAIL_ADDRESS:BOT_API_KEY \\",
" -d 'stream=Denmark'",
"```"
@ -708,15 +712,15 @@ class TestCurlExampleGeneration(ZulipTestCase):
def test_generate_and_render_curl_example_with_nonexistant_endpoints(self) -> None:
with self.assertRaises(KeyError):
generate_curl_example("/mark_this_stream_as_read", "POST")
self.curl_example("/mark_this_stream_as_read", "POST")
with self.assertRaises(KeyError):
generate_curl_example("/mark_stream_as_read", "GET")
self.curl_example("/mark_stream_as_read", "GET")
def test_generate_and_render_curl_without_auth(self) -> None:
generated_curl_example = generate_curl_example("/dev_fetch_api_key", "POST")
generated_curl_example = self.curl_example("/dev_fetch_api_key", "POST")
expected_curl_example = [
"```curl",
"curl -X POST localhost:9991/api/v1/dev_fetch_api_key \\",
"curl -X POST http://localhost:9991/api/v1/dev_fetch_api_key \\",
" -d 'username=iago@zulip.com'",
"```"
]
@ -725,10 +729,10 @@ class TestCurlExampleGeneration(ZulipTestCase):
@patch("zerver.lib.openapi.OpenAPISpec.spec")
def test_generate_and_render_curl_with_default_examples(self, spec_mock: MagicMock) -> None:
spec_mock.return_value = self.spec_mock_without_examples
generated_curl_example = generate_curl_example("/mark_stream_as_read", "POST")
generated_curl_example = self.curl_example("/mark_stream_as_read", "POST")
expected_curl_example = [
"```curl",
"curl -X POST localhost:9991/api/v1/mark_stream_as_read \\",
"curl -X POST http://localhost:9991/api/v1/mark_stream_as_read \\",
" -d 'stream_id=1' \\",
" -d 'bool_param=false'",
"```"
@ -739,13 +743,13 @@ class TestCurlExampleGeneration(ZulipTestCase):
def test_generate_and_render_curl_with_invalid_method(self, spec_mock: MagicMock) -> None:
spec_mock.return_value = self.spec_mock_with_invalid_method
with self.assertRaises(ValueError):
generate_curl_example("/endpoint", "BREW") # see: HTCPCP
self.curl_example("/endpoint", "BREW") # see: HTCPCP
def test_generate_and_render_curl_with_array_example(self) -> None:
generated_curl_example = generate_curl_example("/messages", "GET")
generated_curl_example = self.curl_example("/messages", "GET")
expected_curl_example = [
'```curl',
'curl -X GET -G localhost:9991/api/v1/messages \\',
'curl -X GET -G http://localhost:9991/api/v1/messages \\',
' -u BOT_EMAIL_ADDRESS:BOT_API_KEY \\',
" -d 'anchor=42' \\",
" -d 'use_first_unread_anchor=true' \\",
@ -761,10 +765,10 @@ class TestCurlExampleGeneration(ZulipTestCase):
@patch("zerver.lib.openapi.OpenAPISpec.spec")
def test_generate_and_render_curl_with_object(self, spec_mock: MagicMock) -> None:
spec_mock.return_value = self.spec_mock_using_object
generated_curl_example = generate_curl_example("/endpoint", "GET")
generated_curl_example = self.curl_example("/endpoint", "GET")
expected_curl_example = [
'```curl',
'curl -X GET -G localhost:9991/api/v1/endpoint \\',
'curl -X GET -G http://localhost:9991/api/v1/endpoint \\',
' --data-urlencode param1=\'{"key": "value"}\'',
'```'
]
@ -774,19 +778,20 @@ class TestCurlExampleGeneration(ZulipTestCase):
def test_generate_and_render_curl_with_object_without_example(self, spec_mock: MagicMock) -> None:
spec_mock.return_value = self.spec_mock_using_object_without_example
with self.assertRaises(ValueError):
generate_curl_example("/endpoint", "GET")
self.curl_example("/endpoint", "GET")
@patch("zerver.lib.openapi.OpenAPISpec.spec")
def test_generate_and_render_curl_with_array_without_example(self, spec_mock: MagicMock) -> None:
spec_mock.return_value = self.spec_mock_using_array_without_example
with self.assertRaises(ValueError):
generate_curl_example("/endpoint", "GET")
self.curl_example("/endpoint", "GET")
def test_generate_and_render_curl_wrapper(self) -> None:
generated_curl_example = render_curl_example("/get_stream_id:GET:email:key:chat.zulip.org/api")
generated_curl_example = render_curl_example("/get_stream_id:GET:email:key",
api_url="https://zulip.example.com/api")
expected_curl_example = [
"```curl",
"curl -X GET -G chat.zulip.org/api/v1/get_stream_id \\",
"curl -X GET -G https://zulip.example.com/api/v1/get_stream_id \\",
" -u email:key \\",
" -d 'stream=Denmark'",
"```"
@ -794,10 +799,11 @@ class TestCurlExampleGeneration(ZulipTestCase):
self.assertEqual(generated_curl_example, expected_curl_example)
def test_generate_and_render_curl_example_with_excludes(self) -> None:
generated_curl_example = generate_curl_example("/messages", "GET", exclude=["client_gravatar", "apply_markdown"])
generated_curl_example = self.curl_example("/messages", "GET",
exclude=["client_gravatar", "apply_markdown"])
expected_curl_example = [
'```curl',
'curl -X GET -G localhost:9991/api/v1/messages \\',
'curl -X GET -G http://localhost:9991/api/v1/messages \\',
' -u BOT_EMAIL_ADDRESS:BOT_API_KEY \\',
" -d 'anchor=42' \\",
" -d 'use_first_unread_anchor=true' \\",