在GAE python上为webapp2处理程序定义请求和响应对象

在GAE python上为webapp2处理程序定义请求和响应对象,python,google-app-engine,Python,Google App Engine,我已经有了一个使用webapp2构建的带有GAE python的RESTAPI。我在看protorpc和Cloud Enpoints中使用的protorpc消息,非常喜欢如何定义请求和响应。有没有办法将其合并到我的webapp2处理程序中?首先,我在webapp2方法上使用了一个decorator。我对装饰者的定义如下*: # Takes webapp2 request (self.request on baseHandler) and converts to defined proto

我已经有了一个使用webapp2构建的带有GAE python的RESTAPI。我在看protorpc和Cloud Enpoints中使用的protorpc消息,非常喜欢如何定义请求和响应。有没有办法将其合并到我的webapp2处理程序中?

首先,我在webapp2方法上使用了一个decorator。我对装饰者的定义如下*:

    # Takes webapp2 request (self.request on baseHandler) and converts to defined protoRpc object 
    def jsonMethod(requestType, responseType, http_method='GET'):
            """
            NB: if both URL and POST parameters are used, do not use 'required=True' values in the protorpc Message definition 
                    as this will fail on one of the sets of parms
            """
            def jsonMethodHandler(handler):
                    def jsonMethodInner(self, **kwargs):            
                            requestObject = getJsonRequestObject(self, requestType, http_method, kwargs)

                            logging.info(u'request={0}'.format(requestObject))
                            response = handler(self, requestObject) # Response object       
                            if response:
                                # Convert response to Json
                                responseJson = protojson.encode_message(response)
                            else:
                                responseJson = '{}'
                            logging.info(u'response json={0}'.format(responseJson))
                            if self.response.headers:
                                    self.response.headers['Content-Type'] = 'application/json'
                            if responseJson:
                                    self.response.write(responseJson)
                                    self.response.write('')

                    return jsonMethodInner
            return jsonMethodHandler
jsonMethod装饰器对“requestType”和“responseType”使用protorpc消息。 我已将http_方法约束为GET、POST或DELETE作为方法;您可能希望更改此设置。 请注意,此修饰符必须应用于webapp2.RequestHandler类(请参见下面的示例)上的实例方法,因为它需要访问webapp2请求和响应对象

protorpc消息填充在getJsonRequestObject()中:

最后是一个修饰过的webapp2方法示例:

    from protorpc import messages, message_types

    class FileSearchRequest(messages.Message):
        """
        A combination of file metadata and file information
        """
        filename = messages.StringField(1)
        startDateTime = message_types.DateTimeField(2)
        endDateTime = message_types.DateTimeField(3)

    class ListResponse(messages.Message):
        """
        List of strings response
        """
        items = messages.StringField(1, repeated=True)  

    ...

    class FileHandler(webapp2.RequestHandler):   
        @jsonMethod(FileSearchRequest, ListResponse, http_method='POST')  
        def searchFiles(self, request):
            # Can now use request.filename etc
            ...
            return ListResponse(items=items)
希望这能让您了解如何实现自己的webapp2/protorpc框架

您还可以检查并查看云端点如何实现其protorpc消息处理。您可能还需要深入了解protorpc代码本身

  • 请注意,我试图简化现有的实现,因此您可能会遇到需要在实现中解决的各种问题。 此外,像“logError()”这样的方法和像“ValidationException”这样的类是非标准的,所以您需要根据需要替换它们。 您可能还希望在某个时候删除日志记录

是的,我目前正在webapp2中使用protorpc(不是端点,因为它不适合我的需要)。我需要一点努力;我在webapp2方法上有一个decorator,它(使用POST和GET参数的protorpc‘decode_message’方法)将webapp2请求转换为protorpc消息。当我有一点时间的时候,我会试着写一个像样的答案,让你朝着正确的方向前进。谢谢@ChrisC73。我会留意你的反应。
    def combineRequestObjects(requestType, request1, request2):
        """
        Combines two objects of requestType; Note that request2 values will override request1 values if duplicated
        """
        members = inspect.getmembers(requestType, lambda a:not(inspect.isroutine(a)))
        members = [m for m in members if not m[0].startswith('_')]
        for key, value in members:
                val = getattr(request2, key)
                if val:
                        setattr(request1, key, val)  
        return request1
    from protorpc import messages, message_types

    class FileSearchRequest(messages.Message):
        """
        A combination of file metadata and file information
        """
        filename = messages.StringField(1)
        startDateTime = message_types.DateTimeField(2)
        endDateTime = message_types.DateTimeField(3)

    class ListResponse(messages.Message):
        """
        List of strings response
        """
        items = messages.StringField(1, repeated=True)  

    ...

    class FileHandler(webapp2.RequestHandler):   
        @jsonMethod(FileSearchRequest, ListResponse, http_method='POST')  
        def searchFiles(self, request):
            # Can now use request.filename etc
            ...
            return ListResponse(items=items)