I coded a basic captcha for my web.py form, here’s how:

First I made a function that generates an image and returns it + the code (yea it’s a mess).

import Image, ImageDraw, ImageFont, cStringIO, random

def getCaptcha():
    im = Image.new("RGB", (100, 60))
    draw = ImageDraw.Draw(im)

    for x in range(0, 100):
        for y in range(0, 60):
            draw.point((x, y), (135, 191, 107))

    font = ImageFont.truetype('cracked.ttf', 50)

    alphabet = 'abcdefghijklmnopqrstuvwxyz'

    word = ''
    for i in range(5):
        word = word + alphabet[random.randint(0, len(alphabet) -1)]

    draw.text((5, 5), word, font=font, fill=(0, 0, 0))

    f = cStringIO.StringIO()
    im.save(f, "GIF")
    f.seek(0)
    return word, f

Now here’s the corresponding web.py code:

urls = (
    ...
    '/captcha.gif', 'captcha'
)

if web.config.get('_session') is None:
    session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'captcha': ''})
    web.config._session = session
else:
    session = web.config._session

vcaptcha = form.Validator('Please enter the code',  lambda x:x == session.captcha)

enquiry_form = form.Form(
    ...
    form.Textbox("captcha", vcaptcha, description="Validation Code", pre="<img src='/captcha.gif' valign=center><br>", class_="standard", style="width:70px;"),
)

class captcha:
    def GET(self):
        web.header("Content-Type", "image/gif")
        captcha = getCaptcha()
        session.captcha = captcha[0]
        return captcha[1].read()

To make the form look prettier, I also modified web.py to give the table rows an id and then used CSS to alter their padding etc.

Sorry, I didn’t take much time over this post. Hopefully, the code will get you started though, Dave.