method.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. # Copyright 2015 ksyun.com, Inc. or its affiliates. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"). You
  4. # may not use this file except in compliance with the License. A copy of
  5. # the License is located at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # or in the "license" file accompanying this file. This file is
  10. # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  11. # ANY KIND, either express or implied. See the License for the specific
  12. # language governing permissions and limitations under the License.
  13. import inspect
  14. from kscore.docs.params import RequestParamsDocumenter
  15. from kscore.docs.params import ResponseParamsDocumenter
  16. from kscore.docs.example import ResponseExampleDocumenter
  17. from kscore.docs.example import RequestExampleDocumenter
  18. def get_instance_public_methods(instance):
  19. """Retrieves an objects public methods
  20. :param instance: The instance of the class to inspect
  21. :rtype: dict
  22. :returns: A dictionary that represents an instance's methods where
  23. the keys are the name of the methods and the
  24. values are the handler to the method.
  25. """
  26. instance_members = inspect.getmembers(instance)
  27. instance_methods = {}
  28. for name, member in instance_members:
  29. if not name.startswith('_'):
  30. if inspect.ismethod(member):
  31. instance_methods[name] = member
  32. return instance_methods
  33. def document_model_driven_signature(section, name, operation_model,
  34. include=None, exclude=None):
  35. """Documents the signature of a model-driven method
  36. :param section: The section to write the documentation to.
  37. :param name: The name of the method
  38. :param operation_model: The operation model for the method
  39. :type include: Dictionary where keys are parameter names and
  40. values are the shapes of the parameter names.
  41. :param include: The parameter shapes to include in the documentation.
  42. :type exclude: List of the names of the parameters to exclude.
  43. :param exclude: The names of the parameters to exclude from
  44. documentation.
  45. """
  46. params = {}
  47. if operation_model.input_shape:
  48. params = operation_model.input_shape.members
  49. parameter_names = list(params.keys())
  50. if include is not None:
  51. for member in include:
  52. parameter_names.append(member.name)
  53. if exclude is not None:
  54. for member in exclude:
  55. if member in parameter_names:
  56. parameter_names.remove(member)
  57. signature_params = ''
  58. if parameter_names:
  59. signature_params = '**kwargs'
  60. section.style.start_sphinx_py_method(name, signature_params)
  61. def document_custom_signature(section, name, method,
  62. include=None, exclude=None):
  63. """Documents the signature of a custom method
  64. :param section: The section to write the documentation to.
  65. :param name: The name of the method
  66. :param method: The handle to the method being documented
  67. :type include: Dictionary where keys are parameter names and
  68. values are the shapes of the parameter names.
  69. :param include: The parameter shapes to include in the documentation.
  70. :type exclude: List of the names of the parameters to exclude.
  71. :param exclude: The names of the parameters to exclude from
  72. documentation.
  73. """
  74. args, varargs, keywords, defaults = inspect.getargspec(method)
  75. args = args[1:]
  76. signature_params = inspect.formatargspec(
  77. args, varargs, keywords, defaults)
  78. signature_params = signature_params.lstrip('(')
  79. signature_params = signature_params.rstrip(')')
  80. section.style.start_sphinx_py_method(name, signature_params)
  81. def document_custom_method(section, method_name, method):
  82. """Documents a non-data driven method
  83. :param section: The section to write the documentation to.
  84. :param method_name: The name of the method
  85. :param method: The handle to the method being documented
  86. """
  87. document_custom_signature(
  88. section, method_name, method)
  89. method_intro_section = section.add_new_section('method-intro')
  90. method_intro_section.writeln('')
  91. doc_string = inspect.getdoc(method)
  92. if doc_string is not None:
  93. method_intro_section.style.write_py_doc_string(doc_string)
  94. def document_model_driven_method(section, method_name, operation_model,
  95. event_emitter, method_description=None,
  96. example_prefix=None, include_input=None,
  97. include_output=None, exclude_input=None,
  98. exclude_output=None, document_output=True,
  99. include_signature=True):
  100. """Documents an individual method
  101. :param section: The section to write to
  102. :param method_name: The name of the method
  103. :param operation_model: The model of the operation
  104. :param event_emitter: The event emitter to use to emit events
  105. :param example_prefix: The prefix to use in the method example.
  106. :type include_input: Dictionary where keys are parameter names and
  107. values are the shapes of the parameter names.
  108. :param include_input: The parameter shapes to include in the
  109. input documentation.
  110. :type include_output: Dictionary where keys are parameter names and
  111. values are the shapes of the parameter names.
  112. :param include_input: The parameter shapes to include in the
  113. output documentation.
  114. :type exclude_input: List of the names of the parameters to exclude.
  115. :param exclude_input: The names of the parameters to exclude from
  116. input documentation.
  117. :type exclude_output: List of the names of the parameters to exclude.
  118. :param exclude_input: The names of the parameters to exclude from
  119. output documentation.
  120. :param document_output: A boolean flag to indicate whether to
  121. document the output.
  122. :param include_signature: Whether or not to include the signature.
  123. It is useful for generating docstrings.
  124. """
  125. # Add the signature if specified.
  126. if include_signature:
  127. document_model_driven_signature(
  128. section, method_name, operation_model, include=include_input,
  129. exclude=exclude_input)
  130. # Add the description for the method.
  131. method_intro_section = section.add_new_section('method-intro')
  132. method_intro_section.include_doc_string(method_description)
  133. # Add the example section.
  134. example_section = section.add_new_section('example')
  135. example_section.style.new_paragraph()
  136. example_section.style.bold('Request Syntax')
  137. context = {
  138. 'special_shape_types': {
  139. 'streaming_input_shape': operation_model.get_streaming_input(),
  140. 'streaming_output_shape': operation_model.get_streaming_output()
  141. }
  142. }
  143. if operation_model.input_shape:
  144. RequestExampleDocumenter(
  145. service_name=operation_model.service_model.service_name,
  146. operation_name=operation_model.name,
  147. event_emitter=event_emitter, context=context).document_example(
  148. example_section, operation_model.input_shape,
  149. prefix=example_prefix, include=include_input,
  150. exclude=exclude_input)
  151. else:
  152. example_section.style.new_paragraph()
  153. example_section.style.start_codeblock()
  154. example_section.write(example_prefix + '()')
  155. # Add the request parameter documentation.
  156. request_params_section = section.add_new_section('request-params')
  157. if operation_model.input_shape:
  158. RequestParamsDocumenter(
  159. service_name=operation_model.service_model.service_name,
  160. operation_name=operation_model.name,
  161. event_emitter=event_emitter, context=context).document_params(
  162. request_params_section, operation_model.input_shape,
  163. include=include_input, exclude=exclude_input)
  164. # Add the return value documentation
  165. return_section = section.add_new_section('return')
  166. return_section.style.new_line()
  167. if operation_model.output_shape is not None and document_output:
  168. return_section.write(':rtype: dict')
  169. return_section.style.new_line()
  170. return_section.write(':returns: ')
  171. return_section.style.indent()
  172. return_section.style.new_line()
  173. # Add an example return value
  174. return_example_section = return_section.add_new_section('example')
  175. return_example_section.style.new_line()
  176. return_example_section.style.bold('Response Syntax')
  177. return_example_section.style.new_paragraph()
  178. ResponseExampleDocumenter(
  179. service_name=operation_model.service_model.service_name,
  180. operation_name=operation_model.name,
  181. event_emitter=event_emitter,
  182. context=context).document_example(
  183. return_example_section, operation_model.output_shape,
  184. include=include_output, exclude=exclude_output)
  185. # Add a description for the return value
  186. return_description_section = return_section.add_new_section(
  187. 'description')
  188. return_description_section.style.new_line()
  189. return_description_section.style.bold('Response Structure')
  190. return_description_section.style.new_paragraph()
  191. ResponseParamsDocumenter(
  192. service_name=operation_model.service_model.service_name,
  193. operation_name=operation_model.name,
  194. event_emitter=event_emitter,
  195. context=context).document_params(
  196. return_description_section, operation_model.output_shape,
  197. include=include_output, exclude=exclude_output)
  198. else:
  199. return_section.write(':returns: None')