Is there a way to prevent a computer running OS X from going to sleep from within a Python script?
-
Not a programming answer, but [Caffeine](https://itunes.apple.com/us/app/caffeine/id411246225) is a nice freeware app which stops your computer falling asleep when activated. – Alex Jan 08 '13 at 13:27
-
Thanks @Alex, I've come across several apps that do this, but doing it from inside the script would be cleaner... – christianbrodbeck Jan 08 '13 at 13:30
5 Answers
You can use the built-in caffeinate command.
subprocess.Popen('caffeinate')
This is how I use it:
import sys
import subprocess
if 'darwin' in sys.platform:
print('Running \'caffeinate\' on MacOSX to prevent the system from sleeping')
subprocess.Popen('caffeinate')
You can also run caffeinate
in an external terminal window and leave it open to achieve what the OP wants.
open a terminal
type
caffeinate
press
Enter
Once you have done this, your Mac will stay awake for as long as you leave the Terminal running.
You can minimize or hide it, and your Mac will not go to sleep until you use the keyboard shortcut Ctrl+C to interrupt the command.

- 1,226
- 14
- 28
Since OS 10.6, you have to make use of the IOPMAssertion family of functions, available in Cocoa. This is really well explained there.
Then, you will have to call it from Python. I'm not sure that there're already specific bindings for Cocoa in Python, but you can call Objective-C functions. It is really well described here.
-
So, that would involve using ctypes to implement listing 2 of [qa1340](http://developer.apple.com/library/mac/#qa/qa1340/_index.html)? Are there instructions for that? (E.g., how can I retrieve a value such as kIOPMAssertionTypeNoDisplaySleep?) – christianbrodbeck Jan 08 '13 at 18:02
There is a Python utility that illustrates how to raise the required assertions in Python directly: https://github.com/minrk/appnope

- 2,113
- 2
- 19
- 24
-
appnope is about preventing App Nap not system sleep. See: https://github.com/minrk/appnope/blob/daac76517da8aba6fd0614eb1ab37d9b8ee39633/appnope/_nope.py#L78 – UloPe Nov 06 '19 at 16:17
-
Just look a little further up in the code for the other constants – christianbrodbeck Nov 08 '19 at 00:53
-
Yes, the constants are there but the functionality is not exposed via the documented `nope()` API. – UloPe Nov 08 '19 at 08:48
Another alternative would be to run the below script with
python <location/of/my/script.py> <hour until I want the PC to be awake>
e.g.
python /Users/johndee/Downloads/keep_awake.py 18:30
The script, which is to be saved locally:
#!/usr/bin/env python3
import random
import sys
import time
from datetime import datetime
from tkinter import Tk
import pyautogui
CHECK_STATUS_ONCE_IN = 120
WAIT_FOR_POSITION_CHANGE = 10
def current_position():
tkinter = Tk()
return [tkinter.winfo_pointerx(), tkinter.winfo_pointery()]
def mouse_is_moving():
pos1 = current_position()
time.sleep(WAIT_FOR_POSITION_CHANGE)
pos2 = current_position()
return not pos1 == pos2
def keep_awake():
# Shake the mouse a lil bit
initial_x, initial_y = current_position()
try:
for _ in range(random.randint(1, 10)):
# Mouse
pyautogui.moveTo(random.randint(1, 1000), random.randint(1, 1000))
# Keys
pyautogui.press("shift")
# Restore controls
pyautogui.moveTo(initial_x, initial_y)
except pyautogui.FailSafeException as e:
print(e)
def inspect_activity_until(time_to_stop: datetime):
time_to_stop = datetime.now().replace(
hour=time_to_stop.hour, minute=time_to_stop.minute
)
while datetime.now() < time_to_stop:
if not mouse_is_moving():
keep_awake()
time.sleep(CHECK_STATUS_ONCE_IN)
print(f"Stopping at {datetime.now()}")
if __name__ == "__main__":
given_time = sys.argv[1]
date_time_obj = datetime.strptime(given_time, "%H:%M")
inspect_activity_until(date_time_obj)

- 49
- 1
- 5