Claude Code for http.cookies: Python HTTP Cookie Parser — Claude Skills 360 Blog
Blog / AI / Claude Code for http.cookies: Python HTTP Cookie Parser
AI

Claude Code for http.cookies: Python HTTP Cookie Parser

Published: November 16, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s http.cookies module parses incoming Cookie headers and builds outgoing Set-Cookie headers for HTTP responses. from http.cookies import SimpleCookie, Morsel, CookieError. Create: sc = SimpleCookie() — empty jar. Parse: sc.load("session=abc123; theme=dark") — parses a Cookie or Set-Cookie header string into the jar. Access: sc["session"]Morsel; sc["session"].value"abc123" (decoded); sc["session"].coded_value → quoted wire value; sc["session"].key"session". Set: sc["session"] = "abc123" — creates a new Morsel; sc["session"]["expires"] = "Sat, 01 Jan 2030 00:00:00 GMT"; sc["session"]["path"] = "/", sc["session"]["domain"] = ".example.com", sc["session"]["secure"] = True, sc["session"]["httponly"] = True, sc["session"]["samesite"] = "Lax", sc["session"]["max-age"] = 3600. Output: sc.output()"Set-Cookie: session=abc123\r\nSet-Cookie: theme=dark" (multi-line); sc.output(header="", sep="\n") for custom formatting; sc["session"].OutputString() → single cookie without Set-Cookie: prefix. Exceptions: CookieError raised for illegal keys or values. Claude Code generates cookie readers, Set-Cookie emitters, session token managers, and test cookie harnesses.

CLAUDE.md for http.cookies

## http.cookies Stack
- Stdlib: from http.cookies import SimpleCookie, CookieError
- Parse:  sc = SimpleCookie(); sc.load(cookie_header_string)
-         val = sc["name"].value       # decoded value
-         key = sc["name"].key
- Set:    sc["session"] = "tok123"
-         sc["session"]["httponly"] = True
-         sc["session"]["samesite"] = "Lax"
-         sc["session"]["max-age"] = 3600
- Output: sc.output()                  # multi-line Set-Cookie headers
-         sc.output(header="", sep="\n").strip()   # values only
# app/cookiesutil.py — parse, build, sign, validate, expire cookies
from __future__ import annotations

import hashlib
import hmac
import secrets
import time
from dataclasses import dataclass
from datetime import datetime, timezone, timedelta
from http.cookies import SimpleCookie, Morsel, CookieError


# ─────────────────────────────────────────────────────────────────────────────
# 1. Parse helpers
# ─────────────────────────────────────────────────────────────────────────────

def parse_cookie_header(header: str) -> dict[str, str]:
    """
    Parse a Cookie: request header string into a {name: value} dict.
    Returns empty dict on parse error.

    Example:
        cookies = parse_cookie_header("session=abc; theme=dark; count=3")
        print(cookies["session"])   # 'abc'
    """
    sc = SimpleCookie()
    try:
        sc.load(header)
    except CookieError:
        return {}
    return {key: morsel.value for key, morsel in sc.items()}


def parse_set_cookie_header(header: str) -> dict[str, str | bool]:
    """
    Parse a Set-Cookie: response header value (one cookie with attributes).
    Returns dict with 'name', 'value', and any set attributes.

    Example:
        attrs = parse_set_cookie_header(
            "session=tok123; Path=/; HttpOnly; SameSite=Lax; Max-Age=3600"
        )
    """
    sc = SimpleCookie()
    try:
        sc.load(header)
    except CookieError:
        return {}
    if not sc:
        return {}
    name = next(iter(sc))
    morsel = sc[name]
    result: dict[str, str | bool] = {"name": name, "value": morsel.value}
    for attr in ("expires", "path", "domain", "comment", "max-age", "samesite"):
        v = morsel[attr]
        if v:
            result[attr] = v
    if morsel["secure"]:
        result["secure"] = True
    if morsel["httponly"]:
        result["httponly"] = True
    return result


# ─────────────────────────────────────────────────────────────────────────────
# 2. Cookie builder
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class CookieSpec:
    name:      str
    value:     str
    max_age:   int | None  = None    # seconds; None = session cookie
    path:      str         = "/"
    domain:    str         = ""
    secure:    bool        = True
    httponly:  bool        = True
    samesite:  str         = "Lax"   # "Strict", "Lax", "None"
    comment:   str         = ""


