how to start Crontab in Django Project locally? - python

I still pretty new to the use of crontab in Django. I have followed the instruction in this link https://hprog99.wordpress.com/2014/08/14/how-to-setup-django-cron-jobs/ to help me set up my method, my_scheduled_job() in cron.py file, which I want to call every five minutes.
Here is my updated setting.py
INSTALLED_APPS = (
'django_crontab',
...)
CRONJOBS = [
('*/5 * * * *', 'myproject.cron.my_scheduled_job')
]
After which I ran this: python manage.py crontab add
Output: adding cronjob: (d0428c9ae8227ed78b17bf32aca4bc67) -> ('*/5 * * * *', 'cinemas.cron.my_scheduled_job')
Next: Nothing happens.
How do I start this cron job locally? Is there a way to test if my job ran normally?

In django you can setup cron using django-chronograph or chronograph.
Django-chronograph is a simple application that allows you to control the frequency at which a Django management command gets run.
Step 1:
Create management command of your task in django. For creating django management command refer Writing custom django-admin commands.
Step 2:
After creating django management command configure command in cronograph.
Hope this helps you.

first, you must Specify your project profile, then add the cron job, if your project name is foo, then it is like:
export FOO_PROFILE = 'local'
python manage.py crontab add
and , before run above command, in your settings.local you should config cron environment first, something like:
# django-crontab config
CRONTAB_DJANGO_SETTINGS_MODULE = 'gold.settings.local'

Is there a test tab in Python? Probably a simulation somewhere to get tutorial. Try key word search in agent answer or similar help and command program.

python manage.py runserver
Once you start the server, crontab will automatically execute based on the time specified in settings.py.

Related

Calling Matlab scripts from Django with Python's Popen class

I'm developing a Django app which runs Matlab scripts with Python's Popen class. The python script that calls Matlab scripts lives in the main folder of my Django app (with views.py). When I call the script from command line, it runs like a charm but when I make a request from the client in order to run the corresponding python script, I receive the following warning:
"< M A T L A B (R) > Copyright 1984-2018 The MathWorks, Inc. R2018a (9.4.0.813654) 64-bit (glnxa64) February 23, 2018 To get started, type one of these: helpwin, helpdesk, or demo. For product information, visit www.mathworks.com. >> [Warning: Unable to create preferences folder in /var/www/.matlab/R2018a. Preferences folder location must be writable. Using a temporary preferences folder for this MATLAB session. See the preferences documentation for more details.] >>
My app uses a Python virtual environment and it is being deployed with Apache web server.
Here is my python script that calls Matlab scripts:
import os
import subprocess as sp
import pymat_config
def pymat_run():
pwd = pymat_config.pwd_config['pwd']
cmd1 = "-r \"Arg_in = '/path/to/my/main/folder/input.txt'; Arg_out = '/path/to/my/main/folder/file.txt'; matlab_script1\""
baseCmd1 = ['/usr/local/MATLAB/R2018a/bin/matlab', '-nodesktop', '-nosplash', '-nodisplay', 'nojvm', cmd1]
os.chdir('/path/to/matlab_script1')
sudo_cmd = sp.Popen(['echo', pwd], stdout=sp.PIPE)
exec1 = sp.Popen(['sudo', '-S'] + baseCmd1, stdin=sudo_cmd.stdout, stdout=sp.PIPE, stderr=sp.PIPE)
out, err = exec1.communicate()
return out
Any suggestions ?
Finally I managed to find the solution of that issue by myself. The problem came from the kind of user who called the Matlab's script. When I was running the above script from a Python interpreter or from the shell, it was the user (with the user password) who was running the script while when I was calling the script from the client the user was the web server's user: www-data.
So at first to avoid the above warning I gave permissions to www-data user to the /var/www folder with the following command:
sudo chown -R www-data /var/www/
After that, the "Warning" disappeared but the script still didn't run because it was asking for www-data's password internally and taking user's password from pymat_config file.
To solve this, I edited /etc/sudoers file in order for www-data to be able to call Matlab scripts without asking password. So I added the following line:
www-data ALL=(ALL) NOPASSWD: /usr/local/MATLAB/R2018a/bin/matlab
and now it runs like a charm !

Custom Django management command not running with crontab

I have an app in a django website that looks like in the tutorial of this page django_documentation and it runs very well if I run the command:
python manage.py closepoll.py
After I installed Crontab and I put it in INSTALLED APPS in settings.py file. Also I put this line in my settings.py file:
CRONJOBS = [
('*/5 * * * *', 'django.core.management.call_command', ['closepoll']),
]
To be able to run the script every 5 minutes. I add the cronjob through:
python manage.py crontab add
And it was added perfectly. After I restart the server but nothing is happening every 5 minutes. Do you know what I'm doing wrong?

Running a Python function from Ansible script

I have a Django project hosted on a remote server. This contains a file called tmp_file.py. There's a function called fetch_data() inside that file. Usually I follow the below approach to run that function.
# Inside Django Project
$ python manage.py shell
[Shell] from tmp_file import feth_data
[Shell] fetch_data()
Also the file doesn't contain __name__ section. So can't run as a stand alone script. What's the best way to perform this task using Ansible. I couldn't find anything useful from Ansible docs.
There's --command switch for shell django-admin command.
So you can try in Ansible:
- name: Fetch data
command: "django-admin shell --command='from tmp_file import feth_data; fetch_data()'"
args:
chdir: /path/to/tmp_file

