Pages

Monday, 21 December 2020

How to write a Python script that can run as a command line tool and CGI app?

1 Why

Tools used by a small group inside a company are easily implemented in Python. 
While CGI apps are preferred by general users who don't want to install anything on their own laptops to use tools, Linux/command-line users usually are not into web tools. So tools that can run as both a CGI app and a command-line app are needed.

2 Notes of a CGI app

As a CGI app uses its stdout to write the HTTP response, the app must NOT write other data into the stdout.  To avoid a mess, be careful when using print().

3 Example code

#! /usr/bin/env python3

import os,sys

# return bytes data, don't write to stdout any data inside this function

def main(arg1=None, arg2=None):

        return b'any bytes data'


####################### CGI ########################

# when this script runs as a CGI app

def cgi_main():

        import cgi,traceback

        try:

                # don't print out any thing in this section

                form = cgi.FieldStorage()

                arg1 = form.getvalue('arg1')

                arg2 = form.getvalue('arg2')

                body = main(arg1,arg2)


                # write out http response

                print('Content-Type: any_mime_type\r\n\r\n', end='')

                sys.stdout.flush()

                sys.stdout.buffer.write(body)

        except:

                print('Content-Type: text/plain\r\n\r\n', end='')

                print(traceback.format_exc())


####################### CMD ########################

# when this scriipt runs as a command line tool

def cmd_main():

        arg1 = sys.argv[1]

        arg2 = sys.argv[2]


        body = main(arg1, arg2)

        sys.stdout.flush()

        sys.stdout.buffer.write(body)


####################### ENTRY ########################

# run this script as a command line tool or CGI app

if __name__ == '__main__':

        if os.environ.get('REMOTE_ADDR'):

                cgi_main()

        else:

                cmd_main()


No comments:

Post a Comment