在python客户端localhost上等待python Google Cloud端点超过了HTTP截止日期



我想构建一个python客户端来与我的python Google Cloud端点API对话。我的简单HelloWorld示例在python客户端中遇到HTTPException,我不知道为什么。

我已经按照这个非常有用的线程中的建议设置了一些简单的示例。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上这样简单的第一次调用不应该超过默认的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截止日期,以及如何修复它?

main.py上,您忘记向发现服务url字符串添加一些变量,或者您只是在没有添加变量的情况下将代码复制到这里。从外观上看,您可能应该使用format string方法。

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

最新更新