Run Jupyter Notebooks as a Service on macOS

I was looking for a way to run jupyer notebook without using a constantly open terminal or a screen session. On macOS there is a way to create services using a .plist file and the launchctl command.

Because I use different environments for all Python related stuff, it wasn’t immediately clear to me how to do this when I’ve installed Jupyter only in a pyenv. After some fiddling around, I finally solved it. The key was to set the working directory parameter to the directory in which the environment is loaded. In my case this is ~/notebooks where I automatically load the env by using a .python-version file.

Below you find the .plist file, that enables you to start/stop the notebook server using launchctl <start|stop> local.jupyter.notebook.

It assumes that you have a Python environenment in /Users/USERNAME/notebooks. So simply change it to your needs. Put the file into /Users/USERNAME/Library/LaunchAgents and call launchctl load PATH_TO_FILE once to load it. After this you can start/stop the service as described above.

<?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>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>local.jupyter.notebook</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/USERNAME/.pyenv/shims/jupyter</string>
        <string>notebook</string>
        <string>--notebook-dir</string>
        <string>/Users/USERNAME/notebooks</string>
        <string>--no-browser</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/Users/USERNAME/Library/LaunchAgents/jupyter-notebook.stderr</string>
    <key>StandardOutPath</key>
    <string>/Users/USERNAME/Library/LaunchAgents/jupyter-notebook.stdout</string>
    <key>WorkingDirectory</key>
    <string>/Users/USERNAME/notebooks</string>
</dict>
</plist>

 

Show Download and Upload speed on your LaMetric Time

Following a request at the LaMetric forum I wrote a small Python script for displaying your current download and upload speed  on a LaMetric Time. The script can run on your own laptop or server (preferred).

Basically you need to do two things:

  • Create an app for the LaMetric Time
  • run the script that performs the speed test and push the results to the device

1. Create an indicator app

This is quite an easy thing to do. You need an account for the LaMetric developer area (it’s free, so don’t worry). In the developer area you can create a new app – in this case select indicator application.

On the new page, you can create the layout of the app. You need two text frames, one for the download speed and one for the upload speed. Also choose an icon for each frame, I decided to use a green down and green up arrow. It’s important that you select “Push” so that you can send your information to the LaMetric Time.

My design looks like this, but I later decided to drop the “Mbit/s”. It made the text too long, which is ok, the text will scroll on the display, but it means you have to wait for the scrolling to end, before the next frame is displayed. Plus I know that it’s Mbit/s. I’m also thinking about dropping the “UL” and “DL” prefix, since the arrows give me enough information.

Next you need to enter some information about the app, that is displayed in the store. You nee an App name and a short description, also make sure to check the “Private app” field.

Click “Save” and the app is ready to be published. On the next page you will see the URLs and the access token that is needed to send data to the app. Copy the “Local Push URL” and “Access token”. You could also use the “Push URL” instead of the local one, but I prefer it that way. I find it unnecessary  to send the data from my server at home to the LaMetric servers from where it comes back to my LaMetric Time which stands 5m away from my server.

Hit “Publish” and after a few minutes you should get a mail telling you that your app is ready.

Now you can install the app on your LaMetric Time. The following four screenshots describe how to do this:

Now your LaMetric Time is ready to receive data.

2. Run the script periodically on your server to update the values

The script can be found on GitHub: lm_connection_speed – if you don’t know how to clone a repository, you can also directly download the files: Download

I recommend Python 3, but it should work (no guarantee) with Python 2. It has three dependencies (requests, json and speedtest-cli). Please make sure install those before running the script.

Open the connection_speed.py in an text editor and look for lines 21/22 and insert the access token and push url from above. Save the file and you are good to go.

If you remember I said that I don’t want to see the “Mbit/s” – if you want to see it, you need to change two more lines in the file:

dl_rate = "DL {:.2f}".format(DL / 1000 / 1000)
dl_icon = "i402"
ul_rate = "UL {:.2f}".format(UL / 1000 / 1000)
ul_icon = "i120"

needs to be:

dl_rate = "DL {:.2f} Mbit/s".format(DL / 1000 / 1000)
dl_icon = "i402"
ul_rate = "UL {:.2f} Mbit/s".format(UL / 1000 / 1000)
ul_icon = "i120"

Now you can run the script

python3 connection_speed.py

Have a look the remarks in the README and for running the script periodically please consult your preferred search engine.

Log your played iTunes tracks

A few days ago I was looking for a way to log all tracks that I listen to in iTunes. Something like Last.fm but that works local and for macOS. I did a quick search and couldn’t find anything (maybe there is something already). So I decided to built something simple on my own using AppleScript, which allows me to easily access the iTunes information I need.

Doing some research I found an article at Doug’s AppleScripts that described the problem I wanted to solve. Copy the code below in the Script Editor (or get from GitHub), change the path to the text file and save as an application and don’t forget to check the “Stay open after run handler”.

Save Dialog of Script Editor

Run the app and voilà! I haven’t looked into possibilities to hide the dock icon or anything else. And I guess you can run the code with some modifications as a shell script in the background. Maybe I’ll look into it later.

# based on http://dougscripts.com/itunes/itinfo/idle00.php

global latest_song

on run
	tell application "System Events"
		if not (exists process "iTunes") then return
	end tell
	
	set latest_song to ""
end run

on idle
	tell application "iTunes"
		try
			copy name of current track to current_tracks_name
			if current_tracks_name is not latest_song then
				copy current_tracks_name to latest_song
				copy artist of current track to current_track_artist
				set output to current_track_artist & " - " & latest_song
				set dateString to do shell script "date +'%Y-%m-%d %H:%M'"
				
				do shell script "echo " & dateString & " - " & output & " >> ~/Desktop/test.txt"
			end if
		on error
			return 20
		end try
		return 10
	end tell
end idle

LaMetric & local push

UPDATE: This doesn’t work with firmware 1.6.0 – see updated article here: LaMetric Firmware 1.6.0 and local push

With the latest firmware upgrade (1.50) the LaMetric finally got support for local push – allowing you to sent messages to the LaMetric without needing an internet connection. Because some people in the support forums asked how to use local push I decided to write a tutorial (I do this on OS X).

Continue reading “LaMetric & local push”