File: //snap/google-cloud-cli/current/platform/ext-runtime/java/lib/comm.py
# Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Note: this file is part of the sdk-ext-runtime package. It gets copied into
# individual GAE runtime modules so that they can be easily deployed.
import json
import os
import sys
class JSONObject(object):
"""Wrapper for a JSON object.
Presents a JSON object as a python object (where fields are attributes)
instead of a dictionary. Undefined attributes produce a value of None
instead of an AttributeError.
Note that attribute names beginning with an underscore are excluded.
"""
def __getattr__(self, attr):
return None
def to_dict(self):
result = {}
for attr, val in self.__dict__.iteritems():
if not attr.startswith('_'):
result[attr] = _make_serializable(val)
return result
# Alias old style naming so this interoperates with gcloud's appinfo.
ToDict = to_dict
def _make_serializable(obj):
"""Converts objects to serializable form."""
if isinstance(obj, JSONObject):
return obj.to_dict()
else:
return obj
def _write_msg(**message):
"""Write a message to standard output.
Args:
**message: ({str: object, ...}) A JSON message encoded in keyword
arguments.
"""
json.dump(message, sys.stdout, default=_make_serializable)
sys.stdout.write('\n')
sys.stdout.flush()
def error(message, *args):
_write_msg(type='error', message=message % args)
def warn(message, *args):
_write_msg(type='warn', message=message % args)
def info(message, *args):
_write_msg(type='info', message=message % args)
def debug(message, *args):
_write_msg(type='debug', message=message % args)
def print_status(message, *args):
_write_msg(type='print_status', message=message % args)
def send_runtime_params(params, appinfo=None):
"""Send runtime parameters back to the controller.
Args:
params: ({str: object, ...}) Set of runtime parameters. Must be
json-encodable.
appinfo: ({str: object, ...} or None) Contents of the app.yaml file to
be produced by the runtime definition. Required fields may be
added to this by the framework, the only thing an application
needs to provide is the "runtime" field and any additional data
fields.
"""
if appinfo is not None:
_write_msg(type='runtime_parameters', runtime_data=params,
appinfo=appinfo)
else:
_write_msg(type='runtime_parameters', runtime_data=params)
def get_config():
"""Request runtime parameters from the controller.
Returns:
(object) The runtime parameters represented as an object.
"""
_write_msg(type='get_config')
return dict_to_object(json.loads(sys.stdin.readline()))
def dict_to_object(json_dict):
"""Converts a dictionary to a python object.
Converts key-values to attribute-values.
Args:
json_dict: ({str: object, ...})
Returns:
(JSONObject)
"""
obj = JSONObject()
for name, val in json_dict.iteritems():
if isinstance(val, dict):
val = dict_to_object(val)
setattr(obj, name, val)
return obj
class RuntimeDefinitionRoot(object):
"""Abstraction that allows us to access files in the runtime definiton."""
def __init__(self, path):
self.root = path
def read_file(self, *name):
with open(os.path.join(self.root, *name)) as src:
return src.read()
def gen_file(name, contents):
"""Generate the file.
This writes the file to be generated back to the controller.
Args:
name: (str) The UNIX-style relative path of the file.
contents: (str) The complete file contents.
"""
_write_msg(type='gen_file', filename=name, contents=contents)
def query_user(prompt, default=None):
"""Query the user for data.
Args:
prompt: (str) Prompt to display to the user.
default: (str or None) Default value to use if the user doesn't input
anything.
Returns:
(str) Value returned by the user.
"""
kwargs = {}
kwargs['prompt'] = prompt
if default is not None:
kwargs['default'] = default
_write_msg(type='query_user', **kwargs)
return json.loads(sys.stdin.readline())['result']