Ejemplo n.º 1
0
    def __init__(self, services, tns, name=None,
                          in_protocol=None, out_protocol=None, interface=None):
        self.services = tuple(services)
        self.tns = tns
        self.name = name

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.interface = Interface(self)
        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()
        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)

        self.reinitialize()
Ejemplo n.º 2
0
    def __init__(self, app):
        self.app = app
        self.app.transport = self.transport  # FIXME: this is weird
        self.appinit()

        self.event_manager = EventManager(self)
        self.doc = AllYourInterfaceDocuments(app.interface)
Ejemplo n.º 3
0
    def __init__(self, cls_name, cls_bases, cls_dict):
        super(ServiceBaseMeta, self).__init__(cls_name, cls_bases, cls_dict)

        self.__has_aux_methods = self.__aux__ is not None
        self.public_methods = {}
        self.event_manager = EventManager(
            self, self.__get_base_event_handlers(cls_bases))

        for k, v in cls_dict.items():
            if hasattr(v, '_is_rpc'):
                descriptor = v(_default_function_name=k)

                # these two lines are needed for staticmethod wrapping to work
                setattr(self, k, staticmethod(descriptor.function))
                descriptor.reset_function(getattr(self, k))

                try:
                    getattr(self, k).descriptor = descriptor
                except AttributeError as e:
                    pass
                    # FIXME: this fails with builtins. Temporary hack while we
                    # investigate whether we really need this or not
                descriptor.service_class = self

                self.public_methods[k] = descriptor
                if descriptor.aux is None:
                    if self.__has_aux_methods and self.__aux__ is None:
                        raise Exception(
                            "You can't mix primary and "
                            "auxiliary methods in a single service definition."
                        )
                else:
                    self.__has_aux_methods = True
Ejemplo n.º 4
0
    def __init__(self,
                 services,
                 tns,
                 name=None,
                 prefix_namespace=None,
                 names_parts_in_messages=None,
                 in_protocol=None,
                 out_protocol=None,
                 config=None,
                 classes=()):
        self.services = tuple(services)
        self.tns = tns
        self.name = name
        self.config = config
        self.classes = classes

        self.names_parts_in_messages = names_parts_in_messages

        if prefix_namespace is None:
            self.prefix_namespace = DEFAULT_PREFIX_NAMESPACE
        else:
            self.prefix_namespace = prefix_namespace

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        logger.info("Initializing application {%s}%s...", self.tns, self.name)

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()

        self.check_unique_method_keys()  # is this really necessary nowadays?

        # this needs to be after protocol assignments to give _static_when
        # functions as much info as possible about the application
        self.interface = Interface(self)

        # set_app needs to be after interface init because the protocols use it.
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)
Ejemplo n.º 5
0
    def __init__(self, services, tns, name=None,
                          in_protocol=None, out_protocol=None, config=None):
        self.services = tuple(services)
        self.tns = tns
        self.name = name
        self.config = config

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.interface = Interface(self)
        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()
        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)
Ejemplo n.º 6
0
    def __init__(self, cls_name, cls_bases, cls_dict):
        super(ServiceBaseMeta, self).__init__(cls_name, cls_bases, cls_dict)

        self.__has_aux_methods = self.__aux__ is not None
        self.public_methods = {}
        self.event_manager = EventManager(
            self, self.__get_base_event_handlers(cls_bases))

        for k, v in cls_dict.items():
            if hasattr(v, '_is_rpc'):
                descriptor = v(_default_function_name=k)

                # these two lines are needed for staticmethod wrapping to work
                setattr(self, k, staticmethod(descriptor.function))
                descriptor.reset_function(getattr(self, k))

                getattr(self, k).descriptor = descriptor
                descriptor.service_class = self

                self.public_methods[k] = descriptor
                if descriptor.aux is None:
                    if self.__has_aux_methods and self.__aux__ is None:
                        raise Exception(
                            "You can't mix primary and "
                            "auxiliary methods in a single service definition."
                        )
                else:
                    self.__has_aux_methods = True
Ejemplo n.º 7
0
    def __init__(self, tpt, max_buffer_size=2 * 1024 * 1024):
        assert isinstance(tpt, ServerBase), \
                                        "%r is not a ServerBase instance" % tpt

        self.tpt = tpt
        self.max_buffer_size = max_buffer_size
        self.event_manager = EventManager(self)
