1

I want to build a client for my cloud endpoints in python like described in the Documentation.

I want to build the api from a Managed VM, so i get the path to the API by calling

modules.get_hostname(module="default")

This works fine for the devserver and i can create the complete path to the discovery endpoint, however on the live system this returns the url to a certain version like:

20150628t110011.default.guestbook.appspot.com

Thus the complete path to the API (default module) would be

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

But there is no discovery document, maybe due to the fact, that the certificate does not match a url that long and the https fails.

Is there a proper way to receive the base url to the default module? like so:

default.guestbook.appspot.com

because that would result in a working discovery endpoint:

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

I would like to avoid doing string operations here, because on the local devserver this would not work as the module url resolves to something like localhost:1234.

pfried
  • 5,000
  • 2
  • 38
  • 71

2 Answers2

4

You probably want to go through the GAE URl routing doc: https://cloud.google.com/appengine/docs/python/modules/routing#routing_via_url

Key points in there:

  • Google does not issue SSL certificates for double-wildcard domains hosted at appspot.com, the certificate won't work for https://20150628t110011.default.guestbook.appspot.com
  • You can get the certificate to work using the -dot- delimiters; in particular the default version of the default module can be accessed directly at guestbook.appspot.com

The problem gets even more complicated if your app has multiple modules and also if it's mapped to a custom domain.

While trying to address such complications I realized that 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)

But the info it can return (as applicable depending on the invocation arguments and the execution context) is IMHO extremely useful, allowing one to programatically obtain proper hostnames/URLs for all 3 possible app usage contextes: on the development server, on the .appspot.com domain and on custom domains mapping (including with hostname-based mapping):

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

This would be, for example, my approach for an app not interested in anything below the module name and using hostname-based custom domain dispatch routing - modules mapped to different hostnames):

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:])
Community
  • 1
  • 1
Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97
2

As per this thread, unfortunately manual conversion is required to convert from the . hostname to -dot-.

Community
  • 1
  • 1
saiyr
  • 2,575
  • 1
  • 11
  • 13