Beispiel #1
0
  def apiserving_method_decorator(api_method):
    """Decorator for ProtoRPC method that configures Google's API server.

    Args:
      api_method: Original method being wrapped.

    Returns:
      'remote.invoke_remote_method' function responsible for actual invocation.
      Assigns the following attributes to invocation function:
        remote: Instance of RemoteInfo, contains remote method information.
        remote.request_type: Expected request type for remote method.
        remote.response_type: Response type returned from remote method.
        method_info: Instance of _MethodInfo, api method configuration.
      It is also assigned attributes corresponding to the aforementioned kwargs.

    Raises:
      TypeError: if the request_type or response_type parameters are not
        proper subclasses of messages.Message.
    """
    remote_decorator = remote.method(request_message, response_message)
    remote_method = remote_decorator(api_method)
    remote_method.method_info = _MethodInfo(
        name=name or api_method.__name__, path=path or '',
        http_method=http_method or DEFAULT_HTTP_METHOD,
        cache_control=cache_control, scopes=scopes, audiences=audiences,
        allowed_client_ids=allowed_client_ids)
    return remote_method
Beispiel #2
0
def define_service(service_descriptor, module):
  """Define a new service proxy.

  Args:
    service_descriptor: ServiceDescriptor class that describes the service.
    module: Module to add service to.  Request and response types are found
      relative to this module.

  Returns:
    Service class proxy capable of communicating with a remote server.
  """
  class_dict = {'__module__': module.__name__}
  class_name = service_descriptor.name.encode('utf-8')

  for method_descriptor in service_descriptor.methods or []:
    request_definition = messages.find_definition(
        method_descriptor.request_type, module)
    response_definition = messages.find_definition(
        method_descriptor.response_type, module)

    method_name = method_descriptor.name.encode('utf-8')
    def remote_method(self, request):
      """Actual service method."""
      raise NotImplementedError('Method is not implemented')
    remote_method.__name__ = method_name
    remote_method_decorator = remote.method(request_definition,
                                            response_definition)

    class_dict[method_name] = remote_method_decorator(remote_method)

  service_class = type(class_name, (remote.Service,), class_dict)
  return service_class
Beispiel #3
0
def define_service(service_descriptor, module):
    """Define a new service proxy.

  Args:
    service_descriptor: ServiceDescriptor class that describes the service.
    module: Module to add service to.  Request and response types are found
      relative to this module.

  Returns:
    Service class proxy capable of communicating with a remote server.
  """
    class_dict = {'__module__': module.__name__}
    class_name = service_descriptor.name.encode('utf-8')

    for method_descriptor in service_descriptor.methods or []:
        request_definition = messages.find_definition(
            method_descriptor.request_type, module)
        response_definition = messages.find_definition(
            method_descriptor.response_type, module)

        method_name = method_descriptor.name.encode('utf-8')

        def remote_method(self, request):
            """Actual service method."""
            raise NotImplementedError('Method is not implemented')

        remote_method.__name__ = method_name
        remote_method_decorator = remote.method(request_definition,
                                                response_definition)

        class_dict[method_name] = remote_method_decorator(remote_method)

    service_class = type(class_name, (remote.Service, ), class_dict)
    return service_class
Beispiel #4
0
        def _remote_method(method):

          '''  '''

          # wrap responder
          wrapped = premote.method(request_klass, response_klass)(method)

          # make things transparent
          wrapped.__name__, wrapped.__doc__, wrapped.__inner__ = (
            method.__name__,
            method.__doc__,
            method
          )

          def _respond(self, _request_message):

            ''' '''

            if isinstance(request, type) and issubclass(request, model.Model):
              # convert incoming message to model
              result = wrapped(self, request.from_message(_request_message))

            else:
              # we're using regular messages always
              result = wrapped(self, _request_message)

            # convert outgoing message to model if it isn't already
            if isinstance(result, model.Model):
              return result.to_message()
            return result

          _respond.__inner__ = wrapped

          # quack quack
          _respond.__name__, _respond.__doc__, _respond.remote = (
            method.__name__,
            method.__doc__,
            wrapped.remote
          )

          # just for backup
          wrapped.__remote_name__, wrapped.__remote_doc__, wrapped.__remote__ = (
            method.__name__,
            method.__doc__,
            wrapped.remote
          )

          return _respond
Beispiel #5
0
  def apiserving_method_decorator(api_method):
    """Decorator for ProtoRPC method that configures Google's API server.

    Args:
      api_method: Original method being wrapped.

    Returns:
      Function responsible for actual invocation.
      Assigns the following attributes to invocation function:
        remote: Instance of RemoteInfo, contains remote method information.
        remote.request_type: Expected request type for remote method.
        remote.response_type: Response type returned from remote method.
        method_info: Instance of _MethodInfo, api method configuration.
      It is also assigned attributes corresponding to the aforementioned kwargs.

    Raises:
      TypeError: if the request_type or response_type parameters are not
        proper subclasses of messages.Message.
    """
    remote_decorator = remote.method(request_message, response_message)
    remote_method = remote_decorator(api_method)

    def invoke_remote(service_instance, request):


      users_id_token._maybe_set_current_user_vars(invoke_remote)
      return remote_method(service_instance, request)




    local_scopes = scopes
    if local_scopes is None:
      local_scopes = ['https://www.googleapis.com/auth/userinfo.email']

    invoke_remote.remote = remote_method.remote
    invoke_remote.method_info = _MethodInfo(
        name=name or api_method.__name__, path=path or '',
        http_method=http_method or DEFAULT_HTTP_METHOD,
        cache_control=cache_control, scopes=local_scopes, audiences=audiences,
        allowed_client_ids=allowed_client_ids)
    invoke_remote.__name__ = invoke_remote.method_info.name
    return invoke_remote
