Basic Auth Generator — Python source
Build HTTP Basic Access Authentication headers from a username and password, or decode an existing Authorization header back to its credentials. UTF-8 safe and fully client-side, with a shareable link.
This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.
"""basic-auth-generator — HTTP Basic-Auth header encode/decode.
Language: Python (3.9+, standard library only)
Source: CosmoDev polyglot showcase port of the Basic Auth Generator tool,
ported from src/lib/basic-auth.ts (the canonical TypeScript
implementation) and kept in lock-step with cli/basic-auth-generator.
License: display source — part of CosmoDev's polyglot tool pages.
Design goals:
- Pure + deterministic; never raises (parse returns None on malformed input).
- Functionally equivalent to the TS reference + Go twin: same inputs ->
same outputs, same reject behavior on malformed headers.
- Self-contained: stdlib only (no pip packages).
Python is the dependency-rich polyglot here — the standard library ships a
base64 codec and binascii validation, so unlike the Rust/PHP ports we use the
real RFC 4648 path rather than a hand-rolled codec. ``base64.b64decode`` with
``validate=True`` rejects invalid characters exactly like Go's
``base64.StdEncoding.DecodeString``.
"""
from __future__ import annotations
import base64
import binascii
from dataclasses import dataclass
from typing import Optional, Tuple
__all__ = ["Credentials", "build_basic_auth", "parse_basic_auth"]
@dataclass(frozen=True)
class Credentials:
"""A parsed username/password pair.
Mirrors the Go twin's ``Credentials`` struct and the TS
``BasicAuthCredentials`` interface. Frozen so instances are hashable and
immutable — the parsed value is a plain result, not a mutable bag.
"""
user: str
pass_: str
"""Password. Named ``pass_`` to avoid shadowing the Python keyword."""
def build_basic_auth(user: str, pass_: str) -> str:
"""Build an HTTP Basic-Auth header value: ``Basic <base64(user:pass)>``.
Mirrors ``buildBasicAuth`` in the TS source and ``BuildHeader`` in the Go
twin. ``encode`` returns the UTF-8 byte representation so multibyte
credentials (e.g. ``café:päss``) encode correctly.
"""
token = base64.b64encode(f"{user}:{pass_}".encode("utf-8")).decode("ascii")
return f"Basic {token}"
def parse_basic_auth(header: str) -> Optional[Credentials]:
"""Parse a ``Basic <token>`` header back into credentials, or ``None`` if
the header is malformed or the credentials have no colon separator.
Logic mirrors ``ParseHeader`` in the Go twin exactly: trim the header,
require a case-insensitive ``basic `` prefix, trim the remaining token,
base64-decode it (rejecting invalid characters), then split on the FIRST
colon so a password containing colons round-trips.
"""
h = header.strip()
prefix = "basic "
# Case-insensitive prefix check, mirroring Go's strings.EqualFold(h[:6], "basic ").
if len(h) < len(prefix) or h[: len(prefix)].lower() != prefix:
return None
token = h[len(prefix):].strip()
try:
decoded = base64.b64decode(token, validate=True).decode("utf-8")
except (binascii.Error, ValueError, UnicodeDecodeError):
return None
# split with maxsplit=1 keeps any colons inside the password intact.
if ":" not in decoded:
return None
user, pass_ = decoded.split(":", 1)
return Credentials(user=user, pass_=pass_)
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →