Skip to Content
Course content

257: The uuid Module for Unique Identifiers

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I'm currently working on a prototype for a distributed task queue—basically a system where multiple workers pick up jobs from a shared pool. My first instinct for tracking these jobs was the classic approach: an incrementing integer. job_1, job_2, and so on. It works great on a single machine, but the moment I tried to run three different worker scripts on three different servers, they all started trying to create job_1 at the same time. Total chaos.

The failure of simple counting

# My initial (and flawed) logic
job_ids = []

def create_job(name):
    job_id = len(job_ids) + 1
    job_ids.append(job_id)
    return f"job_{job_id}"

print(create_job("Email User")) # job_1
print(create_job("Clean Cache")) # job_2

If this code lives in one process, it's fine. But in a distributed system, there's no central "counter" without creating a massive bottleneck. I could use a database sequence, sure, but that means every single job creation requires a network round-trip to the DB just to get an ID. That's slow. I need a way to generate an ID that is practically guaranteed to be unique, even if the generator has no idea what other IDs have been created elsewhere.

Finding a better way with uuid

This is exactly why the uuid (Universally Unique Identifier) module exists. Instead of counting, it creates a 128-bit number. I'll start by trying the most common version, uuid4, which is essentially just a massive random number.

import uuid

# Let's generate a few and see what they look like
for _ in range(3):
    print(uuid.uuid4())

# Output looks something like:
# 7b2e8f3a-1a2b-4c3d-8e9f-0a1b2c3d4e5f
# a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d
# f9e8d7c6-b5a4-4321-8765-4321fedcba98

That's a lot of characters, but the probability of two uuid4 calls resulting in the same ID is so astronomically low that for 99.9% of software engineering tasks, we treat it as impossible. I can now let my workers generate their own IDs locally without ever talking to each other, and they'll never collide.

Wait, what about uuid1?

While digging through the docs, I noticed uuid1(). I figured I'd try it out to see if it's "better" or just different. Let's see what happens when I run it a few times in quick succession.

import uuid

print(uuid.uuid1())
print(uuid.uuid1())

I noticed something immediately: the IDs look similar. That's because uuid1 isn't purely random; it uses the host's MAC address and the current timestamp. While this is useful if you need to know when or where an ID was generated, it's usually a bad idea for public-facing APIs. Why? Because you're essentially leaking your machine's hardware address to the world. Unless you have a very specific requirement for time-based sorting or traceability, stick with uuid4. I know I will.

Turning IDs into usable strings

One thing that tripped me up at first was that uuid.uuid4() doesn't return a string; it returns a UUID object. If I try to save that directly into a JSON file or a database that expects a string, it might complain.

import uuid

my_id = uuid.uuid4()
print(type(my_id)) # <class 'uuid.UUID'>

# To actually use it in a text-based system, I need to cast it
id_string = str(my_id)
print(id_string) # Now it's a standard string

It's a small detail, but skipping the str() conversion is a common "Why is my JSON failing?" bug I've seen in peer reviews. Always be explicit about the type when you're handing the ID off to another part of your application.




📋 Practical Task

Building a Unique Session Token Generator

Imagine you are building a login system. You cannot use simple integers for session tokens because users could easily guess other people's tokens by just adding 1 to their own (a classic security flaw called Insecure Direct Object Reference).

Write a Python script that does the following:

  • Imports the uuid module.
  • Creates a function called generate_session_token() that returns a unique ID as a string.
  • Creates a dictionary called active_sessions where the key is the session token and the value is a username (e.g., "Alice", "Bob").
  • Simulate logging in three different users by calling your function and adding them to the dictionary.
  • Print the final active_sessions dictionary to verify that each user has a unique, non-sequential token.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.