def test_exclude_output(self):
     self.add_shape_to_params('Biz', 'String')
     document_model_driven_method(
         self.doc_structure, 'foo', self.operation_model,
         event_emitter=self.event_emitter,
         method_description='This describes the foo method.',
         example_prefix='response = client.foo',
         exclude_output=['Bar']
     )
     self.assert_contains_lines_in_order([
         '.. py:method:: foo(**kwargs)',
         '  This describes the foo method.',
         '  **Request Syntax**',
         '  ::',
         '    response = client.foo(',
         '        Bar=\'string\'',
         '        Biz=\'string\'',
         '    )',
         '  :type Biz: string',
         '  :param Biz:',
         '  :rtype: dict',
         '  :returns:',
         '    **Response Syntax**',
         '    ::',
         '      {',
         '          \'Biz\': \'string\'',
         '      }',
         '    **Response Structure**',
         '    - *(dict) --*',
         '      - **Biz** *(string) --*'
     ])
     self.assert_not_contains_lines([
         '\'Bar\': \'string\'',
         '- **Bar** *(string) --*',
     ])
 def test_include_output(self):
     include_params = [
         DocumentedShape(
             name='Biz', type_name='string', documentation='biz docs')
     ]
     document_model_driven_method(
         self.doc_structure, 'foo', self.operation_model,
         event_emitter=self.event_emitter,
         method_description='This describes the foo method.',
         example_prefix='response = client.foo',
         include_output=include_params
     )
     self.assert_contains_lines_in_order([
         '.. py:method:: foo(**kwargs)',
         '  This describes the foo method.',
         '  **Request Syntax**',
         '  ::',
         '    response = client.foo(',
         '        Bar=\'string\'',
         '    )',
         '  :type Bar: string',
         '  :param Bar:',
         '  :rtype: dict',
         '  :returns:',
         '    **Response Syntax**',
         '    ::',
         '      {',
         '          \'Bar\': \'string\'',
         '          \'Biz\': \'string\'',
         '      }',
         '    **Response Structure**',
         '    - *(dict) --*',
         '      - **Bar** *(string) --*',
         '      - **Biz** *(string) --*'
     ])
    def test_default(self):
        document_model_driven_method(
            self.doc_structure, 'foo', self.operation_model,
            event_emitter=self.event_emitter,
            method_description='This describes the foo method.',
            example_prefix='response = client.foo'
        )

        self.assert_contains_lines_in_order([
            '.. py:method:: foo(**kwargs)',
            '  This describes the foo method.',
           # cross_ref_link,
            '  **Request Syntax**',
            '  ::',
            '    response = client.foo(',
            '        Bar=\'string\'',
            '    )',
            '  :type Bar: string',
            '  :param Bar:',
            '  :rtype: dict',
            '  :returns:',
            '    **Response Syntax**',
            '    ::',
            '      {',
            '          \'Bar\': \'string\'',
            '      }',
            '    **Response Structure**',
            '    - *(dict) --*',
            '      - **Bar** *(string) --*'
        ])
Beispiel #4
0
def document_model_driven_resource_method(
    section,
    method_name,
    operation_model,
    event_emitter,
    method_description=None,
    example_prefix=None,
    include_input=None,
    include_output=None,
    exclude_input=None,
    exclude_output=None,
    document_output=True,
    resource_action_model=None,
    include_signature=True,
):

    document_model_driven_method(
        section=section,
        method_name=method_name,
        operation_model=operation_model,
        event_emitter=event_emitter,
        method_description=method_description,
        example_prefix=example_prefix,
        include_input=include_input,
        include_output=include_output,
        exclude_input=exclude_input,
        exclude_output=exclude_output,
        document_output=document_output,
        include_signature=include_signature,
    )

    # If this action returns a resource modify the return example to
    # appropriately reflect that.
    if resource_action_model.resource:
        if 'return' in section.available_sections:
            section.delete_section('return')
        resource_type = resource_action_model.resource.type

        new_return_section = section.add_new_section('return')
        return_resource_type = '{}.{}'.format(
            operation_model.service_model.service_name, resource_type)

        return_type = f':py:class:`{return_resource_type}`'
        return_description = f'{resource_type} resource'

        if _method_returns_resource_list(resource_action_model.resource):
            return_type = f'list({return_type})'
            return_description = f'A list of {resource_type} resources'

        new_return_section.style.new_line()
        new_return_section.write(f':rtype: {return_type}')
        new_return_section.style.new_line()
        new_return_section.write(f':returns: {return_description}')
        new_return_section.style.new_line()
 def test_streaming_body_in_output(self):
     self.add_shape_to_params('Body', 'Blob')
     self.json_model['shapes']['Blob'] = {'type': 'blob'}
     self.json_model['shapes']['SampleOperationInputOutput']['payload'] = \
         'Body'
     document_model_driven_method(
         self.doc_structure, 'foo', self.operation_model,
         event_emitter=self.event_emitter,
         method_description='This describes the foo method.',
         example_prefix='response = client.foo'
     )
     self.assert_contains_line('**Body** (:class:`.StreamingBody`)')
