Crontab Python Script not running - python

I know this question has been asked before but I still haven't been able to get it to work. My crontab file just has this:
0 5 * * * /home/harry/my_env/bin/python /home/harry/compile_stats/process_tonight.py
Here's what my process_tonight.py looks like:
import datetime
import sys
sys.path.append('/home/harry/compile_stats/')
import compile # Module in above path
print("Processing last night\n")
date = str(datetime.datetime.today().year) + "-" + str(datetime.datetime.today().month) + "-" + str(datetime.datetime.today().day-1)
compile.process(date, date)
This file works perfectly fine when I just run it regularly from the command line but doesn't work when I schedule it.
I also looked at my /var/log/syslog file and the task I'm looking to run isn't showing up there.
Any ideas?
EDIT:
The time it's set to run in my example (5 A.M) is just a random time to put in. It's not running for any time I put in there.
EDIT 2#:
As per user speedyturkey I simplified my python script to better diagnose the problem:
import datetime
#import sys
#sys.path.append('/home/harry/compile_stats/')
#import compile # Module in above path
print("Processing last night\n")
date = str(datetime.datetime.today().year) + "-" + str(datetime.datetime.today().month) + "-" + str(datetime.datetime.today().day-1)
#compile.process(date, date)
Nothing is happening so I guess the problem isn't with the import.

As per the comments, I believe the problem is in how you are calling the python script in the crontab. Run the exact command you've given crontab and fix any problems it returns.

Ok, I was able to get it to work by creating a specific cron file, putting the info and there and loading it in.
So process_tonight.cron contains this:
0 5 * * * /home/harry/my_env/bin/python /home/harry/compile_stats/process_tonight.py
And I just loaded it into crontab:
crontab process_tonight.cron
Not really sure why this works and the other way doesn't (maybe someone else has an idea).

Instead of trying to modify the path from within your python script, you could do something like:
cd /home/harry/compile_stats/ && ./process_tonight.py
which would make it easier to import compile correctly. Note that this would also require making process_tonight.py executable (chmod +x process_tonight.py) and adding a shebang pointing to your Python interpreter (I guess... #!/home/harry/my_env/bin/python).
EDIT in response to Edit #2 above:
It is actually not possible to tell if it is running from the code you have written - the print statements are not being redirected. I suggest changing the code to perform some kind of side effect that you can check. For example, import subprocess and then do (example):
subprocess.call("date > /home/harry/compile_stats/date.txt")
If the script is executed properly, it will redirect the output of date to the file specified.

I know it's a bit silly, but checking your system time/timezone might be helpfull )))
I set my job to run at 5AM and when I logged in at 8AM there was no result of my script. So I spent over 1 hour trying to figure out what's the problem before I noticed that system time is incorrect and 5AM haven't come yet.

Have you tried running it from a shell script? I was having the same issue with my python script. I ended up putting the command in a shell script and running that. It threw an error that the library wasn't imported, so I installed it with pip and the --user flag. Now cron runs the shell script no issues.

Related

Can't complete Cron Job when python code is embed (through reticulate) inside the R script

I've created an R script that first launches a python script through the py_run_file() function and then executes some R code. I need to schedule the launch of such script at a certain hour of the day, and hence I used the package cronR. Unfortunately, when I call the script function just as a cron job, the job freezes and doesn't end. Here's a reproducible example:
library(reticulate)
today <- Sys.Date()
use_python("~/miniconda3/bin/python3.8",
required = TRUE)
py_run_file("~/Desktop/test.py")
print(paste("End on the",
today))
This is the content of the test.py file:
print("python script!")
Do you have any suggestion? Thanks a lot for your help!
for some odd reason, whenever you run an R Cron Job using reticulate package, I figured after a lot of trial and error, we have to use it like this :
reticulate::use_python(python = '/usr/bin/python3', required = T)
reticulate::source_python("FULL_PATH_TO_PYTHON_FILE.py")
instead of importing the library using library(reticulate) this thing strangely works!

Run Python script from Ubuntu cronjob

I am trying to run a simple python script on a VM running Ubuntu 18 hosted on my Synology. The python script simply prints date and time in a file so I can check if it ran or not. It looks like this:
from datetime import datetime
with open('file.txt','a') as file:
file.write('Recorded at: %s\n' % datetime.now())
I made a cronjob that looks like this:
* * * * * /home/anaconda3/bin/python3.7 /home/Documents/crontest.py
I have tried many variations. For instance not writing 3.7 and just simply write 'python'. I tried the default python path /usr/bin/python3.7.
Furthermore I tried to ad the shebang #!/home/anaconda/bin/python3.7 to the script and leaving out the path in the cronjob.
It feels like I am missing something elementary here. I tried many options as posted on Stack and other forums, but none of the options seem to fix my problem.
Using relative links in python scripts is not allowed when running cronjobs. So it works when I write it like this:
from datetime import datetime
with open('/home/Documents/file.txt','a') as file:
file.write('Recorded at: %s\n' % datetime.now())
Furthermore, I used the wrong path to python. I wrote /python3.6 instead of /python3 which I found through typing
which python3
in terminal.

Python script hangs without throwing exception/error on Windows

There isn't a particular point in the script where it hangs (I've seen it getting stuck at random points in the script), so checking the logs didn't yield much insight. It doesn't even throw an exception or an error. It just keeps running while stuck.
I'm basically calling this python script from a powershell file (which later gets called by Task scheduler).
$python = "C:\Python34\python.exe"
$python_path = "C:\Source\main.py"
cd (split-path $python_path)
while($true)
{
& $python $python_path
}
Is there something I need to do to make sure it doesn't get stuck?
You Will have to do your path strings like this path ="c:\\test\\file"
Because it ignorer the first backslash

