I’ve been working my way through 100 days of Code Python Pro bootcamp on Udemy. After 40 days of coursework I’m starting to recognize what various code examples are doing, but I’m still not writing much code from scratch.

To that point, I wanted a bit of code a couple of weeks ago to parse the online Fedora release.json and produce a simple “this is the latest stable version” output. Better yet, I wanted it to send an email to me if the version had changed so I’d be notified to perform an upgrade.

This was borne out of a sort of necessity. Fedora still cannot perform major release automated upgrades such as between version 43 and version 44. And I have found that I simply don’t see the notices on their web page regarding new releases: I don’t visit the Fedora site very frequently. So what I wanted was something to automate at least the notification part of the the release process. If I’m aware of the new release I can maybe do something about it.

I didn’t create this code myself. I used Google AI (the AI that is part of Google search) to produce a code sample that accomplished my objectives. It is fairly simple and, with a few weeks of the code bootcamp under my belt, I now understand most of what it is doing. I also took that code and used macOS ‘launchd’ to schedule it to execute each day reliably.

Why Google AI

Frankly, because it just worked. I entered a search prompt along the lines of “using python produce a script to parse Fedora’s release.json and send me an email if the version has changed”. I received example code including a bit of an explanation of what the code was doing. Even before my introduction to Python coding I was able to see that the sample made “sense” and with a bit of manipulation I got it to work from the command line.

I wanted something that worked and I wasn’t too concerned about whether AI was involved or not. As it turned out, Google AI met the need, and I don’t feel particularly guilty for using it.

Why Launchd

I wanted to schedule my script to run once a day and send myself an email if there was a new version of Fedora available. The script itself does the heavy lifting, and a scheduler would take care of the daily execution. Crontab would fit the need in Unix/Linux environments, but on macOS crontab is a bit unreliable. It doesn’t execute if the user is not active, and if the scheduled execution time is missed e.g.: because the lid on the laptop is closed then nothing happens.

Apple recommends using launchd for scheduling. Getting it set up is a more involved process involving use of .plist files and the launchctl executable to set up scheduled jobs.

The code and an overview of the process

The code for checking the fedora release and for doing this plus sending an email can be found in my FedoraLatestRelease repository on GitHub. There are three files in this repository of note

The setup process for ‘email_on_new_release.py‘ to schedule it with launchd on macOS is as follows:

Step 1: get the email_on_new_release.py code

Step 2: revise the code to point to .env and .fedora_latest_version files i.e. the CACHE_FILE and load_dotenv lines

# use an absolute path so that it will work reliably with scheduling
# revise path accordingly
CACHE_FILE = os.path.expanduser("/Users/kelly/.fedora_latest_version")

# dotenv used as PyCharm wasn't working reliably with .env files in the
# python environment itself.  Revise the folder path for your environment
load_dotenv(dotenv_path="/Users/kelly/PycharmProjects/FedoraLatestRelease/.env")

Step 2a: add values to the .env file of the form

GOOGLE_SENDER_EMAIL=somemail.gmail
GOOGLE_SENDER_PASSWORD=app pass code
RECEIVER_EMAIL=someemail.gmail

Step 3: create / revise a .plist file e.g.:

com.user.dailyfedorapython.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>
    <!-- 1. Unique identifier for the job -->
    <key>Label</key>
    <string>com.user.dailyfedorapython</string>

    <!-- 2. Execution commands: Path to python executable followed by path to script -->
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/python3</string
        <string>/Users/kelly/FedoraLatestRelease/email_on_new_release.py</string>
    </array>

    <!-- 3. Daily Schedule: Runs every day at 02:30 AM -->
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>2</integer>
        <key>Minute</key>
        <integer>30</integer>
    </dict>

    <!-- 4. Logging: Highly recommended to catch Python errors -->
    <key>StandardOutPath</key>
    <string>/tmp/com.user.dailyfedorapython.out</string>
    <key>StandardErrorPath</key>
    <string>/tmp/com.user.dailyfedorapython.err</string>

</dict>

</plist>

3a. revise the ProgramArguments stanza to reflect your correct Python and the full path to the email_on_new_release.py code

Step 4: ensure your chosen python has necessary dependencies e.g.: python-dotenv installed

Step 5: install the .plist for execution by Launchd

5a: move the plist file to ~/Library/LaunchAgents/

5b: install the plist with launchd: launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.user.dailyfedorapython.plist

5c: do a testrun: launchctl kickstart -k gui/$(id -u)/com.user.dailyfedorapython

  • note that the “com.user.dailyfedorapython” comes from the unique label identified in the .plist file

5d: check the .out files in the /tmp folder for any messages


Step 6: confirm that you get an email as expected

  • revise the value in .fedora_latest_version to something below the current stable release version
  • repeat step 5c and confirm that you get an email at the expected address
  • if this fails, check  your Google email and associated app password.  The password is an app password and requires special setup through Google’s UI

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.