The PEAK Developers' Center   HelloWorld UserPreferences
 
HelpContents Search Diffs Info Edit Subscribe XML Print View
Version as of 2003-12-05 15:45:39

Clear message


There's a long tradition of teaching programmers how to use programming systems via "Hello, World!" examples. Why should PEAK be left out? I'm going to try to develop a series of stripped-to-the-essentials examples here that provide complete working PEAK programs that demonstrate some of the basic services provided by PEAK. Don't expect to find deep knowledge here, this article is intended to help you get over the first hump of using PEAK.

Oh, and this is oriented toward unix: the descriptions of how to actually run the programs probably won't work under Windows. Everything else, which is the bulk of the material, will apply equally well under Windows.

1 Basic Configuration

1.1 Introduction

At base, a PEAK program is a python program. PEAK is a toolkit and framework, which means it provides stuff you can use in your python programs to get things done more easily and more quickly, and usually more elegantly.

So, the simplist PEAK "Hello, world!" program is also, in a trivial sense, the python "Hello, world!" program:

 
    print "Hello, World!" 
 
This, however, is very uninteresting.

One of the things PEAK provides is a framework for creating application programs that have associated configuration information that they can access easily. The goal of this first chapter will be to show how to turn the output of the simple "Hello, world!" program into a configured string. I'm going to get us there step by step, keeping the program in a runable state at each step (except the first!)

1.2 Running helloworld under PEAK

Since we are using a configuration framework, our trivially simple python program needs to be complexified by adding a configuration file along side the python code file containing the actual print statement. That configuration file looks like this:

 
    [peak.running] 
 
    app = importString('helloworld:HelloWorld') 
 
What this is doing is defining a configuration item named peak.running.app, and setting it to the results of calling the PEAK importString function on the string helloworld:HelloWorld. The running module of PEAK provides various services for running application programs. To use the PEAK running framework, we'll use the peak command to invoke it, and pass it our helloworld configuration file. If we put the above text into a file named helloworld, we would call it using the peak command as follows:
 
    peak runIni helloworld 
 
At the moment, this will result in nothing but some error messages. To make a working application, we need to actually provide the pieces we have declared through the configuration file.

The peak runIni command expects the peak.running.app configuration variable to point to a python object that provides one of several possible Interfaces. The simplist Interface an app object can provide is just to be callable with no parameters.

So, our helloworld.py file needs to contain a python object that when called with no parameters prints "Hello, world!". That's simple enough to arrange, and hardly more complicated than the trivial python "Hello, world" example:

 
    def HelloWorld(): 
        print "Hello, world!" 
 
Our PEAK application is now runnable.

The importString function acts like a python import statement, with the : replacing the import in the from form. The importString line of the config file show above is equivalent to the following python:

 
    from helloworld import HelloWorld as app 
 
You will note that because we are using an import statement, the module we are importing from is going to have to be on the PYTHONPATH. If we've got our two files (helloworld and helloworld.py) in the current directory, we can execute this working PEAK program as follows:
 
    PYTHONPATH=. peak runIni helloworld 
 
Just as a side note, if a basic (callable) app object like this returns a value, that value has significance. If the value is an integer, it will be used as the return code from the peak command. If it is not an integer, it will be echoed to the terminal, and 1 will be used as the return code from the peak command.

1.3 Execution via Command Name

The configuration file for a complex application is central to that application. Under unix, PEAK allows configuration files to be the "executable" file of the application, the file whose name is entered at the console to invoke the program. We do this using the "magic cookie" of the unix shell:

 
    #!/usr/bin/env peak runIni 
 
    [peak.running] 
 
    app = importString('helloworld:HellowWorld') 
 
This uses the unix utility env to find the peak command in the current PATH, and calls it. peak then parses the file just like it does when called via peak runIni [file] from the command line.

PEAK is still looking for the modules to import in the PYTHONPATH, though, so you have to call this helloworld like this:

 
    PYTHONPATH=. ./helloworld 
 
Don't forget to chown +x helloworld first.

In a real application, you could arrange for your modules to be in a package on the system PYTHONPATH, thus enabling your command to simply be called by name.

If you can't arrange for the package to be on the system PYTHONPATH, or you don't want it to be there, you can instead write a little shell script. In this case you'd probably call the config file helloworld.ini. If helloworld.ini and helloworld.py are in the same directory as the helloworld script, the script might look like this:

 
    #!/bin/sh 
    here=`dirname $0` 
    PYTHONPATH=$here peak runIni $here/helloworld.ini 
 
