Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:MarketSquare Robotframework browser Format Response

From Leeroopedia
Revision as of 11:29, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/MarketSquare_Robotframework_browser_Format_Response.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Format Response

API documentation for the internal helper functions that transform raw HTTP response data into structured Python objects.

Overview

The response formatting helpers are module-level functions defined at the top of Browser/keywords/network.py. They are not Robot Framework keywords -- they are internal Python functions used by the HTTP, Wait For Response, and related keywords to process raw gRPC response data into structured, queryable dictionaries. These functions handle JSON auto-parsing of response bodies, header string-to-dictionary conversion, and Content-Type detection.

Source Location

Function File Lines
_get_headers Browser/keywords/network.py L26-31
_format_response Browser/keywords/network.py L34-40
_jsonize_content Browser/keywords/network.py L43-54

Function: _get_headers

Signature

def _get_headers(body: str, headers: dict):

Purpose

Determines whether the request body is JSON and, if so, automatically adds a Content-Type: application/json header. This function is called before sending an HTTP request (used by the http keyword).

Implementation

def _get_headers(body: str, headers: dict):
    try:
        json.loads(body)
        return {"Content-Type": "application/json", **headers}
    except json.decoder.JSONDecodeError:
        return headers

Behavior

  1. Attempts to parse the body string as JSON using json.loads().
  2. If parsing succeeds: Returns a new dictionary with Content-Type: application/json merged with the caller-provided headers. The caller's headers take precedence due to the **headers spread appearing after the Content-Type entry (if the caller explicitly sets Content-Type, it overrides the auto-detected value).
  3. If parsing fails (raises json.decoder.JSONDecodeError): Returns the caller-provided headers unchanged.

Parameters

Parameter Type Description
body str The request body string to test for JSON validity.
headers dict The caller-provided request headers dictionary.

Returns

A dictionary of headers, potentially with Content-Type: application/json prepended.

Function: _format_response

Signature

def _format_response(response: dict) -> dict:

Purpose

Transforms a raw response dictionary (deserialized from gRPC JSON) into a properly structured dictionary with parsed headers and auto-parsed JSON bodies. This is the main entry point for response formatting.

Implementation

def _format_response(response: dict) -> dict:
    _jsonize_content(response, "body")
    if "request" in response:
        request = response["request"]
        _jsonize_content(request, "postData")
    logger.info(response)
    return response

Behavior

  1. Calls _jsonize_content(response, "body") to parse response headers and conditionally parse the response body as JSON.
  2. If the response dictionary contains a request sub-dictionary (present in Wait For Response results), calls _jsonize_content(request, "postData") to parse request headers and conditionally parse the request's post data as JSON.
  3. Logs the formatted response at INFO level.
  4. Returns the modified response dictionary (the dictionary is mutated in place by _jsonize_content).

Parameters

Parameter Type Description
response dict The raw response dictionary, typically produced by json.loads() on the gRPC response JSON.

Returns

The same dictionary, modified in place with parsed headers and optionally parsed body/postData.

Function: _jsonize_content

Signature

def _jsonize_content(data, bodykey):

Purpose

Converts stringified headers to a dictionary and conditionally parses a body field (identified by bodykey) from JSON string to Python dictionary, based on the Content-Type header.

Implementation

def _jsonize_content(data, bodykey):
    headers = json.loads(data.get("headers", "{}"))
    data["headers"] = headers
    lower_headers = {k.lower(): v for k, v in headers.items()}
    if (
        "content-type" in lower_headers
        and "application/json" in lower_headers["content-type"]
        and bodykey in data
        and data[bodykey]
    ):
        with contextlib.suppress(json.decoder.JSONDecodeError, TypeError):
            data[bodykey] = json.loads(data[bodykey])

Behavior

  1. Header parsing: Parses the headers field from a JSON string to a Python dictionary. If headers is missing, defaults to an empty dictionary ("{}").
  2. Case-insensitive Content-Type check: Creates a lowercase copy of all header keys to perform a case-insensitive lookup for content-type.
  3. Conditional body parsing: If all of the following conditions are true, the body field is parsed as JSON:
    • The headers contain a content-type key (case-insensitive).
    • The content-type value contains the substring application/json.
    • The bodykey exists in the data dictionary.
    • The body value is truthy (not None, not empty string).
  4. Error suppression: If JSON parsing fails (JSONDecodeError) or encounters a type error (TypeError), the error is silently suppressed and the body remains as its original string value.

Parameters

Parameter Type Description
data dict The dictionary to process (either the response dict or the nested request dict).
bodykey str The key name of the body field to conditionally parse. Typically "body" for responses or "postData" for requests.

Returns

None. The function modifies the data dictionary in place.

How These Functions Are Used

In the HTTP keyword (L104):

# Before sending the request:
headers=json.dumps(_get_headers(body, headers))

# After receiving the response:
response_dict = _format_response(json.loads(response.json))
return DotDict(response_dict)

In _wait_for_http_response (L134-140):

response_json = json.loads(responce.json)
# Body may have been streamed in chunks:
if response_json.get("body", not_none) is not None and body:
    response_json["body"] = body
return _format_response(response_json)

Data Flow Diagram

The complete data flow from Node.js to the Robot Framework test:

Node.js (fetch/waitForResponse)
  |
  v
gRPC Response (JSON string)
  |  - headers: '{"content-type": "application/json"}'
  |  - body: '{"users": [{"id": 1, "name": "John"}]}'
  |  - status: 200
  |
  v
json.loads() -> Python dict
  |  - headers: '{"content-type": "application/json"}'  (still a string)
  |  - body: '{"users": [{"id": 1, "name": "John"}]}'   (still a string)
  |
  v
_format_response() -> _jsonize_content()
  |  - headers: {"content-type": "application/json"}     (now a dict)
  |  - body: {"users": [{"id": 1, "name": "John"}]}     (now a dict)
  |
  v
DotDict() wrapping
  |  - ${response.headers}          -> dict
  |  - ${response.body.users}       -> list
  |  - ${response.body.users[0].name} -> "John"
  |
  v
Robot Framework test assertions

Important Notes

  • These functions are module-level (not methods on the Network class), so they do not have access to self or any library state.
  • The _format_response function mutates its input dictionary rather than creating a copy. This is intentional for efficiency.
  • The _get_headers function is only used for outgoing requests (the HTTP keyword), while _format_response and _jsonize_content are used for incoming response processing.
  • The Content-Type check uses in (substring match), so content types like application/json; charset=utf-8 are correctly detected.

Domains

Related

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment