More spring cleaning.
[pyutils.git] / src / pyutils / id_generator.py
1 #!/usr/bin/env python3
2
3 # © Copyright 2021-2023, Scott Gasch
4
5 """
6 A helper class for generating thread safe monotonically increasing
7 id numbers.
8
9 .. note::
10
11     This code is thread safe but not process safe; for use only
12     within one python process.
13 """
14
15 import itertools
16 import logging
17
18 # This module is commonly used by others in here and should avoid
19 # taking any unnecessary dependencies back on them.
20
21 logger = logging.getLogger(__name__)
22 generators = {}
23
24
25 def get(name: str, *, start: int = 0) -> int:
26     """
27     Returns a thread-safe, monotonically increasing id suitable for use
28     as a globally unique identifier.
29
30     Args:
31         name: the sequence identifier name.
32         start: the starting id (i.e. the first id that should be returned)
33
34     Returns:
35         An integer id such that within one sequence identifier name the
36         id returned is unique and is the maximum id ever returned.
37
38     >>> import id_generator
39     >>> id_generator.get('student_id')
40     0
41     >>> id_generator.get('student_id')
42     1
43     >>> id_generator.get('employee_id', start=10000)
44     10000
45     >>> id_generator.get('employee_id', start=10000)
46     10001
47     """
48     if name not in generators:
49         generators[name] = itertools.count(start, 1)
50     x = next(generators[name])
51     logger.debug("Generated next id %d in sequence %s", x, name)
52     return x
53
54
55 if __name__ == "__main__":
56     import doctest
57
58     doctest.testmod()