I have a Python script I want to run at startup and remain running continuously on a Mac. I believe the script is executing but it does not remain running.
The setup is a plist script loaded with launchctl to start a Python script on boot - which should remain running always.
The (always running) Python script uses the 'schedule' module which should execute a function at a specific time.
How can I make this script run for as long as the computer is on? Can I see it running somewhere?
Specifically: If I run just the Python script manually in a terminal it runs continuously, and executes the function at the specified time with schedule module.
If I have the plist script loading at startup the Python script is NOT executing the function at the specified time ALTHOUGH, if I change the Python script to execute the function ONE TIME the plist script will execute it on startup.
[In all code below change '/path/to' to your paths, and to your Mac's username, etc. if replicating.]
The plist script...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs$
<plist version="1.0">
<dict>
<key>Label</key>
<string>Run.The.FB.photoblast</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/python</string>
<string>/path/to/python/script.py</string>
</array>
<key>StandardErrorPath</key>
<string>/var/log/python_script.error</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
I save this file to
/Users/<user_name>/Library/LaunchAgents/FB_Photo_script_launcher.plist
and run...
sudo launchctl load -w /Users/<user_name>/Library/LaunchAgents/FB_Photo_script_launcher.plist
The Python script below should post a photo to a Facebook page at 1:00pm. (For my question the Python script can do anything measurable). Because of the 'while True' at the bottom this script should always be running and waiting for 'schedule.run_pending()' to fire.
import os
import time
import glob
import random
import facebook
import schedule
#wait 13 seconds to give the computer time to wake up
time.sleep(13)
def job():
allphotofiles = glob.glob('/users/<user_name>/documents/fbcal/photos/*.jpg')
one_photo = allphotofiles[random.randint(0, len(allphotofiles)-1)]
#one_photo = glob.glob(one_random + '/*.jpg')[0]
d = {
'Calg Big': 'FACEBOOK_PAGE_TOKEN'}
for i in d:
graph = facebook.GraphAPI(access_token=d[i], version='3.1')
graph.put_photo(image=open(one_photo, "rb"))
print(i)
os.rename(one_photo, '/users/<user_name>/documents/fbcal/used/'+one_photo[43:])
# job()
schedule.every().day.at("13:00").do(job())
while True:
schedule.run_pending()
time.sleep(1)
Thank you for reading this question. My situation is very convoluted. Maybe I need a whole other approach. I tried making an 'app' using Automator but that had several problems. Automator's version of Python couldn't import the Facebook SDK, my computers fans would run at full speed when I started the app manually or on startup. I couldn't figure out how to schedule it, and I already have the scheduling part taken care of in the Python script. I simply need the Python script to run on boot and never ever stop running. Is there another timer I can use to fire the script at the same time each day without using Automator?
I just removed the scheduling inside the Python script and set up the function to fire when the script is called. Then created a cron job to run every day at 2pm.
EDITOR=/usr/bin/nano crontab -e
0 14 * * * is everyday at 2pm
0 14 * * * /anaconda3/bin/python /Users/mycomputername/Documents/FBcal/s2cheduler.py >> ~/cron.log 2>&1