Quick answer
Import the built-in uuid module and call uuid.uuid4() for a random UUID. Wrap it in str() to get the usual 36-character text. On Python 3.14 or newer, call uuid.uuid7() instead when the ID will be a database key, because v7 IDs sort by creation time.
A random UUID with uuid4
uuid4() returns a UUID object built from 122 random bits. It uses the operating system’s secure random source, so it is safe for IDs that must not be guessed.
import uuid
user_id = uuid.uuid4()
print(user_id) # 3256c303-1a91-4d9e-88ef-397ecd8be0a9
print(str(user_id)) # the same 36-character string
print(user_id.hex) # 3256c3031a914d9e88ef397ecd8be0a9
print(user_id.bytes) # 16 raw bytes, for binary columns
print(user_id.version) # 4
The UUID object is not a string. Keep it as an object inside your code, and convert with str() when you write JSON, logs or URLs.
Which function to pick
| You want | Use | Python |
|---|---|---|
| A random ID that reveals nothing | uuid.uuid4() |
any |
| A database key that sorts by time | uuid.uuid7() |
3.14+ |
| The same ID every time for the same input | uuid.uuid5() |
any |
| To match an old system that uses MD5 | uuid.uuid3() |
any |
A time-ordered UUID with uuid7
Python 3.14 added uuid6(), uuid7() and uuid8() to the standard library. Of the three, uuid7() is the one most people want. It starts with the current time in milliseconds and fills the rest with random bits. IDs made later sort after IDs made earlier, which keeps database indexes compact.
import uuid
a = uuid.uuid7()
b = uuid.uuid7()
print(a) # 01a18310-5aa4-71ba-8483-438ff3db217f
print(a < b) # True
print(a.time) # 1793200249508, milliseconds since 1970
Python’s version also adds a counter, so IDs made in the same millisecond by the same process still come out in order.
On Python 3.13 or older
uuid.uuid7() does not exist before 3.14. The uuid6 package on PyPI fills the gap with the same idea:
# pip install uuid6
import uuid6
user_id = uuid6.uuid7()
It returns a normal uuid.UUID subclass, so the rest of your code does not change. When you upgrade to 3.14, you can switch to the standard library.
The same UUID every time with uuid5
Sometimes you want an ID that is the same every time for the same input. For example, one ID per email address or per URL, so that two services agree without talking to each other. That is what uuid5() does. It hashes a namespace UUID and a name together with SHA-1.
import uuid
uuid.uuid5(uuid.NAMESPACE_DNS, "example.com")
# UUID('cfbff0d1-9375-5685-968c-48ce8b15ae17')
uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com/users/42")
# UUID('38fcaf6d-63bc-5c9f-8a4f-de8cf4e651ed')
Python includes four standard namespaces: NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID and NAMESPACE_X500. You can also make your own namespace with uuid4() once and hard-code it.
The result is not secret. Anyone who knows the namespace and the name can make the same UUID. uuid3() works the same way with MD5, and is only worth using to match an older system.
Parse and check a UUID
Pass a string to uuid.UUID() to turn it into an object. It raises ValueError if the string is not a UUID.
import uuid
def parse_uuid(text):
try:
return uuid.UUID(text)
except ValueError:
return None
parse_uuid("01a16818-85c0-7b3e-9f2a-4c6d81e05a73").version # 7
parse_uuid("not-a-uuid") # None
uuid.UUID() is generous. It also accepts upper case, braces, a urn:uuid: prefix and the 32-digit form without hyphens. If you only want the standard form, also check that str(result) == text.lower().
From the command line
Since Python 3.12 you can make UUIDs without writing a script. Python 3.14 added versions 6 to 8 and the -C option for a count.
python -m uuid # one uuid4
python -m uuid -u uuid7 -C 3 # three uuid7 (3.14+)
python -m uuid -u uuid5 -n @dns -N example.com # cfbff0d1-9375-5685-968c-48ce8b15ae17
Good to know
json.dumps cannot handle a UUID
json.dumps({"id": uuid.uuid4()}) raises TypeError. Convert with str() first, or pass default=str.
Special values
Python 3.14 also added uuid.NIL (all zeros) and uuid.MAX (all ones). See nil and max UUIDs for when to use them.
Avoid uuid1 for new code
uuid1() can include your machine’s network address. Use uuid7() for time order or uuid4() for pure randomness. uuid8() is not built from secure random bits by default, so do not use it for anything that must stay unguessable.

