HTTP Methods Reference — Python source
A searchable reference for every HTTP request method - GET, POST, PUT, PATCH, DELETE, and more. See at a glance which are safe, idempotent, and cacheable, then compare any two methods side by side.
This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.
"""HTTP request-method reference — pure, deterministic data + lookups.
CosmoDev polyglot showcase port of the ``http-methods`` tool, ported from
``src/lib/http-methods.ts``. Functionally equivalent to the TypeScript
original: identical inputs yield identical outputs (case-insensitive lookup,
flag + free-text filtering, and a human-readable semantic comparison report).
Property flags (safe / idempotent / cacheable / hasBody) follow RFC 9110
and the MDN reference table.
Display source — part of CosmoDev's polyglot tool pages.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Optional
@dataclass(frozen=True)
class MethodEntry:
"""One HTTP request method and its semantic properties.
Frozen so records are hashable and immutable — the canonical table is a
single source of truth that the helpers hand out references into.
"""
method: str
# Read-only semantics — no server state change.
safe: bool
# Repeating the call has the same effect as a single call.
idempotent: bool
# Responses may be stored by a cache (RFC 9110 / MDN).
cacheable: bool
# The method conventionally carries a request body.
has_body: bool
description: str
typical_use: str
# The nine HTTP request methods (RFC 9110 / 9111), in canonical order.
# Stored as a tuple to make the intent of "immutable sequence" explicit.
METHODS: tuple[MethodEntry, ...] = (
MethodEntry(
method="GET",
safe=True,
idempotent=True,
cacheable=True,
has_body=False,
description="Retrieves a representation of the target resource; a read-only request.",
typical_use="Fetching a web page, reading an API resource, loading an image.",
),
MethodEntry(
method="POST",
safe=False,
idempotent=False,
cacheable=True,
has_body=True,
description="Submits data to be processed, typically creating a new resource or triggering an action.",
typical_use="Submitting a form, creating a record, publishing a message.",
),
MethodEntry(
method="PUT",
safe=False,
idempotent=True,
cacheable=False,
has_body=True,
description="Replaces the target resource entirely with the request body.",
typical_use="Updating a full record at a known URL, uploading a file by its path.",
),
MethodEntry(
method="PATCH",
safe=False,
idempotent=False,
cacheable=False,
has_body=True,
description="Applies a partial modification to the target resource.",
typical_use="Updating one field of a record, toggling a flag.",
),
MethodEntry(
method="DELETE",
safe=False,
idempotent=True,
cacheable=False,
has_body=False,
description="Removes the target resource.",
typical_use="Deleting a record or file by its URL.",
),
MethodEntry(
method="HEAD",
safe=True,
idempotent=True,
cacheable=True,
has_body=False,
description="Identical to GET but returns only the response headers, no body.",
typical_use="Checking existence, size, or freshness before downloading.",
),
MethodEntry(
method="OPTIONS",
safe=True,
idempotent=True,
cacheable=False,
has_body=False,
description="Describes the communication options for the target resource.",
typical_use="CORS preflight requests, discovering allowed methods.",
),
MethodEntry(
method="CONNECT",
safe=False,
idempotent=False,
cacheable=False,
has_body=False,
description="Establishes a tunnel to the server (used with TLS/HTTPS proxies).",
typical_use="Proxying encrypted connections through an intermediary.",
),
MethodEntry(
method="TRACE",
safe=True,
idempotent=True,
cacheable=False,
has_body=False,
description="Performs a message loop-back test along the path to the target (debugging only).",
typical_use="Diagnosing request transformations by intermediaries.",
),
)
@dataclass
class MethodFilter:
"""Narrowing options for :func:`filter_methods`.
Each boolean is ``Optional[bool]`` so callers can distinguish "constrain
to ``False``" from "no constraint" — a tri-state a bare ``bool`` cannot
express. ``None`` (the default) means *no constraint*.
"""
safe: Optional[bool] = None
idempotent: Optional[bool] = None
cacheable: Optional[bool] = None
# Free text matched case-insensitively against method, description, typical_use.
query: Optional[str] = None
@dataclass
class MethodComparison:
"""Semantic diff between two methods."""
# Both methods share the `safe` flag.
same_safety: bool
# Both methods share the `idempotent` flag.
same_idempotence: bool
# One sentence per mismatched property (safe, idempotent, cacheable, has_body).
differences: list[str] = field(default_factory=list)
def get_method(name: str) -> Optional[MethodEntry]:
"""Case-insensitive single-method lookup.
Returns the entry, or ``None`` when unknown — the Python analogue of
TS's ``MethodEntry | null``.
"""
n = name.strip().upper()
return next((m for m in METHODS if m.method == n), None)
def filter_methods(opts: Optional[MethodFilter] = None) -> list[MethodEntry]:
"""Filter the method set by boolean flags and an optional text query.
A method must satisfy *every* present flag AND, when a query is given,
match it in at least one of {method, description, typical_use}.
"""
opts = opts if opts is not None else MethodFilter()
q = (opts.query or "").strip().lower()
def matches(m: MethodEntry) -> bool:
# Each present flag is an AND constraint; None means skip.
if opts.safe is not None and m.safe != opts.safe:
return False
if opts.idempotent is not None and m.idempotent != opts.idempotent:
return False
if opts.cacheable is not None and m.cacheable != opts.cacheable:
return False
if q:
return (
q in m.method.lower()
or q in m.description.lower()
or q in m.typical_use.lower()
)
return True
return [m for m in METHODS if matches(m)]
def compare_methods(a: MethodEntry, b: MethodEntry) -> MethodComparison:
"""Compare two methods, surfacing where their semantics agree and differ.
``differences`` lists every mismatched property (safe, idempotent,
cacheable, has_body) as a human-readable sentence, reproducing the
canonical phrasing verbatim so output stays identical across ports.
"""
differences: list[str] = []
if a.safe != b.safe:
differences.append(
f"{a.method} is {_safe_word(a.safe)}, {b.method} is {_safe_word(b.safe)}."
)
if a.idempotent != b.idempotent:
differences.append(
f"{a.method} is {_idempotent_word(a.idempotent)}, "
f"{b.method} is {_idempotent_word(b.idempotent)}."
)
if a.cacheable != b.cacheable:
differences.append(
f"{a.method} is {_cacheable_word(a.cacheable)}, "
f"{b.method} is {_cacheable_word(b.cacheable)}."
)
if a.has_body != b.has_body:
differences.append(
f"{a.method} {_body_word(a.has_body)}, {b.method} {_body_word(b.has_body)}."
)
return MethodComparison(
same_safety=a.safe == b.safe,
same_idempotence=a.idempotent == b.idempotent,
differences=differences,
)
# Phrasing helpers keep the canonical difference-sentence wording in one
# place, so the output stays in lock-step across every polyglot port.
def _safe_word(value: bool) -> str:
return "safe" if value else "not safe"
def _idempotent_word(value: bool) -> str:
return "idempotent" if value else "not idempotent"
def _cacheable_word(value: bool) -> str:
return "cacheable" if value else "not cacheable"
def _body_word(value: bool) -> str:
return "takes a body" if value else "does not take a body"
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 →