Beispiel #6
0
def document_resource_waiter(
    section,
    resource_name,
    event_emitter,
    service_model,
    resource_waiter_model,
    service_waiter_model,
    include_signature=True,
):
    waiter_model = service_waiter_model.get_waiter(
        resource_waiter_model.waiter_name
    )
    operation_model = service_model.operation_model(waiter_model.operation)

    ignore_params = get_resource_ignore_params(resource_waiter_model.params)
    service_module_name = get_service_module_name(service_model)
    description = (
        'Waits until this {} is {}. This method calls '
        ':py:meth:`{}.Waiter.{}.wait` which polls. '
        ':py:meth:`{}.Client.{}` every {} seconds until '
        'a successful state is reached. An error is returned '
        'after {} failed checks.'.format(
            resource_name,
            ' '.join(resource_waiter_model.name.split('_')[2:]),
            service_module_name,
            xform_name(resource_waiter_model.waiter_name),
            service_module_name,
            xform_name(waiter_model.operation),
            waiter_model.delay,
            waiter_model.max_attempts,
        )
    )
    example_prefix = '{}.{}'.format(
        xform_name(resource_name), resource_waiter_model.name
    )
    document_model_driven_method(
        section=section,
        method_name=resource_waiter_model.name,
        operation_model=operation_model,
        event_emitter=event_emitter,
        example_prefix=example_prefix,
        method_description=description,
        exclude_input=ignore_params,
        include_signature=include_signature,
    )
    if 'return' in section.available_sections:
        # Waiters do not return anything so we should remove
        # any sections that may document the underlying return
        # value of the client method.
        return_section = section.get_section('return')
        return_section.clear_text()
        return_section.remove_all_sections()
        return_section.write(':returns: None')
Beispiel #7
0
def document_model_driven_resource_method(section,
                                          method_name,
                                          operation_model,
                                          event_emitter,
                                          method_description=None,
                                          example_prefix=None,
                                          include_input=None,
                                          include_output=None,
                                          exclude_input=None,
                                          exclude_output=None,
                                          document_output=True,
                                          resource_action_model=None,
                                          include_signature=True):

    document_model_driven_method(section=section,
                                 method_name=method_name,
                                 operation_model=operation_model,
                                 event_emitter=event_emitter,
                                 method_description=method_description,
                                 example_prefix=example_prefix,
                                 include_input=include_input,
                                 include_output=include_output,
                                 exclude_input=exclude_input,
                                 exclude_output=exclude_output,
                                 document_output=document_output,
                                 include_signature=include_signature)

    # If this action returns a resource modify the return example to
    # appropriately reflect that.
    if resource_action_model.resource:
        if 'return' in section.available_sections:
            section.delete_section('return')
        resource_type = resource_action_model.resource.type

        new_return_section = section.add_new_section('return')
        return_resource_type = '%s.%s' % (
            operation_model.service_model.service_name, resource_type)

        return_type = ':py:class:`%s`' % return_resource_type
        return_description = '%s resource' % (resource_type)

        if _method_returns_resource_list(resource_action_model.resource):
            return_type = 'list(%s)' % return_type
            return_description = 'A list of %s resources' % (resource_type)

        new_return_section.style.new_line()
        new_return_section.write(':rtype: %s' % return_type)
        new_return_section.style.new_line()
        new_return_section.write(':returns: %s' % return_description)
        new_return_section.style.new_line()
