Python Central HubSign in

Automation and Scripting / Phase 5: GUI & System Control

Introduction to pyautogui

Control the mouse and keyboard to automate GUI tasks (carefully).

diagram a GUI script drives the whole machine, not just your program mermaid
pyautogui has no idea what it is clicking. It moves the real cursor and types into whatever has focus, so a window appearing at the wrong moment redirects the input somewhere unintended. Everything about writing these safely is about keeping a way to stop and never assuming what is on screen.

Warning

GUI automation can click/delete the wrong things.

  • keep failsafes
  • prefer APIs when possible

Basic controls

Python
import pyautogui
 
print(pyautogui.size())
print(pyautogui.position())

Failsafe

By default, moving the mouse to the top-left corner raises pyautogui.FailSafeException.

Keep it enabled.

What pyautogui is

pyautogui controls the mouse and keyboard, takes screenshots, and shows simple dialogs. Install it with pip install pyautogui. It works on Windows, macOS, and Linux, but with conditions: on macOS you must give your terminal or editor Accessibility (and Screen Recording) permission in System Settings, and on Linux it needs an X11 session, so it does not work under Wayland on many setups.

It sends input to the whole desktop. It has no idea which program or button it is affecting, and that is why this page begins with warnings. The rest of the section builds on the four groups of calls introduced here.

  • Screen: size(), position(), screenshot(), and the locate functions.
  • Mouse: moveTo, click, dragTo, scroll.
  • Keyboard: write, press, hotkey.
  • Dialogs: alert, confirm, prompt.

The three safety settings

Python
import pyautogui
 
pyautogui.FAILSAFE = True   # default: mouse to the top-left corner raises FailSafeException
pyautogui.PAUSE = 0.5       # default is 0.1: seconds to wait after every pyautogui call
 
width, height = pyautogui.size()
x, y = pyautogui.position()
print(f"screen {width}x{height}, mouse at ({x}, {y})")
 
try:
    pyautogui.moveTo(width // 2, height // 2, duration=1)
except pyautogui.FailSafeException:
    print("Stopped by the failsafe corner")

FAILSAFE is your emergency brake. A runaway script that is typing or clicking is hard to stop, because it also controls the mouse you would use to close it. Slamming the cursor into the corner stops it. Do not turn it off. PAUSE slows every call so that you can watch what is happening and the target program can keep up. Raise it while you develop, and lower it only when the script is proven.

Coordinates and scaling

The origin (0, 0) is the top-left, and y grows downwards. On displays with scaling (common on laptops), the numbers pyautogui uses may differ from what your screenshot shows, so always read positions from pyautogui itself, not from an image editor. Multiple monitors extend the coordinate space, and a monitor to the left of the primary one has negative x values.

Habits for writing these scripts

  1. Start with a countdown so you can put the right window in front.
  2. Check before acting. Confirm the window title or find the image, and stop if it is not there.
  3. Log each step, so you can see how far the script got.
  4. Keep scripts short. A long chain of blind clicks fails at step 40, and the rest happen in the wrong place.
  5. Use a test account or spare machine for the first runs.

Common mistakes

  • Turning off FAILSAFE to make a script "smoother".
  • Running on an unfocused window.
  • Ignoring OS permissions and wondering why nothing happens on macOS.
  • Building the script on one monitor setup and running on another.
  • Working on the computer while the script runs. Your own mouse and keyboard fight with it.

Check your understanding

quizCheck yourself
  1. What is the purpose of pyautogui.FAILSAFE?

    Show answer

    A — Moving the mouse to the top-left corner aborts the script — It raises FailSafeException when the cursor reaches the corner, which is the way to stop a runaway script that controls the mouse.

  2. What does pyautogui.PAUSE do?

    Show answer

    B — Adds a delay after every pyautogui call — PAUSE is a global delay after each call. It gives you time to watch and gives the target program time to react.

  3. Where is the pixel (0, 0)?

    Show answer

    C — The top-left corner of the primary screen — The origin is at the top-left, with x to the right and y downward.

Was this page helpful?

Let us know how we did