Example #1
0
 def setUp(self):
     self.model = {
         "metadata": {
             'endpointPrefix': 'myservice',
             'serviceFullName': 'MyService',
         },
         'operations': {
             'OperationName': {
                 'name':
                 'OperationName',
                 'errors': [
                     {
                         'shape': 'ExceptionMissingCode'
                     },
                     {
                         'shape': 'ExceptionWithModeledCode'
                     },
                 ],
             },
             'AnotherOperationName': {
                 'name':
                 'AnotherOperationName',
                 'errors': [
                     {
                         'shape': 'ExceptionForAnotherOperation'
                     },
                     {
                         'shape': 'ExceptionWithModeledCode'
                     },
                 ],
             }
         },
         'shapes': {
             'ExceptionWithModeledCode': {
                 'type': 'structure',
                 'members': {},
                 'error': {
                     'code': 'ModeledCode'
                 },
                 'exception': True,
             },
             'ExceptionMissingCode': {
                 'type': 'structure',
                 'members': {},
                 'exception': True,
             },
             'ExceptionForAnotherOperation': {
                 'type': 'structure',
                 'members': {},
                 'exception': True,
             }
         }
     }
     self.service_model = ServiceModel(self.model)
     self.exceptions_factory = ClientExceptionsFactory()
Example #2
0
def parse_client(session: Session, service_name: ServiceName, shape_parser: ShapeParser) -> Client:
    """
    Parse boto3 client to a structure.

    Arguments:
        session -- boto3 session.
        service_name -- Target service name.

    Returns:
        Client structure.
    """
    client = get_boto3_client(session, service_name)
    public_methods = get_public_methods(client)

    # remove methods that will be overriden
    if "get_paginator" in public_methods:
        del public_methods["get_paginator"]
    if "get_waiter" in public_methods:
        del public_methods["get_waiter"]

    result = Client(
        name=Client.get_class_name(service_name),
        service_name=service_name,
        boto3_client=client,
    )

    shape_method_map = shape_parser.get_client_method_map()
    result.methods.append(result.get_exceptions_property())
    for method_name, public_method in public_methods.items():
        if method_name in shape_method_map:
            method = shape_method_map[method_name]
        else:
            method = parse_method("Client", method_name, public_method, service_name)
        docstring = get_short_docstring(inspect.getdoc(public_method) or "")
        method.docstring = docstring
        result.methods.append(method)

    service_model = client.meta.service_model
    client_exceptions = ClientExceptionsFactory().create_client_exceptions(service_model)
    for exception_class_name in dir(client_exceptions):
        if exception_class_name.startswith("_"):
            continue
        if not exception_class_name[0].isupper():
            continue
        result.exceptions_class.attributes.append(
            Attribute(
                exception_class_name,
                TypeSubscript(
                    Type.Type,
                    [InternalImport("BotocoreClientError", stringify=False)],
                ),
            )
        )

    result.attributes.append(Attribute("meta", TypeClass(ClientMeta)))

    return result
Example #3
0
 def setUp(self):
     self.model = {
         "metadata": {
             'endpointPrefix': 'myservice',
             'serviceFullName': 'MyService',
         },
         'operations': {
             'OperationName': {
                 'name': 'OperationName',
                 'errors': [
                     {'shape': 'ExceptionMissingCode'},
                     {'shape': 'ExceptionWithModeledCode'},
                 ],
             },
             'AnotherOperationName': {
                 'name': 'AnotherOperationName',
                 'errors': [
                     {'shape': 'ExceptionForAnotherOperation'},
                     {'shape': 'ExceptionWithModeledCode'},
                 ],
             }
         },
         'shapes': {
             'ExceptionWithModeledCode': {
                 'type': 'structure',
                 'members': {},
                 'error': {
                     'code': 'ModeledCode'
                 },
                 'exception': True,
             },
             'ExceptionMissingCode': {
                 'type': 'structure',
                 'members': {},
                 'exception': True,
             },
             'ExceptionForAnotherOperation': {
                 'type': 'structure',
                 'members': {},
                 'exception': True,
             }
         }
     }
     self.service_model = ServiceModel(self.model)
     self.exceptions_factory = ClientExceptionsFactory()
 def _register_exceptions_factory(self):
     self._components.register_component('exceptions_factory',
                                         ClientExceptionsFactory())
