Python CGI contact forms

10 July 2007

zetact.py - module for making CGI contact form processors in Python

I have a little contact form processor that I use on my homepage. It works for me, so I thought I would share it, following the principles of open source; namely 'release early' and 'if in doubt share it anyway, someone might find it useful'.

Here is a simple example of the form in action. The files are here. You can also browse the code online here.

It should hopefully just make sense without the rest of this post, so feel free to go there now and play with it.

As I will explain below, this form is designed to be multi-layered, you can use it with no Python knowledge at all, or you can import it as a module from within other Python code.

A contact form with layers

If you clicked on one the above links to download or browse the files online, you might be asking what do all these files do?

Basically zetact.py is the main file. This module is used to make the contact form processors.

zetact.py has two parts to it. Firstly, there is a class called FormProcessor which can be used to make more advanced forms.

There is also a function called simpleform which is used by people who do not care about Python code and just want a form now. simplecontact.py is an example of using zetact.py via the simpleform function.

The html files are just stock files that you can use to test everything, there is a README file that explains this. There is also a COPYING file that is a licence (just in case zetact.py does get into a useful state one day).

Making it right

There is a saying that goes something like "make it work, then make it right, then make it fast". I hear Python people say it often but goes back much longer, and it seems to be attributed to Alan Kay, of Smalltalk fame, assuming it is not older than that.

I probably need to do some more "make it work" on my contact form processor as it currently is only tested on Linux and Apache, it may or may not work if you run it from a Windows server. There is a lot of course that can be done to "make it right". On the programming front, I am in the painting 'for granny' rather than for the 'for national gallery' category. It is a hobby, for the sake of art rather than profit.

There are also millions of free PHP contact forms out there that do the same job, and I know there are many other ways to make a contact form using Python (e.g. Django, Turbogears etc), these are often overkill when you just want to add contact form to a basic HTML site (see Web Design for the long tail).

One advantage of the CGI approach is that is has no dependencies beyond Python and Apache, many cheap shared hosting accounts have these and will not let you install any extra software outside of your directory.

Please do report back if you try to use it

So reports on whether it works for other people would be very helpful, so people who do not know any Python but need a contact form could still test it out on your website and tell me how it did.

If you know Python and are interested in the exciting topic of HTML forms then I would gladly accept your constructive comments or ideas about improvements. I'm sure the FormProcessor class is full of "make it work" and "make it right" issues. As I said, I wrote it for Apache and Linux, I have no idea what happens if you try to use it elsewhere (such as a Windows server or some trendy other httpd), so that would be fun to.

1 David Jones says...

This is a very minor niggle about your python code:

Whilst Python is an Iverson's convention language, it is more modern style to use 'return False' and 'return True' instead of 'return 0' and 'return 1'. Of course it's up to you what versions of Python to support, but True and False have been in since 2.3.

Posted at 1:04 p.m. on July 11, 2007


2 Zeth says...

Interesting stuff, niggle away,

Posted at 2:33 p.m. on July 11, 2007


3 David Jones says...

Well then, you ought to know about r-prefix strings; they're handy for regular expressions. I just realised that since this is a comment form for a blog I have no chance of getting the blackslashes correct. Shame, since the whole point of r-prefix strings is the backslashes. Anyway, go look them up. Basically an r-prefix string, r"like this", is a string literal with an r in front of it. In an ordinary string backslashes are special, in an r-prefix string they're not. This is useful for regular expressions because backslashes crop up a lot, and if you use an ordinary string for a regular expression you end up having to double all your backslashes. With a r-prefix string you can more or less just type in the regular expression as is.

You might know all this already because the only regular expression I saw in your code was copied from someone else.

Posted at 9:36 a.m. on July 12, 2007


4 David Jones says...

Well, buoyed up by your unceasing optimism in your blog software, here goes.