Beispiel #8
0
def document_load_reload_action(
    section,
    action_name,
    resource_name,
    event_emitter,
    load_model,
    service_model,
    include_signature=True,
):
    """Documents the resource load action

    :param section: The section to write to

    :param action_name: The name of the loading action should be load or reload

    :param resource_name: The name of the resource

    :param event_emitter: The event emitter to use to emit events

    :param load_model: The model of the load action

    :param service_model: The model of the service

    :param include_signature: Whether or not to include the signature.
        It is useful for generating docstrings.
    """
    description = (
        'Calls :py:meth:`{}.Client.{}` to update the attributes of the '
        '{} resource. Note that the load and reload methods are '
        'the same method and can be used interchangeably.'.format(
            get_service_module_name(service_model),
            xform_name(load_model.request.operation),
            resource_name,
        ))
    example_resource_name = xform_name(resource_name)
    if service_model.service_name == resource_name:
        example_resource_name = resource_name
    example_prefix = f'{example_resource_name}.{action_name}'
    document_model_driven_method(
        section=section,
        method_name=action_name,
        operation_model=OperationModel({}, service_model),
        event_emitter=event_emitter,
        method_description=description,
        example_prefix=example_prefix,
        include_signature=include_signature,
    )
 def test_streaming_body_in_input(self):
     del self.json_model['operations']['SampleOperation']['output']
     self.add_shape_to_params('Body', 'Blob')
     self.json_model['shapes']['Blob'] = {'type': 'blob'}
     self.json_model['shapes']['SampleOperationInputOutput']['payload'] = \
         'Body'
     document_model_driven_method(
         self.doc_structure, 'foo', self.operation_model,
         event_emitter=self.event_emitter,
         method_description='This describes the foo method.',
         example_prefix='response = client.foo'
     )
     # The line in the example
     self.assert_contains_line('Body=b\'bytes\'|file')
     # The line in the parameter description
     self.assert_contains_line(
         ':type Body: bytes or seekable file-like object')
 def test_no_input_output_shape(self):
     del self.json_model['operations']['SampleOperation']['input']
     del self.json_model['operations']['SampleOperation']['output']
     document_model_driven_method(
         self.doc_structure, 'foo', self.operation_model,
         event_emitter=self.event_emitter,
         method_description='This describes the foo method.',
         example_prefix='response = client.foo'
     )
     self.assert_contains_lines_in_order([
         '.. py:method:: foo()',
         '  This describes the foo method.',
         '  **Request Syntax**',
         '  ::',
         '    response = client.foo()',
         '  :returns: None',
     ])
    def _add_model_driven_method(self, section, method_name):
        service_model = self._client.meta.service_model
        operation_name = self._client.meta.method_to_api_mapping[method_name]
        operation_model = service_model.operation_model(operation_name)

        example_prefix = 'response = client.%s' % method_name
        document_model_driven_method(
            section, method_name, operation_model,
            event_emitter=self._client.meta.events,
            method_description=operation_model.documentation,
            example_prefix=example_prefix,
        )

        # Add the shared examples
        shared_examples = self._shared_examples.get(operation_name)
        if shared_examples:
            document_shared_examples(
                section, operation_model, example_prefix, shared_examples)
def document_wait_method(section,
                         waiter_name,
                         event_emitter,
                         service_model,
                         service_waiter_model,
                         include_signature=True):
    """Documents a the wait method of a waiter

    :param section: The section to write to

    :param waiter_name: The name of the waiter

    :param event_emitter: The event emitter to use to emit events

    :param service_model: The service model

    :param service_waiter_model: The waiter model associated to the service

    :param include_signature: Whether or not to include the signature.
        It is useful for generating docstrings.
    """
    waiter_model = service_waiter_model.get_waiter(waiter_name)
    operation_model = service_model.operation_model(waiter_model.operation)

    wait_description = (
        'Polls :py:meth:`{0}.Client.{1}` every {2} '
        'seconds until a successful state is reached. An error is '
        'returned after {3} failed checks.'.format(
            get_service_module_name(service_model),
            xform_name(waiter_model.operation), waiter_model.delay,
            waiter_model.max_attempts))

    document_model_driven_method(section,
                                 'wait',
                                 operation_model,
                                 event_emitter=event_emitter,
                                 method_description=wait_description,
                                 example_prefix='waiter.wait',
                                 document_output=False,
                                 include_signature=include_signature)