Ejemplo n.º 8
0
    def __init__(self, app=None, validator=None, mime_type=None,
                                                            ignore_uncap=False):
        self.__app = None
        self.validator = None

        self.set_app(app)
        self.event_manager = EventManager(self)
        self.set_validator(validator)
        self.ignore_uncap = ignore_uncap
        if mime_type is not None:
            self.mime_type = mime_type

        self._to_string_handlers = cdict({
            ModelBase: lambda cls, value: cls.to_string(value),
            Time: time_to_string,
            Uuid: uuid_to_string,
            Null: null_to_string,
            Double: double_to_string,
            AnyXml: any_xml_to_string,
            Unicode: unicode_to_string,
            Boolean: boolean_to_string,
            Decimal: decimal_to_string,
            Integer: integer_to_string,
            AnyHtml: any_html_to_string,
            DateTime: datetime_to_string,
            Duration: duration_to_string,
            ByteArray: byte_array_to_string,
            Attachment: attachment_to_string,
            ComplexModelBase: complex_model_base_to_string,
        })

        self._to_string_iterable_handlers = cdict({
            File: file_to_string_iterable,
            ByteArray: byte_array_to_string_iterable,
            ModelBase: lambda prot, cls, value: cls.to_string_iterable(value),
            SimpleModel: simple_model_to_string_iterable,
        })

        self._from_string_handlers = cdict({
            Null: null_from_string,
            Time: time_from_string,
            Date: date_from_string,
            Uuid: uuid_from_string,
            File: file_from_string,
            Double: double_from_string,
            String: string_from_string,
            AnyXml: any_xml_from_string,
            Boolean: boolean_from_string,
            Integer: integer_from_string,
            Unicode: unicode_from_string,
            Decimal: decimal_from_string,
            AnyHtml: any_html_from_string,
            DateTime: datetime_from_string,
            Duration: duration_from_string,
            ByteArray: byte_array_from_string,
            Attachment: attachment_from_string,
            ComplexModelBase: complex_model_base_from_string
        })
Ejemplo n.º 9
0
    def __init__(self, app=None, validator=None, mime_type=None, skip_depth=0, ignore_uncap=False):
        self.__app = None
        self.validator = None

        self.set_app(app)
        self.event_manager = EventManager(self)
        self.set_validator(validator)
        self.skip_depth = skip_depth
        self.ignore_uncap=ignore_uncap
        if mime_type is not None:
            self.mime_type = mime_type
Ejemplo n.º 10
0
def api_handler(request, service):
    service_handler = Settings.get_service_handler(service)
    if service_handler:
        logger.debug("Hitting service %s." % service)
        log = LogEntry(
            url="%s %s" % (request.method, request.get_full_path()),
            application=service)
        request_body = request.META["wsgi.input"].read(
            request._stream.remaining)
        request.META["wsgi.input"] = StringIO(request_body)
        request._stream = LimitedStream(
            request.META["wsgi.input"], request._stream.remaining)
        service_handler.event_manager.add_listener(
            "wsgi_close", partial(handle_wsgi_close, log=log))
        service_handler.app.event_manager.add_listener(
            "method_call_exception", partial(handle_exception, log=log))

        try:
            response = csrf_exempt(service_handler)(request)
        except Exception:
            log.traceback = unicode(traceback.format_exc(), errors="ignore")
            raise
        else:
            if response.content:
                log.response = response.content
        finally:
            if request_body:
                log.request = request_body
            log.save()
            service_handler.event_manager = EventManager(service_handler)
            service_handler.app.event_manager = EventManager(
                service_handler.app)

        return response
    else:
        msg = "Service %s not found" % service
        logger.info(msg)
        raise Http404(msg)
Ejemplo n.º 11
0
    def __init__(self, app=None, mime_type=None, ignore_wrappers=None,
                 binary_encoding=None):
        self.__app = None
        self.set_app(app)

        self.ignore_wrappers = ignore_wrappers
        self.event_manager = EventManager(self)
        self.binary_encoding = binary_encoding
        if self.binary_encoding is None:
            self.binary_encoding = self.default_binary_encoding

        if mime_type is not None:
            self.mime_type = mime_type

        self._attrcache = WeakKeyDictionary()
Ejemplo n.º 12
0
    def __init__(self, tpt):
        assert isinstance(tpt, ServerBase)

        self.tpt = tpt
        self.event_manager = EventManager(self)
