From 4fe91610cb8ef88fdc99aac56686affc4f24529f Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Thu, 11 Dec 2025 12:19:41 -0800 Subject: [PATCH 1/2] update: add uuid --- src/py/mat3ra/utils/uuid.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/py/mat3ra/utils/uuid.py diff --git a/src/py/mat3ra/utils/uuid.py b/src/py/mat3ra/utils/uuid.py new file mode 100644 index 0000000..9500e8b --- /dev/null +++ b/src/py/mat3ra/utils/uuid.py @@ -0,0 +1,24 @@ +import uuid + + +def get_uuid() -> str: + """Generates a UUID v4 string. + + Returns: + str: A UUID string. + """ + return str(uuid.uuid4()) + + +def get_uuid_from_namespace(seed: str = "", namespace: str = "00000000-0000-4000-8000-000000000000") -> str: + """Generates a UUID v5 string based on a namespace and seed. + + Args: + seed (str, optional): The seed string. Defaults to "". + namespace (str, optional): The namespace UUID string. Defaults to "00000000-0000-4000-8000-000000000000". + + Returns: + str: A UUID string. + """ + namespace_uuid = uuid.UUID(namespace) + return str(uuid.uuid5(namespace_uuid, seed)) From 3fe4e3262a27a3785cbdd4db22a0472c1275f08c Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Thu, 11 Dec 2025 12:52:49 -0800 Subject: [PATCH 2/2] update: add uuid test --- tests/py/unit/test_array.py | 2 +- tests/py/unit/test_uuid.py | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/py/unit/test_uuid.py diff --git a/tests/py/unit/test_array.py b/tests/py/unit/test_array.py index 64f0a68..ec90ac9 100644 --- a/tests/py/unit/test_array.py +++ b/tests/py/unit/test_array.py @@ -1,5 +1,4 @@ import pytest - from mat3ra.utils import array as utils REFERENCE_ARRAY = [1, 2, 3, 4, 5] @@ -28,6 +27,7 @@ def test_convert_to_array_if_not(): item = utils.convert_to_array_if_not(REFERENCE_ARRAY[0]) assert item == [REFERENCE_ARRAY[0]] + @pytest.mark.parametrize( "array_a,array_b,expected", [ diff --git a/tests/py/unit/test_uuid.py b/tests/py/unit/test_uuid.py new file mode 100644 index 0000000..5f5bd4a --- /dev/null +++ b/tests/py/unit/test_uuid.py @@ -0,0 +1,54 @@ +import re +import pytest +from mat3ra.utils.uuid import get_uuid, get_uuid_from_namespace + +UUID_PATTERN = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$') +TEST_SEED_1 = "test_seed_1" +TEST_SEED_2 = "test_seed_2" +TEST_NAMESPACE = "00000000-0000-4000-8000-000000000000" +EXPECTED_UUID_FROM_SEED_1 = "2b0e8b5e-6b4a-5d5e-b5e5-5e5e5e5e5e5e" + + +def test_get_uuid(): + uuid_1 = get_uuid() + uuid_2 = get_uuid() + assert UUID_PATTERN.match(uuid_1) + assert UUID_PATTERN.match(uuid_2) + assert uuid_1 != uuid_2 + + +@pytest.mark.parametrize( + "seed,namespace,expected_same", + [ + (TEST_SEED_1, TEST_NAMESPACE, TEST_SEED_1), + (TEST_SEED_2, TEST_NAMESPACE, TEST_SEED_2), + ("", TEST_NAMESPACE, ""), + ], +) +def test_get_uuid_from_namespace_deterministic(seed, namespace, expected_same): + uuid_1 = get_uuid_from_namespace(seed, namespace) + uuid_2 = get_uuid_from_namespace(expected_same, namespace) + assert UUID_PATTERN.match(uuid_1) + assert UUID_PATTERN.match(uuid_2) + assert uuid_1 == uuid_2 + + +@pytest.mark.parametrize( + "seed_a,seed_b,namespace", + [ + (TEST_SEED_1, TEST_SEED_2, TEST_NAMESPACE), + ("seed_a", "seed_b", TEST_NAMESPACE), + (TEST_SEED_1, "", TEST_NAMESPACE), + ], +) +def test_get_uuid_from_namespace_different_seeds(seed_a, seed_b, namespace): + uuid_a = get_uuid_from_namespace(seed_a, namespace) + uuid_b = get_uuid_from_namespace(seed_b, namespace) + assert UUID_PATTERN.match(uuid_a) + assert UUID_PATTERN.match(uuid_b) + assert uuid_a != uuid_b + + +def test_get_uuid_from_namespace_default_params(): + uuid_with_defaults = get_uuid_from_namespace() + assert UUID_PATTERN.match(uuid_with_defaults)