ifixkart-backend/venv/lib/python3.12/site-packages/ulid/__main__.py

169 lines
5.3 KiB
Python

from __future__ import annotations
import argparse
import shutil
import sys
import textwrap
from datetime import datetime
from functools import partial
from typing import Any
from typing import TYPE_CHECKING
from uuid import UUID
import ulid
from ulid import ULID
if TYPE_CHECKING: # pragma: no cover
from collections.abc import Callable
from collections.abc import Sequence
def make_parser(prog: str | None = None) -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog=prog,
description=textwrap.indent(
textwrap.dedent(
"""
Create or inspect ULIDs
A ULID is a universally unique lexicographically sortable identifier
with the following structure
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
48bits 80bits
"""
).strip(),
" ",
),
formatter_class=partial(
argparse.RawDescriptionHelpFormatter,
# Prevent argparse from taking up the entire width of the terminal window
# which impedes readability.
width=min(shutil.get_terminal_size().columns - 2, 127),
),
)
parser.set_defaults(func=lambda _: parser.print_help())
parser.add_argument("--version", "-V", action="version", version=ulid.__version__)
subparsers = parser.add_subparsers(title="subcommands")
b = subparsers.add_parser(
"build",
help="generate ULIDs from different sources",
)
b.add_argument(
"--from-int",
metavar="<int>",
help="create from integer",
)
b.add_argument(
"--from-hex",
metavar="<str>",
help="create from 32 character hex value",
)
b.add_argument(
"--from-str",
metavar="<str>",
help="create from base32 encoded string of length 26",
)
b.add_argument(
"--from-timestamp",
metavar="<int|float>",
help="create from timestamp either as float in secs or int as millis",
)
b.add_argument(
"--from-datetime",
metavar="<iso8601>",
help="create from datetime. The timestamp part of the ULID will be taken from the datetime",
)
b.add_argument(
"--from-uuid",
metavar="<uuid>",
help="create from given UUID. The timestamp part will be random.",
)
b.set_defaults(func=build)
s = subparsers.add_parser("show", help="show properties of a ULID")
s.add_argument("ulid", help="the ULID to inspect. The special value - reads from stdin")
s.add_argument("--uuid", action="store_true", help="convert to fully random UUID")
s.add_argument("--uuid4", action="store_true", help="convert to RFC 4122 compliant UUIDv4")
s.add_argument("--hex", action="store_true", help="convert to hex")
s.add_argument("--int", action="store_true", help="convert to int")
s.add_argument("--timestamp", "--ts", action="store_true", help="show timestamp")
s.add_argument("--datetime", "--dt", action="store_true", help="show datetime")
s.set_defaults(func=show)
return parser
def main(argv: Sequence[str], prog: str | None = None) -> str:
args = make_parser(prog).parse_args(argv)
return args.func(args)
def from_value_or_stdin(value: str, convert: Callable[[str], Any] | None = None) -> Any:
value = sys.stdin.readline().strip() if value == "-" else value
if convert is not None:
return convert(value)
return value
def parse_numeric(s: str) -> int | float:
try:
return int(s)
except ValueError:
return float(s)
def build(args: argparse.Namespace) -> str:
ulid: ULID
if args.from_int is not None:
ulid = ULID.from_int(from_value_or_stdin(args.from_int, int))
elif args.from_hex is not None:
ulid = ULID.from_hex(from_value_or_stdin(args.from_hex))
elif args.from_str is not None:
ulid = ULID.from_str(from_value_or_stdin(args.from_str))
elif args.from_timestamp is not None:
ulid = ULID.from_timestamp(from_value_or_stdin(args.from_timestamp, parse_numeric))
elif args.from_datetime is not None:
ulid = ULID.from_datetime(from_value_or_stdin(args.from_datetime, datetime.fromisoformat))
elif args.from_uuid is not None:
ulid = ULID.from_uuid(from_value_or_stdin(args.from_uuid, UUID))
else:
ulid = ULID()
return str(ulid)
def show(args: argparse.Namespace) -> str:
ulid: ULID = ULID.from_str(from_value_or_stdin(args.ulid))
if args.uuid:
return str(ulid.to_uuid())
if args.uuid4:
return str(ulid.to_uuid4())
if args.hex:
return ulid.hex
if args.int:
return str(int(ulid))
if args.timestamp:
return str(ulid.timestamp)
if args.datetime:
return ulid.datetime.isoformat()
return textwrap.dedent(
f"""
ULID: {ulid!s}
Hex: {ulid.hex}
Int: {int(ulid)}
Timestamp: {ulid.timestamp}
Datetime: {ulid.datetime.isoformat()}
"""
).strip()
def entrypoint() -> None: # pragma: no cover
if (value := main(sys.argv[1:])) is not None:
print(value) # noqa: T201
if __name__ == "__main__": # pragma: no cover
main(sys.argv[1:], "python -m ulid")