Ejemplo n.º 13
0
class Application(object):
    """The Application class is the glue between one or more service
    definitions, input and output protocols.

    :param services:     An iterable of ServiceBase subclasses that defines
                         the exposed services.
    :param tns:          The targetNamespace attribute of the exposed
                         service.
    :param name:         The optional name attribute of the exposed service.
                         The default is the name of the application class
                         which is by default 'Application'.
    :param in_protocol:  A ProtocolBase instance that denotes the input
                         protocol. It's only optional for NullServer transport.
    :param out_protocol: A ProtocolBase instance that denotes the output
                         protocol. It's only optional for NullServer transport.
    :param config:       An arbitrary python object to store random global data.

    Supported events:
        * ``method_call``:
            Called right before the service method is executed

        * ``method_return_object``:
            Called right after the service method is executed

        * ``method_exception_object``:
            Called when an exception occurred in a service method, before the
            exception is serialized.

        * ``method_context_created``:
            Called from the constructor of the MethodContext instance.

        * ``method_context_closed``:
            Called from the ``close()`` function of the MethodContext instance,
            which in turn is called by the transport when the response is fully
            sent to the client (or in the client case, the response is fully
            received from server).
    """

    transport = None

    def __init__(self,
                 services,
                 tns,
                 name=None,
                 in_protocol=None,
                 out_protocol=None,
                 config=None):
        self.services = tuple(services)
        self.tns = tns
        self.name = name
        self.config = config

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.interface = Interface(self)
        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()
        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)

    def process_request(self, ctx):
        """Takes a MethodContext instance. Returns the response to the request
        as a native python object. If the function throws an exception, it
        returns None and sets the exception object to ctx.out_error.

        Overriding this method would break event management. So this is not
        meant to be overridden unless you know what you're doing.
        """

        try:
            # fire events
            self.event_manager.fire_event('method_call', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event('method_call', ctx)

            # in object is always a sequence of incoming values. We need to fix
            # that for bare mode.
            if ctx.descriptor.body_style is BODY_STYLE_BARE:
                ctx.in_object = [ctx.in_object]
            elif ctx.descriptor.body_style is BODY_STYLE_EMPTY:
                ctx.in_object = []

            # call user method
            ctx.out_object = self.call_wrapper(ctx)

            # out object is always a sequence of return values. see
            # MethodContext docstrings for more info
            if ctx.descriptor.body_style is not BODY_STYLE_WRAPPED or \
                                len(ctx.descriptor.out_message._type_info) <= 1:
                # if it's not a wrapped method, OR there's just one return type
                # we wrap it ourselves
                ctx.out_object = [ctx.out_object]

            # Now that the processing is switched to the outgoing message,
            # point ctx.protocol to ctx.out_protocol
            ctx.protocol = ctx.outprot_ctx

            # fire events
            self.event_manager.fire_event('method_return_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                    'method_return_object', ctx)
        except Redirect as e:
            try:
                e.do_redirect()

                ctx.out_object = [None]

                # Now that the processing is switched to the outgoing message,
                # point ctx.protocol to ctx.out_protocol
                ctx.protocol = ctx.outprot_ctx

                # fire events
                self.event_manager.fire_event('method_redirect', ctx)
                if ctx.service_class is not None:
                    ctx.service_class.event_manager.fire_event(
                        'method_redirect', ctx)

            except Exception as e:
                logger_server.exception(e)
                ctx.out_error = Fault('Server',
                                      get_fault_string_from_exception(e))

                # fire events
                self.event_manager.fire_event('method_redirect_exception', ctx)
                if ctx.service_class is not None:
                    ctx.service_class.event_manager.fire_event(
                        'method_redirect_exception', ctx)

        except Fault as e:
            if e.faultcode == 'Client' or e.faultcode.startswith('Client.'):
                logger_client.exception(e)
            else:
                logger.exception(e)

            ctx.out_error = e

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                    'method_exception_object', ctx)

        # we don't catch BaseException because we actually don't want to catch
        # "system-exiting" exceptions. See:
        # https://docs.python.org/2/library/exceptions.html#exceptions.Exception
        except Exception as e:
            logger_server.critical(e, **{'exc_info': 1})

            ctx.out_error = Fault('Server', get_fault_string_from_exception(e))

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                    'method_exception_object', ctx)

    def call_wrapper(self, ctx):
        """This method calls the call_wrapper method in the service definition.
        This can be overridden to make an application-wide custom exception
        management.
        """

        retval = None

        # service rpc
        if ctx.descriptor.no_self:
            retval = ctx.descriptor.service_class.call_wrapper(ctx)

        # class rpc
        else:
            cls = ctx.descriptor.parent_class
            if cls.__orig__ is not None:
                cls = cls.__orig__

            inst = cls.__respawn__(ctx)
            if inst is None:
                raise RespawnError('{%s}%s' %
                                   (cls.get_namespace(), cls.get_type_name()))
            in_cls = ctx.descriptor.in_message

            args = ctx.in_object
            if args is None:
                args = []

            elif ctx.descriptor.body_style is BODY_STYLE_WRAPPED and \
                                        len(in_cls.get_flat_type_info(in_cls)) <= 1:
                args = []

            else:
                args = args[1:]

            if ctx.descriptor.service_class is not None:
                ctx.in_object = [inst, ctx]
                ctx.in_object.extend(args)

                # hack to make sure inst goes first
                ctx.descriptor.no_ctx = True
                retval = ctx.descriptor.service_class.call_wrapper(ctx)

            elif ctx.function is not None:
                if ctx.descriptor.no_ctx:
                    retval = ctx.function(inst, *args)
                else:
                    retval = ctx.function(inst, ctx, *args)

        return retval

    def _has_callbacks(self):
        return self.interface._has_callbacks()

    def reinitialize(self, server):
        """This is normally called on transport instantiation by ServerBase"""

        seen = set()

        from spyne import MethodDescriptor
        for d in self.interface.method_id_map.values():
            assert isinstance(d, MethodDescriptor)

            if d.aux is not None and not id(d.aux) in seen:
                d.aux.initialize(server)
                seen.add(id(d.aux))

            if d.service_class is not None and not id(d.service_class) in seen:
                d.service_class.initialize(server)
                seen.add(id(d.service_class))

    def __hash__(self):
        return hash(tuple((id(s) for s in self.services)))
