Mailing List Archive

Why is CGI module so complicated?
I have been writing an application using the cgi module, and am somewhat
confused as to why data is returned in FieldStorage or MiniField storage
objects, why not just return it in a plain dictionary?

At the moment, lets say you want to access a CGI variable called "pie"
you need to use:

f = cgi.FieldStorage()
print f['pie'].value

But why not just:

f = cgi.FieldStorage()
print f['pie']

That way the FieldStorage object would be a true dictionary, and could
be used as, for example, a TemplateDocument's substitutions dictionary.

I would write a wrapper to get rid of all of the FieldStorage objects,
but I have almost finished my code :-(

Can anyone explain what the point of the FieldStorage and
MiniFieldStorage objects are?

Ian

--
Remove the "NOSPAM." from my email address before replying.
Why is CGI module so complicated? [ In reply to ]
Ian Clarke <I.Clarke@NOSPAM.strs.co.uk> wrote:
: I have been writing an application using the cgi module, and am somewhat
: confused as to why data is returned in FieldStorage or MiniField storage
: objects, why not just return it in a plain dictionary?

: At the moment, lets say you want to access a CGI variable called "pie"
: you need to use:

: f = cgi.FieldStorage()
: print f['pie'].value

: But why not just:

: f = cgi.FieldStorage()
: print f['pie']

: That way the FieldStorage object would be a true dictionary, and could
: be used as, for example, a TemplateDocument's substitutions dictionary.

: I would write a wrapper to get rid of all of the FieldStorage objects,
: but I have almost finished my code :-(

: Can anyone explain what the point of the FieldStorage and
: MiniFieldStorage objects are?

: Ian

Ian, please read my reply in the previous thread:
http://www.dejanews.com/getdoc.xp/AN=502365247

-Arcege
Why is CGI module so complicated? [ In reply to ]
> : Can anyone explain what the point of the FieldStorage and
> : MiniFieldStorage objects are?

> Ian, please read my reply in the previous thread:
> http://www.dejanews.com/getdoc.xp/AN=502365247

Well, unfortunately that link didn't work, but I managed to find the
comment I believe you are referring to, in which case I assume you were
indicating that the FieldStorage and MiniFieldStorage objects were used
for the case where a file upload is taking place.

I can't help but feel that this is not the best way. How about go with
the method I described in my first post (where cgi fields are returned
as the types that they actually are, rather than being encased in
MiniFieldStorage objects). Were more than one item is selected for a
given field a list could be returned, and for a file upload a tuple
could be returned containing the filename and the contents of the file -
or if that is not considered extendable enough, a CGIFileUpload object
could be returned containing the necessary fields.

This would mean that for the vast majority of CGI fields which are just
normal text, retrieval is very straight-forward and intuitive, just like
accessing strings stored in a dictionary. More complexity is only
introduced when the user wants to do more complicated stuff (and even
then, it is pretty simple). As mentioned in my previous post, it would
also allow the fields to be used as the substitutions for a
TemplateDocument directly, which can be quite a useful trick.

If I get some spare time today I will create a small module which will
provide this interface to CGI (although if anyone else wants to do it,
feel free!). It would obviously be better if (assuming I can convince
others that this is a better way) this was integrated into the built-in
cgi module.

Ian.
Why is CGI module so complicated? [ In reply to ]
"Michael P. Reilly" <arcege@shore.net> writes:

>
> Ian, please read my reply in the previous thread:
> http://www.dejanews.com/getdoc.xp/AN=502365247

Invalid reference... Which article are you talking about? (I'm
interested in an explanation too... :)

>
> -Arcege
>

--

Magnus Making no sound / Yet smouldering with passion
Lie The firefly is still sadder / Than the moaning insect
Hetland : Minamoto Shigeyuki
Why is CGI module so complicated? [ In reply to ]
Ian Clarke <I.Clarke@strs.co.uk> wrote:

:> : Can anyone explain what the point of the FieldStorage and
:> : MiniFieldStorage objects are?

:> Ian, please read my reply in the previous thread:
:> http://www.dejanews.com/getdoc.xp/AN=502365247

: Well, unfortunately that link didn't work, but I managed to find the
: comment I believe you are referring to, in which case I assume you were
: indicating that the FieldStorage and MiniFieldStorage objects were used
: for the case where a file upload is taking place.

Nasty, dejanews changed the article number on me (I tested this with
lynx before I posted my article). But yes, that is the article.

The _exact_ URL that I have this morning (8-11-99 11:52EDT) is:
http://x21.deja.com/getdoc.xp?AN=511078528&CONTEXT=934386589.945881145&hitnum=0

: I can't help but feel that this is not the best way. How about go with
: the method I described in my first post (where cgi fields are returned
: as the types that they actually are, rather than being encased in
: MiniFieldStorage objects). Were more than one item is selected for a
: given field a list could be returned, and for a file upload a tuple
: could be returned containing the filename and the contents of the file -
: or if that is not considered extendable enough, a CGIFileUpload object
: could be returned containing the necessary fields.

I wondered why myself at first too, especially since a list is returned
instead of an object that looks like a list (with a value attribute),
when there are multiple fields returned (checkbuttons for example).

I usually have my own routine that converts the objects to a UserDict
(or a real dict) after I run them, unless I expect a file-upload in the
form. It's nothing major, but it helps. It's better to leave the
interface as it is (all fields return the same interface), I think it
works a little better in a HTML 4.0 view of the world.

: This would mean that for the vast majority of CGI fields which are just
: normal text, retrieval is very straight-forward and intuitive, just like
: accessing strings stored in a dictionary. More complexity is only
: introduced when the user wants to do more complicated stuff (and even
: then, it is pretty simple). As mentioned in my previous post, it would
: also allow the fields to be used as the substitutions for a
: TemplateDocument directly, which can be quite a useful trick.

There is a lot of information kept in the FieldStorage object which may
be desirable (like Content-Type parameters, Content-Length, etc.).
When using multipart/mixed instead of x-www-form-urlencoded, each field
(including non file-upload fields) can have these attributes. The
existing interface does not require a _lot_ of special coded to handle
the different cases in the CGI protocol.

: If I get some spare time today I will create a small module which will
: provide this interface to CGI (although if anyone else wants to do it,
: feel free!). It would obviously be better if (assuming I can convince
: others that this is a better way) this was integrated into the built-in
: cgi module.

I think the existing interface is fine, but a "simple" translater
around things might be good; something like:

def FieldStorage2Dict(form):
d = {}
def decode_field(field):
if isinstance(field, type([])):
return map(decode_field, field)
elif hasattr(field, "file") and field.file:
return (field.filename, field.file)
else:
return field.value
for key in form.keys():
d[key] = decode_field(form[key])
return d

What would be _really_ good (IMO) is to have a "toDict" method that
does this.

-Arcege
Why is CGI module so complicated? [ In reply to ]
What about simply adding a __str__ method to these objects?

That way for printing and '%s'%(object) substitution you get the "simple"
response of returning the (likely de-escaped) string value stored in the
field. Similarly, add a "list" method to get the values as a list (possibly
of length one) (is there a special method name that the built-in list
function calls? I could not find it.)

Disclaimer:
I do not use CGI at all anymore, no idea if this even make sense for
day-to-day operations.

Enjoy yourselves,
Mike


-----Original Message-----
From: python-list-request@cwi.nl [mailto:python-list-request@cwi.nl]On
Behalf Of Michael P. Reilly
Sent: August 10, 1999 1:02 PM
To: python-list@cwi.nl
Subject: Re: Why is CGI module so complicated?


Ian Clarke <I.Clarke@NOSPAM.strs.co.uk> wrote:
: I have been writing an application using the cgi module, and am somewhat
: confused as to why data is returned in FieldStorage or MiniField storage
: objects, why not just return it in a plain dictionary?

: At the moment, lets say you want to access a CGI variable called "pie"
: you need to use:

: f = cgi.FieldStorage()
: print f['pie'].value

: But why not just:

: f = cgi.FieldStorage()
: print f['pie']

: That way the FieldStorage object would be a true dictionary, and could
: be used as, for example, a TemplateDocument's substitutions dictionary.

: I would write a wrapper to get rid of all of the FieldStorage objects,
: but I have almost finished my code :-(

: Can anyone explain what the point of the FieldStorage and
: MiniFieldStorage objects are?

: Ian

Ian, please read my reply in the previous thread:
http://www.dejanews.com/getdoc.xp/AN=502365247

-Arcege
Why is CGI module so complicated? [ In reply to ]
> What about simply adding a __str__ method to these objects?
> That way for printing and '%s'%(object) substitution you get the "simple"
> response of returning the (likely de-escaped) string value stored in the
> field. Similarly, add a "list" method to get the values as a list (possibly
> of length one) (is there a special method name that the built-in list
> function calls? I could not find it.)

I think this is an excellent idea... can anyone see any problems with
it?

I think what we are trying to do here is retain the flexibility of the
current method, but prevent the more sophisticated functionality from
making it more difficult to do simple stuff (like, access a text field).

Ian.
Why is CGI module so complicated? [ In reply to ]
Ian Clarke <I.Clarke@strs.co.uk> writes:

> > : Can anyone explain what the point of the FieldStorage and
> > : MiniFieldStorage objects are?

> How about go with
> the method I described in my first post (where cgi fields are returned
> as the types that they actually are, rather than being encased in
> MiniFieldStorage objects). Were more than one item is selected for a
> given field a list could be returned, and for a file upload a tuple
> could be returned containing the filename and the contents of the file -
> or if that is not considered extendable enough, a CGIFileUpload object
> could be returned containing the necessary fields.

Or just a File object... And then we could add a "name" attribute or
something to them... (Which would be empty in cases where the object
is not taken from a standard named file)... :)

> This would mean that for the vast majority of CGI fields which are just
> normal text, retrieval is very straight-forward and intuitive, just like
> accessing strings stored in a dictionary. More complexity is only
> introduced when the user wants to do more complicated stuff (and even
> then, it is pretty simple). As mentioned in my previous post, it would
> also allow the fields to be used as the substitutions for a
> TemplateDocument directly, which can be quite a useful trick.

Or - you could rewrite TemplateDocument to work with the CGI
classes... That would just be a matter of adding some code to
recognize whether it was a standard dictionary or not...

> If I get some spare time today I will create a small module which will
> provide this interface to CGI (although if anyone else wants to do it,
> feel free!). It would obviously be better if (assuming I can convince
> others that this is a better way) this was integrated into the built-in
> cgi module.

Well... I suspect it can be *very* small for simple applications (that
don't use file upload, the methods values() or items())...

----- simplecgi.py -----

import cgi, UserDict

class FieldStorage(userdict.UserDict):
def __init__(self):
self.data = cgi.FieldStorage()
def __getitem__(self, key): return self.data[key].value

------------------------

Or you *could* use the old classes, like FormContentDict that are
already defined (but deprecated).

>
> Ian.

--

Magnus Making no sound / Yet smouldering with passion
Lie The firefly is still sadder / Than the moaning insect
Hetland : Minamoto Shigeyuki
Why is CGI module so complicated? [ In reply to ]
"Michael P. Reilly" <arcege@shore.net> writes:

> Ian Clarke <I.Clarke@strs.co.uk> wrote:
[...]

>
> What would be _really_ good (IMO) is to have a "toDict" method that
> does this.

Why not just a factory function in the cgi module?

-----

import cgi

form = cgi.getFields() # Returns a dictionary version of FormStorage()

-----

To me, this would be intuitive... You wouldn't have to go through a
seemingly unnecessary class on the way.

>
> -Arcege
>

--

Magnus Making no sound / Yet smouldering with passion
Lie The firefly is still sadder / Than the moaning insect
Hetland : Minamoto Shigeyuki
Why is CGI module so complicated? [ In reply to ]
Magnus L. Hetland <mlh@idt.ntnu.no> wrote:
: "Michael P. Reilly" <arcege@shore.net> writes:

:> Ian Clarke <I.Clarke@strs.co.uk> wrote:
: [...]

:>
:> What would be _really_ good (IMO) is to have a "toDict" method that
:> does this.

: Why not just a factory function in the cgi module?

Because (IMO):

a. It would probably be better to have only one interface; especially
when that interface(s) is to instantiate the cgi input only once,
during a program. Remember that POST methods don't allow you to
recreate the form data a second time (it assumes standard input, which
is unseekable). This is a lamer reason than below, but clearer-cut
interfaces are part of what makes Python better than some other
languages (when it's set up like that :).

b. The method is more usable than a factory function called instead of
FieldStorage. You mention being able to use this with TemplateDocument
classes (in another article); what if you want to get access to ALL
the data, but also want to give a dictionary representation to some
other interface as well? The factory function returns the dict and
throws away the rest of the data, whereas creating the class preserves
all the data you need, keeping it available in your app, but also can
give the dictionary you need at other times.

BTW, I also like the idea of adding the __str__ method to
FieldStorage.

: Magnus Making no sound / Yet smouldering with passion
: Lie The firefly is still sadder / Than the moaning insect
: Hetland : Minamoto Shigeyuki

-Arcege