def test_enable_libraries(self): sandbox._THIRD_PARTY_LIBRARY_FORMAT_STRING = ( 'name=%(name)s-version=%(version)s') libs = self.config.libraries libs.add(name='foo', version='12345') libs.add(name='webapp2', version='2.5.1') self.assertEqual( [os.path.join(os.path.dirname(os.path.dirname( google.__file__)), 'name=foo-version=12345'), os.path.join(os.path.dirname(os.path.dirname( google.__file__)), 'name=webapp2-version=2.5.1')], sandbox._enable_libraries(libs))
def test_enable_libraries(self): sandbox._THIRD_PARTY_LIBRARY_FORMAT_STRING = "name=%(name)s-version=%(version)s" libs = self.config.libraries libs.add(name="foo", version="12345") libs.add(name="webapp2", version="2.5.1") self.assertEqual( [ os.path.join(os.path.dirname(os.path.dirname(google.__file__)), "name=foo-version=12345"), os.path.join(os.path.dirname(os.path.dirname(google.__file__)), "name=webapp2-version=2.5.1"), ], sandbox._enable_libraries(libs), )
def activate(sandbox_name, add_sdk_to_path=False): """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 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() # 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") original_path = sys.path[:] sdk_path = _find_sdk_from_python_path() _PATHS = wrapper_util.Paths(sdk_path) sys.path = (_PATHS.script_paths(_SCRIPT_NAME) + _PATHS.scrub_path(_SCRIPT_NAME, sys.path)) # 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]) configuration = application_configuration.ApplicationConfiguration(options.config_paths) # Take dev_appserver paths off sys.path - GAE apps cannot access these sys.path = original_path[:] # 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(0, l) try: 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 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 test_enable_libraries_no_libraries(self): libs = self.config.libraries self.assertEqual([], sandbox._enable_libraries(libs)) self.assertEqual(self.old_path, sys.path)
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
def activate(sandbox_name, add_sdk_to_path=False, new_env_vars=None, app_id=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 # 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 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]) if app_id: configuration = application_configuration.ApplicationConfiguration(options.config_paths, app_id=app_id) else: 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) # 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 activate(sandbox_name, add_sdk_to_path=False): """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 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() # 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" ) original_path = sys.path[:] sdk_path = _find_sdk_from_python_path() _PATHS = wrapper_util.Paths(sdk_path) sys.path = (_PATHS.script_paths(_SCRIPT_NAME) + _PATHS.scrub_path(_SCRIPT_NAME, sys.path)) # 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]) configuration = application_configuration.ApplicationConfiguration( options.config_paths) # Take dev_appserver paths off sys.path - GAE apps cannot access these sys.path = original_path[:] # 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(0, l) try: 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