Example #5
0
class TestClientExceptionsFactory(unittest.TestCase):
    def setUp(self):
        self.model = {
            "metadata": {
                'endpointPrefix': 'myservice',
                'serviceFullName': 'MyService',
            },
            'operations': {
                'OperationName': {
                    'name':
                    'OperationName',
                    'errors': [
                        {
                            'shape': 'ExceptionMissingCode'
                        },
                        {
                            'shape': 'ExceptionWithModeledCode'
                        },
                    ],
                },
                'AnotherOperationName': {
                    'name':
                    'AnotherOperationName',
                    'errors': [
                        {
                            'shape': 'ExceptionForAnotherOperation'
                        },
                        {
                            'shape': 'ExceptionWithModeledCode'
                        },
                    ],
                }
            },
            'shapes': {
                'ExceptionWithModeledCode': {
                    'type': 'structure',
                    'members': {},
                    'error': {
                        'code': 'ModeledCode'
                    },
                    'exception': True,
                },
                'ExceptionMissingCode': {
                    'type': 'structure',
                    'members': {},
                    'exception': True,
                },
                'ExceptionForAnotherOperation': {
                    'type': 'structure',
                    'members': {},
                    'exception': True,
                }
            }
        }
        self.service_model = ServiceModel(self.model)
        self.exceptions_factory = ClientExceptionsFactory()

    def test_class_name(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        self.assertEqual(exceptions.__class__.__name__, 'MyServiceExceptions')

    def test_creates_modeled_exception(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        self.assertTrue(hasattr(exceptions, 'ExceptionWithModeledCode'))
        modeled_exception = exceptions.ExceptionWithModeledCode
        self.assertEqual(modeled_exception.__name__,
                         'ExceptionWithModeledCode')
        self.assertTrue(issubclass(modeled_exception, ClientError))

    def test_collects_modeled_exceptions_for_all_operations(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        # Make sure exceptions were added for all operations by checking
        # an exception only found on an a different operation.
        self.assertTrue(hasattr(exceptions, 'ExceptionForAnotherOperation'))
        modeled_exception = exceptions.ExceptionForAnotherOperation
        self.assertEqual(modeled_exception.__name__,
                         'ExceptionForAnotherOperation')
        self.assertTrue(issubclass(modeled_exception, ClientError))

    def test_creates_modeled_exception_mapping_that_has_code(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        exception = exceptions.from_code('ModeledCode')
        self.assertEqual(exception.__name__, 'ExceptionWithModeledCode')
        self.assertTrue(issubclass(exception, ClientError))

    def test_creates_modeled_exception_mapping_that_has_no_code(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        # For exceptions that do not have an explicit code associated to them,
        # the code is the name of the exception.
        exception = exceptions.from_code('ExceptionMissingCode')
        self.assertEqual(exception.__name__, 'ExceptionMissingCode')
        self.assertTrue(issubclass(exception, ClientError))
Example #6
0
class TestClientExceptionsFactory(unittest.TestCase):
    def setUp(self):
        self.model = {
            "metadata": {
                'endpointPrefix': 'myservice',
                'serviceFullName': 'MyService',
            },
            'operations': {
                'OperationName': {
                    'name': 'OperationName',
                    'errors': [
                        {'shape': 'ExceptionMissingCode'},
                        {'shape': 'ExceptionWithModeledCode'},
                    ],
                },
                'AnotherOperationName': {
                    'name': 'AnotherOperationName',
                    'errors': [
                        {'shape': 'ExceptionForAnotherOperation'},
                        {'shape': 'ExceptionWithModeledCode'},
                    ],
                }
            },
            'shapes': {
                'ExceptionWithModeledCode': {
                    'type': 'structure',
                    'members': {},
                    'error': {
                        'code': 'ModeledCode'
                    },
                    'exception': True,
                },
                'ExceptionMissingCode': {
                    'type': 'structure',
                    'members': {},
                    'exception': True,
                },
                'ExceptionForAnotherOperation': {
                    'type': 'structure',
                    'members': {},
                    'exception': True,
                }
            }
        }
        self.service_model = ServiceModel(self.model)
        self.exceptions_factory = ClientExceptionsFactory()

    def test_class_name(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        self.assertEqual(exceptions.__class__.__name__, 'MyServiceExceptions')

    def test_creates_modeled_exception(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        self.assertTrue(hasattr(exceptions, 'ExceptionWithModeledCode'))
        modeled_exception = exceptions.ExceptionWithModeledCode
        self.assertEqual(
            modeled_exception.__name__, 'ExceptionWithModeledCode')
        self.assertTrue(issubclass(modeled_exception, ClientError))

    def test_collects_modeled_exceptions_for_all_operations(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        # Make sure exceptions were added for all operations by checking
        # an exception only found on an a different operation.
        self.assertTrue(hasattr(exceptions, 'ExceptionForAnotherOperation'))
        modeled_exception = exceptions.ExceptionForAnotherOperation
        self.assertEqual(
            modeled_exception.__name__, 'ExceptionForAnotherOperation')
        self.assertTrue(issubclass(modeled_exception, ClientError))

    def test_creates_modeled_exception_mapping_that_has_code(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        exception = exceptions.from_code('ModeledCode')
        self.assertEqual(exception.__name__, 'ExceptionWithModeledCode')
        self.assertTrue(issubclass(exception, ClientError))

    def test_creates_modeled_exception_mapping_that_has_no_code(self):
        exceptions = self.exceptions_factory.create_client_exceptions(
            self.service_model)
        # For exceptions that do not have an explicit code associated to them,
        # the code is the name of the exception.
        exception = exceptions.from_code('ExceptionMissingCode')
        self.assertEqual(exception.__name__, 'ExceptionMissingCode')
        self.assertTrue(issubclass(exception, ClientError))
Example #7
0
def parse_client(session: Session, service_name: ServiceName,
                 shape_parser: ShapeParser) -> Client:
    """
    Parse boto3 client to a structure.

    Arguments:
        session -- boto3 session.
        service_name -- Target service name.

    Returns:
        Client structure.
    """
    client = get_boto3_client(session, service_name)
    public_methods = get_public_methods(client)

    # remove methods that will be overriden
    if "get_paginator" in public_methods:
        del public_methods["get_paginator"]
    if "get_waiter" in public_methods:
        del public_methods["get_waiter"]

    result = Client(
        name=f"{service_name.class_name}Client",
        service_name=service_name,
        boto3_client=client,
        docstring=(f"[{service_name.class_name}.Client documentation]"
                   f"({service_name.doc_link}.Client)"),
    )

    shape_method_map = shape_parser.get_client_method_map()
    for method_name, public_method in public_methods.items():
        if method_name in shape_method_map:
            method = shape_method_map[method_name]
        else:
            method = parse_method("Client", method_name, public_method,
                                  service_name)
        method.docstring = (f"[Client.{method_name} documentation]"
                            f"({service_name.doc_link}.Client.{method_name})")
        result.methods.append(method)

    service_model = client.meta.service_model
    client_exceptions = ClientExceptionsFactory().create_client_exceptions(
        service_model)
    for exception_class_name in dir(client_exceptions):
        if exception_class_name.startswith("_"):
            continue
        if not exception_class_name[0].isupper():
            continue
        result.exceptions_class.attributes.append(
            Attribute(
                exception_class_name,
                TypeSubscript(
                    Type.Type,
                    [TypeClass(ClientError, alias="Boto3ClientError")]),
            ))

    result.attributes.append(
        Attribute(
            "exceptions",
            InternalImport(
                name=result.exceptions_class.name,
                module_name=ServiceModuleName.client,
                service_name=service_name,
                stringify=False,
            ),
        ))
    return result