Re: A more useful command-line wsgiref.simple_server?
Masklinn <[email protected]> Sun, 1 Apr 2012 16:32:00 +0200
| Newsgroups | gmane.comp.python.web |
|---|---|
| Message-ID | <[email protected]> |
On 2012-03-31, at 05:27 , PJ Eby wrote: > On Fri, Mar 30, 2012 at 2:22 PM, Sasha Hart <[email protected]> wrote: > >> I do really like the idea of having a quick WSGI runner in the stdlib, >> > Regarding modules vs. files, I don't really care that much which way the > capability is spelled, as long as the file vs. module distinction is > explicit. "-m " isn't a lot to add to a command line, and neither is "-f > ". If there's no consensus, just require that one or the other be > specified, and inconvenience both groups of people equally. ;-) Let's go with that. I'm not sure if I should be using sub-commands or options so for now I've used options. UI changes from initial patch: * Exclusive options for getting the application callable from a script (via `exec`) or a module (using `importlib.import_module`) * Application name specification has been moved to an option (default: `application`) * Option to serve the request only once (default: forever) when mounting a custom application * Option to open a browser window/tab to the (host, port) specified (which still default to '' and 8000 respectively) > python -mwsgiref.simple_server -h usage: simple_server.py [-h] [-H HOST] [-p PORT] [-s SCRIPT | -m MODULE] [-a APP] [-1] [-b] Mount and serve a WSGI application. If no script or module is specified, mounts wsgiref.simple_server.demo_app optional arguments: -h, --help show this help message and exit -H HOST, --host HOST Host to listen on -p PORT, --port PORT Port to listen on (defaults to 8000) -s SCRIPT, --script SCRIPT WSGI script file to execute and get the application from -m MODULE, --module MODULE Python module to import and get the application from Script or module options: These options do not apply when mounting the demo_app -a APP, --app APP, --app-name APP Name of the application variable in the script or module, application if none is provided -1, --once Only handles a single request, then exits -b, --browse Launch browser to the served URL _______________________________________________ Web-SIG mailing list [email protected] Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: http://mail.python.org/mailman/options/web-sig/gcpw-web-sig%40m.gmane.org
simple_server.patch
(application/octet-stream, 3.1 KB)
diff --git a/Lib/wsgiref/simple_server.py b/Lib/wsgiref/simple_server.py
--- a/Lib/wsgiref/simple_server.py
+++ b/Lib/wsgiref/simple_server.py
@@ -146,11 +146,63 @@ def make_server(
server.set_app(app)
return server
+if __name__ == '__main__':
+ import argparse
+ import importlib
+ import operator
+ import webbrowser
-if __name__ == '__main__':
- httpd = make_server('', 8000, demo_app)
- sa = httpd.socket.getsockname()
- print("Serving HTTP on", sa[0], "port", sa[1], "...")
- import webbrowser
- webbrowser.open('http://localhost:8000/xyz?abc')
- httpd.handle_request() # serve one request, then exit
+ parser = argparse.ArgumentParser(
+ description="Mount and serve a WSGI application. If no script or "
+ "module is specified, mounts "
+ "wsgiref.simple_server.demo_app")
+
+ parser.add_argument('-H', '--host', default='',
+ help="Host to listen on")
+ parser.add_argument('-p', '--port', type=int, default=8000,
+ help="Port to listen on (defaults to %(default)d)")
+
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument('-s', '--script', default=None,
+ help="WSGI script file to execute and get the application from")
+ group.add_argument('-m', '--module', default=None,
+ help="Python module to import and get the application from")
+
+ custom = parser.add_argument_group(title="Script or module options",
+ description="These options do not apply when mounting the demo_app")
+ custom.add_argument('-a', '--app', '--app-name', default='application',
+ help="Name of the application variable in the script or module, "
+ "%(default)s if none is provided")
+ custom.add_argument('-1', '--once', action='store_const', dest='serve',
+ default=operator.methodcaller('serve_forever'),
+ const=operator.methodcaller('handle_request'),
+ help="Only handles a single request, then exits")
+ custom.add_argument('-b', '--browse', action='store_true', default=False,
+ help="Launch browser to the served URL")
+
+
+ args = parser.parse_args()
+
+ if args.script is None and args.module is None:
+ httpd = make_server(args.host, args.port, demo_app)
+ sa = httpd.socket.getsockname()
+ print("Serving HTTP on", sa[0], "port", sa[1], "...")
+ webbrowser.open('http://localhost:8000/xyz?abc')
+ httpd.handle_request() # serve one request, then exit
+ else:
+ if args.script is not None:
+ variables = {}
+ exec(compile(open(args.script).read(), args.script, 'exec'), variables)
+ else:
+ variables = vars(importlib.import_module(args.module))
+ app = variables[args.app]
+ httpd = make_server(args.host, args.port, app)
+
+ sa = httpd.socket.getsockname()
+ print("Serving HTTP on", sa[0], "port", sa[1], "...")
+
+ if args.browse:
+ webbrowser.open("http://{host}:{port}/".format(
+ host=args.host or 'localhost',
+ port=args.port))
+ args.serve(httpd)