feat(2): mattermost-lts create-message round-trip (§4.3 P3) — first-user→login→team→channel→post→read-back; harness http.post_with_headers (returns response headers, for mattermost login Token)
This commit is contained in:
@ -132,6 +132,40 @@ def http_request(
|
||||
return 0, None
|
||||
|
||||
|
||||
def post_with_headers(
|
||||
url: str,
|
||||
data: dict | bytes | None = None,
|
||||
headers: dict[str, str] | None = None,
|
||||
content_type: str = "application/json",
|
||||
timeout: int = 15,
|
||||
) -> tuple[int, object | None, dict[str, str]]:
|
||||
"""Like http_post but ALSO returns the response headers as a dict — for APIs that hand back an
|
||||
auth token in a response header rather than the body (e.g. mattermost login → `Token` header).
|
||||
Returns (status, parsed_json_or_None, response_headers). status=0 + {} on transport failure."""
|
||||
if isinstance(data, (bytes, bytearray)):
|
||||
body: bytes | None = bytes(data)
|
||||
elif content_type == "application/json" and data is not None:
|
||||
body = json.dumps(data).encode()
|
||||
elif content_type == "application/x-www-form-urlencoded" and data is not None:
|
||||
body = urllib.parse.urlencode(data).encode()
|
||||
else:
|
||||
body = None
|
||||
req = urllib.request.Request(url, data=body, method="POST")
|
||||
req.add_header("Content-Type", content_type)
|
||||
for k, v in (headers or {}).items():
|
||||
req.add_header(k, v)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=timeout, context=_CTX) as resp:
|
||||
return resp.getcode(), _parse_body(resp.read()), dict(resp.headers)
|
||||
except urllib.error.HTTPError as e:
|
||||
try:
|
||||
return e.code, _parse_body(e.read()), dict(e.headers or {})
|
||||
except Exception: # noqa: BLE001
|
||||
return e.code, None, dict(getattr(e, "headers", {}) or {})
|
||||
except Exception: # noqa: BLE001
|
||||
return 0, None, {}
|
||||
|
||||
|
||||
def assert_converges(
|
||||
fn,
|
||||
description: str,
|
||||
|
||||
Reference in New Issue
Block a user