Ejemplo n.º 14
0
class Application(object):
    """The Application class is the glue between one or more service
    definitions, input and output protocols.

    :param services:     An iterable of ServiceBase subclasses that defines
                         the exposed services.
    :param tns:          The targetNamespace attribute of the exposed
                         service.
    :param name:         The optional name attribute of the exposed service.
                         The default is the name of the application class
                         which is by default 'Application'.
    :param in_protocol:  A ProtocolBase instance that denotes the input
                         protocol. It's only optional for NullServer transport.
    :param out_protocol: A ProtocolBase instance that denotes the output
                         protocol. It's only optional for NullServer transport.
    :param config:       An arbitrary python object to store random global data.

    Supported events:
        * ``method_call``:
            Called right before the service method is executed

        * ``method_return_object``:
            Called right after the service method is executed

        * ``method_exception_object``:
            Called when an exception occurred in a service method, before the
            exception is serialized.

        * ``method_context_created``:
            Called from the constructor of the MethodContext instance.

        * ``method_context_closed``:
            Called from the ``close()`` function of the MethodContext instance,
            which in turn is called by the transport when the response is fully
            sent to the client (or in the client case, the response is fully
            received from server).
    """

    transport = None

    def __init__(self, services, tns, name=None,
                          in_protocol=None, out_protocol=None, config=None):
        self.services = tuple(services)
        self.tns = tns
        self.name = name
        self.config = config

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.interface = Interface(self)
        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()
        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)

    def process_request(self, ctx):
        """Takes a MethodContext instance. Returns the response to the request
        as a native python object. If the function throws an exception, it
        returns None and sets the exception object to ctx.out_error.

        Overriding this method would break event management. So this is not
        meant to be overridden unless you know what you're doing.
        """

        try:
            # fire events
            self.event_manager.fire_event('method_call', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event('method_call', ctx)

            # in object is always a sequence of incoming values. We need to fix
            # that for bare mode.
            if ctx.descriptor.body_style is BODY_STYLE_BARE:
                ctx.in_object = [ctx.in_object]
            elif ctx.descriptor.body_style is BODY_STYLE_EMPTY:
                ctx.in_object = []

            # call user method
            ctx.out_object = self.call_wrapper(ctx)

            # out object is always a sequence of return values. see
            # MethodContext docstrings for more info
            if ctx.descriptor.body_style is not BODY_STYLE_WRAPPED or \
                                len(ctx.descriptor.out_message._type_info) <= 1:
                # if it's not a wrapped method, OR there's just one return type
                # we wrap it ourselves
                ctx.out_object = [ctx.out_object]

            # Now that the processing is switched to the outgoing message,
            # point ctx.protocol to ctx.out_protocol
            ctx.protocol = ctx.outprot_ctx

            # fire events
            self.event_manager.fire_event('method_return_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                                    'method_return_object', ctx)
        except Redirect as e:
            try:
                e.do_redirect()

                ctx.out_object = [None]

                # Now that the processing is switched to the outgoing message,
                # point ctx.protocol to ctx.out_protocol
                ctx.protocol = ctx.outprot_ctx

                # fire events
                self.event_manager.fire_event('method_redirect', ctx)
                if ctx.service_class is not None:
                    ctx.service_class.event_manager.fire_event(
                                                         'method_redirect', ctx)

            except Exception as e:
                logger_server.exception(e)
                ctx.out_error = Fault('Server',
                                             get_fault_string_from_exception(e))

                # fire events
                self.event_manager.fire_event('method_redirect_exception', ctx)
                if ctx.service_class is not None:
                    ctx.service_class.event_manager.fire_event(
                                               'method_redirect_exception', ctx)

        except Fault as e:
            if e.faultcode == 'Client' or e.faultcode.startswith('Client.'):
                logger_client.exception(e)
            else:
                logger.exception(e)

            ctx.out_error = e

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                               'method_exception_object', ctx)

        # we don't catch BaseException because we actually don't want to catch
        # "system-exiting" exceptions. See:
        # https://docs.python.org/2/library/exceptions.html#exceptions.Exception
        except Exception as e:
            logger_server.critical(e, **{'exc_info': 1})

            ctx.out_error = Fault('Server', get_fault_string_from_exception(e))

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                                'method_exception_object', ctx)

    def call_wrapper(self, ctx):
        """This method calls the call_wrapper method in the service definition.
        This can be overridden to make an application-wide custom exception
        management.
        """

        retval = None

        # service rpc
        if ctx.descriptor.no_self:
            retval = ctx.descriptor.service_class.call_wrapper(ctx)

        # class rpc
        else:
            cls = ctx.descriptor.parent_class
            if cls.__orig__ is not None:
                cls = cls.__orig__

            inst = cls.__respawn__(ctx)
            if inst is None:
                raise RespawnError('{%s}%s' %
                                     (cls.get_namespace(), cls.get_type_name()))
            in_cls = ctx.descriptor.in_message

            args = ctx.in_object
            if args is None:
                args = []

            elif ctx.descriptor.body_style is BODY_STYLE_WRAPPED and \
                                        len(in_cls.get_flat_type_info(in_cls)) <= 1:
                args = []

            else:
                args = args[1:]

            if ctx.descriptor.service_class is not None:
                ctx.in_object = [inst, ctx]
                ctx.in_object.extend(args)

                # hack to make sure inst goes first
                ctx.descriptor.no_ctx = True
                retval = ctx.descriptor.service_class.call_wrapper(ctx)

            elif ctx.function is not None:
                if ctx.descriptor.no_ctx:
                    retval = ctx.function(inst, *args)
                else:
                    retval = ctx.function(inst, ctx, *args)

        return retval

    def _has_callbacks(self):
        return self.interface._has_callbacks()

    def reinitialize(self, server):
        """This is normally called on transport instantiation by ServerBase"""

        seen = set()

        from spyne import MethodDescriptor
        for d in self.interface.method_id_map.values():
            assert isinstance(d, MethodDescriptor)

            if d.aux is not None and not id(d.aux) in seen:
                d.aux.initialize(server)
                seen.add(id(d.aux))

            if d.service_class is not None and not id(d.service_class) in seen:
                d.service_class.initialize(server)
                seen.add(id(d.service_class))

    def __hash__(self):
        return hash(tuple((id(s) for s in self.services)))
