Python 3 script using libnotify fails as cron job
Question: I've got a Python 3 script that gets some JSON from a URL, processes it, and
notifies me if there's any significant changes to the data I get. I've tried
using [notify2](https://pypi.python.org/pypi/notify2) and
[PyGObject](https://live.gnome.org/PyGObject/)'s libnotify bindings
(gi.repository.Notify) and get similar results with either method. This script
works a-ok when I run it from a terminal, but chokes when cron tries to run
it.

    
    
    import notify2
    from gi.repository import Notify
    
    def notify_pygobject(new_stuff):
        Notify.init('My App')
        notify_str = '\n'.join(new_stuff)
        print(notify_str)
        popup = Notify.Notification.new('Hey! Listen!', notify_str,
                                        'dialog-information')
        popup.show()
    
    def notify_notify2(new_stuff):
        notify2.init('My App')
        notify_str = '\n'.join(new_stuff)
        print(notify_str)
        popup = notify2.Notification('Hey! Listen!', notify_str,
                                     'dialog-information')
        popup.show()
    

Now, if I create a script that calls `notify_pygobject` with a list of
strings, cron throws this error back at me via the mail spool:

    
    
    Traceback (most recent call last):
      File "/home/p0lar_bear/Documents/devel/notify-test/test1.py", line 3, in <module>
        main()
      File "/home/p0lar_bear/Documents/devel/notify-test/test1.py", line 4, in main
        testlib.notify(notify_projects)
      File "/home/p0lar_bear/Documents/devel/notify-test/testlib.py", line 8, in notify
        popup.show()
      File "/usr/lib/python3/dist-packages/gi/types.py", line 113, in function
        return info.invoke(*args, **kwargs)
    gi._glib.GError: Error spawning command line `dbus-launch --autolaunch=776643a88e264621544719c3519b8310 --binary-syntax --close-stderr': Child process exited with code 1
    

...and if I change it to call `notify_notify2()` instead:

    
    
    Traceback (most recent call last):
      File "/home/p0lar_bear/Documents/devel/notify-test/test2.py", line 3, in <module>
        main()
      File "/home/p0lar_bear/Documents/devel/notify-test/test2.py", line 4, in main
        testlib.notify(notify_projects)
      File "/home/p0lar_bear/Documents/devel/notify-test/testlib.py", line 13, in notify
        notify2.init('My App')
      File "/usr/lib/python3/dist-packages/notify2.py", line 93, in init
        bus = dbus.SessionBus(mainloop=mainloop)
      File "/usr/lib/python3/dist-packages/dbus/_dbus.py", line 211, in __new__
        mainloop=mainloop)
      File "/usr/lib/python3/dist-packages/dbus/_dbus.py", line 100, in __new__
        bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
      File "/usr/lib/python3/dist-packages/dbus/bus.py", line 122, in __new__
        bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
    dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
    

I did some research and saw suggestions to put a `PATH=` into my crontab, or
to export `$DISPLAY` (I did this within the script by calling
`os.system('export DISPLAY=:0')`) but neither resulted in any change...


Answer: You are in the right track. This behavior is because cron is run in a
multiuser headless environment (think of it as running as root in a terminal
without GUI, kinda), so he doesn't know to what display (X Window Server
session) and user target to. If your application open, for example, windows or
notification to some user desktop, then this problems is raised.

I suppose you edit your cron with `crontab -e` and the entry looks like this:

`m h dom mon dow command`

Something like:

`0 5 * * 1 /usr/bin/python /home/foo/myscript.py`

Note that I use full path to Python, is better if this kind of situation where
PATH environment variable could be different.

Then just change to:

`0 5 * * 1 export DISPLAY=:0 && /usr/bin/python /home/foo/myscript.py`

If this still doesn't work you need to allow your user to control the X
Windows server:

Add to your `.bash_rc`:

`xhost +si:localuser:$(whoami)`

