Forums

How does executable file for periodic tasks should look like?

I'd like to ask you all to help me to understand the concept of what should be inside executable file to run periodic tasks. Say I got django project with tasks app inside among others apps. There is a tasks.py file inside the tasks app. Tasks.py file should check all main project's users registered and send email to them once a week. I hope that tasks.py should query all users just like doing it normally in models.py but I suppose that I should bind somehow tasks.py file with hole project to access project's data and functionalities because tasks.py file is running in some separation as lonely file. Correct me please if the concept is different. But if it looks like this more or less how should I set settings correctly. I saw that I should use settings.configure() or DJANGO_SETTINGS_MODULE. The second option should be made in $VIRTUALENV/bin as I suppose. If so, the tasks.py file should be run inside virtualenv? I don't think so. Could any good soul help me with that mess in my head, please?

The easiest is probably to write a management command and get it working from a console (have a look in the Django docs for the version you're using about how to do this). Then you can run the management command using the python that is in your virtualenv bin directory.

I created exectuable file which looks like this for now and works quite well, however need some polishing.

"# !/usr/local/bin/python3.4"
from django.conf import settings
import os, sys
project_path = "/path/to/project/"

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
sys.path.append(project_path)

os.chdir(project_path)

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

main code goes here

Hi Rafal,

Modern django versions suggest you use django.setup() to initialise a standalone script (that's probably currently happening as a side-effect of get_wsgi_application()). https://docs.djangoproject.com/en/1.9/topics/settings/#calling-django-setup-is-required-for-standalone-django-usage

If you can though, I'd definitely recommend trying to figure out how to use a management command. They're the recommended way to make executable things for django. https://docs.djangoproject.com/en/1.9/howto/custom-management-commands/

Thank you Harry. I really don't like "setup things" but it's all getting to be more logical for me each day I think of it and try different possibilities. Thanks for directing me.

Is it possible to write management command which runs virtualenv? I have standalone file which I use to run periodic task. But this file can not get access to django project because can't find some settings. Some settings are stored as environment variables and are set up by postactivate file of virtualenv. I think that when the standalone file will "magically" start this virtualenv environment variable will be "visible" for this file it should get the acess to django project. Am I correct? Can I go this way?

Hi Rafal,

The virtualenv postactivate script only gets run when you activate the script in Bash. To get it to work in a scheduled task, you'd need to use a bash command-line, something like this:

workon my-virtualenv && cd /home/rafal/my-project && python manage.py my_command

Does that make sense? Alternatively, you could source the postactivate script directly, and use the virtualenv python directly:

source /home/rafal/.virtualenvs/my-virtualenv/bin/postactivate && /home/rafal/.virtualenvs/bin/python /home/rafal/my_project/manage.py my_command

I haven't actually tested these solutions myself, but they should work -- let me know how you get on? I'll add some official documentation if we find a good solution...

I almost sure this one works at least

 source /home/RafalSzymanski/.virtualenvs/novenv/bin/postactivate && /home/RafalSzymanski/.virtualenvs/novenv/bin/python /home/RafalSzymanski/ab/manage.py task1

I tried different solutions but only this one works. I'm not sure because google blocked sending email form my second account but I think your command is good because google reacted.

thanks for sharing your findings!