def document_paginate_method(section,
                             paginator_name,
                             event_emitter,
                             service_model,
                             paginator_config,
                             include_signature=True):
    """Documents the paginate method of a paginator

    :param section: The section to write to

    :param paginator_name: The name of the paginator. It is snake cased.

    :param event_emitter: The event emitter to use to emit events

    :param service_model: The service model

    :param paginator_config: The paginator config associated to a particular
        paginator.

    :param include_signature: Whether or not to include the signature.
        It is useful for generating docstrings.
    """
    # Retrieve the operation model of the underlying operation.
    operation_model = service_model.operation_model(paginator_name)

    # Add representations of the request and response parameters
    # we want to include in the description of the paginate method.
    # These are parameters we expose via the ibm_botocore interface.
    pagination_config_members = OrderedDict()

    pagination_config_members['MaxItems'] = DocumentedShape(
        name='MaxItems',
        type_name='integer',
        documentation=('<p>The total number of items to return. If the total '
                       'number of items available is more than the value '
                       'specified in max-items then a <code>NextToken</code> '
                       'will be provided in the output that you can use to '
                       'resume pagination.</p>'))

    pagination_config_members['PageSize'] = DocumentedShape(
        name='PageSize',
        type_name='integer',
        documentation='<p>The size of each page.<p>')

    pagination_config_members['StartingToken'] = DocumentedShape(
        name='StartingToken',
        type_name='string',
        documentation=('<p>A token to specify where to start paginating. '
                       'This is the <code>NextToken</code> from a previous '
                       'response.</p>'))

    botocore_pagination_params = [
        DocumentedShape(
            name='PaginationConfig',
            type_name='structure',
            documentation=(
                '<p>A dictionary that provides parameters to control '
                'pagination.</p>'),
            members=pagination_config_members)
    ]

    botocore_pagination_response_params = [
        DocumentedShape(name='NextToken',
                        type_name='string',
                        documentation=('<p>A token to resume pagination.</p>'))
    ]

    service_pagination_params = []

    # Add the normal input token of the method to a list
    # of input paramters that we wish to hide since we expose our own.
    if isinstance(paginator_config['input_token'], list):
        service_pagination_params += paginator_config['input_token']
    else:
        service_pagination_params.append(paginator_config['input_token'])

    # Hide the limit key in the documentation.
    if paginator_config.get('limit_key', None):
        service_pagination_params.append(paginator_config['limit_key'])

    # Hide the output tokens in the documentation.
    service_pagination_response_params = []
    if isinstance(paginator_config['output_token'], list):
        service_pagination_response_params += paginator_config['output_token']
    else:
        service_pagination_response_params.append(
            paginator_config['output_token'])

    paginate_description = (
        'Creates an iterator that will paginate through responses '
        'from :py:meth:`{0}.Client.{1}`.'.format(
            get_service_module_name(service_model),
            xform_name(paginator_name)))

    document_model_driven_method(
        section,
        'paginate',
        operation_model,
        event_emitter=event_emitter,
        method_description=paginate_description,
        example_prefix='response_iterator = paginator.paginate',
        include_input=botocore_pagination_params,
        include_output=botocore_pagination_response_params,
        exclude_input=service_pagination_params,
        exclude_output=service_pagination_response_params,
        include_signature=include_signature)
def document_wait_method(section,
                         waiter_name,
                         event_emitter,
                         service_model,
                         service_waiter_model,
                         include_signature=True):
    """Documents a the wait method of a waiter

    :param section: The section to write to

    :param waiter_name: The name of the waiter

    :param event_emitter: The event emitter to use to emit events

    :param service_model: The service model

    :param service_waiter_model: The waiter model associated to the service

    :param include_signature: Whether or not to include the signature.
        It is useful for generating docstrings.
    """
    waiter_model = service_waiter_model.get_waiter(waiter_name)
    operation_model = service_model.operation_model(waiter_model.operation)

    waiter_config_members = OrderedDict()

    waiter_config_members['Delay'] = DocumentedShape(
        name='Delay',
        type_name='integer',
        documentation=('<p>The amount of time in seconds to wait between '
                       'attempts. Default: {0}</p>'.format(
                           waiter_model.delay)))

    waiter_config_members['MaxAttempts'] = DocumentedShape(
        name='MaxAttempts',
        type_name='integer',
        documentation=('<p>The maximum number of attempts to be made. '
                       'Default: {0}</p>'.format(waiter_model.max_attempts)))

    botocore_waiter_params = [
        DocumentedShape(
            name='WaiterConfig',
            type_name='structure',
            documentation=(
                '<p>A dictionary that provides parameters to control '
                'waiting behavior.</p>'),
            members=waiter_config_members)
    ]

    wait_description = (
        'Polls :py:meth:`{0}.Client.{1}` every {2} '
        'seconds until a successful state is reached. An error is '
        'returned after {3} failed checks.'.format(
            get_service_module_name(service_model),
            xform_name(waiter_model.operation), waiter_model.delay,
            waiter_model.max_attempts))

    document_model_driven_method(section,
                                 'wait',
                                 operation_model,
                                 event_emitter=event_emitter,
                                 method_description=wait_description,
                                 example_prefix='waiter.wait',
                                 include_input=botocore_waiter_params,
                                 document_output=False,
                                 include_signature=include_signature)
Beispiel #15
0
 def _write_docstring(self, *args, **kwargs):
     document_model_driven_method(*args, **kwargs)