Pattern for foo tool <-> API <-> shell|GUI

kyosohma at gmail.com kyosohma at gmail.com
Sat Mar 24 18:55:18 CET 2007


On Mar 24, 10:31 am, Anastasios Hatzis <a... at hatzis.de> wrote:
> I'm looking for a pattern where different client implementations can use the
> same commands of some fictive tool ("foo") by accessing some kind of API.
> Actually I have the need for such pattern for my own tool
> (http://openswarm.sourceforge.net). I already started restructuring my code
> to separate the actual command implementations from the command-line scripts
> (which is optparser-based now) and have some ideas how to proceed. But
> probably there is already a good pattern used for Python-based tools.
>
> In the case that some of you are interested into this topic and my recent
> thoughts, you may want to have a look at the description below. Any comments
> are very much appreciated. Hopefully this list is a good place for discussing
> a pattern, otherwise I would be okay to move this to another place. Thank
> you.
>
> Here we go:
> The tool package itself provides several commands, although not important for
> the pattern itself, here some examples: modifying user-specific preferences,
> creating and changing project settings files, project-related
> code-generation, or combinations of such commands ... later also commands for
> transformation between several XML formats etc. The classes which implement
> these commands are currently in multiple modules, each having a class named
> CmdHandler.
>
> I have some Python scripts (each having a ScriptHandler classes), for use via
> command-line. Each ScriptHandler class is responsible to add all related
> command-line options and process those provided by the user (based on
> optparse library from Python standard lib). The script then calls the
> corresponding command and provide the verified options as parameters.
>
> Due to the nature of the tool under specific conditions the following results
> may come during command execution:
> * successful execution, no interaction
> * critical error, execution cancelled
> * user interaction needed (e.g. prompt user to approve replace existing
> directory (yes/no), prompt user to provide an alternative option)
>
> Command-line interactions work simply with raw_input().
>
> So far this works. Nevertheless, there are some other aspects that could be
> improved, but this is another topic: The tool uses custom exceptions (e.g.
> for critical errors) and logging features (based on logging from Python
> standard lib). Currently no automated tests, but I have to add.
>
> For the next step I plan to support not only my own command-line scripts, but
> also a GUI to access the commands, as well as 3rd-party products (themselves
> command-line scripts or GUIs, such as foo plugins for any 3rd-party-tools). As
> far as I see, these clients need to implement a handler that:
> (1) Collecting all required parameters and optional parameters from a user
> (2) Provide these parameters for a particular call to command API
> (3) Provides some kind of hooks that are called back from the API on specific
> events, e.g. Question with user-choice; Information with user-input
> (4) Provide a logging handler object from the tool logging
> class or a sub-class of that in the case that a client-specific logging object
> should be triggered on each debug, message, warning etc.
>
> (1) is very client-specific, e.g. in a GUI via dialogs.
>
> (2) Each command provides a signature for all required/optional parameters.
> They are all verified from the command itself, although a client could do
> some verification at the first place.
>
> (3) Example use-case: a command needs to know if the user wants the command to
> proceed with a particular action, e.g. "Do you want to delete bar.txt?"
> with "Yes", "No" and "Cancel" choice. So the client's handler object (which
> is provided as first parameter to each command) implements client-specific
> features to show the user this question (e.g. pop-up dialog with question and
> three buttons), receive the user input (clicking one of the buttons) and pass
> this choice back to the foo API. Alternatively some kind of text information
> could be required, as in raw_input(), so actually this probably would be two
> different interaction features to be implemented.
>
> (4) The foo API also provides a logging class. The client needs to initialize
> such an object and provide it as member of the handler object provided to the
> API. I wonder if some clients may have own logging features and want to
> include all log messages from foo tool to the own logs. In this case a client
> could its own sub-class of the foo logging class and extending it with
> callbacks to its (client-)native logging object.
>
> What do you think about this?
>
> Best regards,
> Anastasios

I think if you want to use a GUI, wxpython or Tkinter would work well
for you. wxPython has more widgets from the start, but is also more
complex. Tkinter is good for quick and dirty GUIs, but gets
increasingly more complicated to deal with the more complex the GUI
has to be, in general. At least, that's what I am told.

I started out using Tkinter. It's great for prototyping, but I had to
port VBA code to a Python GUI and Tkinter just didn't have the widgets
I needed (including the the submodules PMW and Tix). So I went with
wxPython. I personally like it quite a bit. Plus you can use XRC with
wxPython to help separate out the GUI code from the logic.

Both toolkits can accept user input in myriads of ways and both have
standard dialogs that look almost or exactly native to the OS they are
running on. Download wxPython's demo to see all that it can do.
Tkinter is already installed and it has demos in its subdirectory
under Python.

There's my 2 cents.

Mike




More information about the Python-list mailing list