So imagine you want a regular expression that matches the string «a*». Because «*» is magic in regular expressions (it's the Kleene closure) you need to escape it with a backslash. The regular expression that matches it is «a*». When converted to an ordinary Python string you need to escape the backslash:

>>> re.search('a\\*', 'a*')
<_sre.SRE_Match object at 0x3bec8>

But if you use an r-prefix string, you don't need to escape the backslash, you can just use the RE directly:

>>> re.search(r'a\*', 'a*')
<_sre.SRE_Match object at 0x6d598>

This gets even more helpful if you happen to want to match a backslash with your regular expression:

>>> re.search('\\\\\\*', '\\*')
<_sre.SRE_Match object at 0x3bec8>
>>> re.search(r'\\\*', '\\*')
<_sre.SRE_Match object at 0x6d598>

Posted at 12:53 p.m. on July 12, 2007


5 David says...

Using SMTP to send the mail: is it a good idea if you are on shared hosting and have to include ID and password information in the script??

Posted at 7:31 p.m. on July 25, 2008


6 Jordan says...

Zeth attention! Your form, http://zeth.me.uk/contact/, is not working The explorer says connecting ..but nothing happens Sorry for my poor English: I am Spanish Regards

Posted at 1:15 p.m. on November 29, 2009


7 Zeth says...

Hi Jordan, yes that URL is gone now. I have a new contact form on this site.

Posted at 6:28 p.m. on November 29, 2009


What do you have to say?

Show Editing Help

About

Hello, my name is Zeth, I'll be your host here.

Command Line Warriors is about taking control of your own technology, it looks at our experiences of computing; especially using GNU/Linux, the Python programming language, the command-line and issues such as techno-ethics, best practices and whatever is cool now. If you take control of your technology then you are a Warrior too!

This site is your site too which means that you can contribute and get involved. You can leave comments using the facility provided. For me, the comments and discussions are by far the best part of the site. So please do have your say!

Latest Discussions

Zeth

November 29, 2009
Hi Jordan, yes that URL is gone now. I have a new contact form on this site.
Python CGI contact forms

Jordan

November 29, 2009
Zeth attention! Your form, http://zeth.me.uk/contact/, is not working The explorer says connecting ..but nothing happens Sorry for my poor English: I am Spanish Regards
Python CGI contact forms

Jordan

November 26, 2009
Sorry: tell me , not tellme (I'm spaniard) And http://zeth.me.uk/contact/ don't work
You got the touch, you got the power

David Jones

November 25, 2009
Your mad skillz are too l33t! for me. I specifically switched to Google Reader so that I could show people what blogs I read. But I couldn't work out how ...
How to find the fashionable blogs quickly

Brian R. Hickey

November 20, 2009
Symantec picked it up too.
How to bring down Internet Explorer with six words

Zeth

November 17, 2009
Thanks djm, I am the moose here. Christian, assuming one actually does Internationalise the countries, it should still work I guess, as the gettext stuff will happen before the list ...
Countries in Django

Phillip Temple

November 17, 2009
Good start, but: a) wouldn't I want None back rather than 'ZZ'? b) why not add a 'shortcut' boolean, then prepend flagged fields (plus usual '-----' separator) to the actual ...
Countries in Django

djm

November 17, 2009
Am I being a moose or did you mean: from whatever.countries import CountryField instead of from whatever.countries import CharField ? Good post though, cheers.
Countries in Django

Christian Joergensen

November 17, 2009
Wouldn't the ordering get messed up after i18n?
Countries in Django

Steve - Electronic Cigarettes Fan

November 17, 2009
Very well done. Is your blog just you writing? Nicely done, Steven.
Blogger vs Wordpress

vetetix

November 15, 2009
Sorry to bother you nearly two years after you wrote this blog article, but I can't manage to find how to modify an existing field. I am trying to change ...
Three Useful Python Bindings - ClamAV, Apt and Evolution

Manju

November 4, 2009
I am transferring some files using psftp to other device's FAT partition. But the filestamp of the file being transferred is modified to that of FAT device, after the transfer. ...
PuTTY Series: Using PSFTP

iki

November 2, 2009
or simpler: socket.gethostbyname_ex(socket.gethostname())[2]
How to find out your IP address in Python

iki

November 2, 2009
local_ip = set([ i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None) if i[0] == 2 ])
How to find out your IP address in Python

Fred

November 2, 2009
testing rst ------------- - point 1
An Introduction to ReStructuredText

Ano

October 27, 2009
"You simply found the license of the StumbleUpon Toolbar for Internet Explorer." That's possible. I've got some more interesting information to add. Firstly, go to this page: https://addons.mozilla.org/en-US/firefox/addon/138 - this ...
Are your Firefox extensions proprietary software?

Ken

October 21, 2009
Stumbled in here at lunch. This is the best find of the week. Thanks.
Three classic command line tips

Jim

October 19, 2009
Thanks for the rtsp:// post - that's something that has been bugging me for a while!
Three classic command line tips

Zeth

October 18, 2009
Thanks for the comments guys. Great to see the all the gang are still here!
Three classic command line tips

Bubba

October 18, 2009
Is there any way psftp can return the true transfer rates oberved during the actual transfer?
PuTTY Series: Using PSFTP