Question

I currently use argparse for writing command line driven scripts in python. I'm considering making a server which provides a front-end for many of these scripts (some computers may not have the RAM, processing speed, etc. to run them locally). So I'm wondering about different ways to hook into these scripts via a webpage.

The goal would to have the equivalent of a webpage generated off the argparse content (for instance, the arguments with choices would display as a combo-box, arguments that are boolean would be a checkbox, etc.). Since argparse is fairly well defined, I imagine it might be possible to create a wrapper around argparse functions to generate the needed HTML.

Any suggestions for how to do this painlessly?

Edit: Here's an example of what I am envisioning.

Here is a simple script using argparse and below it some html which I am envisioning being translated from argparse.

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file', nargs='?', help="The fasta file to process.", type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument('-o', '--out', nargs='?', help="The file to write processed file to.", type=argparse.FileType('w'), default=sys.stdout)
parser.add_argument('--something', help="This does something", choices=['a','b'], type=str, default='a')
parser.add_argument('--somethingelse', help="This does something else", action='store_true', type=bool)

def main():
    args = parser.parse_args()
    #do stuff here such a reading in files, processing, and delivering output

if __name__ == "__main__":
    sys.exit(main())

With html this is like this (I'm terrible at HTML, so it's probably wrong/a hack)

<form>
File: <input type="text" name="file"><br>
Out: <input type="text" name="out"><br>
<select name="something">
<option value="a" selected>a</option>
<option value="b">b</option>
</select><br>
Somethingelse: <input type="checkbox" name="somethingelse" value="true"><br>
<input type="submit" value="Submit">
</form>

Where then hitting submit would cause the server to execute the script with those parameters. In essence, I want my server to then send the command as if I typed it in, if we're working with an output file it would give the user something downloadable (but that's a problem for another time)

Was it helpful?

Solution

Is this roughly what you want to do?

import argparse
parser = argparse.ArgumentParser(description='sample parser')
arg1 = parser.add_argument('--foo')
print parser
print arg1

html = """
<form name="%(prog)s action="%(action)s" method="get">
%(description)s
<input type="text" name="%(dest)s"><br>
<input type="submit" value="Submit">
</form>
"""
d = vars(parser)
d.update(vars(arg1))
d['action'] = 'html_form.xxx'
print html%d

which displays:

ArgumentParser(prog='stack21586315.py', usage=None, description='sample parser',
    version=None, formatter_class=<class 'argparse.HelpFormatter'>,
    conflict_handler='error', add_help=True)

_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None,
    default=None, type=None, choices=None, help=None, metavar=None)

<form name="stack21586315.py action="html_form.xxx" method="get">
sample parser
<input type="text" name="foo"><br>
<input type="submit" value="Submit">
</form>

I'm generating a dictionary from the attributes of the parser and its action, and using those to fill in slots in the form string.


A basic WSGI function involves sending a response via start_response, and receiving a request (here in the envirion argument). Details with vary with the framework.

The url of this module (and function) is specified in the form's action attribute. How the values are sent depends on the method (get/post). The values are found in environ['QUERY_STRING']. There are various tools for parsing this string, either in the cgi or urlparse modules (or see your framework). The parsed request should end up looking much like vars(args).

def my_send_app(environ, start_response):
    status = '200 OK' # HTTP Status
    headers = [('Content-type', 'text/plain')] # HTTP Headers
    start_response(status, headers)

    # The returned object is going to be printed
    # create the HTML including the form; return as list of strings
    return [...]

def my_receive_app(envirion, start_responce):
    # Returns a dictionary containing lists as values.
    d = urlparse.parse_qs(environ['QUERY_STRING'])
    # d should be similar to vars(args)
    # apply the values in d
    # use start_responce to reply to the browser

http://webpython.codepoint.net/wsgi_request_parsing_get

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top