codekingpro/portable-devtools
114k
1# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.2#3# Licensed under the Apache License, Version 2.0 (the "License"). You4# may not use this file except in compliance with the License. A copy of5# the License is located at6#7# http://aws.amazon.com/apache2.0/8#9# or in the "license" file accompanying this file. This file is10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF11# ANY KIND, either express or implied. See the License for the specific12# language governing permissions and limitations under the License.13import os14 15from botocore import xform_name16from botocore.compat import OrderedDict17from botocore.docs.bcdoc.restdoc import DocumentStructure18from botocore.docs.method import document_model_driven_method19from botocore.docs.utils import DocumentedShape20from botocore.utils import get_service_module_name21 22 23class PaginatorDocumenter:24 def __init__(self, client, service_paginator_model, root_docs_path):25 self._client = client26 self._client_class_name = self._client.__class__.__name__27 self._service_name = self._client.meta.service_model.service_name28 self._service_paginator_model = service_paginator_model29 self._root_docs_path = root_docs_path30 self._USER_GUIDE_LINK = (31 'https://boto3.amazonaws.com/'32 'v1/documentation/api/latest/guide/paginators.html'33 )34 35 def document_paginators(self, section):36 """Documents the various paginators for a service37 38 param section: The section to write to.39 """40 section.style.h2('Paginators')41 self._add_overview(section)42 section.style.new_line()43 section.writeln('The available paginators are:')44 section.style.toctree()45 46 paginator_names = sorted(47 self._service_paginator_model._paginator_config48 )49 50 # List the available paginators and then document each paginator.51 for paginator_name in paginator_names:52 section.style.tocitem(53 f'{self._service_name}/paginator/{paginator_name}'54 )55 # Create a new DocumentStructure for each paginator and add contents.56 paginator_doc_structure = DocumentStructure(57 paginator_name, target='html'58 )59 self._add_paginator(paginator_doc_structure, paginator_name)60 # Write paginators in individual/nested files.61 # Path: <root>/reference/services/<service>/paginator/<paginator_name>.rst62 paginator_dir_path = os.path.join(63 self._root_docs_path, self._service_name, 'paginator'64 )65 paginator_doc_structure.write_to_file(66 paginator_dir_path, paginator_name67 )68 69 def _add_paginator(self, section, paginator_name):70 breadcrumb_section = section.add_new_section('breadcrumb')71 breadcrumb_section.style.ref(72 self._client_class_name, f'../../{self._service_name}'73 )74 breadcrumb_section.write(f' / Paginator / {paginator_name}')75 section.add_title_section(paginator_name)76 77 # Docment the paginator class78 paginator_section = section.add_new_section(paginator_name)79 paginator_section.style.start_sphinx_py_class(80 class_name=(81 f'{self._client_class_name}.Paginator.{paginator_name}'82 )83 )84 paginator_section.style.start_codeblock()85 paginator_section.style.new_line()86 87 # Document how to instantiate the paginator.88 paginator_section.write(89 f"paginator = client.get_paginator('{xform_name(paginator_name)}')"90 )91 paginator_section.style.end_codeblock()92 paginator_section.style.new_line()93 # Get the pagination model for the particular paginator.94 paginator_config = self._service_paginator_model.get_paginator(95 paginator_name96 )97 document_paginate_method(98 section=paginator_section,99 paginator_name=paginator_name,100 event_emitter=self._client.meta.events,101 service_model=self._client.meta.service_model,102 paginator_config=paginator_config,103 )104 105 def _add_overview(self, section):106 section.style.new_line()107 section.write(108 'Paginators are available on a client instance '109 'via the ``get_paginator`` method. For more detailed instructions '110 'and examples on the usage of paginators, see the '111 'paginators '112 )113 section.style.external_link(114 title='user guide',115 link=self._USER_GUIDE_LINK,116 )117 section.write('.')118 section.style.new_line()119 120 121def document_paginate_method(122 section,123 paginator_name,124 event_emitter,125 service_model,126 paginator_config,127 include_signature=True,128):129 """Documents the paginate method of a paginator130 131 :param section: The section to write to132 133 :param paginator_name: The name of the paginator. It is snake cased.134 135 :param event_emitter: The event emitter to use to emit events136 137 :param service_model: The service model138 139 :param paginator_config: The paginator config associated to a particular140 paginator.141 142 :param include_signature: Whether or not to include the signature.143 It is useful for generating docstrings.144 """145 # Retrieve the operation model of the underlying operation.146 operation_model = service_model.operation_model(paginator_name)147 148 # Add representations of the request and response parameters149 # we want to include in the description of the paginate method.150 # These are parameters we expose via the botocore interface.151 pagination_config_members = OrderedDict()152 153 pagination_config_members['MaxItems'] = DocumentedShape(154 name='MaxItems',155 type_name='integer',156 documentation=(157 '<p>The total number of items to return. If the total '158 'number of items available is more than the value '159 'specified in max-items then a <code>NextToken</code> '160 'will be provided in the output that you can use to '161 'resume pagination.</p>'162 ),163 )164 165 if paginator_config.get('limit_key', None):166 pagination_config_members['PageSize'] = DocumentedShape(167 name='PageSize',168 type_name='integer',169 documentation='<p>The size of each page.<p>',170 )171 172 pagination_config_members['StartingToken'] = DocumentedShape(173 name='StartingToken',174 type_name='string',175 documentation=(176 '<p>A token to specify where to start paginating. '177 'This is the <code>NextToken</code> from a previous '178 'response.</p>'179 ),180 )181 182 botocore_pagination_params = [183 DocumentedShape(184 name='PaginationConfig',185 type_name='structure',186 documentation=(187 '<p>A dictionary that provides parameters to control '188 'pagination.</p>'189 ),190 members=pagination_config_members,191 )192 ]193 194 botocore_pagination_response_params = [195 DocumentedShape(196 name='NextToken',197 type_name='string',198 documentation=('<p>A token to resume pagination.</p>'),199 )200 ]201 202 service_pagination_params = []203 204 # Add the normal input token of the method to a list205 # of input paramters that we wish to hide since we expose our own.206 if isinstance(paginator_config['input_token'], list):207 service_pagination_params += paginator_config['input_token']208 else:209 service_pagination_params.append(paginator_config['input_token'])210 211 # Hide the limit key in the documentation.212 if paginator_config.get('limit_key', None):213 service_pagination_params.append(paginator_config['limit_key'])214 215 # Hide the output tokens in the documentation.216 service_pagination_response_params = []217 if isinstance(paginator_config['output_token'], list):218 service_pagination_response_params += paginator_config['output_token']219 else:220 service_pagination_response_params.append(221 paginator_config['output_token']222 )223 224 paginate_description = (225 'Creates an iterator that will paginate through responses '226 'from :py:meth:`{}.Client.{}`.'.format(227 get_service_module_name(service_model), xform_name(paginator_name)228 )229 )230 231 document_model_driven_method(232 section,233 'paginate',234 operation_model,235 event_emitter=event_emitter,236 method_description=paginate_description,237 example_prefix='response_iterator = paginator.paginate',238 include_input=botocore_pagination_params,239 include_output=botocore_pagination_response_params,240 exclude_input=service_pagination_params,241 exclude_output=service_pagination_response_params,242 include_signature=include_signature,243 )244 