48

I have a string that should be a UUID. Is there any built-in Python function available to check whether the UUID is valid or not, and to check its version?

0

4 Answers 4

208

I found this question while I was looking for a Python answer. To help people in the same situation, I've added the Python solution.

You can use the uuid module:

#!/usr/bin/env python

from uuid import UUID

def is_valid_uuid(uuid_to_test, version=4):
    """
    Check if uuid_to_test is a valid UUID.
    
     Parameters
    ----------
    uuid_to_test : str
    version : {1, 2, 3, 4}
    
     Returns
    -------
    `True` if uuid_to_test is a valid UUID, otherwise `False`.
    
     Examples
    --------
    >>> is_valid_uuid('c9bf9e57-1685-4c89-bafb-ff5af830be8a')
    True
    >>> is_valid_uuid('c9bf9e58')
    False
    """
    
    try:
        uuid_obj = UUID(uuid_to_test, version=version)
    except ValueError:
        return False
    return str(uuid_obj) == uuid_to_test


if __name__ == '__main__':
    import doctest
    doctest.testmod()
4
  • 3
    This answer is wrong. Python won't always raise a ValueError. It will sometimes silently fix the input. uuid.UUID('6a3f6f5c-8df8-5b4e-8ec3-a8b2df62a40b', version=4) UUID('6a3f6f5c-8df8-4b4e-8ec3-a8b2df62a40b') mind the (5b4e-block in the middle!) Commented May 4, 2020 at 7:27
  • 1
    Be aware that str(uuid_obj) == uuid_to_test will cause valid uuids (but without dashes) to be identified as invalid. Because UUID(uuid_to_test) will add them even if not provided at first. Commented May 15, 2022 at 12:55
  • Why do you think leaving the dashes away is valid? Is there a standard which defines them as optional? Can arbitrary many dashes be added? Commented May 15, 2022 at 20:39
  • 1
    @MartinThoma I'm not sure about the standards honestly but uuid.UUID itself considers it valid and it actually removes any dashes before constructing the uuid object as you can see here Commented May 16, 2022 at 9:37
54

All the existing answers use regex. If you're using Python, you might want to consider a try/except in case you don't want to use regex: (Bit shorter than the answer above).

Our validator would then be:

import uuid

def is_valid_uuid(val):
    try:
        uuid.UUID(str(val))
        return True
    except ValueError:
        return False

>>> is_valid_uuid(1)
False
>>> is_valid_uuid("123-UUID-wannabe")
False
>>> is_valid_uuid({"A":"b"})
False
>>> is_valid_uuid([1, 2, 3])
False
>>> is_valid_uuid(uuid.uuid4())
True
>>> is_valid_uuid(str(uuid.uuid4()))
True
>>> is_valid_uuid(uuid.uuid4().hex)
True
>>> is_valid_uuid(uuid.uuid3(uuid.NAMESPACE_DNS, 'example.net'))
True
>>> is_valid_uuid(uuid.uuid5(uuid.NAMESPACE_DNS, 'example.net'))
True
>>> is_valid_uuid("{20f5484b-88ae-49b0-8af0-3a389b4917dd}")
True
>>> is_valid_uuid("20f5484b88ae49b08af03a389b4917dd")
True
3
  • 1
    Watch out for UUID syntax variants that uuid.UUID() accepts: "{20f5484b-88ae-49b0-8af0-3a389b4917dd}", "20f5484b88ae49b08af03a389b4917dd" Commented Feb 20, 2020 at 8:30
  • Thanks @PēterisCaune nice addition - the case with .hex essentially covers the last one you added but it's worth adding regardless. Wasn't aware of the "{uuid}" case.
    – slajma
    Commented Mar 31, 2020 at 5:07
  • 1
    Also this is true. is_valid_uuid('-2b1eb780-8a03-4031-b1e5-2f7674c60df3') >> True
    – Vikram Ray
    Commented Aug 25, 2021 at 5:30
30

To check the validity of a UUID string, simply try to create a new uuid object with it. If it's invalid...

uuid.UUID("foo")
# => ValueError: badly formed hexadecimal UUID string

If you need to know the version of the UUID, it's right there in the UUID API:

uuid.UUID('302a4299-736e-4ef3-84fc-a9f400e84b24').version
# => 4
2
  • i have to check whether the UUID i have is in proper format or not and its version.
    – Karma Yogi
    Commented Dec 19, 2018 at 8:57
  • 3
    Try except this using ValueError: val = UUID(your_uuid_string, version=4)
    – radtek
    Commented Feb 4, 2020 at 19:10
8
import re

UUID_PATTERN = re.compile(r'^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}$', re.IGNORECASE)
uuid = '20f5484b-88ae-49b0-8af0-3a389b4917dd'

return bool(UUID_PATTERN.match(uuid))
3
  • 4
    Maybe you could explain a bit? By the way : return UUID_PATTERN.match(uuid)? Commented Jun 30, 2016 at 7:49
  • Actually yeah, just return the match is better. What bit do you not understand here? Commented Jul 11, 2016 at 6:14
  • 1
    By the way - I tested that code and found that re.IGNORECASE is too expensive - much cheaper is apply lower() to uuid Commented Aug 28, 2020 at 11:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.