Ejemplo n.º 15
0
 def __init__(self, interface):
     self.interface = interface
     self.event_manager = EventManager(self)
Ejemplo n.º 16
0
 def __init__(self, app, base=MessagePackServerBase):
     self.app = app
     self.base = base
     self.event_manager = EventManager(self)
Ejemplo n.º 17
0
 def __init__(self, interface):
     self.import_base_namespaces=True
     self.interface = interface
     self.event_manager = EventManager(self)
Ejemplo n.º 18
0
    def __init__(self,
                 app=None,
                 validator=None,
                 mime_type=None,
                 ignore_uncap=False,
                 ignore_wrappers=False,
                 binary_encoding=None):
        self.validator = None
        self.set_validator(validator)

        self.__app = None
        self.set_app(app)

        self._attrcache = WeakKeyDictionary()

        self.event_manager = EventManager(self)
        self.ignore_uncap = ignore_uncap
        self.ignore_wrappers = ignore_wrappers
        self.message = None
        self.binary_encoding = binary_encoding
        if self.binary_encoding is None:
            self.binary_encoding = self.default_binary_encoding

        if mime_type is not None:
            self.mime_type = mime_type

        self._to_string_handlers = cdict({
            ModelBase:
            self.model_base_to_string,
            File:
            self.file_to_string,
            Time:
            self.time_to_string,
            Uuid:
            self.uuid_to_string,
            Null:
            self.null_to_string,
            Double:
            self.double_to_string,
            AnyXml:
            self.any_xml_to_string,
            Unicode:
            self.unicode_to_string,
            Boolean:
            self.boolean_to_string,
            Decimal:
            self.decimal_to_string,
            Integer:
            self.integer_to_string,
            AnyHtml:
            self.any_html_to_string,
            DateTime:
            self.datetime_to_string,
            Duration:
            self.duration_to_string,
            ByteArray:
            self.byte_array_to_string,
            Attachment:
            self.attachment_to_string,
            XmlAttribute:
            self.xmlattribute_to_string,
            ComplexModelBase:
            self.complex_model_base_to_string,
        })

        self._to_unicode_handlers = cdict({
            ModelBase:
            self.model_base_to_unicode,
            File:
            self.file_to_unicode,
            Time:
            self.time_to_string,
            Uuid:
            self.uuid_to_string,
            Null:
            self.null_to_string,
            Double:
            self.double_to_string,
            AnyXml:
            self.any_xml_to_unicode,
            Unicode:
            self.unicode_to_unicode,
            Boolean:
            self.boolean_to_string,
            Decimal:
            self.decimal_to_string,
            Integer:
            self.integer_to_string,
            AnyHtml:
            self.any_html_to_unicode,
            # FIXME: Would we need a to_unicode for localized dates?
            DateTime:
            self.datetime_to_string,
            Duration:
            self.duration_to_string,
            ByteArray:
            self.byte_array_to_unicode,
            XmlAttribute:
            self.xmlattribute_to_unicode,
            ComplexModelBase:
            self.complex_model_base_to_string,
        })

        self._to_string_iterable_handlers = cdict({
            File:
            self.file_to_string_iterable,
            ByteArray:
            self.byte_array_to_string_iterable,
            ModelBase:
            self.model_base_to_string_iterable,
            SimpleModel:
            self.simple_model_to_string_iterable,
            ComplexModelBase:
            self.complex_model_to_string_iterable,
        })

        fsh = {
            Null: self.null_from_string,
            Time: self.time_from_string,
            Date: self.date_from_string,
            Uuid: self.uuid_from_string,
            File: self.file_from_string,
            Array: self.array_from_string,
            Double: self.double_from_string,
            String: self.string_from_string,
            AnyXml: self.any_xml_from_string,
            Boolean: self.boolean_from_string,
            Integer: self.integer_from_string,
            Unicode: self.unicode_from_string,
            Decimal: self.decimal_from_string,
            AnyHtml: self.any_html_from_string,
            DateTime: self.datetime_from_string,
            Duration: self.duration_from_string,
            ByteArray: self.byte_array_from_string,
            EnumBase: self.enum_base_from_string,
            ModelBase: self.model_base_from_string,
            Attachment: self.attachment_from_string,
            XmlAttribute: self.xmlattribute_from_string,
            ComplexModelBase: self.complex_model_base_from_string
        }

        self._from_string_handlers = cdict(fsh)
        self._from_unicode_handlers = cdict(fsh)

        self._datetime_dsmap = {
            None: self._datetime_from_string,
            'sec': self._datetime_from_sec,
            'sec_float': self._datetime_from_sec_float,
            'msec': self._datetime_from_msec,
            'msec_float': self._datetime_from_msec_float,
            'usec': self._datetime_from_usec,
        }
