def test_directory_with_backends_yaml(self): os.path.isdir('/appdir').AndReturn(True) os.path.exists(os.path.join('/appdir', 'app.yaml')).AndReturn(True) os.path.isdir(os.path.join('/appdir', 'app.yaml')).AndReturn(False) os.path.exists(os.path.join('/appdir', 'backends.yaml')).AndReturn(True) os.path.isdir(os.path.join('/appdir', 'backends.yaml')).AndReturn(False) module_config = ModuleConfigurationStub() application_configuration.ModuleConfiguration( os.path.join('/appdir', 'app.yaml'), None).AndReturn(module_config) backend_config = ModuleConfigurationStub(module_name='backend') backends_config = self.mox.CreateMock( application_configuration.BackendsConfiguration) backends_config.get_backend_configurations().AndReturn( [backend_config]) application_configuration.BackendsConfiguration( os.path.join('/appdir', 'app.yaml'), os.path.join('/appdir', 'backends.yaml'), None).AndReturn(backends_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config, backend_config], config.modules)
def test_yaml_files_with_backends_and_dispatch_yaml(self): os.path.isdir('/appdir/app.yaml').AndReturn(False) module_config = ModuleConfigurationStub(module_name='default') application_configuration.ModuleConfiguration( '/appdir/app.yaml', None).AndReturn(module_config) os.path.isdir('/appdir/backends.yaml').AndReturn(False) backend_config = ModuleConfigurationStub(module_name='backend') backends_config = self.mox.CreateMock( application_configuration.BackendsConfiguration) backends_config.get_backend_configurations().AndReturn( [backend_config]) application_configuration.BackendsConfiguration( os.path.join('/appdir', 'app.yaml'), os.path.join('/appdir', 'backends.yaml'), None).AndReturn(backends_config) os.path.isdir('/appdir/dispatch.yaml').AndReturn(False) dispatch_config = DispatchConfigurationStub([(None, 'default'), (None, 'backend')]) application_configuration.DispatchConfiguration( '/appdir/dispatch.yaml').AndReturn(dispatch_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration([ '/appdir/app.yaml', '/appdir/backends.yaml', '/appdir/dispatch.yaml' ]) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config, backend_config], config.modules) self.assertEqual(dispatch_config, config.dispatch)
def configure(self, options, config): super(NoseGAE, self).configure(options, config) if not self.enabled: return if sys.version_info[0:2] < (2, 7): raise EnvironmentError( "Python version must be 2.7 or greater, like the Google App Engine environment. " "Tests are running with: %s" % sys.version) try: self._app_path = options.gae_app.split(',') except AttributeError: self._app_path = [config.workingDir] self._data_path = options.gae_data or os.path.join( tempfile.gettempdir(), 'nosegae.sqlite3') if options.gae_lib_root not in sys.path: options.gae_lib_root = os.path.realpath(options.gae_lib_root) sys.path.insert(0, options.gae_lib_root) for path_ in self._app_path: path_ = os.path.realpath(path_) if not os.path.isdir(path_): path_ = os.path.dirname(path_) if path_ not in sys.path: sys.path.append(path_) if 'google' in sys.modules: # make sure an egg (e.g. protobuf) is not cached # with the wrong path: reload(sys.modules['google']) try: import appengine_config except ImportError: pass # TODO: this may need to happen after parsing your yaml files in # The case of modules but I need to investigate further import dev_appserver dev_appserver.fix_sys_path( ) # add paths to libs specified in app.yaml, etc # This file handles some OS compat settings. Most notably the `TZ` stuff # to resolve https://github.com/Trii/NoseGAE/issues/14. # It may need to be removed in the future if Google changes the functionality import google.appengine.tools.os_compat from google.appengine.tools.devappserver2 import application_configuration # get the app id out of your app.yaml and stuff self.configuration = application_configuration.ApplicationConfiguration( self._app_path) os.environ['APPLICATION_ID'] = self.configuration.app_id # simulate same environment as devappserver2 os.environ['CURRENT_VERSION_ID'] = self.configuration.modules[ 0].version_id self.is_doctests = options.enable_plugin_doctest
def test_config_with_yaml_and_xml(self): absnames = self._make_file_hierarchy( ['module1/app.yaml', 'module1/dispatch.yaml', 'module2/WEB-INF/appengine-web.xml', 'module2/WEB-INF/web.xml']) app_yaml = absnames[0] dispatch_yaml = absnames[1] appengine_web_xml = absnames[2] module2 = os.path.dirname(os.path.dirname(appengine_web_xml)) module1_config = ModuleConfigurationStub(module_name='default') application_configuration.ModuleConfiguration( app_yaml, None).AndReturn(module1_config) dispatch_config = DispatchConfigurationStub( [(None, 'default'), (None, 'module2')]) application_configuration.DispatchConfiguration( dispatch_yaml).AndReturn(dispatch_config) module2_config = ModuleConfigurationStub(module_name='module2') application_configuration.ModuleConfiguration( appengine_web_xml, None).AndReturn(module2_config) self.mox.ReplayAll() with _java_temporarily_supported(): config = application_configuration.ApplicationConfiguration( [app_yaml, dispatch_yaml, module2]) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual( [module1_config, module2_config], config.modules) self.assertEqual(dispatch_config, config.dispatch)
def test_yaml_files_with_backends_and_dispatch_yaml(self): absnames = self._make_file_hierarchy( ['appdir/app.yaml', 'appdir/backends.yaml', 'appdir/dispatch.yaml']) module_config = ModuleConfigurationStub(module_name='default') application_configuration.ModuleConfiguration( absnames[0], None).AndReturn(module_config) backend_config = ModuleConfigurationStub(module_name='backend') backends_config = self.mox.CreateMock( application_configuration.BackendsConfiguration) backends_config.get_backend_configurations().AndReturn([backend_config]) application_configuration.BackendsConfiguration( absnames[0], absnames[1], None).AndReturn(backends_config) dispatch_config = DispatchConfigurationStub( [(None, 'default'), (None, 'backend')]) application_configuration.DispatchConfiguration( absnames[2]).AndReturn(dispatch_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration(absnames) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config, backend_config], config.modules) self.assertEqual(dispatch_config, config.dispatch)
def main(): """Parses command line options and launches the API server.""" shutdown.install_signal_handlers() # Initialize logging early -- otherwise some library packages may # pre-empt our log formatting. NOTE: the level is provisional; it may # be changed based on the --debug flag. logging.basicConfig( level=logging.INFO, format= '%(levelname)-8s %(asctime)s %(filename)s:%(lineno)s] %(message)s') options = cli_parser.create_command_line_parser( cli_parser.API_SERVER_CONFIGURATION).parse_args() logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) # Parse the application configuration if config_paths are provided, else # provide sensible defaults. if options.config_paths: app_config = application_configuration.ApplicationConfiguration( options.config_paths, options.app_id) app_id = app_config.app_id app_root = app_config.modules[0].application_root else: app_id = (options.app_id if options.app_id else DEFAULT_API_SERVER_APP_ID) app_root = tempfile.mkdtemp() # pylint: disable=protected-access # TODO: Rename LocalFakeDispatcher or re-implement for api_server.py. request_info = wsgi_request_info.WSGIRequestInfo( request_info_lib._LocalFakeDispatcher()) # pylint: enable=protected-access os.environ['APPLICATION_ID'] = app_id os.environ['APPNAME'] = app_id os.environ['NGINX_HOST'] = options.nginx_host def request_context(environ): return request_info.request(environ, None) server = create_api_server(request_info=request_info, storage_path=get_storage_path( options.storage_path, app_id), options=options, app_id=app_id, app_root=app_root, request_context=request_context) if options.pidfile: with open(options.pidfile, 'w') as pidfile: pidfile.write(str(os.getpid())) try: server.start() shutdown.wait_until_shutdown() finally: server.quit()
def main(): """Parses command line options and launches the API server.""" shutdown.install_signal_handlers() options = PARSER.parse_args() logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) # Parse the application configuration if config_paths are provided, else # provide sensible defaults. if options.config_paths: app_config = application_configuration.ApplicationConfiguration( options.config_paths, options.app_id) app_id = app_config.app_id app_root = app_config.modules[0].application_root else: app_id = (options.app_id_prefix + options.app_id if options.app_id else DEFAULT_API_SERVER_APP_ID) app_root = tempfile.mkdtemp() util.setup_environ(app_id) # pylint: disable=protected-access if options.java_app_base_url: # If the user specified a java_app_base_url, then the actual app is running # via the classic Java SDK, so we use the appropriate dispatcher that will # send requests to the Java app rather than forward them internally to a # devappserver2 module. dispatcher = _LocalJavaAppDispatcher( java_app_base_url=options.java_app_base_url) else: # TODO: Rename LocalFakeDispatcher or re-implement for # api_server.py. dispatcher = request_info_lib._LocalFakeDispatcher() request_info = wsgi_request_info.WSGIRequestInfo(dispatcher) # pylint: enable=protected-access metrics_logger = metrics.GetMetricsLogger() metrics_logger.Start( options.google_analytics_client_id, user_agent=options.google_analytics_user_agent, support_datastore_emulator=options.support_datastore_emulator, category=metrics.API_SERVER_CATEGORY) # When Cloud Datastore Emulator is invoked from api_server, it should be in # test mode, which stores in memory. options.datastore_emulator_is_test_mode = True server = create_api_server(request_info=request_info, storage_path=get_storage_path( options.storage_path, app_id), options=options, app_id=app_id, app_root=app_root) try: server.start() shutdown.wait_until_shutdown() finally: metrics.GetMetricsLogger().Stop() server.quit()
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. """ logging.getLogger().setLevel( _LOG_LEVEL_TO_PYTHON_CONSTANT[options.dev_appserver_log_level]) configuration = application_configuration.ApplicationConfiguration( options.yaml_files) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) if options.port == 0: logging.warn( 'DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') _setup_environ(configuration.app_id) self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, _LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], self._create_php_config(options), self._create_python_config(options), self._create_cloud_sql_config(options), self._create_module_to_setting(options.max_module_instances, configuration, '--max_module_instances'), options.use_mtime_file_watcher, options.automatic_restart, options.allow_skipped_files, self._create_module_to_setting(options.threadsafe_override, configuration, '--threadsafe_override')) request_data = wsgi_request_info.WSGIRequestInfo(self._dispatcher) storage_path = _get_storage_path(options.storage_path, configuration.app_id) apis = self._create_api_server(request_data, storage_path, options, configuration) apis.start() self._running_modules.append(apis) self._dispatcher.start(options.api_host, apis.port, request_data) self._running_modules.append(self._dispatcher) xsrf_path = os.path.join(storage_path, 'xsrf') admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path) admin.start() self._running_modules.append(admin)
def test_app_yaml(self): absnames = self._make_file_hierarchy(['appdir/app.yaml']) module_config = ModuleConfigurationStub() application_configuration.ModuleConfiguration( absnames[0], None).AndReturn(module_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration(absnames) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config], config.modules)
def test_app_yaml(self): os.path.isdir('/appdir/app.yaml').AndReturn(False) os.path.isdir('/appdir/app.yaml').AndReturn(False) module_config = ModuleConfigurationStub() application_configuration.ModuleConfiguration( '/appdir/app.yaml').AndReturn(module_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir/app.yaml'], None) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config], config.modules)
def test_app_yaml(self): os.path.isdir('/appdir/app.yaml').AndReturn(False) os.path.isdir('/appdir/app.yaml').AndReturn(False) server_config = ServerConfigurationStub() application_configuration.ServerConfiguration( '/appdir/app.yaml').AndReturn(server_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir/app.yaml']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([server_config], config.servers)
def main(): """Parses command line options and launches the API server.""" shutdown.install_signal_handlers() options = PARSER.parse_args() logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) # Parse the application configuration if config_paths are provided, else # provide sensible defaults. if options.config_paths: app_config = application_configuration.ApplicationConfiguration( options.config_paths, options.app_id) app_id = app_config.app_id app_root = app_config.modules[0].application_root else: app_id = (options.app_id_prefix + options.app_id if options.app_id else DEFAULT_API_SERVER_APP_ID) app_root = tempfile.mkdtemp() util.setup_environ(app_id) # pylint: disable=protected-access if options.java_app_base_url: # If the user specified a java_app_base_url, then the actual app is running # via the classic Java SDK, so we use the appropriate dispatcher that will # send requests to the Java app rather than forward them internally to a # devappserver2 module. dispatcher = _LocalJavaAppDispatcher( java_app_base_url=options.java_app_base_url) else: # TODO: Rename LocalFakeDispatcher or re-implement for # api_server.py. dispatcher = request_info_lib._LocalFakeDispatcher() request_info = wsgi_request_info.WSGIRequestInfo(dispatcher) # pylint: enable=protected-access server = create_api_server(request_info=request_info, storage_path=get_storage_path( options.storage_path, app_id), options=options, app_id=app_id, app_root=app_root) try: server.start() shutdown.wait_until_shutdown() finally: server.quit()
def test_directory(self): os.path.isdir('/appdir').AndReturn(True) os.path.exists(os.path.join('/appdir', 'app.yaml')).AndReturn(True) os.path.exists(os.path.join('/appdir', 'backends.yaml')).AndReturn(False) os.path.exists(os.path.join('/appdir', 'backends.yml')).AndReturn(False) os.path.isdir(os.path.join('/appdir', 'app.yaml')).AndReturn(False) server_config = ServerConfigurationStub() application_configuration.ServerConfiguration( os.path.join('/appdir', 'app.yaml')).AndReturn(server_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration(['/appdir']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([server_config], config.servers)
def test_directory_and_module(self): absnames = self._make_file_hierarchy( ['appdir/app.yaml', 'otherdir/mymodule.yaml']) app_yaml_config = ModuleConfigurationStub() application_configuration.ModuleConfiguration( absnames[0], None).AndReturn(app_yaml_config) my_module_config = ModuleConfigurationStub(module_name='my_module') application_configuration.ModuleConfiguration( absnames[1], None).AndReturn(my_module_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( [os.path.dirname(absnames[0]), absnames[1]]) self.mox.VerifyAll() self.assertSequenceEqual( [app_yaml_config, my_module_config], config.modules)
def test_directory_web_inf(self): absnames = self._make_file_hierarchy( ['appdir/WEB-INF/appengine-web.xml', 'appdir/WEB-INF/web.xml']) appdir = os.path.dirname(os.path.dirname(absnames[0])) module_config = ModuleConfigurationStub(module_name='default') application_configuration.ModuleConfiguration( absnames[0], None).AndReturn(module_config) self.mox.ReplayAll() with _java_temporarily_supported(): config = application_configuration.ApplicationConfiguration([appdir]) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config], config.modules)
def test_yaml_files(self): os.path.isdir('/appdir/app.yaml').AndReturn(False) server_config1 = ServerConfigurationStub() application_configuration.ServerConfiguration( '/appdir/app.yaml').AndReturn(server_config1) os.path.isdir('/appdir/other.yaml').AndReturn(False) server_config2 = ServerConfigurationStub(server_name='other') application_configuration.ServerConfiguration( '/appdir/other.yaml').AndReturn(server_config2) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir/app.yaml', '/appdir/other.yaml']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([server_config1, server_config2], config.servers)
def test_yaml_files(self): os.path.isdir('/appdir/app.yaml').AndReturn(False) module_config1 = ModuleConfigurationStub() application_configuration.ModuleConfiguration( '/appdir/app.yaml', None).AndReturn(module_config1) os.path.isdir('/appdir/other.yaml').AndReturn(False) module_config2 = ModuleConfigurationStub(module_name='other') application_configuration.ModuleConfiguration( '/appdir/other.yaml', None).AndReturn(module_config2) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir/app.yaml', '/appdir/other.yaml']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config1, module_config2], config.modules)
def main(): """Parses command line options and launches the API server.""" shutdown.install_signal_handlers() options = cli_parser.create_command_line_parser( cli_parser.API_SERVER_CONFIGURATION).parse_args() logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) # Parse the application configuration if config_paths are provided, else # provide sensible defaults. if options.config_paths: app_config = application_configuration.ApplicationConfiguration( options.config_paths, options.app_id) app_id = app_config.app_id app_root = app_config.modules[0].application_root else: app_id = (options.app_id if options.app_id else DEFAULT_API_SERVER_APP_ID) app_root = tempfile.mkdtemp() # pylint: disable=protected-access # TODO: Rename LocalFakeDispatcher or re-implement for api_server.py. request_info = wsgi_request_info.WSGIRequestInfo( request_info_lib._LocalFakeDispatcher()) # pylint: enable=protected-access os.environ['APPNAME'] = app_id os.environ['NGINX_HOST'] = options.nginx_host server = create_api_server(request_info=request_info, storage_path=get_storage_path( options.storage_path, app_id), options=options, app_id=app_id, app_root=app_root) try: server.start() shutdown.wait_until_shutdown() finally: server.quit()
def test_directory_with_backends_yaml(self): absnames = self._make_file_hierarchy( ['appdir/app.yaml', 'appdir/backends.yaml']) module_config = ModuleConfigurationStub() application_configuration.ModuleConfiguration( absnames[0], None).AndReturn(module_config) backend_config = ModuleConfigurationStub(module_name='backend') backends_config = self.mox.CreateMock( application_configuration.BackendsConfiguration) backends_config.get_backend_configurations().AndReturn([backend_config]) application_configuration.BackendsConfiguration( absnames[0], absnames[1], None).AndReturn(backends_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( [os.path.dirname(absnames[0])]) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config, backend_config], config.modules)
def test_directory_app_yml_only(self): os.path.isdir('/appdir').AndReturn(True) os.path.exists(os.path.join('/appdir', 'app.yaml')).AndReturn(False) os.path.exists(os.path.join('/appdir', 'app.yml')).AndReturn(True) os.path.exists(os.path.join('/appdir', 'backends.yaml')).AndReturn(False) os.path.exists(os.path.join('/appdir', 'backends.yml')).AndReturn(False) os.path.isdir(os.path.join('/appdir', 'app.yml')).AndReturn(False) module_config = ModuleConfigurationStub() application_configuration.ModuleConfiguration( os.path.join('/appdir', 'app.yml'), None).AndReturn(module_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([module_config], config.modules)
def test_yaml_files_with_backends_yaml(self): os.path.isdir('/appdir/app.yaml').AndReturn(False) server_config = ServerConfigurationStub() application_configuration.ServerConfiguration( '/appdir/app.yaml').AndReturn(server_config) os.path.isdir('/appdir/backends.yaml').AndReturn(False) backend_config = ServerConfigurationStub(server_name='backend') backends_config = self.mox.CreateMock( application_configuration.BackendsConfiguration) backends_config.get_backend_configurations().AndReturn([backend_config]) application_configuration.BackendsConfiguration( '/appdir/app.yaml', '/appdir/backends.yaml').AndReturn(backends_config) self.mox.ReplayAll() config = application_configuration.ApplicationConfiguration( ['/appdir/app.yaml', '/appdir/backends.yaml']) self.mox.VerifyAll() self.assertEqual('myapp', config.app_id) self.assertSequenceEqual([server_config, backend_config], config.servers)
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. Raises: PhpPathError: php executable path is not specified for php72. MissingDatastoreEmulatorError: dev_appserver.py is not invoked from the right directory. """ self._options = options self._options.datastore_emulator_cmd = self._correct_datastore_emulator_cmd( self._options.datastore_emulator_cmd) self._check_datastore_emulator_support() logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) parsed_env_variables = dict(options.env_variables or []) configuration = application_configuration.ApplicationConfiguration( config_paths=options.config_paths, app_id=options.app_id, runtime=options.runtime, env_variables=parsed_env_variables) all_module_runtimes = { module.runtime for module in configuration.modules } self._check_platform_support(all_module_runtimes) storage_path = api_server.get_storage_path(options.storage_path, configuration.app_id) datastore_path = api_server.get_datastore_path(storage_path, options.datastore_path) datastore_data_type = ( datastore_converter.get_stub_type(datastore_path) if os.path.isfile(datastore_path) else None) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) # There is no good way to set the default encoding from application code # (it needs to be done during interpreter initialization in site.py or # sitecustomize.py) so just warn developers if they have a different # encoding than production. if sys.getdefaultencoding() != constants.PROD_DEFAULT_ENCODING: logging.warning( 'The default encoding of your local Python interpreter is set to %r ' 'while App Engine\'s production environment uses %r; as a result ' 'your code may behave differently when deployed.', sys.getdefaultencoding(), constants.PROD_DEFAULT_ENCODING) if options.port == 0: logging.warn( 'DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') util.setup_environ(configuration.app_id) php_version = self._get_php_runtime(configuration) if not options.php_executable_path and php_version == 'php72': raise PhpPathError( 'For php72, --php_executable_path must be specified.') if options.ssl_certificate_path and options.ssl_certificate_key_path: ssl_certificate_paths = self._create_ssl_certificate_paths_if_valid( options.ssl_certificate_path, options.ssl_certificate_key_path) else: if options.ssl_certificate_path or options.ssl_certificate_key_path: logging.warn('Must provide both --ssl_certificate_path and ' '--ssl_certificate_key_path to enable SSL. Since ' 'only one flag was provided, not using SSL.') ssl_certificate_paths = None if options.google_analytics_client_id: metrics_logger = metrics.GetMetricsLogger() metrics_logger.Start( options.google_analytics_client_id, options.google_analytics_user_agent, all_module_runtimes, {module.env or 'standard' for module in configuration.modules}, options.support_datastore_emulator, datastore_data_type, bool(ssl_certificate_paths), options, multi_module=len(configuration.modules) > 1, dispatch_config=configuration.dispatch is not None, ) self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, constants.LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], self._create_php_config(options, php_version), self._create_python_config(options), self._create_java_config(options), self._create_go_config(options), self._create_custom_config(options), self._create_cloud_sql_config(options), self._create_vm_config(options), self._create_module_to_setting(options.max_module_instances, configuration, '--max_module_instances'), options.use_mtime_file_watcher, options.watcher_ignore_re, options.automatic_restart, options.allow_skipped_files, self._create_module_to_setting(options.threadsafe_override, configuration, '--threadsafe_override'), options.external_port, options.specified_service_ports, options.enable_host_checking, ssl_certificate_paths) wsgi_request_info_ = wsgi_request_info.WSGIRequestInfo( self._dispatcher) apiserver = api_server.create_api_server( wsgi_request_info_, storage_path, options, configuration.app_id, configuration.modules[0].application_root) apiserver.start() self._running_modules.append(apiserver) self._dispatcher.start(options.api_host, apiserver.port, wsgi_request_info_) xsrf_path = os.path.join(storage_path, 'xsrf') admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path, options.enable_host_checking, options.enable_console) admin.start() self._running_modules.append(admin) try: default = self._dispatcher.get_module_by_name('default') apiserver.set_balanced_address(default.balanced_address) except request_info.ModuleDoesNotExistError: logging.warning('No default module found. Ignoring.')
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. """ logging.getLogger().setLevel( _LOG_LEVEL_TO_PYTHON_CONSTANT[options.dev_appserver_log_level]) configuration = application_configuration.ApplicationConfiguration( options.config_paths, options.app_id) if options.enable_cloud_datastore: # This requires the oauth server stub to return that the logged in user # is in fact an admin. os.environ['OAUTH_IS_ADMIN'] = '1' gcd_module = application_configuration.ModuleConfiguration( gcd_application.generate_gcd_app( configuration.app_id.split('~')[1])) configuration.modules.append(gcd_module) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) # There is no good way to set the default encoding from application code # (it needs to be done during interpreter initialization in site.py or # sitecustomize.py) so just warn developers if they have a different # encoding than production. if sys.getdefaultencoding() != _PROD_DEFAULT_ENCODING: logging.warning( 'The default encoding of your local Python interpreter is set to %r ' 'while App Engine\'s production environment uses %r; as a result ' 'your code may behave differently when deployed.', sys.getdefaultencoding(), _PROD_DEFAULT_ENCODING) if options.port == 0: logging.warn( 'DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') _setup_environ(configuration.app_id) self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, _LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], self._create_php_config(options), self._create_python_config(options), self._create_java_config(options), self._create_cloud_sql_config(options), self._create_vm_config(options), self._create_module_to_setting(options.max_module_instances, configuration, '--max_module_instances'), options.use_mtime_file_watcher, options.automatic_restart, options.allow_skipped_files, self._create_module_to_setting(options.threadsafe_override, configuration, '--threadsafe_override')) request_data = wsgi_request_info.WSGIRequestInfo(self._dispatcher) storage_path = _get_storage_path(options.storage_path, configuration.app_id) apis = self._create_api_server(request_data, storage_path, options, configuration) apis.start() self._running_modules.append(apis) self._dispatcher.start(options.api_host, apis.port, request_data) xsrf_path = os.path.join(storage_path, 'xsrf') admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path) admin.start() self._running_modules.append(admin)
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. """ self._options = options logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) parsed_env_variables = dict(options.env_variables or []) configuration = application_configuration.ApplicationConfiguration( config_paths=options.config_paths, app_id=options.app_id, runtime=options.runtime, env_variables=parsed_env_variables) if options.google_analytics_client_id: metrics_logger = metrics.GetMetricsLogger() metrics_logger.Start( options.google_analytics_client_id, options.google_analytics_user_agent, {module.runtime for module in configuration.modules}, {module.env or 'standard' for module in configuration.modules}) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) # There is no good way to set the default encoding from application code # (it needs to be done during interpreter initialization in site.py or # sitecustomize.py) so just warn developers if they have a different # encoding than production. if sys.getdefaultencoding() != constants.PROD_DEFAULT_ENCODING: logging.warning( 'The default encoding of your local Python interpreter is set to %r ' 'while App Engine\'s production environment uses %r; as a result ' 'your code may behave differently when deployed.', sys.getdefaultencoding(), constants.PROD_DEFAULT_ENCODING) if options.port == 0: logging.warn( 'DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') _setup_environ(configuration.app_id) self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, constants.LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], self._create_php_config(options), self._create_python_config(options), self._create_java_config(options), self._create_go_config(options), self._create_custom_config(options), self._create_cloud_sql_config(options), self._create_vm_config(options), self._create_module_to_setting(options.max_module_instances, configuration, '--max_module_instances'), options.use_mtime_file_watcher, options.watcher_ignore_re, options.automatic_restart, options.allow_skipped_files, self._create_module_to_setting(options.threadsafe_override, configuration, '--threadsafe_override'), options.external_port) wsgi_request_info_ = wsgi_request_info.WSGIRequestInfo( self._dispatcher) storage_path = api_server.get_storage_path(options.storage_path, configuration.app_id) apiserver = api_server.create_api_server( wsgi_request_info_, storage_path, options, configuration.app_id, configuration.modules[0].application_root) apiserver.start() self._running_modules.append(apiserver) self._dispatcher.start(options.api_host, apiserver.port, wsgi_request_info_) xsrf_path = os.path.join(storage_path, 'xsrf') admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path) admin.start() self._running_modules.append(admin) try: default = self._dispatcher.get_module_by_name('default') apiserver.set_balanced_address(default.balanced_address) except request_info.ModuleDoesNotExistError: logging.warning('No default module found. Ignoring.')
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. """ self._options = options logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) parsed_env_variables = dict(options.env_variables or []) configuration = application_configuration.ApplicationConfiguration( config_paths=options.config_paths, app_id=options.app_id, runtime=options.runtime, env_variables=parsed_env_variables) if options.google_analytics_client_id: metrics_logger = metrics.GetMetricsLogger() metrics_logger.Start( options.google_analytics_client_id, options.google_analytics_user_agent, {module.runtime for module in configuration.modules}, {module.env or 'standard' for module in configuration.modules}) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) # There is no good way to set the default encoding from application code # (it needs to be done during interpreter initialization in site.py or # sitecustomize.py) so just warn developers if they have a different # encoding than production. if sys.getdefaultencoding() != constants.PROD_DEFAULT_ENCODING: logging.warning( 'The default encoding of your local Python interpreter is set to %r ' 'while App Engine\'s production environment uses %r; as a result ' 'your code may behave differently when deployed.', sys.getdefaultencoding(), constants.PROD_DEFAULT_ENCODING) if options.port == 0: logging.warn( 'DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') _setup_environ(configuration.app_id) # grpc_proxy is only needed for python2 because remote_api_stub.py is # imported in local python runtime sandbox. For more details, see # grpc_proxy_util.py. grpc_proxy_port = portpicker.PickUnusedPort() self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, constants.LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], self._create_php_config(options), self._create_python_config(options, grpc_proxy_port), self._create_java_config(options), self._create_go_config(options), self._create_custom_config(options), self._create_cloud_sql_config(options), self._create_vm_config(options), self._create_module_to_setting(options.max_module_instances, configuration, '--max_module_instances'), options.use_mtime_file_watcher, options.watcher_ignore_re, options.automatic_restart, options.allow_skipped_files, self._create_module_to_setting(options.threadsafe_override, configuration, '--threadsafe_override'), options.external_port) wsgi_request_info_ = wsgi_request_info.WSGIRequestInfo( self._dispatcher) storage_path = api_server.get_storage_path(options.storage_path, configuration.app_id) datastore_emulator_host = ( parsed_env_variables['DATASTORE_EMULATOR_HOST'] if 'DATASTORE_EMULATOR_HOST' in parsed_env_variables else None) apiserver = api_server.create_api_server( wsgi_request_info_, storage_path, options, configuration.app_id, configuration.modules[0].application_root, datastore_emulator_host) apiserver.start() self._running_modules.append(apiserver) if options.grpc_apis: grpc_apiserver = api_server.GRPCAPIServer(options.grpc_api_port) grpc_apiserver.start() self._running_modules.append(grpc_apiserver) # We declare grpc_proxy_util as global, otherwise it cannot be accessed # from outside of this function. global grpc_proxy_util # pylint: disable=g-import-not-at-top # We lazy import here because grpc binaries are not always present. from google.appengine.tools.devappserver2 import grpc_proxy_util grpc_proxy = grpc_proxy_util.GrpcProxyServer(grpc_proxy_port) grpc_proxy.start() self._running_modules.append(grpc_proxy) self._dispatcher.start(options.api_host, apiserver.port, wsgi_request_info_, options.grpc_apis) xsrf_path = os.path.join(storage_path, 'xsrf') admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path) admin.start() self._running_modules.append(admin) try: default = self._dispatcher.get_module_by_name('default') apiserver.set_balanced_address(default.balanced_address) except request_info.ModuleDoesNotExistError: logging.warning('No default module found. Ignoring.')
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. """ logging.getLogger().setLevel(constants.LOG_LEVEL_TO_PYTHON_CONSTANT[ options.dev_appserver_log_level]) configuration = application_configuration.ApplicationConfiguration( options.config_paths, options.app_id) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) if options.port == 0: logging.warn( 'DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') _setup_environ(configuration.app_id, configuration.modules[0].version_id) python_config = runtime_config_pb2.PythonConfig() if options.python_startup_script: python_config.startup_script = os.path.abspath( options.python_startup_script) if options.python_startup_args: python_config.startup_args = options.python_startup_args php_executable_path = (options.php_executable_path and os.path.abspath( options.php_executable_path)) cloud_sql_config = runtime_config_pb2.CloudSQL() cloud_sql_config.mysql_host = options.mysql_host cloud_sql_config.mysql_port = options.mysql_port cloud_sql_config.mysql_user = options.mysql_user cloud_sql_config.mysql_password = options.mysql_password if options.mysql_socket: cloud_sql_config.mysql_socket = options.mysql_socket if options.max_module_instances is None: module_to_max_instances = {} elif isinstance(options.max_module_instances, int): module_to_max_instances = { module_configuration.module_name: options.max_module_instances for module_configuration in configuration.modules } else: module_to_max_instances = options.max_module_instances if options.threadsafe_override is None: module_to_threadsafe_override = {} elif isinstance(options.threadsafe_override, bool): module_to_threadsafe_override = { module_configuration.module_name: options.threadsafe_override for module_configuration in configuration.modules } else: module_to_threadsafe_override = options.threadsafe_override self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, constants.LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], php_executable_path, options.php_remote_debugging, python_config, cloud_sql_config, module_to_max_instances, options.use_mtime_file_watcher, options.automatic_restart, options.allow_skipped_files, module_to_threadsafe_override, options.external_api_port) request_data = wsgi_request_info.WSGIRequestInfo(self._dispatcher) storage_path = api_server.get_storage_path(options.storage_path, configuration.app_id) apis = api_server.create_api_server( request_data, storage_path, options, configuration.app_id, configuration.modules[0].application_root) apis.start() self._running_modules.append(apis) self._dispatcher.start(apis.port, request_data) self._running_modules.append(self._dispatcher) xsrf_path = os.path.join(storage_path, 'xsrf') admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path) admin.start() self._running_modules.append(admin)
def activate(sandbox_name, add_sdk_to_path=False, new_env_vars=None, **overrides): """Context manager for command-line scripts started outside of dev_appserver. :param sandbox_name: str, one of 'local', 'remote' or 'test' :param add_sdk_to_path: bool, optionally adds the App Engine SDK to sys.path :param options_override: an options structure to pass down to dev_appserver setup Available sandboxes: local: Adds libraries specified in app.yaml to the path and initializes local service stubs as though dev_appserver were running. remote: Adds libraries specified in app.yaml to the path and initializes remote service stubs. test: Adds libraries specified in app.yaml to the path and sets up no service stubs. Use this with `google.appengine.ext.testbed` to provide isolation for tests. Example usage: import djangae.sandbox as sandbox with sandbox.activate('local'): from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) """ if sandbox_name not in SANDBOXES: raise RuntimeError('Unknown sandbox "{}"'.format(sandbox_name)) project_root = environment.get_application_root() # Store our original sys.path before we do anything, this must be tacked # onto the end of the other paths so we can access globally installed things (e.g. ipdb etc.) original_path = sys.path[:] # Setup paths as though we were running dev_appserver. This is similar to # what the App Engine script wrappers do. if add_sdk_to_path: try: import wrapper_util # Already on sys.path except ImportError: sys.path[0:0] = [_find_sdk_from_path()] import wrapper_util else: try: import wrapper_util except ImportError: raise RuntimeError("Couldn't find a recent enough Google App Engine SDK, make sure you are using at least 1.9.6") sdk_path = _find_sdk_from_python_path() _PATHS = wrapper_util.Paths(sdk_path) project_paths = [] # Paths under the application root system_paths = [] # All other paths app_root = environment.get_application_root() # We need to look at the original path, and make sure that any paths # which are under the project root are first, then any other paths # are added after the SDK ones for path in _PATHS.scrub_path(_SCRIPT_NAME, original_path): if commonprefix([app_root, path]) == app_root: project_paths.append(path) else: system_paths.append(path) # We build a list of SDK paths, and add any additional ones required for # the oauth client appengine_paths = _PATHS.script_paths(_SCRIPT_NAME) for path in _PATHS.oauth_client_extra_paths: if path not in appengine_paths: appengine_paths.append(path) # Now, we make sure that paths within the project take precedence, followed # by the SDK, then finally any paths from the system Python (for stuff like # ipdb etc.) sys.path = ( project_paths + appengine_paths + system_paths ) # Gotta set the runtime properly otherwise it changes appengine imports, like wepapp # when you are not running dev_appserver import yaml with open(os.path.join(project_root, 'app.yaml'), 'r') as app_yaml: app_yaml = yaml.load(app_yaml) os.environ['APPENGINE_RUNTIME'] = app_yaml.get('runtime', '') # Initialize as though `dev_appserver.py` is about to run our app, using all the # configuration provided in app.yaml. import google.appengine.tools.devappserver2.application_configuration as application_configuration import google.appengine.tools.devappserver2.python.sandbox as sandbox import google.appengine.tools.devappserver2.devappserver2 as devappserver2 import google.appengine.tools.devappserver2.wsgi_request_info as wsgi_request_info import google.appengine.ext.remote_api.remote_api_stub as remote_api_stub import google.appengine.api.apiproxy_stub_map as apiproxy_stub_map gae_args = [ s for s in sys.argv if any(s.lstrip('--').startswith(gae_option) for gae_option in WHITELISTED_DEV_APPSERVER_OPTIONS) ] # The argparser is the easiest way to get the default options. options = devappserver2.PARSER.parse_args([project_root] + gae_args) options.enable_task_running = False # Disable task running by default, it won't work without a running server options.skip_sdk_update_check = True for option in overrides: if not hasattr(options, option): raise ValueError("Unrecognized sandbox option: {}".format(option)) setattr(options, option, overrides[option]) configuration = application_configuration.ApplicationConfiguration(options.config_paths, app_id=options.app_id) # Enable built-in libraries from app.yaml without enabling the full sandbox. module = configuration.modules[0] for l in sandbox._enable_libraries(module.normalized_libraries): sys.path.insert(1, l) # Propagate provided environment variables to the sandbox. # This is required for the runserver management command settings flag, # which sets an environment variable needed by Django. from google.appengine.api.appinfo import EnvironmentVariables old_env_vars = module.env_variables if module.env_variables else {} if new_env_vars is None: new_env_vars = {} module._app_info_external.env_variables = EnvironmentVariables.Merge( old_env_vars, new_env_vars, ) try: global _OPTIONS global _CONFIG _CONFIG = configuration _OPTIONS = options # Store the options globally so they can be accessed later kwargs = dict( devappserver2=devappserver2, configuration=configuration, options=options, wsgi_request_info=wsgi_request_info, remote_api_stub=remote_api_stub, apiproxy_stub_map=apiproxy_stub_map, ) with SANDBOXES[sandbox_name](**kwargs): yield finally: sys.path = original_path
def start(self, options): """Start devappserver2 servers based on the provided command line arguments. Args: options: An argparse.Namespace containing the command line arguments. """ logging.getLogger().setLevel( _LOG_LEVEL_TO_PYTHON_CONSTANT[options.dev_appserver_log_level]) configuration = application_configuration.ApplicationConfiguration( options.yaml_files, options.app_id) if options.skip_sdk_update_check: logging.info('Skipping SDK update check.') else: update_checker.check_for_updates(configuration) if options.port == 0: logging.warn('DEFAULT_VERSION_HOSTNAME will not be set correctly with ' '--port=0') _setup_environ(configuration.app_id, configuration.modules[0].version_id) python_config = runtime_config_pb2.PythonConfig() if options.python_startup_script: python_config.startup_script = os.path.abspath( options.python_startup_script) if options.python_startup_args: python_config.startup_args = options.python_startup_args cloud_sql_config = runtime_config_pb2.CloudSQL() cloud_sql_config.mysql_host = options.mysql_host cloud_sql_config.mysql_port = options.mysql_port cloud_sql_config.mysql_user = options.mysql_user cloud_sql_config.mysql_password = options.mysql_password if options.mysql_socket: cloud_sql_config.mysql_socket = options.mysql_socket if options.max_module_instances is None: module_to_max_instances = {} elif isinstance(options.max_module_instances, int): module_to_max_instances = { module_configuration.module_name: options.max_module_instances for module_configuration in configuration.modules} else: module_to_max_instances = options.max_module_instances self._dispatcher = dispatcher.Dispatcher( configuration, options.host, options.port, options.auth_domain, _LOG_LEVEL_TO_RUNTIME_CONSTANT[options.log_level], options.php_executable_path, options.php_remote_debugging, python_config, cloud_sql_config, module_to_max_instances, options.use_mtime_file_watcher, options.automatic_restart, options.allow_skipped_files, options.external_api_port) request_data = wsgi_request_info.WSGIRequestInfo(self._dispatcher) storage_path = _get_storage_path(options.storage_path, configuration.app_id) datastore_path = options.datastore_path or os.path.join(storage_path, 'datastore.db') logs_path = options.logs_path or os.path.join(storage_path, 'logs.db') xsrf_path = os.path.join(storage_path, 'xsrf') search_index_path = options.search_indexes_path or os.path.join( storage_path, 'search_indexes') prospective_search_path = options.prospective_search_path or os.path.join( storage_path, 'prospective-search') blobstore_path = options.blobstore_path or os.path.join(storage_path, 'blobs') if options.clear_datastore: _clear_datastore_storage(datastore_path) if options.clear_prospective_search: _clear_prospective_search_storage(prospective_search_path) if options.clear_search_indexes: _clear_search_indexes_storage(search_index_path) if options.auto_id_policy==datastore_stub_util.SEQUENTIAL: logging.warn("--auto_id_policy='sequential' is deprecated. This option " "will be removed in a future release.") application_address = '%s' % options.host if options.port and options.port != 80: application_address += ':' + str(options.port) user_login_url = '/%s?%s=%%s' % (login.LOGIN_URL_RELATIVE, login.CONTINUE_PARAM) user_logout_url = '%s&%s=%s' % (user_login_url, login.ACTION_PARAM, login.LOGOUT_ACTION) if options.datastore_consistency_policy == 'time': consistency = datastore_stub_util.TimeBasedHRConsistencyPolicy() elif options.datastore_consistency_policy == 'random': consistency = datastore_stub_util.PseudoRandomHRConsistencyPolicy() elif options.datastore_consistency_policy == 'consistent': consistency = datastore_stub_util.PseudoRandomHRConsistencyPolicy(1.0) else: assert 0, ('unknown consistency policy: %r' % options.datastore_consistency_policy) api_server.maybe_convert_datastore_file_stub_data_to_sqlite( configuration.app_id, datastore_path) api_server.setup_stubs( request_data=request_data, app_id=configuration.app_id, application_root=configuration.modules[0].application_root, # The "trusted" flag is only relevant for Google administrative # applications. trusted=getattr(options, 'trusted', False), blobstore_path=blobstore_path, datastore_path=datastore_path, datastore_consistency=consistency, datastore_require_indexes=options.require_indexes, datastore_auto_id_policy=options.auto_id_policy, images_host_prefix='http://%s' % application_address, logs_path=logs_path, mail_smtp_host=options.smtp_host, mail_smtp_port=options.smtp_port, mail_smtp_user=options.smtp_user, mail_smtp_password=options.smtp_password, mail_enable_sendmail=options.enable_sendmail, mail_show_mail_body=options.show_mail_body, matcher_prospective_search_path=prospective_search_path, search_index_path=search_index_path, taskqueue_auto_run_tasks=options.enable_task_running, taskqueue_default_http_server=application_address, uaserver_path=options.uaserver_path, user_login_url=user_login_url, user_logout_url=user_logout_url, xmpp_path=options.xmpp_path) # The APIServer must bind to localhost because that is what the runtime # instances talk to. apis = api_server.APIServer('localhost', options.api_port, configuration.app_id) apis.start() self._running_modules.append(apis) self._running_modules.append(self._dispatcher) self._dispatcher.start(apis.port, request_data) admin = admin_server.AdminServer(options.admin_host, options.admin_port, self._dispatcher, configuration, xsrf_path) admin.start() self._running_modules.append(admin)
import os from google.appengine.api import apiproxy_stub_map from google.appengine.api.app_identity import get_application_id have_appserver = bool(apiproxy_stub_map.apiproxy.GetStub('datastore_v3')) if have_appserver: appid = get_application_id() else: try: from google.appengine.tools.devappserver2 import application_configuration from djangoappengine.boot import PROJECT_DIR appconfig = application_configuration.ApplicationConfiguration([PROJECT_DIR]) appid = appconfig.app_id.replace('dev~', '') except ImportError, e: raise Exception("Could not get appid. Is your app.yaml file missing? " "Error was: %s" % e) on_production_server = have_appserver and \ not os.environ.get('SERVER_SOFTWARE', '').lower().startswith('devel')
def activate(sandbox_name, add_sdk_to_path=False, **overrides): """Context manager for command-line scripts started outside of dev_appserver. :param sandbox_name: str, one of 'local', 'remote' or 'test' :param add_sdk_to_path: bool, optionally adds the App Engine SDK to sys.path :param options_override: an options structure to pass down to dev_appserver setup Available sandboxes: local: Adds libraries specified in app.yaml to the path and initializes local service stubs as though dev_appserver were running. remote: Adds libraries specified in app.yaml to the path and initializes remote service stubs. test: Adds libraries specified in app.yaml to the path and sets up no service stubs. Use this with `google.appengine.ext.testbed` to provide isolation for tests. Example usage: import djangae.sandbox as sandbox with sandbox.activate('local'): from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) """ if sandbox_name not in SANDBOXES: raise RuntimeError('Unknown sandbox "{}"'.format(sandbox_name)) project_root = utils.find_project_root() # Store our original sys.path before we do anything, this must be tacked # onto the end of the other paths so we can access globally installed things (e.g. ipdb etc.) original_path = sys.path[:] # Setup paths as though we were running dev_appserver. This is similar to # what the App Engine script wrappers do. if add_sdk_to_path: try: import wrapper_util # Already on sys.path except ImportError: sys.path[0:0] = [_find_sdk_from_path()] import wrapper_util else: try: import wrapper_util except ImportError: raise RuntimeError("Couldn't find a recent enough Google App Engine SDK, make sure you are using at least 1.9.6") sdk_path = _find_sdk_from_python_path() _PATHS = wrapper_util.Paths(sdk_path) # Set the path to just the app engine SDK sys.path[:] = _PATHS.script_paths(_SCRIPT_NAME) + _PATHS.scrub_path(_SCRIPT_NAME, original_path) # Gotta set the runtime properly otherwise it changes appengine imports, like wepapp # when you are not running dev_appserver import yaml with open(os.path.join(project_root, 'app.yaml'), 'r') as app_yaml: app_yaml = yaml.load(app_yaml) os.environ['APPENGINE_RUNTIME'] = app_yaml.get('runtime', '') # Initialize as though `dev_appserver.py` is about to run our app, using all the # configuration provided in app.yaml. import google.appengine.tools.devappserver2.application_configuration as application_configuration import google.appengine.tools.devappserver2.python.sandbox as sandbox import google.appengine.tools.devappserver2.devappserver2 as devappserver2 import google.appengine.tools.devappserver2.wsgi_request_info as wsgi_request_info import google.appengine.ext.remote_api.remote_api_stub as remote_api_stub import google.appengine.api.apiproxy_stub_map as apiproxy_stub_map # The argparser is the easiest way to get the default options. options = devappserver2.PARSER.parse_args([project_root]) options.enable_task_running = False # Disable task running by default, it won't work without a running server for option in overrides: if not hasattr(options, option): raise ValueError("Unrecognized sandbox option: {}".format(option)) setattr(options, option, overrides[option]) configuration = application_configuration.ApplicationConfiguration(options.config_paths) # Enable built-in libraries from app.yaml without enabling the full sandbox. module = configuration.modules[0] for l in sandbox._enable_libraries(module.normalized_libraries): sys.path.insert(1, l) try: global _OPTIONS _OPTIONS = options # Store the options globally so they can be accessed later kwargs = dict( devappserver2=devappserver2, configuration=configuration, options=options, wsgi_request_info=wsgi_request_info, remote_api_stub=remote_api_stub, apiproxy_stub_map=apiproxy_stub_map, ) with SANDBOXES[sandbox_name](**kwargs): yield finally: sys.path = original_path