2

I want to make a simple python program to generate a captcha for a flask website. I can generate the image, but if I save it in for e.g. in /images/captcha_{id}.png ,then I would have tons of old Captchas as the website gets used.

I've tried to create a script that uses the sleep function to remove the old captchas every N time, but the problem is then, that I disable all the activity in the website for the N time.

The Captcha system is the following :

import secrets, string
from PIL import Image, ImageFont, ImageDraw

def gen_captcha(id):
    alpha = string.ascii_letters + string.digits
    captcha = "".join(secrets.choice(alpha) for i in range(8))

    img = Image.new("RGBA", (200,100), (3, 115, 252))
    font = ImageFont.truetype("arial.ttf",20)
    w,h = font.getsize(captcha)
    draw = ImageDraw.Draw(img)
    draw.text((50,50), captcha, font=font, fill=(255, 239, 0))

    img.save("captcha_{}.png".format(str(id))

    return captcha

The flask app basically requests an input and displays the captcha based on the given id, and then says if req_captcha == captcha: return "You solved the captcha" it also gives an error if you don't solve it.

What I would like to know, is if I can make a little script that runs as a background process that deletes my old captchas.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • You could use a counter that wraps around. Save the file to `image_{i}.png` where you get `i` from something like `itertools.cycle(range(10000))` and just have it overwrite the old captchas automatically. – Boris Verkhovskiy Oct 26 '19 at 23:04
  • You could use celery to schedule captcha deletion for a later time, every time you create a captcha. – Boris Verkhovskiy Oct 26 '19 at 23:07
  • The easiest would be to run a Cron job that periodically deleted all files older than X days, as per this question https://stackoverflow.com/q/13868821/3064538 – Boris Verkhovskiy Oct 26 '19 at 23:08

2 Answers2

0

I think what you're looking for is a cron job. Set one up to run a bash script that cleans up yesterdays captchas.

danwilson
  • 186
  • 1
  • 8
0

One of the possible approaches would be to use either the multiprocessing or threading modules available in Python. They're both quite similar in terms of API. I will base my answer on the multiprocessing approach, but you can yourself evaluate if the threaded approach suits your needs more. You can refer to this question as an example. Here's a sample implementation:

import os
import time
from multiprocessing import Process

def remove_old_captchas():
    if os.fork() != 0:
        return
    print('Running process to remove captchas every 5 seconds ...')
    while True:
        time.sleep(5)
        print("... Captcha removed")

if __name__ == '__main__':
    p = Process(target=remove_old_captchas)
    p.daemon = True
    p.start()
    p.join()
    print('Main code running as well ...')
    while True:
        time.sleep(1)
        print("... Request served")

In the output of that you can see the captchas being removed in a regular time interval:

Running process to remove captchas every 5 seconds ...
Main code running as well ...
... Request served
... Request served
... Request served
... Request served
... Captcha removed
... Request served
... Request served
... Request served
... Request served
... Request served
... Captcha removed
... Request served
... Request served
... Request served

In terms of design I would probably still go with a cron job like mentioned in another answer, but you asked about running a background task, so that would one possible answer. You may also like the subprocess module.

losik123
  • 580
  • 5
  • 20