Ejemplo n.º 19
0
class Application(object):
    """The Application class is the glue between one or more service
    definitions, input and output protocols.

    :param services:     An iterable of ServiceBase subclasses that defines
                         the exposed services.
    :param tns:          The targetNamespace attribute of the exposed
                         service.
    :param name:         The optional name attribute of the exposed service.
                         The default is the name of the application class
                         which is by default 'Application'.
    :param in_protocol:  A ProtocolBase instance that denotes the input
                         protocol. It's only optional for NullServer transport.
    :param out_protocol: A ProtocolBase instance that denotes the output
                         protocol. It's only optional for NullServer transport.
    :param interface:    Ignored. Kept for backwards-compatibility purposes.

    Supported events:
        * ``method_call``:
            Called right before the service method is executed

        * ``method_return_object``:
            Called right after the service method is executed

        * ``method_exception_object``:
            Called when an exception occurred in a service method, before the
            exception is serialized.

        * ``method_context_created``:
            Called from the constructor of the MethodContext instance.

        * ``method_context_closed``:
            Called from the ``close()`` function of the MethodContext instance,
            which in turn is called by the transport when the response is fully
            sent to the client (or in the client case, the response is fully
            received from server).
    """

    transport = None

    def __init__(self, services, tns, name=None,
                          in_protocol=None, out_protocol=None, interface=None):
        self.services = tuple(services)
        self.tns = tns
        self.name = name

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.interface = Interface(self)
        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()
        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)

        self.reinitialize()

    def process_request(self, ctx):
        """Takes a MethodContext instance. Returns the response to the request
        as a native python object. If the function throws an exception, it
        returns None and sets the exception object to ctx.out_error.

        Overriding this method would break event management. So this is not
        meant to be overridden unless you know what you're doing.
        """

        try:
            # fire events
            self.event_manager.fire_event('method_call', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event('method_call', ctx)

            # call the method
            ctx.out_object = self.call_wrapper(ctx)

            # out object is always an iterable of return values. see
            # MethodContext docstrings for more info
            if ctx.descriptor.body_style is not BODY_STYLE_WRAPPED or \
                                len(ctx.descriptor.out_message._type_info) <= 1:
                # the return value should already be wrapped by a sequence.
                ctx.out_object = [ctx.out_object]

            # fire events
            self.event_manager.fire_event('method_return_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                                    'method_return_object', ctx)

        except Fault as e:
            if e.faultcode == 'Client' or e.faultcode.startswith('Client.'):
                logger_client.exception(e)
            else:
                logger.exception(e)

            ctx.out_error = e

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                               'method_exception_object', ctx)

        except Exception as e:
            logger.exception(e)

            ctx.out_error = Fault('Server', get_fault_string_from_exception(e))

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                                'method_exception_object', ctx)

    def call_wrapper(self, ctx):
        """This method calls the call_wrapper method in the service definition.
        This can be overridden to make an application-wide custom exception
        management.
        """

        if ctx.descriptor.body_style is BODY_STYLE_BARE:
            ctx.in_object = [ctx.in_object]
        elif ctx.descriptor.body_style is BODY_STYLE_EMPTY:
            ctx.in_object = []

        retval = None

        # service rpc
        if ctx.descriptor.no_self:
            retval = ctx.descriptor.service_class.call_wrapper(ctx)

        # class rpc
        else:
            cls = ctx.descriptor.parent_class
            if cls.__orig__ is not None:
                cls = cls.__orig__

            inst = cls.__respawn__(ctx)
            if inst is None:
                raise RespawnError('{%s}%s' %
                                     (cls.get_namespace(), cls.get_type_name()))
            in_cls = ctx.descriptor.in_message

            args = ctx.in_object
            if args is None:
                args = []

            elif ctx.descriptor.body_style is BODY_STYLE_WRAPPED and \
                                        len(in_cls.get_flat_type_info(in_cls)) <= 1:
                args = []

            else:
                args = args[1:]

            if ctx.descriptor.service_class is not None:
                ctx.in_object = [inst, ctx]
                ctx.in_object.extend(args)

                # hack to make sure inst goes first
                ctx.descriptor.no_ctx = True
                retval = ctx.descriptor.service_class.call_wrapper(ctx)

            elif ctx.function is not None:
                if ctx.descriptor.no_ctx:
                    retval = ctx.function(inst, *args)
                else:
                    retval = ctx.function(inst, ctx, *args)

        return retval

    def _has_callbacks(self):
        return self.interface._has_callbacks()

    def reinitialize(self):
        from spyne.server import ServerBase

        server = ServerBase(self)
        aux_memo = set()
        for d in self.interface.method_id_map.values():
            if d.aux is not None and not id(d.aux) in aux_memo:
                d.aux.initialize(server)
                aux_memo.add(id(d.aux))

    def __hash__(self):
        return hash(tuple((id(s) for s in self.services)))
