Lib/secrets.py
cpython 3.14 @ ab2d84fe1023/Lib/secrets.py
The secrets module provides functions for generating cryptographically strong random values suitable for managing passwords, account authentication, security tokens, and related secrets. It was added in Python 3.6 (PEP 506) as a clear, high-level interface that steers application code away from the random module, which is designed for simulations and games and must not be used for security-sensitive work.
Internally, secrets is a thin wrapper around os.urandom and random.SystemRandom. The SystemRandom class seeds itself from the OS entropy source on every call, so the values it produces are suitable for use in tokens that must be unguessable. The module exposes a module-level SystemRandom instance named _sysrand and routes all high-level helpers through it.
The three token_* helpers share a common pattern: each calls token_bytes to obtain the requested number of bytes from os.urandom, then optionally re-encodes the result as hex or URL-safe base64. The default token length (when nbytes is None) is DEFAULT_ENTROPY, currently 32 bytes, chosen to provide 256 bits of entropy.
Map
| Lines | Symbol | Role | gopy |
|---|---|---|---|
| 1-20 | module header, imports | imports os, random, base64, binascii; defines __all__ | |
| 21-30 | _sysrand, randbits, choice | module-level SystemRandom instance; re-exports randbits and choice | |
| 31-40 | randbelow(exclusive_upper_bound) | delegates to _sysrand.randbelow; used by choice internally | |
| 41-50 | token_bytes(nbytes=None) | returns nbytes raw bytes from os.urandom; uses DEFAULT_ENTROPY when nbytes is None | |
| 51-60 | token_hex(nbytes=None) | hex-encodes the output of token_bytes | |
| 61-70 | token_urlsafe(nbytes=None) | URL-safe base64-encodes the output of token_bytes, strips padding |
Reading
Module bootstrap and SystemRandom exposure (lines 1 to 30)
cpython 3.14 @ ab2d84fe1023/Lib/secrets.py#L1-30
The file imports os, random, base64, and binascii, then builds __all__ to list exactly the public API. A single SystemRandom instance is created at import time as _sysrand. Rather than exposing the instance directly, secrets cherry-picks two of its methods, randbits and choice, and publishes them as module-level names. This keeps the surface small and prevents callers from reaching the full Random interface.
_sysrand = random.SystemRandom()
randbits = _sysrand.randbits
choice = _sysrand.choice
randbelow (lines 31 to 40)
cpython 3.14 @ ab2d84fe1023/Lib/secrets.py#L31-40
randbelow(exclusive_upper_bound) returns a random integer in [0, n) drawn from the OS entropy source. The implementation simply calls _sysrand.randbelow, which uses rejection sampling over urandom-backed bits to avoid modulo bias. This is the primitive used by choice under the hood.
def randbelow(exclusive_upper_bound):
return _sysrand.randbelow(exclusive_upper_bound)
token_bytes and the DEFAULT_ENTROPY sentinel (lines 41 to 50)
cpython 3.14 @ ab2d84fe1023/Lib/secrets.py#L41-50
DEFAULT_ENTROPY = 32 fixes the default byte count. When nbytes is None, the function substitutes DEFAULT_ENTROPY, so callers that just want a safe default do not need to pass an argument. The actual bytes come directly from os.urandom, bypassing the SystemRandom object entirely for the token helpers.
DEFAULT_ENTROPY = 32
def token_bytes(nbytes=None):
if nbytes is None:
nbytes = DEFAULT_ENTROPY
return os.urandom(nbytes)
token_hex and token_urlsafe (lines 51 to 70)
cpython 3.14 @ ab2d84fe1023/Lib/secrets.py#L51-70
Both helpers call token_bytes and re-encode the result. token_hex uses binascii.hexlify and decodes to a str. token_urlsafe uses base64.urlsafe_b64encode and strips the trailing = padding characters, since URL tokens do not need them. The result lengths are longer than nbytes because encoding expands the data.
def token_hex(nbytes=None):
return binascii.hexlify(token_bytes(nbytes)).decode('ascii')
def token_urlsafe(nbytes=None):
tok = token_bytes(nbytes)
return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii')
gopy mirror
Not yet ported.