20

I am very new to python as well as MAC OSX. For my academic project I need to download a bunch of tweets from twitter using twitter streaming API. I need to download atleast 5000000 tweets. So I have written a python script and placed it in start-up. "System Preference -> Users and Groups -> Login items" and added my script there. But I see that the script is not executed when I login to the system ! Please help me resolve this issue.

Matthias Winkelmann
  • 15,870
  • 7
  • 64
  • 76
whitetiger
  • 412
  • 1
  • 4
  • 13

4 Answers4

15

Adapt the following accordingly, name it something like myscript_launcher.plist, and put it in either one of three locations: /System/Library/LaunchAgents, /System/Library/LaunchDaemons, /Users/<username>/Library/LaunchAgents.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>my.python.script.name</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>

Also, let's assume you put the plist file in ~/Library/LaunchAgents. You can start and stop it with the launchctl. To start, use launchctl load ~/Library/LaunchAgents/myscript_launcher.plist. To stop it, do the same but use the unload argument

Tommy
  • 580
  • 4
  • 7
  • 1
    thanks for the answer. This is the right way to solve the problem. – whitetiger Apr 22 '15 at 17:56
  • 7
    I'm not sure if this changed on OS X Yosemite or if I had Linux on the brain when I wrote this, but to load and unload a plist you use `launchctl` rather than `initctl`. Again, it may have been `initctl` pre Yosemite, but if that fails then use `launchctl`. – Tommy May 08 '15 at 22:18
  • Unless you have SIP turned off, the `/System` directories are no longer an option. Best to use `~/Library/LaunchAgents` or `/Library/LaunchAgents`. Still working for me on 10.15.6. – Tommy Aug 17 '20 at 18:41
  • I have tried above script with launchctl it was working but in order to load it after boot-up i need to put it into LaunchAgents compulsory. – Enginerd Sunio Sep 15 '21 at 12:22
7

You need to create a shell file that launches your python code. Tell the shell script to start at log in.

example

#!/bin/bash
python username/Desktop/startupscripts/file.py

save the file with the .sh extension.

add the .sh file to "System Preference -> Users and Groups -> Login items", the .sh script will call the python file.

This is what you should have in the shell file. I'm assume this is the path to the file, if it isn't modify it.

#!/bin/bash
python /Users/username/moviebuzz-api/flask/bin/streaming_movies.py

nothing else.

reticentroot
  • 3,612
  • 2
  • 22
  • 39
  • 1
    when I try this method, system is not executing the script ! It just opens the file in the default editor of shell scripts..that is xcode in my case ! – whitetiger Mar 30 '15 at 04:28
  • 1
    Right click, get info, set open with to terminal. – reticentroot Mar 30 '15 at 04:29
  • 1
    Also, if this answer is to your satisfaction, then it is proper etiquette to select an answer as being the correct answer. – reticentroot Mar 30 '15 at 04:34
  • thanks for your answer. But when I choose "Terminal" as the application to open the script, it is getting started at the login...but terminal shows that it is starting the script...but the script is not executed...and then shows just "exit". – whitetiger Mar 30 '15 at 18:00
  • 1
    Make sure that the shell file and python file are in the same directory. – reticentroot Mar 30 '15 at 18:05
  • 1
    In terminal you may have to make sure both files have execute permissions. Open up terminal, type chmod +x pathtofile, do this for both the shell script and python script – reticentroot Mar 30 '15 at 18:09
  • yes, both the files are given executable permission ! – whitetiger Mar 30 '15 at 19:28
  • Then as log as you typed in the path to your python file correctly, the entire path. It should work. I use this method all the time. – reticentroot Mar 30 '15 at 20:38
  • To be very clear. The path to your python file must the the file's absolute path for your local username. If you do not know how to find that path. Open up terminal and drag and drop your python file inside the window. Terminal will automatically generate the absolute path. – reticentroot Mar 30 '15 at 21:05
  • Example. /username/Desktop/startupscripts/file.py. The reason why you need to use the absolute path is because when python opens up it opens in the local username directory, not the location of your file. You must tell terminal exactly where that file lives. – reticentroot Mar 30 '15 at 21:07
  • I have used absolute path of python in my script ! – whitetiger Mar 31 '15 at 00:55
  • my shell script looks like `code` #! /bin/bash cd /Users/username/moviebuzz-api/ /Users/username/moviebuzz-api/flask/bin/python streaming_movies.py – whitetiger Mar 31 '15 at 01:03
  • It should look like the example above. Until you get more comfortable with bash you shouldn't make it so complicated. Typing the words python followed by the script path is more then enough, you're trying to execute multiple commands which requires a semicolon to separate statements. – reticentroot Mar 31 '15 at 01:06
  • thank you very much @hrand . Now the script is working. Your suggestion helped me... – whitetiger Mar 31 '15 at 01:19
2

But I see that the script is not executed when I login to the system !

The problem is, .py files are usually opened by some text editor by default. In order to execute the script as Login Items, you need to make the script to be opened by Terminal.app (or anything execute the script) by default.

After that, you cat set the script as Login Items in the way you posted.


How to set Terminal.app as default:

  1. Put a #! line on the top of the script:
#!/usr/bin/env python3

print("hello world")
  1. Add execute permission to the script:
chmod u+x script.py
  1. Change the file extension .py to .command (to associate the file with Terminal.app):
mv script.py script.command

At this point, you should be able to run the script by double clicking on Finder.
If you can not, try the following:

  1. Right click on the script file on Finder.
  2. Select Get Info
  3. Click the dropdown of Open with: option.
  4. Select Terminal.app

By the way, the above applies to not only python, but other scripts such as bash.

For example of bash, change !# like so:

#!/usr/bin/env bash
catwith
  • 875
  • 10
  • 13
1

Here's the full solution I am using on Mojave:

Plist: ~/Library/LaunchAgents/play.with.mpv.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/Users/e/Library/Python/3.7/bin:/usr/local/bin</string>
    </dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>play.with.mpv</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/python3</string>
        <string>/Users/e/Library/Python/3.7/bin/play-with-mpv</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/tmp/play.with.mpv.stderr</string>
    <key>StandardOutPath</key>
    <string>/tmp/play.with.mpv.stdout</string>
</dict>
</plist>

Mind the PATH to python3 - find it with which python3 and the play-with-mpv python script!

Load plist:

launchctl load ~/Library/LaunchAgents/play.with.mpv.plist

If your video is dropping frames as hell, create mpv config in ~/.config/mpv/mpv.conf and put there this:

video-sync=display-resample

if that do doesn't help, try this instead

opengl-early-flush=no
5ulo
  • 749
  • 1
  • 8
  • 21