print(secrets.token_bytes(int(args[i+1])))
doesn't particularly work, or at least not in a form I'd expect. It's possible for a script to want to call this and read from stdout in binary format, but that's not what your code does - instead, it basically prints the repr of some bytes, so some will be encoded and others won't. I imagine that a caller would either want raw binary, or use the hex version instead. With raw binary, you'll also want to make a decision (more carefully than I have) about how to separate different tokens - \n risks being ambiguous.
Use the built-in argparse. A caveat: unless you get much more creative, this is going to reorder command-line switches and group by type.
import argparse
import secrets
import sys
def positive(arg: str) -> int:
value = int(arg)
if value < 1:
raise ValueError(f'Must pass a positive integer, not {value}')
return value
def get_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description='Generate token data from the secrets module',
)
parser.add_argument(
'-b', '--bytes', type=positive, action='append', default=[],
)
parser.add_argument(
'-x', '--hex', type=positive, action='append', default=[],
)
parser.add_argument(
'-u', '--urlsafe', type=positive, action='append', default=[],
)
return parser.parse_args()
def main() -> None:
args = get_args()
if len(args.bytes) > 0:
sys.stdout.buffer.write(b'\n'.join(
secrets.token_bytes(size)
for size in args.bytes
))
sys.stdout.buffer.flush()
print()
if len(args.hex) > 0:
print('\n'.join(
secrets.token_hex(size) for size in args.hex
))
if len(args.urlsafe) > 0:
print('\n'.join(
secrets.token_urlsafe(size) for size in args.urlsafe
))
if __name__ == '__main__':
main()
▬
�♠
a606bc
0f7f54b6
pQ
Yk0