So, the bad news is that PIL can't do that. I trhow a couple of ideas bellow, unfortunatelly none of which is straightforward.
GIMP (GNU Image Manipulation Program) does have an awesome "ligthning effects" plug-in,
GIMP is scriptable in Python, and it is possible to call teh plug-in paramtrically.
The drawback is that your plug-in has to urn from within GIMP's process. (So you'd either estart GIMP as a batch for a one time run, or have to design a server python plug-in that processes your images through the lightning effects plug-in)
Other optionn I ma familiar with also involves off-process rendering would be use POVRay: render your image as the pigment-map for a 1x1x0.1 plane slab and then you can place "real" light-sources around.
Another way is using OpenGL yourself - I browseddarond a bit, and maybe this "gloss" project can provide a way for you to use light sources without havign to descend into lowlevel opengl:
http://www.tuxradar.com/gloss
Or -- "fake" it with a rectangular grid of black and white rectangles that you combine with your through color multiplication.
This is the only way that would allow yiou to keep with PIL alone, but the "grid" lines are too visible, and I think that trying to smooth with blur would not cut it:
def fake_light(image, tilesize=50):
WIDTH, HEIGHT = i.size
for x in xrange(0, WIDTH, tilesize):
for y in xrange(0, HEIGHT, tilesize):
br = int(255 * (1 - x / float(WIDTH) * y /float(HEIGHT)))
tile = Image.new("RGBA", (tilesize, tilesize), (255,255,255,128))
image.paste((br,br,br), (x, y, x + tilesize, y + tilesize), mask=tile)