Crontab fails to run django manage commands

I have written a script in django that send queued emails saved in the database to the users. There is a mangement command which should be called by crontab every hour to send the emails. However, whenever the crontab job get executed I receive the following error:
django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: libpq.so.5: cannot open shared object file: No such file or directory
My django app works fine without any error. But running crontab fails. The following is my crontab config:
0 * * * * source /opt/portal/virtEnv/bin/activate && python /opt/portal/websource/manage.py send_queued_messages --limit=1
Does anybody know how to solve the problem?
AFAIK you cant use the activate script in cronjob, just point it to the python interpreter which is in your virtualenv and it will work:
0 * * * * /opt/portal/virtEnv/bin/python /opt/portal/websource/manage.py send_queued_messages --limit=1
I found the solution.
I had to add LD_LIBRARY_PATH environment variable to the crontab configuration with the path pointing to the lib folder of postgres db.
Now it works smoothly.
try to point to python version inside virtualenv. Do not activate and use python.
Try this:
0 * * * * /opt/portal/virtEnv/bin/python /opt/portal/websource/manage.py send_queued_messages --limit=1
Edited: Removed 'source' at the beginning of the command.

Django App Install Script - How to add app to INSTALLED_APPS setting?

I've written a Django app, and now I want to make it easy to deploy on multiple servers.
The basic installation is:
Copy the app folder into the Django project folder
Add it to INSTALLED_APPS in settings.py
Run ./manage.py collectstatic
This particular app doesn't need to use the DB, but if it did, I'd use south and run ./manage.py migrate, but that's another story.
The part I'm having trouble with is #2. I don't want to have to manually edit this file every time. What's the easiest/most robust way to update that?
I was thinking I could use the inspect module to find the variable and then somehow append it, but I'm not having any luck. inspect.getsourcelines won't find variables.
You can modify your settings.py using bash.
#set $SETTINGS_FILE variable to full path of the your django project settings.py file
SETTINGS_FILE="/path/to/your/django/project/settings.py"
# checks that app $1 is in the django project settings file
is_app_in_django_settings() {
# checking that django project settings file exists
if [ ! -f $SETTINGS_FILE ]; then
echo "Error: The django project settings file '$SETTINGS_FILE' does not exist"
exit 1
fi
cat $SETTINGS_FILE | grep -Pzo "INSTALLED_APPS\s?=\s?\[[\s\w\.,']*$1[\s\w\.,']*\]\n?" > /dev/null 2>&1
# now $?=0 if app is in settings file
# $? not 0 otherwise
}
# adds app $1 to the django project settings
add_app2django_settings() {
is_app_in_django_settings $1
if [ $? -ne 0 ]; then
echo "Info. The app '$1' is not in the django project settings file '$SETTINGS_FILE'. Adding."
sed -i -e '1h;2,$H;$!d;g' -re "s/(INSTALLED_APPS\s?=\s?\[[\n '._a-zA-Z,]*)/\1 '$1',\n/g" $SETTINGS_FILE
# checking that app $1 successfully added to django project settings file
is_app_in_django_settings $1
if [ $? -ne 0 ]; then
echo "Error. Could not add the app '$1' to the django project settings file '$SETTINGS_FILE'. Add it manually, then run this script again."
exit 1
else
echo "Info. The app '$1' was successfully added to the django settings file '$SETTINGS_FILE'."
fi
else
echo "Info. The app '$1' is already in the django project settings file '$SETTINGS_FILE'"
fi
}
Use:
add_app2django_settings "my_app"
Here are my reasons why I think this would be wrong:
it is extra code complexity without any big need, adding one line to settings every time is not that bad, especially if you are doing step #1 and #3.
it will become not explicit what apps your project is using. When another developer will work on your project, he might not know that your app is installed.
you should do step #1 and step #2 on code versioning system, test the whole system and then commit the changes and just then deploy it.
I think you have something wrong (from my point of view) in your develop/deploy process if you are looking for such an "optimization". I think it is much easier and better to use INSTALLED_APPS.
If you are building something for public use and you want to make it as easy as possible to add modules then it would be nice. In this case I would recommend to package project and it's apps as python eggs and make use of entry points. Then you could deploy an app into project like this:
pip install my-app-name
Without even step #1 and #3! Step #1 will be done by pip, and step #2 and #3 will be done by setup hooks defined in your project.
Paste script is a good example of entry-points utilization:
# Install paste script:
pip install pastescript
# install django templates for pastescript:
pip install fez.djangoskel
# now paste script knows about fez.djangoskel because of entry-points
# start a new django project from fez's templates:
paste create -t django_buildout
Here is a portion of setup.py from fez.djangoskel package:
...
entry_points="""
[paste.paster_create_template]
django_buildout=fez.djangoskel.pastertemplates:DjangoBuildoutTemplate
django_app=fez.djangoskel.pastertemplates:DjangoAppTemplate
...
zc.buildout is another great tool which might make your deployments much easier. Python eggs plays very nice with buildout.

Categories

Resources