Ejemplo n.º 20
0
 def __init__(self, app):
     self.app = app
     self.app.transport = self.transport
     self.event_manager = EventManager(self)
     self.doc = AllYourInterfaceDocuments(app.interface)
Ejemplo n.º 21
0
Archivo: _base.py Proyecto: pxiol/spyne
    def __init__(self, app=None, validator=None, mime_type=None,
                                       ignore_uncap=False, ignore_wrappers=False):
        self.__app = None
        self.set_app(app)

        self.validator = None
        self.set_validator(validator)

        self.event_manager = EventManager(self)
        self.ignore_uncap = ignore_uncap
        self.ignore_wrappers = ignore_wrappers
        self.message = None

        if mime_type is not None:
            self.mime_type = mime_type

        self._to_string_handlers = cdict({
            ModelBase: self.model_base_to_string,
            Time: self.time_to_string,
            Uuid: self.uuid_to_string,
            Null: self.null_to_string,
            Double: self.double_to_string,
            AnyXml: self.any_xml_to_string,
            Unicode: self.unicode_to_string,
            Boolean: self.boolean_to_string,
            Decimal: self.decimal_to_string,
            Integer: self.integer_to_string,
            AnyHtml: self.any_html_to_string,
            DateTime: self.datetime_to_string,
            Duration: self.duration_to_string,
            ByteArray: self.byte_array_to_string,
            Attachment: self.attachment_to_string,
            XmlAttribute: self.xmlattribute_to_string,
            ComplexModelBase: self.complex_model_base_to_string,
        })

        self._to_string_iterable_handlers = cdict({
            File: self.file_to_string_iterable,
            ByteArray: self.byte_array_to_string_iterable,
            ModelBase: self.model_base_to_string_iterable,
            SimpleModel: self.simple_model_to_string_iterable,
            ComplexModelBase: self.complex_model_to_string_iterable,
        })

        self._from_string_handlers = cdict({
            Null: self.null_from_string,
            Time: self.time_from_string,
            Date: self.date_from_string,
            Uuid: self.uuid_from_string,
            File: self.file_from_string,
            Double: self.double_from_string,
            String: self.string_from_string,
            AnyXml: self.any_xml_from_string,
            Boolean: self.boolean_from_string,
            Integer: self.integer_from_string,
            Unicode: self.unicode_from_string,
            Decimal: self.decimal_from_string,
            AnyHtml: self.any_html_from_string,
            DateTime: self.datetime_from_string,
            Duration: self.duration_from_string,
            ByteArray: self.byte_array_from_string,
            ModelBase: self.model_base_from_string,
            Attachment: self.attachment_from_string,
            ComplexModelBase: self.complex_model_base_from_string
        })

        self._datetime_dsmap = {
            None: self._datetime_from_string,
            'sec': self._datetime_from_sec,
            'sec_float': self._datetime_from_sec_float,
            'msec': self._datetime_from_msec,
            'msec_float': self._datetime_from_msec_float,
            'usec': self._datetime_from_usec,
        }
