Python post osx notification
Question:
Using python I am wanting to post a message to the OSX Notification Center.
What library do I need to use? should i write a program in objective-c and then call that program from python?
update
How do I access the features of notification center for 10.9 such as the buttons and the text field?
Answers:
You should install terminal-notifier first with Ruby for example:
$ [sudo] gem install terminal-notifier
And then you can use this code:
import os
# The notifier function
def notify(title, subtitle, message):
t = '-title {!r}'.format(title)
s = '-subtitle {!r}'.format(subtitle)
m = '-message {!r}'.format(message)
os.system('terminal-notifier {}'.format(' '.join([m, t, s])))
# Calling the function
notify(title = 'A Real Notification',
subtitle = 'with python',
message = 'Hello, this is me, notifying you!')
And there you go:
For a Python only implementation, I’ve modified the code that someone posted as part of another related question, and is working well for me:
import mmap, os, re, sys
from PyObjCTools import AppHelper
import Foundation
import objc
import AppKit
import time
from threading import Timer
from datetime import datetime, date
# objc.setVerbose(1)
class MountainLionNotification(Foundation.NSObject):
# Based on http://stackoverflow.com/questions/12202983/working-with-mountain-lions-notification-center-using-pyobjc
def init(self):
self = super(MountainLionNotification, self).init()
if self is None: return None
# Get objc references to the classes we need.
self.NSUserNotification = objc.lookUpClass('NSUserNotification')
self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
return self
def clearNotifications(self):
"""Clear any displayed alerts we have posted. Requires Mavericks."""
NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
NSUserNotificationCenter.defaultUserNotificationCenter().removeAllDeliveredNotifications()
def notify(self, title, subtitle, text, url):
"""Create a user notification and display it."""
notification = self.NSUserNotification.alloc().init()
notification.setTitle_(str(title))
notification.setSubtitle_(str(subtitle))
notification.setInformativeText_(str(text))
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setHasActionButton_(True)
notification.setActionButtonTitle_("View")
notification.setUserInfo_({"action":"open_url", "value":url})
self.NSUserNotificationCenter.defaultUserNotificationCenter().setDelegate_(self)
self.NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
# Note that the notification center saves a *copy* of our object.
return notification
# We'll get this if the user clicked on the notification.
def userNotificationCenter_didActivateNotification_(self, center, notification):
"""Handler a user clicking on one of our posted notifications."""
userInfo = notification.userInfo()
if userInfo["action"] == "open_url":
import subprocess
# Open the log file with TextEdit.
subprocess.Popen(['open', "-e", userInfo["value"]])
You could likely clean up the import statements to remove some unneeded imports.
copy from: https://gist.github.com/baliw/4020619
following works for me.
import Foundation
import objc
import AppKit
import sys
NSUserNotification = objc.lookUpClass('NSUserNotification')
NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
def notify(title, subtitle, info_text, delay=0, sound=False, userInfo={}):
notification = NSUserNotification.alloc().init()
notification.setTitle_(title)
notification.setSubtitle_(subtitle)
notification.setInformativeText_(info_text)
notification.setUserInfo_(userInfo)
if sound:
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setDeliveryDate_(Foundation.NSDate.dateWithTimeInterval_sinceDate_(delay, Foundation.NSDate.date()))
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
notify("Test message", "Subtitle", "This message should appear instantly, with a sound", sound=True)
sys.stdout.write("Notification sent...n")
All the other answers here require third party libraries; this one doesn’t require anything. It just uses an apple script to create the notification:
import os
def notify(title, text):
os.system("""
osascript -e 'display notification "{}" with title "{}"'
""".format(text, title))
notify("Title", "Heres an alert")
Note that this example does not escape quotes, double quotes, or other special characters, so these characters will not work correctly in the text or title of the notification.
Update: This should work with any strings, no need to escape anything. It works by passing the raw strings as args to the apple script instead of trying to embed them in the text of the apple script program.
import subprocess
CMD = '''
on run argv
display notification (item 2 of argv) with title (item 1 of argv)
end run
'''
def notify(title, text):
subprocess.call(['osascript', '-e', CMD, title, text])
# Example uses:
notify("Title", "Heres an alert")
notify(r'Weird/|"!@#$%^&*()ntitle', r'!@#$%^&*()"')
Try ntfy if you also want the script to be able to communicate with you over other devices.
Installation
[sudo] pip install ntfy
where pip
refers to the Package Installer of the target Python version
For Python3 installation:
[sudo] pip3 install ntfy
Usage
I use this simple function for notifications regarding command executions and download completions:
def notification(title, message):
"""Notifies the logged in user about the download completion."""
import os
cmd = 'ntfy -t {0} send {1}'.format(title, message)
os.system(cmd)
notification("Download Complete", "Mr.RobotS01E05.mkv saved at /path")
Advantages of ntfy
-
This tool is quite handy as it logs all the notifications directly to the Notification Center rather than referring to other third-party application.
-
Multiple Backend supports: This tool can connect to you over any device through services such as PushBullet, SimplePush, Slack, Telegram etc. Check the entire list of supported backend services here.
Here is a way (You need the Foundation module):
from Foundation import NSUserNotification
from Foundation import NSUserNotificationCenter
from Foundation import NSUserNotificationDefaultSoundName
class Notification():
def notify(self, _title, _message, _sound = False):
self._title = _title
self._message = _message
self._sound = _sound
self.notification = NSUserNotification.alloc().init()
self.notification.setTitle_(self._title)
self.notification.setInformativeText_(self._message)
if self._sound == True:
self.notification.setSoundName_(NSUserNotificationDefaultSoundName)
center = NSUserNotificationCenter.defaultUserNotificationCenter()
center.deliverNotification_(self.notification)
N = Notification()
N.notify(_title="SOME", _message="Something", _sound=True)
This works only for MAC. Hope you enjoy!
Another choice is a python
lib named pync, maybe it’s a better choice. pync is a simple Python wrapper around the terminal-notifier
command-line tool, which allows you to send User Notifications to the Notification Center on Mac OS X 10.10, or higher.
Installation:
pip install pync
Examples:
from pync import Notifier
Notifier.notify('Hello World')
Notifier.notify('Hello World', title='Python')
Notifier.notify('Hello World', group=os.getpid())
Notifier.notify('Hello World', activate='com.apple.Safari')
Notifier.notify('Hello World', open='http://github.com/')
Notifier.notify('Hello World', execute='say "OMG"')
Notifier.remove(os.getpid())
Notifier.list(os.getpid())
I recommend using the new library macos-notifcations. It is a Python library to make it as easy as possible to create interactable notifications.
A simple example:
from mac_notifications import client
client.create_notification(
title="Meeting starts now!",
subtitle="Team Standup",
icon="/Users/jorrick/zoom.png",
action_button_str="Join zoom meeting",
action_button_callback=partial(join_zoom_meeting, conf_number=zoom_conf_number)
)
Features
- Easy python interface. It’s as simple as ‘client.create_notification(title="Meeting starts now!", subtitle="Team Standup")’
- Ability to add action buttons with callbacks!
- Ability to reply to notifications!
- ⌚ Delayed notifications.
- Just a single dependency on
pyobjc
.
Disclaimer: I am the creator of macos-notifications.
Using python I am wanting to post a message to the OSX Notification Center.
What library do I need to use? should i write a program in objective-c and then call that program from python?
update
How do I access the features of notification center for 10.9 such as the buttons and the text field?
You should install terminal-notifier first with Ruby for example:
$ [sudo] gem install terminal-notifier
And then you can use this code:
import os
# The notifier function
def notify(title, subtitle, message):
t = '-title {!r}'.format(title)
s = '-subtitle {!r}'.format(subtitle)
m = '-message {!r}'.format(message)
os.system('terminal-notifier {}'.format(' '.join([m, t, s])))
# Calling the function
notify(title = 'A Real Notification',
subtitle = 'with python',
message = 'Hello, this is me, notifying you!')
And there you go:
For a Python only implementation, I’ve modified the code that someone posted as part of another related question, and is working well for me:
import mmap, os, re, sys
from PyObjCTools import AppHelper
import Foundation
import objc
import AppKit
import time
from threading import Timer
from datetime import datetime, date
# objc.setVerbose(1)
class MountainLionNotification(Foundation.NSObject):
# Based on http://stackoverflow.com/questions/12202983/working-with-mountain-lions-notification-center-using-pyobjc
def init(self):
self = super(MountainLionNotification, self).init()
if self is None: return None
# Get objc references to the classes we need.
self.NSUserNotification = objc.lookUpClass('NSUserNotification')
self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
return self
def clearNotifications(self):
"""Clear any displayed alerts we have posted. Requires Mavericks."""
NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
NSUserNotificationCenter.defaultUserNotificationCenter().removeAllDeliveredNotifications()
def notify(self, title, subtitle, text, url):
"""Create a user notification and display it."""
notification = self.NSUserNotification.alloc().init()
notification.setTitle_(str(title))
notification.setSubtitle_(str(subtitle))
notification.setInformativeText_(str(text))
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setHasActionButton_(True)
notification.setActionButtonTitle_("View")
notification.setUserInfo_({"action":"open_url", "value":url})
self.NSUserNotificationCenter.defaultUserNotificationCenter().setDelegate_(self)
self.NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
# Note that the notification center saves a *copy* of our object.
return notification
# We'll get this if the user clicked on the notification.
def userNotificationCenter_didActivateNotification_(self, center, notification):
"""Handler a user clicking on one of our posted notifications."""
userInfo = notification.userInfo()
if userInfo["action"] == "open_url":
import subprocess
# Open the log file with TextEdit.
subprocess.Popen(['open', "-e", userInfo["value"]])
You could likely clean up the import statements to remove some unneeded imports.
copy from: https://gist.github.com/baliw/4020619
following works for me.
import Foundation
import objc
import AppKit
import sys
NSUserNotification = objc.lookUpClass('NSUserNotification')
NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
def notify(title, subtitle, info_text, delay=0, sound=False, userInfo={}):
notification = NSUserNotification.alloc().init()
notification.setTitle_(title)
notification.setSubtitle_(subtitle)
notification.setInformativeText_(info_text)
notification.setUserInfo_(userInfo)
if sound:
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setDeliveryDate_(Foundation.NSDate.dateWithTimeInterval_sinceDate_(delay, Foundation.NSDate.date()))
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
notify("Test message", "Subtitle", "This message should appear instantly, with a sound", sound=True)
sys.stdout.write("Notification sent...n")
All the other answers here require third party libraries; this one doesn’t require anything. It just uses an apple script to create the notification:
import os
def notify(title, text):
os.system("""
osascript -e 'display notification "{}" with title "{}"'
""".format(text, title))
notify("Title", "Heres an alert")
Note that this example does not escape quotes, double quotes, or other special characters, so these characters will not work correctly in the text or title of the notification.
Update: This should work with any strings, no need to escape anything. It works by passing the raw strings as args to the apple script instead of trying to embed them in the text of the apple script program.
import subprocess
CMD = '''
on run argv
display notification (item 2 of argv) with title (item 1 of argv)
end run
'''
def notify(title, text):
subprocess.call(['osascript', '-e', CMD, title, text])
# Example uses:
notify("Title", "Heres an alert")
notify(r'Weird/|"!@#$%^&*()ntitle', r'!@#$%^&*()"')
Try ntfy if you also want the script to be able to communicate with you over other devices.
Installation
[sudo] pip install ntfy
where pip
refers to the Package Installer of the target Python version
For Python3 installation:
[sudo] pip3 install ntfy
Usage
I use this simple function for notifications regarding command executions and download completions:
def notification(title, message):
"""Notifies the logged in user about the download completion."""
import os
cmd = 'ntfy -t {0} send {1}'.format(title, message)
os.system(cmd)
notification("Download Complete", "Mr.RobotS01E05.mkv saved at /path")
Advantages of ntfy
-
This tool is quite handy as it logs all the notifications directly to the Notification Center rather than referring to other third-party application.
-
Multiple Backend supports: This tool can connect to you over any device through services such as PushBullet, SimplePush, Slack, Telegram etc. Check the entire list of supported backend services here.
Here is a way (You need the Foundation module):
from Foundation import NSUserNotification
from Foundation import NSUserNotificationCenter
from Foundation import NSUserNotificationDefaultSoundName
class Notification():
def notify(self, _title, _message, _sound = False):
self._title = _title
self._message = _message
self._sound = _sound
self.notification = NSUserNotification.alloc().init()
self.notification.setTitle_(self._title)
self.notification.setInformativeText_(self._message)
if self._sound == True:
self.notification.setSoundName_(NSUserNotificationDefaultSoundName)
center = NSUserNotificationCenter.defaultUserNotificationCenter()
center.deliverNotification_(self.notification)
N = Notification()
N.notify(_title="SOME", _message="Something", _sound=True)
This works only for MAC. Hope you enjoy!
Another choice is a python
lib named pync, maybe it’s a better choice. pync is a simple Python wrapper around the terminal-notifier
command-line tool, which allows you to send User Notifications to the Notification Center on Mac OS X 10.10, or higher.
Installation:
pip install pync
Examples:
from pync import Notifier
Notifier.notify('Hello World')
Notifier.notify('Hello World', title='Python')
Notifier.notify('Hello World', group=os.getpid())
Notifier.notify('Hello World', activate='com.apple.Safari')
Notifier.notify('Hello World', open='http://github.com/')
Notifier.notify('Hello World', execute='say "OMG"')
Notifier.remove(os.getpid())
Notifier.list(os.getpid())
I recommend using the new library macos-notifcations. It is a Python library to make it as easy as possible to create interactable notifications.
A simple example:
from mac_notifications import client
client.create_notification(
title="Meeting starts now!",
subtitle="Team Standup",
icon="/Users/jorrick/zoom.png",
action_button_str="Join zoom meeting",
action_button_callback=partial(join_zoom_meeting, conf_number=zoom_conf_number)
)
Features
- Easy python interface. It’s as simple as ‘client.create_notification(title="Meeting starts now!", subtitle="Team Standup")’
- Ability to add action buttons with callbacks!
- Ability to reply to notifications!
- ⌚ Delayed notifications.
- Just a single dependency on
pyobjc
.
Disclaimer: I am the creator of macos-notifications.