在 python 客户端本地主机上等待 python Google 云端点超过 HTTP 截止时间

HTTP Deadline exceeded waiting for python Google Cloud Endpoints on python client localhost

我想构建一个 python 客户端来与我的 python Google 云端点 API 通信。我的简单 HelloWorld 示例在 python 客户端中出现 HTTPException,我不知道为什么。

我已经按照 this 非常有用的帖子中的建议设置了简单示例。 GAE 端点 API 在 localhost:8080 上 运行 没有问题 - 我可以在 API 资源管理器中成功访问它。在我添加有问题的 service = build() 行之前,我的简单客户端 运行 在 localhost:8080.

上运行良好

当试图让客户端与端点对话时 API,我收到以下错误:

File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/dist27/gae_override/httplib.py", line 526, in getresponse
raise HTTPException(str(e))
HTTPException: Deadline exceeded while waiting for HTTP response from URL: http://localhost:8080/_ah/api/discovery/v1/apis/helloworldendpoints/v1/rest?userIp=%3A%3A1

我试过延长 http 截止日期。这不仅没有帮助,而且在 localhost 上这样一个简单的第一次调用不应该超过默认的 5 秒截止日期。我也试过直接在浏览器中访问发现 URL,效果也很好。

这是我的简单代码。首先是客户端,main.py:

import webapp2
import os
import httplib2

from apiclient.discovery import build

http = httplib2.Http()

# HTTPException happens on the following line:
# Note that I am using http, not https
service = build("helloworldendpoints", "v1", http=http, 
  discoveryServiceUrl=("http://localhost:8080/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest"))

# result = service.resource().method([parameters]).execute()

class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-type'] = 'text/plain'
        self.response.out.write("Hey, this is working!")

app = webapp2.WSGIApplication(
    [('/', MainPage)],
    debug=True)

这是 Hello World 端点,helloworld.py:

"""Hello World API implemented using Google Cloud Endpoints.

Contains declarations of endpoint, endpoint methods,
as well as the ProtoRPC message class and container required
for endpoint method definition.
"""
import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote


# If the request contains path or querystring arguments,
# you cannot use a simple Message class.
# Instead, you must use a ResourceContainer class
REQUEST_CONTAINER = endpoints.ResourceContainer(
    message_types.VoidMessage,
    name=messages.StringField(1),
)


package = 'Hello'


class Hello(messages.Message):
    """String that stores a message."""
    greeting = messages.StringField(1)


@endpoints.api(name='helloworldendpoints', version='v1')
class HelloWorldApi(remote.Service):
    """Helloworld API v1."""

    @endpoints.method(message_types.VoidMessage, Hello,
      path = "sayHello", http_method='GET', name = "sayHello")
    def say_hello(self, request):
      return Hello(greeting="Hello World")

    @endpoints.method(REQUEST_CONTAINER, Hello,
      path = "sayHelloByName", http_method='GET', name = "sayHelloByName")
    def say_hello_by_name(self, request):
      greet = "Hello {}".format(request.name)
      return Hello(greeting=greet)

api = endpoints.api_server([HelloWorldApi])

最后,这是我的 app.yaml 文件:

application: <<my web client id removed for stack overflow>>
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:

- url: /_ah/spi/.*
  script: helloworld.api
  secure: always

# catchall - must come last!
- url: /.*
  script: main.app
  secure: always


libraries:

- name: endpoints
  version: latest

- name: webapp2
  version: latest

为什么我会收到 HTTP Deadline Exceeded 以及如何解决?

在您的 main.py 上,您忘记将一些变量添加到您的发现服务 url 字符串中,或​​者您只是在没有它的情况下复制了代码。从它的外观来看,您可能假设使用格式字符串方法。

"http://localhost:8080/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest".format(api='helloworldendpoints', apiVersion="v1")

通过查看日志,您可能会看到如下内容:

INFO     2015-11-19 18:44:51,562 module.py:794] default: "GET /HTTP/1.1" 500 -
INFO     2015-11-19 18:44:51,595 module.py:794] default: "POST /_ah/spi/BackendService.getApiConfigs HTTP/1.1" 200 3109
INFO     2015-11-19 18:44:52,110 module.py:794] default: "GET /_ah/api/discovery/v1/apis/helloworldendpoints/v1/rest?userIp=127.0.0.1 HTTP/1.1" 200 3719

先超时再"working".

将服务发现请求移到请求处理程序中:

class MainPage(webapp2.RequestHandler):
    def get(self):
        service = build("helloworldendpoints", "v1",
                    http=http,
                    discoveryServiceUrl=("http://localhost:8080/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest")
                    .format(api='helloworldendpoints', apiVersion='v1'))