diff --git a/README.md b/README.md index 0d8b311..7dbb44e 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,25 @@ pip install uuid05 ``` python from uuid05 import UUID05 -# May be parametrized by workers: int, ttl: int, precision: int -# defaults are: workers=10, ttl=2 days, precision=1 +# basic usage uid = UUID05.make() suffix: str = uid.as_b64() object_name: str = f'autotest_object_{suffix}' + +# .make() may be parametrized by workers: int, ttl: int, precision: int +# defaults are: workers=10, ttl=2 days, precision=1 +uid: int = UUID05.make(workers=16, ttl=86400, precision=6) # 1419554951415 +uid.as_b64() # 'AUqEXzNy' + +# you may also want to just shorten your existing integer identifiers. +suffix: str = UUID05(123123123123).as_b64() +assert suffix == 'HKq1w7M' + +# How to get maximum UUID value/length with given params? +max_value = UUID05.max_value(machines=16, ttl=86400, precision=6) # 1586399913600 +len(str(max_value)) == 13 +len(max_value.as_b64()) == 8 # AXFczaaA +len(f'autotest_object_{max_value.as_b64()}') == 23 # autotest_object_AXFczaaA ``` It can be also used as an utility from command-line: @@ -83,7 +97,8 @@ Otherwise Redis, Memcached or another database with a single INCRementing counte - If your objects are persistent - you'd better use [py-nanoid](https://github.com/puyuan/py-nanoid). - If you need to generate multiple UIDs for multiple object really _quick_: - generate one and reuse it, using a semantic or loop variable as a suffix; - - pass **precision** argument to `uuid05()`. It scales automatically with worker count, but if there are less than 16 workers, default is 1 which means 1 uuid per 0.1 second, usually it's enough. + - pass **precision** argument to `uuid05()`. It scales automatically with worker count, + but if there are less than 16 workers, default is 1 which means 1 uuid per 0.1 second, usually it's enough. - `precision=3` argument will use milliseconds. - `precision=6` for microseconds. - if `precision=6` is not enough stop trying to make your identifier compact. diff --git a/cli/uuid05 b/cli/uuid05 index 3d296db..023e3d7 100644 --- a/cli/uuid05 +++ b/cli/uuid05 @@ -12,6 +12,7 @@ def main(): parser.add_argument('-p', '--precision', type=int, help='Increase up to 6 if you create objects frequently.') parser.add_argument('-b', '--base64', action='store_true', help='Use base64 to compact it event more') parser.add_argument('-a', '--altchars', type=str, help='Alternative characters for b64encode') + parser.add_argument('-m', '--max-value', action='store_true', help='Return maximum possible value for given params') args = parser.parse_args() kwargs = {} if args.workers: @@ -20,7 +21,7 @@ def main(): kwargs['ttl'] = args.ttl if args.precision: kwargs['precision'] = args.precision - uid: UUID05 = UUID05.make(**kwargs) + uid: UUID05 = UUID05.max_value(**kwargs) if args.max_value else UUID05.make(**kwargs) print((uid.as_b64(altchars=args.altchars.encode()) if args.altchars else uid.as_b64()) if args.base64 else uid) diff --git a/setup.py b/setup.py index 5b571e3..22ee7ac 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='uuid05', - version='0.0.2', + version='0.0.3', packages=['uuid05'], url='https://github.com/strizhechenko/uuid05', license='MIT', diff --git a/uuid05/__init__.py b/uuid05/__init__.py index ec5f489..8771264 100644 --- a/uuid05/__init__.py +++ b/uuid05/__init__.py @@ -17,7 +17,9 @@ def as_b64(self, *args, **kwargs) -> str: If you're using uuid05 results as strings and want it to be more compact, and being integer or not doesn't matter you may use this function to encode it to base64. You can transparently pass arguments of b64encode function here. As there's not decoding assumed padding symbols are removed. - %timeit b64(uuid05()) - 2.87 µs ± 13.9 ns per loop @ 3.2GHz + %timeit UUID05.make().as_b64() - 2.87 µs ± 13.9 ns per loop @ 3.2 GHz + %timeit UUID05.make().as_b64() - 1.54 µs ± 5.25 ns per loop @ 3.8 GHz + %timeit UUID05(1333).as_b64() - 608 ns ± 2.68 ns per loop (with static UUID (skips generation)) >>> UUID05(34714).as_b64(altchars=b'_-') 'h5o' >>> UUID05(11402098).as_b64(altchars=b'_-') @@ -36,7 +38,9 @@ def make(cls, workers=10, ttl=2 * day, precision=0) -> 'UUID05': Compact human-readable unique identifiers for temporary objects in small non-synchronizing distributed systems. If your objects are persistent - you'd better use nanoid. If you need to generate multiple UIDs for multiple object at once - generate one and use loop variable as suffix. - %timeit uuid05() - 2.1 µs ± 2.08 ns per loop @ 3.2GHz + %timeit UUID05.make() - 2.1 µs ± 2.08 ns per loop @ 3.2GHz + %timeit UUID05.make() - 849 ns ± 1.73 ns per loop @ 3.8GHz + %timeit UUID05.make() - 717 ns ± 1.76 ns per loop @ 4.7GHz :arg workers - count of hosts in a system; :arg ttl - how many seconds a temporary object lives in a system (maximum) before being deleted; :arg precision (optional) - you can override (increase) a precision if objects are created frequently (max - 6); @@ -53,10 +57,10 @@ def make(cls, workers=10, ttl=2 * day, precision=0) -> 'UUID05': return UUID05(f'{run_id}{time_id}') @classmethod - def uuid05_max_value(cls, machines=10, ttl=2 * day, precision=0) -> 'UUID05': + def max_value(cls, workers=10, ttl=2 * day, precision=0) -> 'UUID05': """:returns - maximum value of an uuid05 with given params""" - precision = min(precision or int(machines ** (1 / 4)), 6) - run_id = machines - 1 + precision = min(precision or int(workers ** (1 / 4)), 6) + run_id = workers - 1 time_id = ttl * ((10 ** precision) - 1) return UUID05(f'{run_id}{time_id}') @@ -67,6 +71,6 @@ def uuid05_max_value(cls, machines=10, ttl=2 * day, precision=0) -> 'UUID05': for _workers in 2, 4, 10, 16, 32, 256: worker_id = randint(0, _workers) example_value = UUID05.make(_workers, _ttl) - max_value = UUID05.uuid05_max_value(_workers, _ttl) + max_value = UUID05.max_value(_workers, _ttl) max_in_b64 = max_value.as_b64(altchars=b'-_') print(f'| {_ttl} | {_workers} | {worker_id} | {example_value} | {max_value} | {max_in_b64} |')