def build_set_cookie(spec: CookieSpec) -> str:
    """
    Build a Set-Cookie header value from a CookieSpec.
    Returns the full header line including 'Set-Cookie: ' prefix.

    Example:
        header = build_set_cookie(CookieSpec("session", "tok123", max_age=3600))
        print(header)
    """
    sc = SimpleCookie()
    sc[spec.name] = spec.value
    m = sc[spec.name]
    m["path"] = spec.path
    if spec.domain:
        m["domain"] = spec.domain
    if spec.max_age is not None:
        m["max-age"] = spec.max_age
    m["secure"] = spec.secure
    m["httponly"] = spec.httponly
    m["samesite"] = spec.samesite
    if spec.comment:
        m["comment"] = spec.comment
    return m.OutputString()


def build_cookie_jar(specs: list[CookieSpec]) -> list[str]:
    """
    Build a list of Set-Cookie header values from multiple CookieSpecs.

    Example:
        headers = build_cookie_jar([
            CookieSpec("session", "tok123", max_age=3600),
            CookieSpec("pref",    "dark",   max_age=86400*30),
        ])
        for h in headers:
            print(f"Set-Cookie: {h}")
    """
    return [build_set_cookie(s) for s in specs]


def expire_cookie(name: str, path: str = "/", domain: str = "") -> str:
    """
    Build a Set-Cookie header that immediately expires (deletes) a cookie.

    Example:
        header = expire_cookie("session")
        print(f"Set-Cookie: {header}")
    """
    return build_set_cookie(CookieSpec(
        name=name, value="", max_age=0,
        path=path, domain=domain,
        secure=False, httponly=False, samesite="Lax",
    ))


# ─────────────────────────────────────────────────────────────────────────────
# 3. Signed session token
# ─────────────────────────────────────────────────────────────────────────────

def _sign(value: str, secret: str) -> str:
    sig = hmac.new(secret.encode(), value.encode(), hashlib.sha256).hexdigest()
    return f"{value}.{sig}"


def _verify(signed: str, secret: str) -> str | None:
    """Return the payload if signature is valid, else None."""
    if "." not in signed:
        return None
    payload, _, sig = signed.rpartition(".")
    expected = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
    if hmac.compare_digest(sig, expected):
        return payload
    return None


def make_session_token(data: str, secret: str) -> str:
    """
    Create an HMAC-signed session token string (not base64 — plain hex sig).

    Example:
        token = make_session_token("user_id=42", secret="supersecret")
        verified = verify_session_token(token, secret="supersecret")
    """
    return _sign(data, secret)


def verify_session_token(token: str, secret: str) -> str | None:
    """
    Verify a signed session token.
    Returns the original data string if valid, None if tampered or invalid.

    Example:
        data = verify_session_token(cookie_value, secret="supersecret")
        if data is None:
            raise PermissionError("invalid session")
    """
    return _verify(token, secret)


def new_session_cookie(
    user_id: str | int,
    secret: str,
    max_age: int = 3600,
    domain: str = "",
) -> str:
    """
    Generate a new signed session cookie Set-Cookie value.

    Example:
        header = new_session_cookie(user_id=42, secret="mysecret")
        # response.headers["Set-Cookie"] = header
    """
    payload = f"uid={user_id};ts={int(time.time())}"
    token = make_session_token(payload, secret)
    spec = CookieSpec(
        name="session",
        value=token,
        max_age=max_age,
        domain=domain,
        secure=True,
        httponly=True,
        samesite="Lax",
    )
    return build_set_cookie(spec)


# ─────────────────────────────────────────────────────────────────────────────
# 4. Cookie audit
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class CookieAuditResult:
    name:     str
    warnings: list[str]

    @property
    def ok(self) -> bool:
        return len(self.warnings) == 0

    def __str__(self) -> str:
        if self.ok:
            return f"[OK]   {self.name}"
        return f"[WARN] {self.name}: {'; '.join(self.warnings)}"