Beispiel #6
0
def method(request_message=message_types.VoidMessage,
           response_message=message_types.VoidMessage,
           name=None,
           path=None,
           http_method='POST',
           scopes=None,
           audiences=None,
           allowed_client_ids=None,
           auth_level=None,
           api_key_required=None,
           metric_costs=None,
           use_request_uri=None):
    """Method decorator for API endpoint.

    Note that the path attribute _must_ match the name of the decorated method.

    https://github.com/cloudendpoints/endpoints-python/blob/9da60817aefbb0f2a4b9145c17ee39b9115067b0/endpoints/api_config.py#L1263
    """
    return remote.method(request_type=request_message,
                         response_type=response_message)
Beispiel #7
0
        def _remote_method_responder(method):

          '''  '''

          def _respond(self, _request_message):

            ''' '''

            if isinstance(request, type) and issubclass(request, model.Model):
              # convert incoming message to model
              result = method(self, request.from_message(_request_message))

            else:
              # we're using regular messages always
              result = method(self, _request_message)

            # convert outgoing message to model if it isn't already
            if isinstance(result, model.Model):
              return result.to_message()
            return result

          # wrap responder
          return premote.method(request_klass, response_klass)(_respond)
Beispiel #8
0
                def _remote_method_responder(method):
                    '''  '''
                    def _respond(self, _request_message):
                        ''' '''

                        if isinstance(request, type) and issubclass(
                                request, model.Model):
                            # convert incoming message to model
                            result = method(
                                self, request.from_message(_request_message))

                        else:
                            # we're using regular messages always
                            result = method(self, _request_message)

                        # convert outgoing message to model if it isn't already
                        if isinstance(result, model.Model):
                            return result.to_message()
                        return result

                    # wrap responder
                    return premote.method(request_klass,
                                          response_klass)(_respond)
Beispiel #9
0
    def __call__(self, api_method):
        # Append the API path to the docstring
        if api_method.__doc__ is None:
            api_method.__doc__ = ""
        api_method.__doc__ += " ( /{0} )".format(self.path
                                                 or api_method.__name__)

        if isinstance(self.request_message, endpoints.ResourceContainer):
            remote_decorator = remote.method(
                self.request_message.combined_message_class,
                self.response_message)
        else:
            remote_decorator = remote.method(self.request_message,
                                             self.response_message)

        remote_method = remote_decorator(api_method)

        def invoke_remote(service_instance, request):
            endpoints.users_id_token._maybe_set_current_user_vars(
                invoke_remote,
                api_info=getattr(service_instance, 'api_info', None),
                request=request)

            try:
                for middleware in self.pre_middlewares:
                    resp = middleware(service_instance, request)
                    if resp:
                        return resp

                response = remote_method(service_instance, request)

                for middleware in self.post_middlewares:
                    resp = middleware(service_instance, request, response)
                    if resp:
                        response = resp

                return response
            except Exception as e:
                for middleware in self.error_middlewares:
                    resp = middleware(service_instance, request, e)
                    if resp:
                        return resp
                raise

        invoke_remote.remote = remote_method.remote
        if isinstance(self.request_message, endpoints.ResourceContainer):
            endpoints.ResourceContainer.add_to_cache(invoke_remote.remote,
                                                     self.request_message)

        invoke_remote.method_info = _MethodInfo(
            name=self.name or api_method.__name__,
            path=self.path or api_method.__name__,
            http_method=self.http_method or "POST",
            scopes=self.scopes,
            audiences=self.audiences,
            allowed_client_ids=self.allowed_client_ids,
            auth_level=self.auth_level)
        invoke_remote.method_info.relative_path = self.path
        invoke_remote.api_method = api_method

        invoke_remote.__name__ = invoke_remote.method_info.name
        invoke_remote.__doc__ = api_method.__doc__  # for sphinx docs
        return invoke_remote
Beispiel #10
0
        def _remote_method(method):

          """ Closure to wrap the target ``method`` at construction time with
              appropriate tooling to execute remote RPCs.

              :param method: Remote-capable method to be wrapped.

              :returns: Wrapped closure ``_respond`` that, when called,
                dispatches the target ``method``. """

          def _respond(self, _request_message):

            """ Inner closure designed to wrap the raw remote ``method`` and
                enforce validation/conversion of ProtoRPC types to native Python
                ones.

                Also handles conversion in/out of Canteen models, if the remote
                method so chooses, by binding to ``canteen.Model`` subclasses
                instead of ProtoRPC ``message.Message``s.

                :param _request_message: Remotely-submitted ``request`` to
                (potentially) be converted and submitted to inner service
                ``method``.

                :returns: Result of calling ``method`` with ``_request_message``
                  as the originating request, so long as the request was
                  successfully executed and passed all client-related
                  constraints. """

            if isinstance(request, type) and issubclass(request, model.Model):
              # convert incoming message to model
              result = method(self, request.from_message(_request_message))

            else:
              # we're using regular messages always
              result = method(self, _request_message)

            # convert outgoing message to model if it isn't already
            if isinstance(result, model.Model):
              return result.to_message()
            return result

          # wrap responder
          wrapped = premote.method(request_klass, response_klass)(_respond)

          # make things transparent
          wrapped.__name__, wrapped.__doc__, wrapped.__inner__ = (
            method.__name__,
            method.__doc__,
            method)

          _respond.__inner__ = wrapped

          # quack quack
          _respond.__name__, _respond.__doc__, _respond.remote = (
            method.__name__,
            method.__doc__,
            wrapped.remote)

          # just for backup
          wrapped.__remote_name__, wrapped.__remote_doc__ = (
            method.__name__,
            method.__doc__,)

          # add remote info
          wrapped.__remote__ = wrapped.remote

          return _respond