def _create_test_db(self, verbosity, autoclobber): from google.appengine.datastore import datastore_stub_util # Testbed exists in memory test_database_name = ':memory:' # Init test stubs self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_app_identity_stub() self.testbed.init_blobstore_stub() self.testbed.init_capability_stub() self.testbed.init_channel_stub() self.testbed.init_datastore_v3_stub( use_sqlite=True, auto_id_policy=testbed.AUTO_ID_POLICY_SCATTERED, consistency_policy=datastore_stub_util. PseudoRandomHRConsistencyPolicy(probability=1)) self.testbed.init_files_stub() # FIXME! dependencies PIL # self.testbed.init_images_stub() self.testbed.init_logservice_stub() self.testbed.init_mail_stub() self.testbed.init_memcache_stub() self.testbed.init_taskqueue_stub(root_path=find_project_root()) self.testbed.init_urlfetch_stub() self.testbed.init_user_stub() self.testbed.init_xmpp_stub() # self.testbed.init_search_stub() # Init all the stubs! # self.testbed.init_all_stubs() return test_database_name
def _create_test_db(self, verbosity, autoclobber): from google.appengine.datastore import datastore_stub_util # Testbed exists in memory test_database_name = ':memory:' # Init test stubs self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_app_identity_stub() self.testbed.init_blobstore_stub() self.testbed.init_capability_stub() self.testbed.init_channel_stub() self.testbed.init_datastore_v3_stub( use_sqlite=True, auto_id_policy=testbed.AUTO_ID_POLICY_SCATTERED, consistency_policy=datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=1) ) self.testbed.init_files_stub() # FIXME! dependencies PIL # self.testbed.init_images_stub() self.testbed.init_logservice_stub() self.testbed.init_mail_stub() self.testbed.init_memcache_stub() self.testbed.init_taskqueue_stub(root_path=find_project_root()) self.testbed.init_urlfetch_stub() self.testbed.init_user_stub() self.testbed.init_xmpp_stub() # self.testbed.init_search_stub() # Init all the stubs! # self.testbed.init_all_stubs() return test_database_name
def init_testbed(): # We don't initialize the datastore stub here, that needs to be done by Django's create_test_db and destroy_test_db. IGNORED_STUBS = ["init_datastore_v3_stub"] stub_kwargs = {"init_taskqueue_stub": {"root_path": find_project_root()}} bed = testbed.Testbed() bed.activate() for init_name in testbed.INIT_STUB_METHOD_NAMES.values(): if init_name in IGNORED_STUBS: continue getattr(bed, init_name)(**stub_kwargs.get(init_name, {})) return bed
def init_testbed(): # We don't initialize the datastore stub here, that needs to be done by Django's create_test_db and destroy_test_db. IGNORED_STUBS = [ "init_datastore_v3_stub" ] stub_kwargs = { "init_taskqueue_stub": { "root_path": find_project_root() } } bed = testbed.Testbed() bed.activate() for init_name in testbed.INIT_STUB_METHOD_NAMES.values(): if init_name in IGNORED_STUBS: continue getattr(bed, init_name)(**stub_kwargs.get(init_name, {})) return bed
def _create_test_db(self, verbosity, autoclobber): from google.appengine.datastore import datastore_stub_util # Testbed exists in memory test_database_name = ':memory:' # Init test stubs self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_app_identity_stub() self.testbed.init_blobstore_stub() self.testbed.init_capability_stub() self.testbed.init_channel_stub() # We allow users to disable scattered IDs in tests. This primarily for running Django tests that # assume implicit ordering (yeah, annoying) use_scattered = not getattr(settings, "DJANGAE_SEQUENTIAL_IDS_IN_TESTS", False) self.testbed.init_datastore_v3_stub( use_sqlite=True, auto_id_policy=testbed.AUTO_ID_POLICY_SCATTERED if use_scattered else testbed.AUTO_ID_POLICY_SEQUENTIAL, consistency_policy=datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=1) ) self.testbed.init_files_stub() # FIXME! dependencies PIL # self.testbed.init_images_stub() self.testbed.init_logservice_stub() self.testbed.init_mail_stub() self.testbed.init_memcache_stub() self.testbed.init_taskqueue_stub(root_path=find_project_root()) self.testbed.init_urlfetch_stub() self.testbed.init_user_stub() self.testbed.init_xmpp_stub() # self.testbed.init_search_stub() # Init all the stubs! # self.testbed.init_all_stubs() return test_database_name
import os import re import sys import argparse import djangae.sandbox as sandbox from djangae.utils import find_project_root # Set some Django-y defaults DJANGO_DEFAULTS = { "storage_path": os.path.join(find_project_root(), ".storage"), "port": 8000, "admin_port": 8001, "api_port": 8002, "automatic_restart": "True", "allow_skipped_files": "True", } def _execute_from_command_line(sandbox_name, argv, **sandbox_overrides): # Parses for a settings flag, adding it as an environment variable to # the sandbox if found. parser = argparse.ArgumentParser(prog='manage.py') parser.add_argument('--settings', nargs='?') parsed = parser.parse_known_args(argv) settings = parsed[0].settings env_vars = {} if settings: env_vars['DJANGO_SETTINGS_MODULE'] = settings # retrieve additional overridden module settings
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 _get_index_file(): from djangae.utils import find_project_root index_file = os.path.join(find_project_root(), "djangaeidx.yaml") return index_file
def inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') do_reload = options.get('use_reloader', True) #We use the old dev appserver if threading is disabled or --old was passed use_old_dev_appserver = options.get( 'use_old_dev_appserver') or not options.get("use_threading") quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root, data_root from djangae.sandbox import _find_sdk_from_python_path from django.conf import settings from django.utils import translation #Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write( ("%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n") % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) #Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() if use_old_dev_appserver: dev_appserver = os.path.join(sdk_path, "old_dev_appserver.py") command = [ dev_appserver, find_project_root(), "-p", self.port, "-h", self.addr, "--use_sqlite", "--high_replication", "--allow_skipped_files", ] else: dev_appserver = os.path.join(sdk_path, "dev_appserver.py") command = [ dev_appserver, find_project_root(), "--port", self.port, "--host", self.addr, "--admin_port", str(int(self.port) + 1), "--automatic_restart", "True" if do_reload else "False", "--allow_skipped_files" ] process = Popen(command, stdout=sys.__stdout__, stderr=sys.__stderr__, cwd=find_project_root()) #This makes sure that dev_appserver gets killed on reload import atexit atexit.register(process.kill) try: process.wait() except KeyboardInterrupt: #Tell the dev appserver to shutdown and forcibly kill #if it takes too long process.send_signal(signal.SIGTERM) time.sleep(2) process.kill() if shutdown_message: sys.stdout.write(shutdown_message) #Some weird race condition crazy sometimes makes this None... if sys: sys.exit(process.returncode)
For more information on this file, see https://docs.djangoproject.com/en/1.6/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.6/ref/settings/ """ from djangae.settings_base import * # set up some AppEngine specific stuff from djangae.utils import find_project_root from django.core.urlresolvers import reverse_lazy from google.appengine.api.app_identity.app_identity import get_default_gcs_bucket_name # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os PROJECT_DIR = find_project_root() SITE_URL = "https://virtualart.chromeexperiments.com" SHORT_URL = "g.co/VirtualArtSessions" # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ from ..boot import get_app_config # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = get_app_config().secret_key # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True # Application definition
def inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root from djangae.sandbox import _find_sdk_from_python_path from djangae.blobstore_service import stop_blobstore_service from django.conf import settings from django.utils import translation stop_blobstore_service() # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write(( "%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n" ) % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() from google.appengine.tools.devappserver2 import devappserver2 from google.appengine.tools.devappserver2 import python_runtime from djangae import sandbox # Add any additional modules specified in the settings additional_modules = getattr(settings, "DJANGAE_ADDITIONAL_MODULES", []) if additional_modules: sandbox._OPTIONS.config_paths.extend(additional_modules) if int(self.port) != sandbox._OPTIONS.port or additional_modules: # Override the port numbers sandbox._OPTIONS.port = int(self.port) sandbox._OPTIONS.admin_port = int(self.port) + len(additional_modules) + 1 sandbox._OPTIONS.api_port = int(self.port) + len(additional_modules) + 2 if self.addr != sandbox._OPTIONS.host: sandbox._OPTIONS.host = sandbox._OPTIONS.admin_host = sandbox._OPTIONS.api_host = self.addr # Extra options for `dev_appserver.py` for param, value in self.gae_options.items(): setattr(sandbox._OPTIONS, param, value) # External port is a new flag introduced in 1.9.19 current_version = _VersionList(GetVersionObject()['release']) if current_version >= _VersionList('1.9.19'): sandbox._OPTIONS.external_port = None sandbox._OPTIONS.automatic_restart = self.use_reloader if sandbox._OPTIONS.host == "127.0.0.1" and os.environ["HTTP_HOST"].startswith("localhost"): hostname = "localhost" else: hostname = sandbox._OPTIONS.host os.environ["HTTP_HOST"] = "%s:%s" % (hostname, sandbox._OPTIONS.port) os.environ['SERVER_NAME'] = os.environ['HTTP_HOST'].split(':', 1)[0] os.environ['SERVER_PORT'] = os.environ['HTTP_HOST'].split(':', 1)[1] os.environ['DEFAULT_VERSION_HOSTNAME'] = '%s:%s' % (os.environ['SERVER_NAME'], os.environ['SERVER_PORT']) class NoConfigDevServer(devappserver2.DevelopmentServer): def _create_api_server(self, request_data, storage_path, options, configuration): self._dispatcher = sandbox._create_dispatcher(configuration, options) self._dispatcher._configuration = configuration self._dispatcher._port = options.port self._dispatcher._host = options.host self._dispatcher.request_data = request_data request_data._dispatcher = self._dispatcher sandbox._API_SERVER._host = options.api_host sandbox._API_SERVER.bind_addr = (options.api_host, options.api_port) from google.appengine.api import apiproxy_stub_map task_queue = apiproxy_stub_map.apiproxy.GetStub('taskqueue') # Make sure task running is enabled (it's disabled in the sandbox by default) if not task_queue._auto_task_running: task_queue._auto_task_running = True task_queue.StartBackgroundExecution() return sandbox._API_SERVER from google.appengine.tools.devappserver2 import module def logging_wrapper(func): """ Changes logging to use the DJANGO_COLORS settings """ def _wrapper(level, format, *args, **kwargs): if args and len(args) == 1 and isinstance(args[0], dict): args = args[0] status = str(args.get("status", 200)) else: status = "200" try: msg = format % args except UnicodeDecodeError: msg += "\n" # This is what Django does in WSGIRequestHandler.log_message # Utilize terminal colors, if available if status[0] == '2': # Put 2XX first, since it should be the common case msg = self.style.HTTP_SUCCESS(msg) elif status[0] == '1': msg = self.style.HTTP_INFO(msg) elif status == '304': msg = self.style.HTTP_NOT_MODIFIED(msg) elif status[0] == '3': msg = self.style.HTTP_REDIRECT(msg) elif status == '404': msg = self.style.HTTP_NOT_FOUND(msg) elif status[0] == '4': # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x if status.startswith(str('\x16\x03')): msg = ("You're accessing the development server over HTTPS, " "but it only supports HTTP.\n") msg = self.style.HTTP_BAD_REQUEST(msg) else: # Any 5XX, or any other response msg = self.style.HTTP_SERVER_ERROR(msg) return func(level, msg) return _wrapper module.logging.log = logging_wrapper(module.logging.log) python_runtime._RUNTIME_PATH = os.path.join(sdk_path, '_python_runtime.py') python_runtime._RUNTIME_ARGS = [sys.executable, python_runtime._RUNTIME_PATH] dev_server = NoConfigDevServer() try: dev_server.start(sandbox._OPTIONS) try: shutdown.wait_until_shutdown() except KeyboardInterrupt: pass finally: dev_server.stop() if shutdown_message: sys.stdout.write(shutdown_message) return
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 inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') do_reload = options.get('use_reloader', True) # We use the old dev appserver if threading is disabled or --old was passed use_old_dev_appserver = options.get('use_old_dev_appserver') or not options.get("use_threading") quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root, data_root from djangae.sandbox import _find_sdk_from_python_path from django.conf import settings from django.utils import translation # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write(( "%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n" ) % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() if use_old_dev_appserver: dev_appserver = os.path.join(sdk_path, "old_dev_appserver.py") command = [ dev_appserver, find_project_root(), "-p", self.port, "-h", self.addr, "--use_sqlite", "--high_replication", "--allow_skipped_files", ] else: dev_appserver = os.path.join(sdk_path, "dev_appserver.py") command = [ dev_appserver, find_project_root(), "--port", self.port, "--host", self.addr, "--admin_port", str(int(self.port) + 1), "--automatic_restart", "True" if do_reload else "False", "--allow_skipped_files", "--skip_sdk_update_check" ] process = Popen( command, stdout=sys.__stdout__, stderr=sys.__stderr__, cwd=find_project_root() ) # This makes sure that dev_appserver gets killed on reload import atexit atexit.register(process.kill) try: process.wait() except KeyboardInterrupt: # Tell the dev appserver to shutdown and forcibly kill # if it takes too long process.send_signal(signal.SIGTERM) time.sleep(2) process.kill() if shutdown_message: sys.stdout.write(shutdown_message) # Some weird race condition crazy sometimes makes this None... if sys: sys.exit(process.returncode)
import os import sys import argparse import djangae.sandbox as sandbox from djangae.utils import find_project_root # Set some Django-y defaults DJANGO_DEFAULTS = { "storage_path": os.path.join(find_project_root(), ".storage"), "port": 8000, "admin_port": 8001, "api_port": 8002, "automatic_restart": "True", "allow_skipped_files": "True", } def _execute_from_command_line(sandbox_name, argv, **sandbox_overrides): with sandbox.activate(sandbox_name, add_sdk_to_path=True, **sandbox_overrides): import django.core.management as django_management # Now on the path return django_management.execute_from_command_line(argv) def execute_from_command_line(argv=None, **sandbox_overrides): """Wraps Django's `execute_from_command_line` to initialize a djangae sandbox before running a management command. Note: The '--sandbox' arg must come first. All other args are forwarded to Django as normal. """
def inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root from djangae.sandbox import _find_sdk_from_python_path from djangae.blobstore_service import stop_blobstore_service from django.conf import settings from django.utils import translation stop_blobstore_service() # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write(( "%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n" ) % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() from google.appengine.tools.devappserver2 import devappserver2 from google.appengine.tools.devappserver2 import python_runtime from djangae import sandbox if int(self.port) != sandbox._OPTIONS.port: # Override the port numbers sandbox._OPTIONS.port = int(self.port) sandbox._OPTIONS.admin_port = int(self.port) + 1 sandbox._OPTIONS.api_port = int(self.port) + 2 if self.addr != sandbox._OPTIONS.host: sandbox._OPTIONS.host = sandbox._OPTIONS.admin_host = sandbox._OPTIONS.api_host = self.addr # External port is a new flag introduced in 1.9.19 current_version = _VersionList(GetVersionObject()['release']) if current_version >= _VersionList('1.9.19'): sandbox._OPTIONS.external_port = None sandbox._OPTIONS.automatic_restart = self.use_reloader if sandbox._OPTIONS.host == "127.0.0.1" and os.environ["HTTP_HOST"].startswith("localhost"): hostname = "localhost" else: hostname = sandbox._OPTIONS.host os.environ["HTTP_HOST"] = "%s:%s" % (hostname, sandbox._OPTIONS.port) os.environ['SERVER_NAME'] = os.environ['HTTP_HOST'].split(':', 1)[0] os.environ['SERVER_PORT'] = os.environ['HTTP_HOST'].split(':', 1)[1] os.environ['DEFAULT_VERSION_HOSTNAME'] = '%s:%s' % (os.environ['SERVER_NAME'], os.environ['SERVER_PORT']) class NoConfigDevServer(devappserver2.DevelopmentServer): def _create_api_server(self, request_data, storage_path, options, configuration): self._dispatcher = sandbox._create_dispatcher(configuration, options) self._dispatcher._port = options.port self._dispatcher._host = options.host self._dispatcher.request_data = request_data request_data._dispatcher = self._dispatcher sandbox._API_SERVER._host = options.api_host sandbox._API_SERVER.bind_addr = (options.api_host, options.api_port) from google.appengine.api import apiproxy_stub_map task_queue = apiproxy_stub_map.apiproxy.GetStub('taskqueue') # Make sure task running is enabled (it's disabled in the sandbox by default) if not task_queue._auto_task_running: task_queue._auto_task_running = True task_queue.StartBackgroundExecution() return sandbox._API_SERVER python_runtime._RUNTIME_PATH = os.path.join(sdk_path, '_python_runtime.py') python_runtime._RUNTIME_ARGS = [sys.executable, python_runtime._RUNTIME_PATH] dev_server = NoConfigDevServer() try: dev_server.start(sandbox._OPTIONS) try: shutdown.wait_until_shutdown() except KeyboardInterrupt: pass finally: dev_server.stop() if shutdown_message: sys.stdout.write(shutdown_message) return
def inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root from djangae.sandbox import _find_sdk_from_python_path from django.conf import settings from django.utils import translation # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write( ("%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n") % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() from google.appengine.tools.devappserver2 import devappserver2 from google.appengine.tools.devappserver2 import python_runtime from djangae import sandbox if int(self.port) != sandbox._OPTIONS.port: # Override the port numbers sandbox._OPTIONS.port = int(self.port) sandbox._OPTIONS.admin_port = int(self.port) + 1 sandbox._OPTIONS.api_port = int(self.port) + 2 if self.addr != sandbox._OPTIONS.host: sandbox._OPTIONS.host = sandbox._OPTIONS.admin_host = sandbox._OPTIONS.api_host = self.addr # External port is a new flag introduced in 1.9.19 current_version = _VersionList(GetVersionObject()['release']) if current_version >= _VersionList('1.9.19'): sandbox._OPTIONS.external_port = None sandbox._OPTIONS.automatic_restart = self.use_reloader class NoConfigDevServer(devappserver2.DevelopmentServer): def _create_api_server(self, request_data, storage_path, options, configuration): self._dispatcher = sandbox._create_dispatcher( configuration, options) self._dispatcher._port = options.port self._dispatcher._host = options.host # Make sure the dispatcher uses the WSGIRequestInfo object already instantiated in local sandbox. # Without this, there will be references to two different request info objects, causing errors when trying # to access a request in one that was started in the other. def request_data_override(func, _request_data): def _wrapped(api_host, api_port, request_data): return func(api_host, api_port, _request_data) return _wrapped self._dispatcher.start = request_data_override( self._dispatcher.start, self._dispatcher._request_data) sandbox._API_SERVER._host = options.api_host sandbox._API_SERVER.bind_addr = (options.api_host, options.api_port) request_data._dispatcher = self._dispatcher from google.appengine.api import apiproxy_stub_map task_queue = apiproxy_stub_map.apiproxy.GetStub('taskqueue') # Make sure task running is enabled (it's disabled in the sandbox by default) if not task_queue._auto_task_running: task_queue._auto_task_running = True task_queue.StartBackgroundExecution() return sandbox._API_SERVER python_runtime._RUNTIME_PATH = os.path.join(sdk_path, '_python_runtime.py') python_runtime._RUNTIME_ARGS = [ sys.executable, python_runtime._RUNTIME_PATH ] dev_server = NoConfigDevServer() try: dev_server.start(sandbox._OPTIONS) try: shutdown.wait_until_shutdown() except KeyboardInterrupt: pass finally: dev_server.stop() if shutdown_message: sys.stdout.write(shutdown_message) return
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 inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root from djangae.sandbox import _find_sdk_from_python_path from django.conf import settings from django.utils import translation # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write(( "%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n" ) % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() from google.appengine.tools.devappserver2 import devappserver2 from google.appengine.tools.devappserver2 import python_runtime from djangae import sandbox sandbox._OPTIONS.port = int(self.port) if self.port else sandbox._OPTIONS.port sandbox._OPTIONS.host = self.addr if self.addr else sandbox._OPTIONS.host class NoConfigDevServer(devappserver2.DevelopmentServer): @staticmethod def _create_api_server(request_data, storage_path, options, configuration): return sandbox._API_SERVER python_runtime._RUNTIME_PATH = os.path.join(sdk_path, '_python_runtime.py') python_runtime._RUNTIME_ARGS = [sys.executable, python_runtime._RUNTIME_PATH] devappserver = NoConfigDevServer() devappserver.start(sandbox._OPTIONS) if shutdown_message: sys.stdout.write(shutdown_message) return
def inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root from djangae.sandbox import _find_sdk_from_python_path from djangae.blobstore_service import stop_blobstore_service from django.conf import settings from django.utils import translation stop_blobstore_service() # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.check(display_num_errors=True) self.stdout.write( ("%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n") % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() from google.appengine.tools.devappserver2 import devappserver2 from google.appengine.tools.devappserver2 import python_runtime from djangae import sandbox # Add any additional modules specified in the settings additional_modules = getattr(settings, "DJANGAE_ADDITIONAL_MODULES", []) if additional_modules: sandbox._OPTIONS.config_paths.extend(additional_modules) if int(self.port) != sandbox._OPTIONS.port or additional_modules: # Override the port numbers sandbox._OPTIONS.port = int(self.port) sandbox._OPTIONS.admin_port = int( self.port) + len(additional_modules) + 1 sandbox._OPTIONS.api_port = int( self.port) + len(additional_modules) + 2 if self.addr != sandbox._OPTIONS.host: sandbox._OPTIONS.host = sandbox._OPTIONS.admin_host = sandbox._OPTIONS.api_host = self.addr # Extra options for `dev_appserver.py` for param, value in self.gae_options.items(): setattr(sandbox._OPTIONS, param, value) # External port is a new flag introduced in 1.9.19 current_version = _VersionList(GetVersionObject()['release']) if current_version >= _VersionList('1.9.19'): sandbox._OPTIONS.external_port = None sandbox._OPTIONS.automatic_restart = self.use_reloader if sandbox._OPTIONS.host == "127.0.0.1" and os.environ[ "HTTP_HOST"].startswith("localhost"): hostname = "localhost" sandbox._OPTIONS.host = "localhost" else: hostname = sandbox._OPTIONS.host os.environ["HTTP_HOST"] = "%s:%s" % (hostname, sandbox._OPTIONS.port) os.environ['SERVER_NAME'] = os.environ['HTTP_HOST'].split(':', 1)[0] os.environ['SERVER_PORT'] = os.environ['HTTP_HOST'].split(':', 1)[1] os.environ['DEFAULT_VERSION_HOSTNAME'] = '%s:%s' % ( os.environ['SERVER_NAME'], os.environ['SERVER_PORT']) from google.appengine.api.appinfo import EnvironmentVariables class NoConfigDevServer(devappserver2.DevelopmentServer): def _create_api_server(self, request_data, storage_path, options, configuration): # sandbox._create_dispatcher returns a singleton dispatcher instance made in sandbox self._dispatcher = sandbox._create_dispatcher( configuration, options) # the dispatcher may have passed environment variables, it should be propagated env_vars = self._dispatcher._configuration.modules[ 0]._app_info_external.env_variables or EnvironmentVariables( ) for module in configuration.modules: module_name = module._module_name if module_name == 'default': module_settings = 'DJANGO_SETTINGS_MODULE' else: module_settings = '%s_DJANGO_SETTINGS_MODULE' % module_name if module_settings in env_vars: module_env_vars = module.env_variables or EnvironmentVariables( ) module_env_vars['DJANGO_SETTINGS_MODULE'] = env_vars[ module_settings] old_env_vars = module._app_info_external.env_variables new_env_vars = EnvironmentVariables.Merge( module_env_vars, old_env_vars) module._app_info_external.env_variables = new_env_vars self._dispatcher._configuration = configuration self._dispatcher._port = options.port self._dispatcher._host = options.host self._dispatcher.request_data = request_data request_data._dispatcher = self._dispatcher sandbox._API_SERVER._host = options.api_host sandbox._API_SERVER.bind_addr = (options.api_host, options.api_port) from google.appengine.api import apiproxy_stub_map task_queue = apiproxy_stub_map.apiproxy.GetStub('taskqueue') # Make sure task running is enabled (it's disabled in the sandbox by default) if not task_queue._auto_task_running: task_queue._auto_task_running = True task_queue.StartBackgroundExecution() return sandbox._API_SERVER from google.appengine.tools.devappserver2 import module def fix_watcher_files(regex): from google.appengine.tools.devappserver2 import watcher_common watcher_common._IGNORED_REGEX = regex watcher_common.ignore_file = ignore_file regex = sandbox._CONFIG.modules[0].skip_files if regex: fix_watcher_files(regex) def logging_wrapper(func): """ Changes logging to use the DJANGO_COLORS settings """ def _wrapper(level, format, *args, **kwargs): if args and len(args) == 1 and isinstance(args[0], dict): args = args[0] status = str(args.get("status", 200)) else: status = "200" try: msg = format % args except UnicodeDecodeError: msg += "\n" # This is what Django does in WSGIRequestHandler.log_message # Utilize terminal colors, if available if status[0] == '2': # Put 2XX first, since it should be the common case msg = self.style.HTTP_SUCCESS(msg) elif status[0] == '1': msg = self.style.HTTP_INFO(msg) elif status == '304': msg = self.style.HTTP_NOT_MODIFIED(msg) elif status[0] == '3': msg = self.style.HTTP_REDIRECT(msg) elif status == '404': msg = self.style.HTTP_NOT_FOUND(msg) elif status[0] == '4': # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x if status.startswith(str('\x16\x03')): msg = ( "You're accessing the development server over HTTPS, " "but it only supports HTTP.\n") msg = self.style.HTTP_BAD_REQUEST(msg) else: # Any 5XX, or any other response msg = self.style.HTTP_SERVER_ERROR(msg) return func(level, msg) return _wrapper module.logging.log = logging_wrapper(module.logging.log) python_runtime._RUNTIME_PATH = os.path.join(sdk_path, '_python_runtime.py') python_runtime._RUNTIME_ARGS = [ sys.executable, python_runtime._RUNTIME_PATH ] dev_server = NoConfigDevServer() try: dev_server.start(sandbox._OPTIONS) try: shutdown.wait_until_shutdown() except KeyboardInterrupt: pass finally: dev_server.stop() if shutdown_message: sys.stdout.write(shutdown_message) return
def inner_run(self, *args, **options): import sys shutdown_message = options.get('shutdown_message', '') quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' from djangae.utils import find_project_root from djangae.sandbox import _find_sdk_from_python_path from djangae.blobstore_service import stop_blobstore_service from django.conf import settings from django.utils import translation stop_blobstore_service() # Check for app.yaml expected_path = os.path.join(find_project_root(), "app.yaml") if not os.path.exists(expected_path): sys.stderr.write("Unable to find app.yaml at '%s'\n" % expected_path) sys.exit(1) self.stdout.write("Validating models...\n\n") self.validate(display_num_errors=True) self.stdout.write( ("%(started_at)s\n" "Django version %(version)s, using settings %(settings)r\n" "Starting development server at http://%(addr)s:%(port)s/\n" "Quit the server with %(quit_command)s.\n") % { "started_at": datetime.now().strftime('%B %d, %Y - %X'), "version": self.get_version(), "settings": settings.SETTINGS_MODULE, "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, "port": self.port, "quit_command": quit_command, }) sys.stdout.write("\n") sys.stdout.flush() # django.core.management.base forces the locale to en-us. We should # set it up correctly for the first request (particularly important # in the "--noreload" case). translation.activate(settings.LANGUAGE_CODE) # Will have been set by setup_paths sdk_path = _find_sdk_from_python_path() from google.appengine.tools.devappserver2 import devappserver2 from google.appengine.tools.devappserver2 import python_runtime from djangae import sandbox if int(self.port) != sandbox._OPTIONS.port: # Override the port numbers sandbox._OPTIONS.port = int(self.port) sandbox._OPTIONS.admin_port = int(self.port) + 1 sandbox._OPTIONS.api_port = int(self.port) + 2 if self.addr != sandbox._OPTIONS.host: sandbox._OPTIONS.host = sandbox._OPTIONS.admin_host = sandbox._OPTIONS.api_host = self.addr # Extra options for `dev_appserver.py` for param, value in self.gae_options.items(): setattr(sandbox._OPTIONS, param, value) # External port is a new flag introduced in 1.9.19 current_version = _VersionList(GetVersionObject()['release']) if current_version >= _VersionList('1.9.19'): sandbox._OPTIONS.external_port = None sandbox._OPTIONS.automatic_restart = self.use_reloader if sandbox._OPTIONS.host == "127.0.0.1" and os.environ[ "HTTP_HOST"].startswith("localhost"): hostname = "localhost" else: hostname = sandbox._OPTIONS.host os.environ["HTTP_HOST"] = "%s:%s" % (hostname, sandbox._OPTIONS.port) os.environ['SERVER_NAME'] = os.environ['HTTP_HOST'].split(':', 1)[0] os.environ['SERVER_PORT'] = os.environ['HTTP_HOST'].split(':', 1)[1] os.environ['DEFAULT_VERSION_HOSTNAME'] = '%s:%s' % ( os.environ['SERVER_NAME'], os.environ['SERVER_PORT']) class NoConfigDevServer(devappserver2.DevelopmentServer): def _create_api_server(self, request_data, storage_path, options, configuration): self._dispatcher = sandbox._create_dispatcher( configuration, options) self._dispatcher._port = options.port self._dispatcher._host = options.host self._dispatcher.request_data = request_data request_data._dispatcher = self._dispatcher sandbox._API_SERVER._host = options.api_host sandbox._API_SERVER.bind_addr = (options.api_host, options.api_port) from google.appengine.api import apiproxy_stub_map task_queue = apiproxy_stub_map.apiproxy.GetStub('taskqueue') # Make sure task running is enabled (it's disabled in the sandbox by default) if not task_queue._auto_task_running: task_queue._auto_task_running = True task_queue.StartBackgroundExecution() return sandbox._API_SERVER python_runtime._RUNTIME_PATH = os.path.join(sdk_path, '_python_runtime.py') python_runtime._RUNTIME_ARGS = [ sys.executable, python_runtime._RUNTIME_PATH ] dev_server = NoConfigDevServer() try: dev_server.start(sandbox._OPTIONS) try: shutdown.wait_until_shutdown() except KeyboardInterrupt: pass finally: dev_server.stop() if shutdown_message: sys.stdout.write(shutdown_message) return