In the interest of fairness, I should point out that Python’s newer str.format method
could achieve much the same effect as the traditional % format expression used by this
script, and it provides specific syntax for referencing object attributes which to some
might seem more explicit than using dict keys:
>>> D = {'say': 5, 'get': 'shrubbery'}
>>> '%(say)s => %(get)s' % D # expression: key reference
'5 => shrubbery'
>>> '{say} => {get}'.format(**D) # method: key reference
'5 => shrubbery'
>>> from person import Person
>>> bob = Person('Bob', 35)
>>> '%(name)s, %(age)s' % bob.__dict__ # expression: __dict__ keys
'Bob, 35'
>>> '{0.name} => {0.age}'.format(bob) # method: attribute syntax
'Bob => 35'
Because we need to escape attribute values first, though, the format method call’s at-
tribute syntax can’t be used directly this way; the choice is really between both tech-
nique’s key reference syntax above. (At this writing, it’s not clear which formatting
technique may come to dominate, so we take liberties with using either in this book;
if one replaces the other altogether someday, you’ll want to go with the winner.)
In the interest of security, I also need to remind you one last time that the eval call used
in this script to convert inputs to Python objects is powerful, but not secure—it happily
runs any Python code, which can perform any system modifications that the script’s
process has permission to make. If you care, you’ll need to trust the input source, run
in a restricted environment, or use more focused input converters like int and float.
This is generally a larger concern in the Web world, where request strings might arrive
from arbitrary sources. Since we’re all friends here, though, we’ll ignore the threat.
Using the website
Despite the extra complexities of servers, directories, and strings, using the web inter-
face is as simple as using the GUI, and it has the added advantage of running on any
machine with a browser and Web connection. To fetch a record, fill in the Key field
and click Fetch; the script populates the page with field data grabbed from the corre-
sponding class instance in the shelve, as illustrated in Figure 1-15 for key bob.
Figure 1-15 shows what happens when the key comes from the posted form. As usual,
you can also invoke the CGI script by instead passing inputs on a query string at the
end of the URL; Figure 1-16 shows the reply we get when accessing a URL of the
following form:
http://localhost/cgi-bin/peoplecgi.py?action=Fetch&key=sue
64 | Chapter 1: A Sneak Preview