Google Cloud Endpoints Python Quickstart echo示例问题

时间:2017-02-28 23:27:56

标签: python google-cloud-endpoints

在python标准环境快速入门中,端点方法test_api_key返回503 Service Unavailable。使用dev_appser.py运行时以及部署API时,API Explorer中会发生错误。它的代码是:

import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote

class TestResponse(messages.Message):
    content = messages.StringField(1)

@endpoints.api(name='practice', version='v1', description='My Practice API')
class PracticeApi(remote.Service):

    @endpoints.method(
        message_types.VoidMessage,
        TestResponse,
        path='test/getApiKey',
        http_method='GET',
        name='test_api_key')
    def test_api_key(self, request):
        return TestResponse(content=request.get_unrecognized_field_info('key'))

api = endpoints.api_server([PracticeApi])

我对.get_unrecognized_field_info('key')没有很好的理解,所以我不确定是什么问题?感谢。

2 个答案:

答案 0 :(得分:1)

首先,我建议您阅读Google Protocol RPC Library Overview,因为它的Google Cloud Endpoints广泛使用它。

@ endpoints.method允许您在API中配置特定方法。配置选项记录在Google Cloud Platform文档中,使用Cloud Endpoints Frameworks for App Engine创建API,在Defining an API method (@endpoints.method)部分中。

如果您要限制对test/getApiKey/test_api_key方法的访问权限,则必须使用api_key_required=True选项配置该方法。 Restricting API Access with API Keys (Frameworks)进一步讨论了这个问题,但您的方法注释应该是:

@endpoints.method(
        message_types.VoidMessage,
        TestResponse,
        path='test/getApiKey',
        http_method='GET',
        name='test_api_key',
        api_key_required=True
)

请注意,您的方法接受表示HTTP请求的请求参数(即使用您的API的客户端):

def test_api_key(self, request):

但是,request参数实际上是Google Protocol RPC Message(Proto RPC)Message对象,因此定义非常明确。如果ProtoRPC请求参数中存在其他字段,超出正式定义的范围,它们仍与请求对象一起存储,但必须使用以下方法检索:

def get_unrecognized_field_info(self, key, value_default=None,
                                  variant_default=None):
    """Get the value and variant of an unknown field in this message.
    Args:
      key: The name or number of the field to retrieve.
      value_default: Value to be returned if the key isn't found.
      variant_default: Value to be returned as variant if the key isn't
        found.
    Returns:
      (value, variant), where value and variant are whatever was passed
      to set_unrecognized_field.
    """

Message class code on GitHub有很好的记录。

请求正文中不会出现任何参数,因为您已将方法配置为使用HTTP GET调用:

http_method='GET'

...您正确使用了值message_types.VoidMessage

就您的错误而言,503只是一般服务器错误,您能否提供StackDriver logs的任何信息?它们会指向您的代码中的确切行和错误。

答案 1 :(得分:0)

有三件事情造成503错误。

首先,我需要制作方法或整个Api require an Api Key。在这种情况下,我只是将其应用于整个Api:

@endpoints.api(name='practice', version='v1', api_key_required=True)
class PracticeApi(remote.Service):

其次,在云控制台中生成Api密钥后,我需要put the Key into the openapi.json file才能部署它。

最后,我仍然收到验证错误:

ValidationError: Expected type <type 'unicode'> for field content, found (u'My Api Key', Variant(STRING, 9)) (type <type 'tuple'>)

get_unrecognized_field_info()函数returns a tuple of (value, variant)。响应没有预期元组,所以我更新了方法只显示值:

    def test_api_key(self, request):
        return TestResponse(content=request.get_unrecognized_field_info('key')[0])