HTTP截止日期超过等待python客户端localhost

时间:2015-11-19 15:49:14

标签: python-2.7 google-app-engine google-cloud-endpoints google-api-python-client httpexception

我想构建一个python客户端来与我的python Google Cloud Endpoints API交谈。我的简单HelloWorld示例在python客户端中遇到HTTPException,我无法弄清楚原因。

我按照this非常有用的主题提示设置了简单示例。 GAE端点API在localhost:8080上运行,没有任何问题 - 我可以在API Explorer中成功访问它。在我添加有问题的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的这种简单的第一次调用不应该超过默认的5s截止日期。我也尝试直接在浏览器中访问发现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截止日期已超出,以及如何解决?

1 个答案:

答案 0 :(得分:1)

main.py上,您忘了向搜索服务网址字符串添加一些变量,或者您只是在没有它的情况下复制了代码。根据它的外观,你可能会想要使用格式字符串方法。

"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

首先超时,然后“正常工作”。

在请求处理程序中移动服务发现请求:

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'))