def test_classes_in_namespaces_converter(self): class A(object): pass class B(object): pass class C(object): pass class_list_converter = classes_in_namespaces_converter( name_of_class_option='a_class') i = class_list_converter('A,B,C') eq_(i.subordinate_namespace_names, ['A', 'B', 'C']) eq_(i.class_option_name, 'a_class') ok_(i.required_config) eq_(len(i.required_config), 3) class_keys_in_namespaces = [ x for x in i.required_config.keys_breadth_first() ] eq_( # order is preserved class_keys_in_namespaces, ['A.a_class', 'B.a_class', 'C.a_class']) classes = [A, B, C] class_options_from_namespaces = [ i.required_config[k] for k in class_keys_in_namespaces ] for bare_class, class_wrapped_in_option_object in zip( classes, class_options_from_namespaces): eq_(bare_class.__name__, class_wrapped_in_option_object.default)
def test_classes_in_namespaces_converter(self): class A(object): pass class B(object): pass class C(object): pass class_list_converter = classes_in_namespaces_converter( name_of_class_option='a_class' ) i = class_list_converter('A,B,C') eq_(i.subordinate_namespace_names, ['A', 'B', 'C']) eq_(i.class_option_name, 'a_class') ok_(i.required_config) eq_(len(i.required_config), 3) class_keys_in_namespaces = [ x for x in i.required_config.keys_breadth_first() ] eq_( # order is preserved class_keys_in_namespaces, ['A.a_class', 'B.a_class', 'C.a_class'] ) classes = [A, B, C] class_options_from_namespaces = [ i.required_config[k] for k in class_keys_in_namespaces ] for bare_class, class_wrapped_in_option_object in zip( classes, class_options_from_namespaces ): eq_(bare_class.__name__, class_wrapped_in_option_object.default)
class DataserviceApp(App): app_name = 'dataservice' app_version = '1.0' # return to original roots app_description = __doc__ #-------------------------------------------------------------------------- # in this section, define any configuration requirements required_config = Namespace() #-------------------------------------------------------------------------- # web services namespace # this namespace is for listing the services offered by Dataservice #-------------------------------------------------------------------------- required_config.namespace('services') required_config.services.add_option( 'service_list', default=SERVICES_LIST, from_string_converter=classes_in_namespaces_converter()) #-------------------------------------------------------------------------- # web_server namespace # this namespace is for config parameters the web server #-------------------------------------------------------------------------- required_config.namespace('web_server') required_config.web_server.add_option( 'wsgi_server_class', doc='a class implementing a wsgi web server', default='socorro.webapi.servers.CherryPy', from_string_converter=class_converter) #-------------------------------------------------------------------------- # sentry namespace # this namespace is for Sentry error capturing with Raven #-------------------------------------------------------------------------- required_config.namespace('sentry') required_config.sentry.add_option( 'dsn', doc='DSN for Sentry via raven', default='', reference_value_from='secrets.sentry', ) # because the socorro.webapi.servers classes bring up their own default # configurations like port number, the only way to override the default # is like this: from socorro.webapi.servers import StandAloneServer StandAloneServer.required_config.port.set_default(8883, force=True) #-------------------------------------------------------------------------- def main(self): # modwsgi requireds a module level name 'application' global application services_list = [] # populate the 'services_list' with the tuples that will define the # urls and services offered by dataservice. for impl_class_namespace in ( self.config.services.service_list.subordinate_namespace_names): impl_class = self.config.services[impl_class_namespace].cls services_list.append(impl_class) if not services_list: raise RuntimeError( "No services configured." "See the [services].service_list setting in the config file") self.web_server = self.config.web_server.wsgi_server_class( self.config, services_list) # for modwsgi the 'run' method returns the wsgi function that # will use. For other webservers, the 'run' method actually starts # the standalone web server. application = self.web_server.run()
) from socorro.app.socorro_app import App from socorro.dataservice.util import ( classes_in_namespaces_converter, ) SERVICES_LIST = ('socorro.external.postgresql.bugs_service.Bugs',) # Allow configman to dynamically load the configuration and classes # for our API dataservice objects def_source = Namespace() def_source.namespace('services') def_source.services.add_option( 'service_list', default=','.join(SERVICES_LIST), from_string_converter=classes_in_namespaces_converter() ) settings.DATASERVICE_CONFIG = configuration( definition_source=[ def_source, App.get_required_config(), ], values_source_list=[ settings.DATASERVICE_CONFIG_BASE, # ConfigFileFutureProxy, environment ] )