Ejemplo n.º 22
0
class Application(object):
    """The Application class is the glue between one or more service
    definitions, input and output protocols.

    :param services:     An iterable of ServiceBase subclasses that defines
                         the exposed services.
    :param tns:          The targetNamespace attribute of the exposed
                         service.
    :param name:         The optional name attribute of the exposed service.
                         The default is the name of the application class
                         which is by default 'Application'.
    :param in_protocol:  A ProtocolBase instance that denotes the input
                         protocol. It's only optional for NullServer transport.
    :param out_protocol: A ProtocolBase instance that denotes the output
                         protocol. It's only optional for NullServer transport.
    :param interface:    Ignored. Kept for backwards-compatibility purposes.

    Supported events:
        * ``method_call``:
            Called right before the service method is executed

        * ``method_return_object``:
            Called right after the service method is executed

        * ``method_exception_object``:
            Called when an exception occurred in a service method, before the
            exception is serialized.

        * ``method_context_created``:
            Called from the constructor of the MethodContext instance.

        * ``method_context_closed``:
            Called from the ``close()`` function of the MethodContext instance,
            which in turn is called by the transport when the response is fully
            sent to the client (or in the client case, the response is fully
            received from server).
    """

    transport = None

    def __init__(self, services, tns, name=None,
                          in_protocol=None, out_protocol=None, interface=None):
        self.services = tuple(services)
        self.tns = tns
        self.name = name

        if self.name is None:
            self.name = self.__class__.__name__.split('.')[-1]

        self.event_manager = EventManager(self)
        self.error_handler = None

        self.interface = Interface(self)
        self.in_protocol = in_protocol
        self.out_protocol = out_protocol

        if self.in_protocol is None:
            from spyne.protocol import ProtocolBase
            self.in_protocol = ProtocolBase()
        self.in_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.in_protocol.message = self.in_protocol.REQUEST

        if self.out_protocol is None:
            from spyne.protocol import ProtocolBase
            self.out_protocol = ProtocolBase()
        self.out_protocol.set_app(self)
        # FIXME: this normally is another parameter to set_app but it's kept
        # separate for backwards compatibility reasons.
        self.out_protocol.message = self.out_protocol.RESPONSE

        register_application(self)

        self.reinitialize()

    def process_request(self, ctx):
        """Takes a MethodContext instance. Returns the response to the request
        as a native python object. If the function throws an exception, it
        returns None and sets the exception object to ctx.out_error.

        Overriding this method would break event management. So this is not
        meant to be overridden unless you know what you're doing.
        """

        try:
            # fire events
            self.event_manager.fire_event('method_call', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event('method_call', ctx)

            # call the method
            ctx.out_object = self.call_wrapper(ctx)

            # out object is always an iterable of return values. see
            # MethodContext docstrings for more info
            if ctx.descriptor.body_style is not BODY_STYLE_WRAPPED or \
                                len(ctx.descriptor.out_message._type_info) <= 1:
                # the return value should already be wrapped by a sequence.
                ctx.out_object = [ctx.out_object]

            # fire events
            self.event_manager.fire_event('method_return_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                                    'method_return_object', ctx)

        except Fault as e:
            if e.faultcode == 'Client' or e.faultcode.startswith('Client.'):
                logger_client.exception(e)
            else:
                logger.exception(e)

            ctx.out_error = e

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                               'method_exception_object', ctx)

        except Exception as e:
            logger.exception(e)

            ctx.out_error = Fault('Server', get_fault_string_from_exception(e))

            # fire events
            self.event_manager.fire_event('method_exception_object', ctx)
            if ctx.service_class is not None:
                ctx.service_class.event_manager.fire_event(
                                                'method_exception_object', ctx)

    def call_wrapper(self, ctx):
        """This method calls the call_wrapper method in the service definition.
        This can be overridden to make an application-wide custom exception
        management.
        """

        if ctx.descriptor.body_style is BODY_STYLE_BARE:
            ctx.in_object = [ctx.in_object]
        elif ctx.descriptor.body_style is BODY_STYLE_EMPTY:
            ctx.in_object = []

        # service rpc
        if ctx.descriptor.service_class is not None:
            return ctx.descriptor.service_class.call_wrapper(ctx)

        # class rpc
        cls = ctx.descriptor.parent_class
        if cls.__orig__ is not None:
            cls = cls.__orig__
        inst = cls.__respawn__(ctx)
        if inst is None:
            raise ResourceNotFoundError('{%s}%s' %
                                     (cls.get_namespace(), cls.get_type_name()))
        args = ctx.in_object[1:]
        if ctx.function is not None:
            if ctx.descriptor.no_ctx:
                return ctx.function(inst, *args)
            else:
                return ctx.function(inst, ctx, *args)

    def _has_callbacks(self):
        return self.interface._has_callbacks()

    def reinitialize(self):
        from spyne.server import ServerBase

        server = ServerBase(self)
        aux_memo = set()
        for d in self.interface.method_id_map.values():
            if d.aux is not None and not id(d.aux) in aux_memo:
                d.aux.initialize(server)
                aux_memo.add(id(d.aux))

    def __hash__(self):
        return hash(tuple((id(s) for s in self.services)))