Hey all-

In early July there was a thread about "Running an existing python script?".

I happened to have that need yesterday[0].  I quickly found out in my
initial attempt to monkeypatch sys.stdout that it was not threadsafe.
Some searching led to July's conversation and I used Ian Bicking's
code to get stdout redirection to be somewhat threadsafe (at least it
looks that way).  I've posted my code below, hopefully it might be of
use to someone.  My only concern is that my monkeypatching of sys.argv
is not threadsafe.

But I guess if users (me included) follow Guido's suggested practice
for main [1], then their issues will be resolved.  (ie def
main(argv=None) ).

If anyone has any comments on how to make sys.argv threadsafe without
patching my code (not that it's a big deal here) let me know.  Also,
I'm passing in the command line arguments in an "args" parameter and
delimiting them with the delimiter specified in the "delim" param.  It
feels sortof hackish, if anyone has a cleaner solution, I'm all ears.
(I'm also thinking that wrapping it in json might prove useful
too.....)

thanks,

-matt


0 - http://panela.blog-city.com/does_oracle_really_love_rails.htm
1 - http://www.artima.com/weblogs/viewpost.jsp?thread=4829

Here's my test controllers::

    def teststdout_bicking(self):
        from webstack.lib import foocmd
        from paste.util import threadedprint
        from paste.debug import prints
        global _threadedprint_installed
        if not _threadedprint_installed:
            # @@: Not strictly threadsafe
            _threadedprint_installed = True
            threadedprint.install(leave_stdout=True)
        #run foocmd.py through a web interface
        delimiter = request.params.get("delim", " ")
        #convert request.params['args'] to sys.args

        sys.argv = request.params.get("args", "").split(delimiter)
        #insert extra arg at front
        sys.argv.insert(0, "")

        print "ARGS", sys.argv

        fout = StringIO()
        threadedprint.register(prints.TeeFile([fout]))

        try:
            foocmd.main()
        finally:
            threadedprint.deregister()

        response = Response("")
        response.headers["content-type"] = "text/plain"
        response.content = fout.getvalue()

        return response

    def teststdout_naive(self):
        """Messes up with concurrent calls!!! Dont' use!"""
        from webstack.lib import foocmd
        #run foocmd.py through a web interface
        delimiter = request.params.get("delim", " ")

        #convert request.params['args'] to sys.args
        old_args = sys.argv

        sys.argv = request.params.get("args", "").split(delimiter)
        #insert extra arg to front
        sys.argv.insert(0, "")

        print "ARGS", sys.argv
        fout = StringIO()
        old_out = sys.stdout
        sys.stdout = fout

        foocmd.main()

        sys.argv = old_args
        sys.stdout = old_out

        response = Response("")
        response.headers["content-type"] = "text/plain"
        response.content = fout.getvalue()

        return response

Here's my foocmd.py test code::

import optparse
import time


def make_output(repeat, pause):
    for i in range(repeat):
        print "Count \ti:",i
        time.sleep(pause)

def main():
    p = optparse.OptionParser()
    p.add_option("-r", action="store", dest="repeat")
    p.add_option("-p", action="store", dest="pause")

    opt, args = p.parse_args()

    make_output(int(opt.repeat), int(opt.pause))

if __name__ == "__main__":
    main()

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to pylons-discuss@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to