Running Another program from python

I want to call a program multiple times from a python code, and save the output of that program in a text file. My first problem right now is just calling the other code. I have to redirect to a different directory and call ./rank on output.txt. This is how Im trying to do it:
TheCommand = "~/src/rank-8-9-2011/rank output.txt"
os.system(TheCommand)
but im getting a parsing error.
[Parsing error on line ]Unknown error: 0
Im running python2.7 on Mac OS 10.5.8. Im not sure what the problem is. I also tried using subprocess:
subprocess.call(["~/src/rank-8-9-2011/rank", "output.txt"])
This does not find the directory (I have a feeling Im using the subprocess incorrectly), but I dont know what is wrong with the os.system.
the name of the program in the first argument to subprocess.Popen must not contain ~ as it doesn't pass the string to the shell for processing (which like always using parameterized queries in sql, protects one from string injection attacks, e.g. if instead of output.text one had ;rm -rf /, the system version would run rank and then run rm -rf . but the subprocess.Popen would only have rank open a file named ;rm -rf .), so one should expand it by calling os.path.expanduser:
subprocess.Popen([os.path.expanduser('~/src/rank-8-9-2011/rank'), "output.txt"])
although it is possible to turn shell processing on by passing shell=True, it is not recommended for the aforementioned reason.
you should try http://docs.python.org/library/os.path.html#os.path.expanduser
import os.path
subprocess.call([os.path.expanduser("~/src/rank-8-9-2011/rank"), "output.txt"])
I'm fairly certain your parsing error is coming from rank, not from your os.system command, as nothing there looks weird. What happens if you run rank manually?
subprocess seems to have a problem with '~', although I'm not immediately sure why. Put the full path and it should work (although you'll likely get that parsing error if it is indeed a problem with rank).

Parse a cron entry in Python

All. I am trying to find a python module that I can use to parse a cron entry and get the next time it will run. With perl I use the Schedule::Cron::Events module but I would like to convert to python. Thanks in advance.
The documentation for python-crontab is in docstrings in the source code, as is usual for python. You can also explore the documentation via the python interpreter with the built-in help() function. The full source for python-crontab is less than 500 lines anyway and is very readable.
Example from the source code:
from crontab import CronTab
tab = CronTab()
cron = tab.new(command='/usr/bin/echo')
cron.minute().during(5,50).every(5)
cron.hour().every(4)
cron2 = tab.new(command='/foo/bar',comment='SomeID')
cron2.every_reboot()
list = tab.find('bar')
cron3 = list[0]
cron3.clear()
cron3.minute().every(1)
print unicode(tab.render())
for cron4 in tab.find('echo'):
print cron4
for cron5 in tab:
print cron5
tab.remove_all('echo')
t.write()
I could be wrong but doesn't python crontab offer ways to read and write to crontab but nothing regarding parsing the crontab to determine the time until the next time a job will be run?
Take a look at python-crontab.

Categories

Resources