解决 App Engine 模块上的发现路径

Resolve Discovery path on App Engine Module

我想在 python 中为我的云端点构建一个客户端,如 the Documentation 中所述。

我想从托管 VM 构建 api,所以我通过调用

获得 API 的路径
modules.get_hostname(module="default")

这适用于开发服务器,我可以创建到发现端点的完整路径,但是在实时系统上,returns url 到某个版本,例如:

20150628t110011.default.guestbook.appspot.com

因此 API(默认模块)的完整路径将是

https://20150628t110011.default.guestbook.appspot.com/_ah/api/discovery/v1/apis/guestbook/v1/rest?userIp=182.177.0.4"

但是没有发现文档,可能是因为证书不匹配 url 那么长,https 失败。

是否有正确的方法将基础 url 接收到默认模块?像这样:

default.guestbook.appspot.com

因为这会产生一个有效的发现端点:

https://default.guestbook.appspot.com/_ah/api/discovery/v1/apis/guestbook/v1/rest?userIp=182.177.0.4"

我想避免在这里进行字符串操作,因为在本地开发服务器上这不会工作,因为模块 url 解析为 localhost:1234.

之类的东西

根据 this thread,不幸的是,需要手动转换才能从 . 主机名转换为 -dot-

您可能想要完成 GAE URl routing doc: https://cloud.google.com/appengine/docs/python/modules/routing#routing_via_url

里面的要点:

  • Google 不为双通配符域颁发 SSL 证书 托管在 appspot.com,证书不适用于 https://20150628t110011.default.guestbook.appspot.com
  • 您可以使用 -dot- 分隔符使证书生效;特别是 default 版本的 default 模块可以直接在 guestbook.appspot.com
  • 访问

如果您的应用有多个模块并且映射到自定义域,问题会变得更加复杂。

在尝试解决这些并发症时,我意识到 modules.get_hostname() is nowadays no longer able to perform the original function that its name implies (I guess because of the multiple possible paths for accessing the same entity). Which probably explains why they won't attempt to fix the api to return a proper hostname: (see this Q&A)

但是它 可以 return 的信息(视调用参数和执行上下文而定)是恕我直言非常有用,允许以编程方式获得适当的 hostnames/URLs 对于所有 3 种可能的应用程序使用上下文:在开发服务器上、在 .appspot.com 域和自定义域映射(包括基于主机名的映射):

<instance_id>.<module_version>.<module_name>.<app_name>.(appspot.com|<devserver_hostname>:<port#>)

例如,对于一个对模块名称以下的任何内容都不感兴趣并使用基于主机名的自定义域调度路由的应用程序,这将是我的方法 - 映射到不同主机名的模块):

def get_module_url(self, module_name='default'):
    host_name = modules.get_hostname(module=module_name)
    if os.environ.get('SERVER_SOFTWARE').startswith('Development'):
        return 'http://' + host_name
    app_name = app_identity.get_application_id()
    split_name = self.request.host.split(':')[0].split('.')
    if split_name[-2] == 'appspot':
        new_host_name = app_name if module_name == 'default' else module_name + '-dot-' + app_name
    else:
        # custom hostname-based domain mapping, default module goes to `www`.mydomain.com
        new_host_name = 'www' if module_name == 'default' else module_name
        if app_name.endswith('-staging'):
            #  copy of the GAE app for staging purposes on mydomain.com
            new_host_name += '-staging'
    return '.'.join(['https://' + new_host_name] + split_name[1:])