From 50cebd7dea8a11188c383200f81e63a0b8b377ae Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 28 Mar 2017 02:19:47 -0500 Subject: require "open_url" setting in order to know what browser to open Parsing the port from the server section could be brought back but it would be a fallback that depends on finding a "port" variable in the [server:server_name] section of the config. --- pyramid/scripts/pserve.py | 49 ++++++++++++++++++------------- pyramid/tests/test_scripts/test_pserve.py | 4 +-- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index b89f9b982..caa73704a 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -22,10 +22,6 @@ from paste.deploy import ( loadapp, loadserver, ) -from paste.deploy.loadwsgi import ( - SERVER, - loadcontext, -) from pyramid.compat import PY2 from pyramid.compat import configparser @@ -87,7 +83,9 @@ class PServeCommand(object): '-b', '--browser', dest='browser', action='store_true', - help="Open a web browser to server url") + help=("Open a web browser to the server url. The server url is " + "determined from the 'open_url' setting in the 'pserve' " + "section of the configuration file.")) parser.add_argument( '-v', '--verbose', default=default_verbosity, @@ -119,6 +117,8 @@ class PServeCommand(object): loadapp = staticmethod(loadapp) # testing loadserver = staticmethod(loadserver) # testing + open_url = None + _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) def __init__(self, argv, quiet=False): @@ -127,7 +127,7 @@ class PServeCommand(object): self.args.verbose = 0 if self.args.reload: self.worker_kwargs = {'argv': argv, "quiet": quiet} - self.watch_files = [] + self.watch_files = set() def out(self, msg): # pragma: no cover if self.args.verbose > 0: @@ -150,7 +150,7 @@ class PServeCommand(object): try: items = dict(config.items('pserve')) except configparser.NoSectionError: - return + items = {} watch_files = aslist(items.get('watch_files', ''), flatten=False) @@ -161,7 +161,11 @@ class PServeCommand(object): file = resolver.resolve(file).abspath() elif not os.path.isabs(file): file = os.path.join(here, file) - self.watch_files.append(os.path.abspath(file)) + self.watch_files.add(os.path.abspath(file)) + + open_url = items.get('open_url') + if open_url: + self.open_url = open_url def run(self): # pragma: no cover if not self.args.config_uri: @@ -188,16 +192,21 @@ class PServeCommand(object): # do not open the browser on each reload so check hupper first if self.args.browser and not hupper.is_active(): - def open_browser(): - context = loadcontext( - SERVER, app_spec, name=server_name, relative_to=base, - global_conf=vars) - url = 'http://127.0.0.1:{port}/'.format(**context.config()) - time.sleep(1) - webbrowser.open(url) - t = threading.Thread(target=open_browser) - t.setDaemon(True) - t.start() + self.pserve_file_config(config_path, global_conf=vars) + url = self.open_url + if not url: + self.out('WARNING: could not determine the server\'s url to ' + 'open the browser. To fix this set the "open_url" ' + 'setting in the [pserve] section of the ' + 'configuration file.') + + else: + def open_browser(): + time.sleep(1) + webbrowser.open(url) + t = threading.Thread(target=open_browser) + t.setDaemon(True) + t.start() if self.args.reload and not hupper.is_active(): if self.args.verbose > 1: @@ -213,11 +222,11 @@ class PServeCommand(object): if config_path: setup_logging(config_path, global_conf=vars) self.pserve_file_config(config_path, global_conf=vars) - self.watch_files.append(config_path) + self.watch_files.add(config_path) if hupper.is_active(): reloader = hupper.get_reloader() - reloader.watch_files(self.watch_files) + reloader.watch_files(list(self.watch_files)) server = self.loadserver( server_spec, name=server_name, relative_to=base, global_conf=vars) diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index 8eb63b8d6..bb3303a10 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -74,11 +74,11 @@ class TestPServeCommand(unittest.TestCase): 'a': '1', 'here': os.path.abspath('/base'), }) - self.assertEqual(inst.watch_files, [ + self.assertEqual(inst.watch_files, set([ os.path.abspath('/base/foo'), os.path.abspath('/baz'), os.path.abspath(os.path.join(here, '*.py')), - ]) + ])) def test_reload_call_hupper_with_correct_args(self): from pyramid.scripts import pserve -- cgit v1.2.3 From 248669dbaedc4848e627c449e4e43928628b86be Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 28 Mar 2017 02:48:52 -0500 Subject: support opening the browser via pserve.open_url config setting --- pyramid/scripts/pserve.py | 29 ++++++++++++++++++++++++++++- pyramid/tests/test_scripts/test_pserve.py | 26 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index caa73704a..c469dde04 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -150,7 +150,7 @@ class PServeCommand(object): try: items = dict(config.items('pserve')) except configparser.NoSectionError: - items = {} + return watch_files = aslist(items.get('watch_files', ''), flatten=False) @@ -163,10 +163,31 @@ class PServeCommand(object): file = os.path.join(here, file) self.watch_files.add(os.path.abspath(file)) + # attempt to determine the url of the server open_url = items.get('open_url') if open_url: self.open_url = open_url + def _guess_server_url(self, filename, server_name, + global_conf=None): # pragma: no cover + server_name = server_name or 'main' + here = os.path.abspath(os.path.dirname(filename)) + defaults = {} + if global_conf: + defaults.update(global_conf) + defaults['here'] = here + + config = self.ConfigParser(defaults=defaults) + config.optionxform = str + config.read(filename) + try: + items = dict(config.items('server:' + server_name)) + except configparser.NoSectionError: + return + + if 'port' in items: + return 'http://127.0.0.1:{port}'.format(**items) + def run(self): # pragma: no cover if not self.args.config_uri: self.out('You must give a config file') @@ -194,6 +215,12 @@ class PServeCommand(object): if self.args.browser and not hupper.is_active(): self.pserve_file_config(config_path, global_conf=vars) url = self.open_url + + # do not guess the url if the server is sourced from a different + # location than the config_path + if not url and server_spec == app_spec: + url = self._guess_server_url(config_path, server_name, vars) + if not url: self.out('WARNING: could not determine the server\'s url to ' 'open the browser. To fix this set the "open_url" ' diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index bb3303a10..d5578b3ea 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -80,6 +80,32 @@ class TestPServeCommand(unittest.TestCase): os.path.abspath(os.path.join(here, '*.py')), ])) + def test_config_file_finds_open_url(self): + inst = self._makeOne('development.ini') + self.config_factory.items = [( + 'open_url', 'http://127.0.0.1:8080/', + )] + inst.pserve_file_config('/base/path.ini', global_conf={'a': '1'}) + self.assertEqual(self.config_factory.defaults, { + 'a': '1', + 'here': os.path.abspath('/base'), + }) + self.assertEqual(inst.open_url, 'http://127.0.0.1:8080/') + + def test__guess_server_url(self): + inst = self._makeOne('development.ini') + self.config_factory.items = [( + 'port', '8080', + )] + url = inst._guess_server_url( + '/base/path.ini', 'main', global_conf={'a': '1'}) + self.assertEqual(self.config_factory.defaults, { + 'a': '1', + 'here': os.path.abspath('/base'), + }) + self.assertEqual(self.config_factory.parser.section, 'server:main') + self.assertEqual(url, 'http://127.0.0.1:8080') + def test_reload_call_hupper_with_correct_args(self): from pyramid.scripts import pserve -- cgit v1.2.3 From 839dbff79f43a8f76d2be9edd95f78308a316deb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 28 Mar 2017 20:57:04 -0500 Subject: changelog for #2984 --- CHANGES.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 9056320c5..7676a69f9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,6 +10,14 @@ Features request that the policy may create more than one request for retry purposes. See https://github.com/Pylons/pyramid/pull/2964 +- Support an ``open_url`` config setting in the ``pserve`` section of the + config file. This url is used to open a web browser when ``pserve --browser`` + is invoked. When this setting is unavailable the ``pserve`` script will + attempt to guess the port the server is using from the + ``server:`` section of the config file but there is no + requirement that the server is being run in this format so it may fail. + See https://github.com/Pylons/pyramid/pull/2984 + Bug Fixes --------- -- cgit v1.2.3