def audit_cookie(name: str, header_value: str) -> CookieAuditResult:
    """
    Audit a Set-Cookie header value for common security issues.

    Example:
        result = audit_cookie("session", "session=tok; Path=/")
        print(result)
    """
    attrs = parse_set_cookie_header(header_value)
    warnings = []
    if not attrs.get("httponly"):
        warnings.append("missing HttpOnly (accessible via JS)")
    if not attrs.get("secure"):
        warnings.append("missing Secure (sent over HTTP)")
    samesite = str(attrs.get("samesite", "")).lower()
    if samesite not in ("strict", "lax"):
        warnings.append(f"SameSite={samesite!r} (prefer Strict or Lax)")
    if not attrs.get("max-age") and not attrs.get("expires"):
        warnings.append("session cookie (no expiry)")
    return CookieAuditResult(name=name, warnings=warnings)


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== http.cookies demo ===")

    # ── parse_cookie_header ───────────────────────────────────────────────────
    print("\n--- parse_cookie_header ---")
    cookies = parse_cookie_header("session=abc123; theme=dark; count=3")
    for k, v in cookies.items():
        print(f"  {k} = {v!r}")

    # ── build_set_cookie ───────────────────────────────────────────────────────
    print("\n--- build_set_cookie ---")
    spec = CookieSpec(
        name="session", value="tok_xyz789",
        max_age=3600, path="/", domain=".example.com",
        secure=True, httponly=True, samesite="Strict",
    )
    header = build_set_cookie(spec)
    print(f"  Set-Cookie: {header}")

    # ── build_cookie_jar ──────────────────────────────────────────────────────
    print("\n--- build_cookie_jar ---")
    headers = build_cookie_jar([
        CookieSpec("session", "tok_abc", max_age=3600),
        CookieSpec("pref",    "dark_mode", max_age=86400 * 30, httponly=False),
    ])
    for h in headers:
        print(f"  Set-Cookie: {h}")

    # ── expire_cookie ─────────────────────────────────────────────────────────
    print("\n--- expire_cookie ---")
    print(f"  Set-Cookie: {expire_cookie('session')}")

    # ── signed session token ───────────────────────────────────────────────────
    print("\n--- signed session ---")
    secret = secrets.token_hex(16)
    cookie_hdr = new_session_cookie(user_id=42, secret=secret)
    print(f"  Set-Cookie: {cookie_hdr[:80]}...")

    cookies2 = parse_cookie_header(f"session={cookie_hdr.split('=', 1)[1].split(';')[0]}")
    raw_token = cookies2.get("session", "")
    data = verify_session_token(raw_token, secret)
    print(f"  verified data: {data}")

    tampered = raw_token + "x"
    print(f"  tampered:      {verify_session_token(tampered, secret)}")

    # ── audit_cookie ───────────────────────────────────────────────────────────
    print("\n--- audit_cookie ---")
    tests = [
        ("good",    build_set_cookie(CookieSpec("good", "v", max_age=3600))),
        ("no-flags","no_flags=v; Path=/"),
        ("no-expiry", build_set_cookie(CookieSpec("noexp", "v", max_age=None))),
    ]
    for name, hdr in tests:
        result = audit_cookie(name, hdr)
        print(f"  {result}")

    print("\n=== done ===")

For the http.cookiejar alternative — http.cookiejar.CookieJar and urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar)) handle automatic cookie sending and storage in client-side HTTP sessions, with MozillaCookieJar and LWPCookieJar for file persistence — use http.cookiejar when you are writing an HTTP client that needs to automatically manage cookies across redirects and requests (like a browser session); use http.cookies when you are writing an HTTP server or middleware that needs to parse incoming Cookie: headers and generate outgoing Set-Cookie: headers. For the itsdangerous (PyPI) alternative — itsdangerous.URLSafeTimedSerializer(secret).dumps(data) and .loads(token, max_age=3600) provide tamper-proof, optionally timestamped signed cookies with structured data serialization — use itsdangerous in production web apps that need signed session cookies with expiry enforcement and structured payload; use http.cookies for zero-dependency header parsing and simple Set-Cookie generation in lightweight or stdlib-only environments. The Claude Skills 360 bundle includes http.cookies skill sets covering parse_cookie_header()/parse_set_cookie_header() parsers, CookieSpec with build_set_cookie()/build_cookie_jar()/expire_cookie() builders, make_session_token()/verify_session_token()/new_session_cookie() HMAC signing, and CookieAuditResult with audit_cookie() security checker. Start with the free tier to try HTTP cookie patterns and http.cookies pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free