def on_state_change(settings): try: tabpy = settings['tabpy'] py_handler = settings['py_handler'] log_info("Loading state from state file") config = util._get_state_from_file(settings['state_file_path']) new_ps_state = TabPyState(config=config) (has_changes, changes) = _get_latest_service_state(settings, new_ps_state) if not has_changes: log_info("Nothing changed, return.") return new_endpoints = new_ps_state.get_endpoints() for object_name in changes['endpoints']: (object_type, object_version, object_path) = changes['endpoints'][object_name] if not object_path and not object_version: # removal log_info("Removing object", uri=object_name) py_handler.manage_request(DeleteObjects([object_name])) cleanup_endpoint_files(object_name, settings['upload_dir']) else: endpoint_info = new_endpoints[object_name] is_update = object_version > 1 if object_type == 'alias': msg = LoadObject(object_name, endpoint_info['target'], object_version, is_update, 'alias') else: local_path = object_path msg = LoadObject(object_name, local_path, object_version, is_update, object_type) py_handler.manage_request(msg) wait_for_endpoint_loaded(py_handler, object_name) # cleanup old version of endpoint files if object_version > 2: cleanup_endpoint_files( object_name, settings['upload_dir'], [object_version, object_version - 1]) except Exception as e: err_msg = format_exception(e, 'on_state_change') log_warning("Error submitting update model request", error=err_msg)
def main(): args = parse_arguments() port = args.port if not port: port = DEFAULT_TABPY_PORT log_info("Loading state from state file") state_file_path = os.environ['TABPY_STATE_PATH'] config = _get_state_from_file(state_file_path) tabpy = TabPyState(config=config) python_service_handler = PythonServiceHandler(PythonService()) state_file_path = os.path.realpath( os.path.normpath( os.path.expanduser(os.environ.get('TABPY_STATE_PATH', './state')))) # initialize settings for application handlers settings = { "compress_response" if TORNADO_MAJOR >= 4 else "gzip": True, "tabpy": tabpy, "py_handler": python_service_handler, "port": port, "state_file_path": state_file_path, "static_path": os.path.join(os.path.dirname(__file__), "static") } log_info('Initializing TabPy...') tornado.ioloop.IOLoop.instance().run_sync(lambda: init_ps_server(settings)) log_info('Done initializing TabPy.') executor = concurrent.futures.ThreadPoolExecutor( max_workers=multiprocessing.cpu_count()) # initialize Tornado application application = tornado.web.Application( [ # skip MainHandler to use StaticFileHandler .* page requests and default to index.html # (r"/", MainHandler), (r'/query/([^/]+)', QueryPlaneHandler), (r'/status', StatusHandler), (r'/info', ServiceInfoHandler), (r'/endpoints', EndpointsHandler), (r'/endpoints/([^/]+)?', EndpointHandler), (r'/evaluate', EvaluationPlaneHandler, dict(executor=executor)), (r'/configurations/endpoint_upload_destination', UploadDestinationHandler), (r'/(.*)', tornado.web.StaticFileHandler, dict(path=settings['static_path'], default_filename="index.html")), ], debug=False, **settings) settings = application.settings init_model_evaluator(settings) application.listen(port) log_info('Web service listening on port ' + str(port)) tornado.ioloop.IOLoop.instance().start()
def on_state_change(settings): try: tabpy = settings['tabpy'] py_handler = settings['py_handler'] log_info("Loading state from state file") state_file_path = os.environ['TABPY_STATE_PATH'] config = util._get_state_from_file(state_file_path) new_ps_state = TabPyState(config=config) (has_changes, changes) = _get_latest_service_state(settings, new_ps_state) if not has_changes: log_info("Nothing changed, return.") return new_endpoints = new_ps_state.get_endpoints() for object_name in changes['endpoints']: (object_type, object_version, object_path) = changes['endpoints'][object_name] if not object_path and not object_version: # removal log_info("Removing object", uri=object_name) py_handler.manage_request(DeleteObjects([object_name])) cleanup_endpoint_files(object_name) else: endpoint_info = new_endpoints[object_name] is_update = object_version > 1 if object_type == 'alias': msg = LoadObject(object_name, endpoint_info['target'], object_version, is_update, 'alias') else: local_path = object_path msg = LoadObject(object_name, local_path, object_version, is_update, object_type) py_handler.manage_request(msg) wait_for_endpoint_loaded(py_handler, object_name) # cleanup old version of endpoint files if object_version > 2: cleanup_endpoint_files(object_name, [object_version, object_version - 1]) except Exception as e: err_msg = format_exception(e, 'on_state_change') log_warning("Error submitting update model request", error=err_msg)
def get_config(): """Provide consistent mechanism for pulling in configuration. Attempt to retain backward compatibility for existing implementations by grabbing port setting from CLI first. Take settings in the following order: 1. CLI arguments, if present - port only - may be able to deprecate 2. common.config file, and 3. OS environment variables (for ease of setting defaults if not present) 4. current defaults if a setting is not present in any location Additionally provide similar configuration capabilities in between common.config and environment variables. For consistency use the same variable name in the config file as in the os environment. For naming standards use all capitals and start with 'TABPY_' """ if os.path.isfile('./common/config.py'): import common.config as config else: config = None settings = {} cli_args = parse_arguments() if cli_args.port is not None: settings['port'] = cli_args.port else: try: settings['port'] = config.TABPY_PORT except AttributeError: settings['port'] = os.getenv('TABPY_PORT', 9004) try: settings['server_version'] = config.TABPY_SERVER_VERSION except AttributeError: settings['server_version'] = os.getenv('TABPY_SERVER_VERSION', 'Alpha') try: settings['bind_ip'] = config.TABPY_BIND_IP except AttributeError: settings['bind_ip'] = os.getenv('TABPY_BIND_IP', '0.0.0.0') try: settings['upload_dir'] = config.TABPY_QUERY_OBJECT_PATH except AttributeError: settings['upload_dir'] = os.getenv('TABPY_QUERY_OBJECT_PATH', '/tmp/query_objects') if not os.path.exists(settings['upload_dir']): os.makedirs(settings['upload_dir']) try: _state_file_path = config.TABPY_STATE_PATH except AttributeError: _state_file_path = os.getenv('TABPY_STATE_PATH', './') settings['state_file_path'] = os.path.realpath( os.path.normpath(os.path.expanduser(_state_file_path))) # if state.ini does not exist try and create it - remove last dependence # on batch/shell script if not os.path.isfile('{}/state.ini'.format(settings['state_file_path'])): shutil.copy('./state.ini.template', '{}/state.ini'.format(settings['state_file_path'])) log_info("Loading state from state file") tabpy_state = _get_state_from_file(settings['state_file_path']) settings['tabpy'] = TabPyState(config=tabpy_state) settings['py_handler'] = PythonServiceHandler(PythonService()) settings['compress_response'] = True if TORNADO_MAJOR >= 4 else "gzip" settings['static_path'] = os.path.join(os.path.dirname(__file__), "static") # Set subdirectory from config if applicable subdirectory = "" if tabpy_state.has_option("Service Info", "Subdirectory"): subdirectory = "/" + tabpy_state.get("Service Info", "Subdirectory") return settings, subdirectory