Automating Passport Appointment Checks

My partner recently needed to visit a very unwell family member overseas. But her current passport was about to expire, and we needed to renew it ASAP.

The UK Government website has a way to fast-track the process, but it’s near-impossible to actually secure a slot. The slots appear randomly throughout the day and disappear within a minute of being posted. In other words, it’s a game of Russian roulette with you constantly refreshing the page every half hour.

After about a day or two of trying, I figured this is exactly the kind of situation Python excels at.

The Goal

To automate checking for fast-track passport slots and notify us instantly with an email and an audible sound alert.

The Plan

Before doing something technical, I like to map out a workflow as it helps structure my approach. Here’s what it looked like:

Step 1: Setting Up

First, I imported these libraries:

  • ‘requests’ and ‘BeautifulSoup’ for web scraping.
  • ‘ctypes’ and ‘winsound’ to handle desktop notifications.
  • ‘smtplib’ and ’email’ to fire off email notifications.
import requests
from bs4 import BeautifulSoup
import time
import ctypes
import winsound
from time import sleep
from random import randint
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

Step 2: Configuration

Next, I configured various parameters to control the script’s behaviour. This included a random sleep timer (to avoid being blocked by the website for looking like we’re trying to DDoS it with too many requests), the government page URL (so it knows where to find the slots), and the sound alert duration and frequency (to make sure we hear it!).

duration = 1000
freq = 440
sleepTimer = randint(240, 420)
url = "https://www.passportappointment.service.gov.uk/messages/AppointmentsAvailability.html"

Step 3: Email Setup

Setting up the email aspect was pretty straightforward. I stored the sender and recipient email addresses and created a simple message template that spams “PASSPORT SLOT AVAILABLE!” to our inboxes.

email_user = 'xxx@gmail.com'
email_password = 'xxx'
email_send = 'xxx@gmail.com'
subject = 'Passport Slot Available!'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body = 'Fast-track passport slot available!'
msg.attach(MIMEText(body, 'plain'))

Step 4: Checking Slot Availability

The core function, availabilityChecker, fetches the webpage, parses it, and looks for specific text indicating no available appointments.

If appointments are available, it triggers the email, audible alert and pop-up notification. In other words, there’s no reason we should miss it.

def availabilityChecker():
    r = requests.get(url)
    soup = BeautifulSoup(r.content, "html.parser")
    if "Sorry, there are no available appointments" in soup.text:
        print("No appointments available")
    else:
        text = msg.as_string()
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.starttls()
        server.login(email_user, email_password)
        server.sendmail(email_user, email_send, text)
        server.quit()
        winsound.Beep(freq, duration)
        ctypes.windll.user32.MessageBoxW(0, "Appointments are available, book now!", "AvailabilityChecker", 1)

The email aspect is all handled within the script, but you’ll need to provide the correct port number for your email provider in order to set up the SMTP client session correctly. This is just so the email actually goes to the correct server, otherwise your notification will get lost in the ether.

Step 5: Keeping it Running

To keep the script running, I set up an infinite loop to keep checking for available slots at random intervals between 4 to 7 minutes until I decide to turn it off.

while True:
    availabilityChecker()
    sleep(sleepTimer)

The Results

After manually trying for days with no luck, this script helped us secure a slot within 3 hours! It’s not the prettiest code, but it worked…

If you find yourself doing something repetitive and thinking “there’s got to be a better way,”: there probably is – and it probably involves python.

more insights

Deploying AI

Some notes on AI deployment from Sol Rashidi’s book ‘Your AI Survival Guide: Scraped Knees, Bruised Elbows, and Lessons Learned from Real-World AI Deployments‘. She’s

Read more >

SQL Dump

Crib notes from when I used SQL to manage my online platform’s database. Focuses on the most practical 20% that delivers 80% of the results.

Read more >

Automating Construction News

Reading industry news is part of the job. But doing it manually every day—clicking headlines, skimming paragraphs, filtering out noise—is a time sink. So I

Read more >