Of course, in a real app you'd probably put the script in your /usr/local/bin directory or equivalent and the module files in some special directory, and replace here with the actual path to those module files.

1.4 Application Configuration

Now we'll move the string our helloworld is going to print out into the configuration file. The configration file follows ini format, which means you have "sections" in square brackets followed by lines that set values for various names within the section. PEAK doesn't place any restrictions on what sections or names can appear in an ini file, so we can pretty much choose whatever section name and variable names we want.

We'll be very unoriginal and call our configuration section helloworld. The text of our message will be placed in the message configuration variable:

 
    #!/usr/bin/env peak runIni 
 
    [peak.running] 
 
    app = importString('helloworld:HellowWorld') 
 
    [helloworld] 
 
    message = "Hello, world!" 
 
At this point you could run helloworld again, and nothing would have changed. PEAK will have loaded the new configuration information we provided, but our program doesn't yet actually use that information.

To use the configuration information we need to obtain it from the PEAK framework. At this point we are actually starting to use PEAK facilities directly in our python code, so we'll need to get them out of the PEAK package. PEAK provides a simple way to access the vast majority of the PEAK facilities through its api module:

 
    from peak.api import * 
 
This will load into the local namespace a minimal set of names through which the PEAK framework can be accessed. It uses a lazy import mechanism, so ultimately your program will only end up loading into memory those PEAK facilities it actually uses.

In addition, we can no longer use a simple, dumb executable object as our app object. In order to access the configuration information, the app object must participate in the framework.

In this case, the framework for a simple command line command such as our helloworld is provided by the AbstractCommand class of the PEAK running.commands module:

 
    class HelloWorld(running.commands.AbstractCommand): 
 
An Abstract class is a superclass that cannot be used by itself. To be used, it must be subclassed and certain abstract methods overridden with "real" code in the concrete subclass.

In the case of AbstractCommand, there is only one method we need to define, the _run command, which should do the actual work of our application. So, without getting into the configurability yet, our complete helloworld.py file would now look like this:

 
    from peak.api import * 
 
    class HelloWorld(running.commands.AbstractCommand): 
 
        def _run(self): 
            print "Hello, world!" 
 
So, again, we can run our program at this point and get the same results as before. But we still haven't used the configuration information. To do that, we use the binding module.

The function of PEAK's binding module that we are interested in here is the Obtain function. Obtain, coupled with the ?PropertyName function, allows us to pull values out of the configuration file:

 
    message = binding.Obtain(PropertyName('helloworld.message')) 
 
Obtain can find things using mechanisms other than ?PropertyName, but ?PropertyName is the one we are interested in here. It takes as its argument the fully qualified property name. By that I mean the name of the section the property is found in, followed by a dot, followed by the variable name. So our message property from our helloworld section becomes the ?PropertyName helloworld.message.

Now, in order for a binding to be found, Obtain must be called from within a *context* in which the binding is defined. The running component provides such a context, but it provides it to the instance object created from the ?AbstractCommand subclass. This means that our call to binding.Obtain will only work inside the class:

 
    from peak.api import * 
 
    class HelloWorld(running.commands.AbstractCommand): 
 
        message = binding.Obtain(PropertyName('helloworld.message')) 
 
        def _run(self): 
            print self.message 
 
With this version of helloworld.py we are finally using the configuration information provided in the helloworld file. To prove this, first run the helloworld command:
 
    PYTHONPATH=. ./helloworld 
 
Now copy helloworld to hellonewworld and edit it to look like this::

If you now run this new command:

 
    PYTHONPATH=. ./hellonewworld 
 
you'll be greated by our new message:
 
    Hello, new world! 
 
Although this is a very simple example, it should already be clear that PEAK provides an easy to use and powerful configuration mechanism. Simple ?PropertyNames and values provided in config files barely even scratch the surface of what PEAK can do, but even if you used nothing else PEAK would still be useful just for making it easy to write configurable python shell scripts!
PythonPowered
EditText of this page (last modified 2003-12-05 15:45:39)
FindPage by browsing, title search , text search or an index
Or try one of these actions: AttachFile, DeletePage, LikePages, LocalSiteMap, SpellCheck