def _dt_to_utc_timestamp(t): if t.tzname() == 'UTC': return (t - datetime(1970, 1, 1, tzinfo=_utc)).total_seconds() elif not t.tzinfo: return mktime(t.timetuple()) else: log_and_raise('Only local time and UTC time is supported', ValueError)
def _validate_transfer_protocol_settings(self): if SettingsParameters.TransferProtocol not in self.settings: log_and_raise('Missing transfer protocol information.', RuntimeError) protocol = self.settings[SettingsParameters.TransferProtocol] if protocol == 'http': return if protocol != 'https': log_and_raise( 'Unsupported transfer protocol: {}.'.format(protocol), RuntimeError) self._validate_cert_key_state( 'The parameter(s) {} must be set.', SettingsParameters.CertificateFile in self.settings, SettingsParameters.KeyFile in self.settings) cert = self.settings[SettingsParameters.CertificateFile] self._validate_cert_key_state( 'The parameter(s) {} must point to ' 'an existing file.', os.path.isfile(cert), os.path.isfile(self.settings[SettingsParameters.KeyFile])) tabpy_server.app.util.validate_cert(cert)
def write_state_config(state, settings): if 'state_file_path' in settings: state_path = settings['state_file_path'] else: log_and_raise( '{} is not set'.format(ConfigParameters.TABPY_STATE_PATH), ValueError) logger.debug("State path is {}".format(state_path)) state_key = os.path.join(state_path, 'state.ini') tmp_state_file = state_key with open(tmp_state_file, 'w') as f: state.write(f)
def _validate_cert_key_state(msg, cert_valid, key_valid): cert_and_key_param = '{} and {}'.format( ConfigParameters.TABPY_CERTIFICATE_FILE, ConfigParameters.TABPY_KEY_FILE) https_error = 'Error using HTTPS: ' err = None if not cert_valid and not key_valid: err = https_error + msg.format(cert_and_key_param) elif not cert_valid: err = https_error + \ msg.format(ConfigParameters.TABPY_CERTIFICATE_FILE) elif not key_valid: err = https_error + msg.format(ConfigParameters.TABPY_KEY_FILE) if err is not None: log_and_raise(err, RuntimeError)
def _get_state_from_file(state_path): state_key = os.path.join(state_path, 'state.ini') tmp_state_file = state_key if not os.path.exists(tmp_state_file): log_and_raise("Missing config file at %r" % (tmp_state_file, ), ValueError) config = _ConfigParser(allow_no_value=True) config.optionxform = str config.read(tmp_state_file) if not config.has_section('Service Info'): log_and_raise( "Config error: Expected 'Service Info' section in %s" % (tmp_state_file, ), ValueError) return config
def run(self): application = self._create_tornado_web_app() init_model_evaluator( self.settings, self.tabpy_state, self.python_service) if self.settings['transfer_protocol'] == 'http': application.listen(self.settings['port']) elif self.settings['transfer_protocol'] == 'https': application.listen(self.settings['port'], ssl_options={ 'certfile': self.settings['certificate_file'], 'keyfile': self.settings['key_file'] }) else: log_and_raise('Unsupported transfer protocol.', RuntimeError) logger.info('Web service listening on port {}'.format( str(self.settings['port']))) tornado.ioloop.IOLoop.instance().start()
def run(self): application = self._create_tornado_web_app() init_model_evaluator(self.settings, self.tabpy_state, self.python_service) protocol = self.settings[SettingsParameters.TransferProtocol] if protocol == 'http': application.listen(self.settings[SettingsParameters.Port]) elif protocol == 'https': application.listen( self.settings[SettingsParameters.Port], ssl_options={ 'certfile': self.settings[SettingsParameters.CertificateFile], 'keyfile': self.settings[SettingsParameters.KeyFile] }) else: log_and_raise(f'Unsupported transfer protocol {protocol}.', RuntimeError) logger.info('Web service listening on port {}'.format( str(self.settings[SettingsParameters.Port]))) tornado.ioloop.IOLoop.instance().start()
def _parse_config(self, config_file): """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 2. config file 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 config file 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_' """ self.settings = {} self.subdirectory = "" self.tabpy_state = None self.python_service = None self.credentials = {} parser = configparser.ConfigParser() if os.path.isfile(config_file): with open(config_file) as f: parser.read_string(f.read()) else: logger.warning("Unable to find config file at '{}', " "using default settings.".format(config_file)) def set_parameter(settings_key, config_key, default_val=None, check_env_var=False): if config_key is not None and\ parser.has_option('TabPy', config_key): self.settings[settings_key] = parser.get('TabPy', config_key) elif check_env_var: self.settings[settings_key] = os.getenv( config_key, default_val) elif default_val is not None: self.settings[settings_key] = default_val set_parameter(SettingsParameters.Port, ConfigParameters.TABPY_PORT, default_val=9004, check_env_var=True) set_parameter(SettingsParameters.ServerVersion, None, default_val=__version__) set_parameter(SettingsParameters.UploadDir, ConfigParameters.TABPY_QUERY_OBJECT_PATH, default_val='/tmp/query_objects', check_env_var=True) if not os.path.exists(self.settings[SettingsParameters.UploadDir]): os.makedirs(self.settings[SettingsParameters.UploadDir]) # set and validate transfer protocol set_parameter(SettingsParameters.TransferProtocol, ConfigParameters.TABPY_TRANSFER_PROTOCOL, default_val='http') self.settings[SettingsParameters.TransferProtocol] =\ self.settings[SettingsParameters.TransferProtocol].lower() set_parameter(SettingsParameters.CertificateFile, ConfigParameters.TABPY_CERTIFICATE_FILE) set_parameter(SettingsParameters.KeyFile, ConfigParameters.TABPY_KEY_FILE) self._validate_transfer_protocol_settings() # if state.ini does not exist try and create it - remove # last dependence on batch/shell script set_parameter(SettingsParameters.StateFilePath, ConfigParameters.TABPY_STATE_PATH, default_val='./tabpy-server/tabpy_server', check_env_var=True) self.settings[SettingsParameters.StateFilePath] = os.path.realpath( os.path.normpath( os.path.expanduser( self.settings[SettingsParameters.StateFilePath]))) state_file_path = self.settings[SettingsParameters.StateFilePath] logger.info("Loading state from state file %s" % os.path.join(state_file_path, "state.ini")) tabpy_state = _get_state_from_file(state_file_path) self.tabpy_state = TabPyState(config=tabpy_state, settings=self.settings) self.python_service = PythonServiceHandler(PythonService()) self.settings['compress_response'] = True if TORNADO_MAJOR >= 4\ else "gzip" set_parameter(SettingsParameters.StaticPath, ConfigParameters.TABPY_STATIC_PATH, default_val='./') self.settings[SettingsParameters.StaticPath] =\ os.path.abspath(self.settings[SettingsParameters.StaticPath]) logger.debug(f'Static pages folder set to ' f'"{self.settings[SettingsParameters.StaticPath]}"') # Set subdirectory from config if applicable if tabpy_state.has_option("Service Info", "Subdirectory"): self.subdirectory = "/" + \ tabpy_state.get("Service Info", "Subdirectory") # If passwords file specified load credentials set_parameter(ConfigParameters.TABPY_PWD_FILE, ConfigParameters.TABPY_PWD_FILE) if ConfigParameters.TABPY_PWD_FILE in self.settings: if not self._parse_pwd_file(): log_and_raise( 'Failed to read passwords file %s' % self.settings[ConfigParameters.TABPY_PWD_FILE], RuntimeError) else: logger.info("Password file is not specified: " "Authentication is not enabled") features = self._get_features() self.settings[SettingsParameters.ApiVersions] =\ {'v1': {'features': features}} set_parameter(SettingsParameters.LogRequestContext, ConfigParameters.TABPY_LOG_DETAILS, default_val='false') self.settings[SettingsParameters.LogRequestContext] = ( self.settings[SettingsParameters.LogRequestContext].lower() != 'false') logger.info( 'Call context logging is {}'.format('enabled' if self.settings[ SettingsParameters.LogRequestContext] else 'disabled'))