Skip to content

Mapping

Overview

The mapping module provides bidirectional attribute translation between developer-friendly snake_case names and native MQSC parameter names. The mapper is used internally by MQRESTSession and is not typically called directly.

See Mapping Pipeline for a conceptual overview of how mapping works.

Mapping functions

The module exposes three public functions that perform the actual translation. These are called internally by MQRESTSession during command execution:

  • map_request_attributes() — Translates request parameters from snake_case to MQSC before sending to the REST API. Performs key mapping, value mapping, and key-value mapping in sequence.

  • map_response_attributes() — Translates a single response dict from MQSC to snake_case after receiving from the REST API.

  • map_response_list() — Translates a list of response dicts (the common return type for DISPLAY commands).

The mapper performs three types of translation in each direction:

  • Key mapping: Attribute name translation (e.g. current_queue_depthCURDEPTH)
  • Value mapping: Enumerated value translation (e.g. "yes""YES", "server_connection""SVRCONN")
  • Key-value mapping: Combined name+value translation for cases where both key and value change together (e.g. channel_type="server_connection"CHLTYPE("SVRCONN"))

Mapping data

The mapping tables are loaded from the JSON resource file at:

pymqrest/mapping_data.json

The data is organized by qualifier (e.g. queue, channel, qmgr) with separate maps for request and response directions. Each qualifier contains:

  • request_key_mapsnake_case → MQSC key mapping for requests
  • request_value_map — value translations for request attributes
  • request_key_value_map — combined key+value translations for requests
  • response_key_map — MQSC → snake_case key mapping for responses
  • response_value_map — value translations for response attributes

The mapping data was originally bootstrapped from IBM MQ 9.4 documentation and covers all standard MQSC attributes across 42 qualifiers.

Diagnostics

MappingIssue

Tracks mapping problems encountered during translation:

  • Unknown attribute names (not found in key map)
  • Unknown attribute values (not found in value map)
  • Ambiguous mappings

In strict mode, any MappingIssue causes a MappingError. In lenient mode, issues are collected but the unmapped values pass through unchanged.

MappingError

Raised when attribute mapping fails in strict mode. Contains the list of MappingIssue instances that caused the failure.

try:
    session.display_queue("MY.QUEUE",
        response_parameters=["invalid_attribute_name"])
except MappingError as e:
    # e describes the unmappable attributes
    print(e)

API reference

Map request attributes from snake_case into MQSC parameter names.

Translates Python-friendly attribute names and values into the native MQSC forms expected by the MQ REST API.

Parameters:

Name Type Description Default
qualifier str

The mapping qualifier (e.g. "queue", "channel"). See :doc:/mappings/index for available qualifiers.

required
attributes Mapping[str, object]

Request attributes keyed by snake_case names.

required
strict bool

When True (default), raise :class:MappingError on any unrecognised key, value, or qualifier. When False, pass unrecognised attributes through unchanged.

True
mapping_data Mapping[str, object] | None

Optional mapping data to use instead of the built-in :data:MAPPING_DATA. When None (default), the module-level data is used.

None

Returns:

Type Description
dict[str, object]

A new dict with MQSC parameter names as keys.

Raises:

Type Description
MappingError

If strict is True and any attribute cannot be mapped.

Source code in src/pymqrest/mapping.py
def map_request_attributes(
    qualifier: str,
    attributes: Mapping[str, object],
    *,
    strict: bool = True,
    mapping_data: Mapping[str, object] | None = None,
) -> dict[str, object]:
    """Map request attributes from ``snake_case`` into MQSC parameter names.

    Translates Python-friendly attribute names and values into the
    native MQSC forms expected by the MQ REST API.

    Args:
        qualifier: The mapping qualifier (e.g. ``"queue"``, ``"channel"``).
            See :doc:`/mappings/index` for available qualifiers.
        attributes: Request attributes keyed by ``snake_case`` names.
        strict: When ``True`` (default), raise :class:`MappingError`
            on any unrecognised key, value, or qualifier. When ``False``,
            pass unrecognised attributes through unchanged.
        mapping_data: Optional mapping data to use instead of the
            built-in :data:`MAPPING_DATA`. When ``None`` (default),
            the module-level data is used.

    Returns:
        A new dict with MQSC parameter names as keys.

    Raises:
        MappingError: If *strict* is ``True`` and any attribute cannot
            be mapped.

    """
    qualifier_data = _get_qualifier_data(qualifier, mapping_data=mapping_data)
    if qualifier_data is None:
        return _handle_unknown_qualifier(
            qualifier,
            attributes,
            direction="request",
            strict=strict,
        )
    return _map_attributes(
        qualifier=qualifier,
        attributes=attributes,
        key_map=_get_key_map(qualifier_data, "request_key_map"),
        key_value_map=_get_key_value_map(qualifier_data, "request_key_value_map"),
        value_map=_get_value_map(qualifier_data, "request_value_map"),
        direction="request",
        strict=strict,
    )

Map response attributes from MQSC parameter names to snake_case.

Translates native MQSC attribute names and values returned by the MQ REST API into Python-friendly snake_case forms.

Parameters:

Name Type Description Default
qualifier str

The mapping qualifier (e.g. "queue", "channel"). See :doc:/mappings/index for available qualifiers.

required
attributes Mapping[str, object]

Response attributes keyed by MQSC parameter names.

required
strict bool

When True (default), raise :class:MappingError on any unrecognised key, value, or qualifier. When False, pass unrecognised attributes through unchanged.

True
mapping_data Mapping[str, object] | None

Optional mapping data to use instead of the built-in :data:MAPPING_DATA. When None (default), the module-level data is used.

None

Returns:

Type Description
dict[str, object]

A new dict with snake_case attribute names as keys.

Raises:

Type Description
MappingError

If strict is True and any attribute cannot be mapped.

Source code in src/pymqrest/mapping.py
def map_response_attributes(
    qualifier: str,
    attributes: Mapping[str, object],
    *,
    strict: bool = True,
    mapping_data: Mapping[str, object] | None = None,
) -> dict[str, object]:
    """Map response attributes from MQSC parameter names to ``snake_case``.

    Translates native MQSC attribute names and values returned by the
    MQ REST API into Python-friendly ``snake_case`` forms.

    Args:
        qualifier: The mapping qualifier (e.g. ``"queue"``, ``"channel"``).
            See :doc:`/mappings/index` for available qualifiers.
        attributes: Response attributes keyed by MQSC parameter names.
        strict: When ``True`` (default), raise :class:`MappingError`
            on any unrecognised key, value, or qualifier. When ``False``,
            pass unrecognised attributes through unchanged.
        mapping_data: Optional mapping data to use instead of the
            built-in :data:`MAPPING_DATA`. When ``None`` (default),
            the module-level data is used.

    Returns:
        A new dict with ``snake_case`` attribute names as keys.

    Raises:
        MappingError: If *strict* is ``True`` and any attribute cannot
            be mapped.

    """
    qualifier_data = _get_qualifier_data(qualifier, mapping_data=mapping_data)
    if qualifier_data is None:
        return _handle_unknown_qualifier(
            qualifier,
            attributes,
            direction="response",
            strict=strict,
        )
    return _map_attributes(
        qualifier=qualifier,
        attributes=attributes,
        key_map=_get_key_map(qualifier_data, "response_key_map"),
        key_value_map={},
        value_map=_get_value_map(qualifier_data, "response_value_map"),
        direction="response",
        strict=strict,
    )

Map a list of response objects from MQSC names to snake_case.

This is the batch equivalent of :func:map_response_attributes. Each object in the list is mapped independently, and issue tracking includes the object_index so problems can be traced to a specific item.

Parameters:

Name Type Description Default
qualifier str

The mapping qualifier (e.g. "queue", "channel"). See :doc:/mappings/index for available qualifiers.

required
objects Sequence[Mapping[str, object]]

Sequence of response attribute dicts to map.

required
strict bool

When True (default), raise :class:MappingError if any attribute in any object cannot be mapped. When False, pass unrecognised attributes through unchanged.

True
mapping_data Mapping[str, object] | None

Optional mapping data to use instead of the built-in :data:MAPPING_DATA. When None (default), the module-level data is used.

None

Returns:

Type Description
list[dict[str, object]]

A list of dicts with snake_case attribute names.

Raises:

Type Description
MappingError

If strict is True and any attribute cannot be mapped. The error's :attr:~MappingError.issues may span multiple objects.

Source code in src/pymqrest/mapping.py
def map_response_list(
    qualifier: str,
    objects: Sequence[Mapping[str, object]],
    *,
    strict: bool = True,
    mapping_data: Mapping[str, object] | None = None,
) -> list[dict[str, object]]:
    """Map a list of response objects from MQSC names to ``snake_case``.

    This is the batch equivalent of :func:`map_response_attributes`.
    Each object in the list is mapped independently, and issue tracking
    includes the ``object_index`` so problems can be traced to a
    specific item.

    Args:
        qualifier: The mapping qualifier (e.g. ``"queue"``, ``"channel"``).
            See :doc:`/mappings/index` for available qualifiers.
        objects: Sequence of response attribute dicts to map.
        strict: When ``True`` (default), raise :class:`MappingError`
            if any attribute in any object cannot be mapped. When
            ``False``, pass unrecognised attributes through unchanged.
        mapping_data: Optional mapping data to use instead of the
            built-in :data:`MAPPING_DATA`. When ``None`` (default),
            the module-level data is used.

    Returns:
        A list of dicts with ``snake_case`` attribute names.

    Raises:
        MappingError: If *strict* is ``True`` and any attribute cannot
            be mapped. The error's :attr:`~MappingError.issues` may
            span multiple objects.

    """
    qualifier_data = _get_qualifier_data(qualifier, mapping_data=mapping_data)
    if qualifier_data is None:
        return _handle_unknown_qualifier_list(
            qualifier,
            objects,
            direction="response",
            strict=strict,
        )
    key_map = _get_key_map(qualifier_data, "response_key_map")
    value_map = _get_value_map(qualifier_data, "response_value_map")
    mapped_objects: list[dict[str, object]] = []
    issues: list[MappingIssue] = []
    for object_index, attributes in enumerate(objects):
        mapped_attributes, attribute_issues = _map_attributes_internal(
            qualifier=qualifier,
            attributes=attributes,
            key_map=key_map,
            key_value_map={},
            value_map=value_map,
            direction="response",
            object_index=object_index,
        )
        mapped_objects.append(mapped_attributes)
        issues.extend(attribute_issues)
    if strict and issues:
        raise MappingError(issues)
    return mapped_objects

Single mapping issue recorded during attribute translation.

Each issue describes one attribute that could not be fully mapped (unknown key, unknown value, or unknown qualifier).

Attributes:

Name Type Description
direction MappingDirection

Whether the issue occurred during "request" or "response" mapping.

reason MappingReason

Category of the mapping failure — "unknown_key", "unknown_value", or "unknown_qualifier".

attribute_name str

The attribute name that triggered the issue.

attribute_value object | None

The attribute value, if relevant to the issue.

object_index int | None

Zero-based index within a response list, or None for single-object operations.

qualifier str | None

The qualifier that was being mapped, or None if not applicable.

Source code in src/pymqrest/mapping.py
@dataclass(frozen=True)
class MappingIssue:
    """Single mapping issue recorded during attribute translation.

    Each issue describes one attribute that could not be fully mapped
    (unknown key, unknown value, or unknown qualifier).

    Attributes:
        direction: Whether the issue occurred during ``"request"`` or
            ``"response"`` mapping.
        reason: Category of the mapping failure — ``"unknown_key"``,
            ``"unknown_value"``, or ``"unknown_qualifier"``.
        attribute_name: The attribute name that triggered the issue.
        attribute_value: The attribute value, if relevant to the issue.
        object_index: Zero-based index within a response list, or
            ``None`` for single-object operations.
        qualifier: The qualifier that was being mapped, or ``None``
            if not applicable.

    """

    direction: MappingDirection
    reason: MappingReason
    attribute_name: str
    attribute_value: object | None = None
    object_index: int | None = None
    qualifier: str | None = None

    def to_payload(self) -> dict[str, object | None]:
        """Return the issue as a JSON-serialisable dict.

        Returns:
            A dict with keys ``direction``, ``reason``,
            ``attribute_name``, ``attribute_value``, ``object_index``,
            and ``qualifier``.

        """
        return {
            "direction": self.direction,
            "reason": self.reason,
            "attribute_name": self.attribute_name,
            "attribute_value": _serialize_value(self.attribute_value),
            "object_index": self.object_index,
            "qualifier": self.qualifier,
        }

to_payload()

Return the issue as a JSON-serialisable dict.

Returns:

Type Description
dict[str, object | None]

A dict with keys direction, reason,

dict[str, object | None]

attribute_name, attribute_value, object_index,

dict[str, object | None]

and qualifier.

Source code in src/pymqrest/mapping.py
def to_payload(self) -> dict[str, object | None]:
    """Return the issue as a JSON-serialisable dict.

    Returns:
        A dict with keys ``direction``, ``reason``,
        ``attribute_name``, ``attribute_value``, ``object_index``,
        and ``qualifier``.

    """
    return {
        "direction": self.direction,
        "reason": self.reason,
        "attribute_name": self.attribute_name,
        "attribute_value": _serialize_value(self.attribute_value),
        "object_index": self.object_index,
        "qualifier": self.qualifier,
    }

Bases: Exception

Raised when attribute mapping fails in strict mode.

Contains one or more :class:MappingIssue instances describing exactly which attributes could not be mapped and why.

Attributes:

Name Type Description
issues

Tuple of :class:MappingIssue instances captured during the failed mapping operation.

Source code in src/pymqrest/mapping.py
class MappingError(Exception):
    """Raised when attribute mapping fails in strict mode.

    Contains one or more :class:`MappingIssue` instances describing
    exactly which attributes could not be mapped and why.

    Attributes:
        issues: Tuple of :class:`MappingIssue` instances captured
            during the failed mapping operation.

    """

    def __init__(self, issues: Sequence[MappingIssue], message: str | None = None) -> None:
        """Initialize a mapping error with the captured issues.

        Args:
            issues: One or more mapping issues that caused the failure.
            message: Optional override message. When ``None``, a message
                is built automatically from the issues.

        """
        self.issues = tuple(issues)
        if message is None:
            message = self._build_message()
        super().__init__(message)

    def _build_message(self) -> str:
        if not self.issues:
            return "Mapping failed with no issues reported."
        issue_lines = []
        for issue in self.issues:
            index_label = "-"
            if issue.object_index is not None:
                index_label = str(issue.object_index)
            qualifier_label = issue.qualifier or "-"
            value_label = "-"
            if issue.attribute_value is not None:
                value_label = repr(issue.attribute_value)
            issue_lines.append(
                " | ".join(
                    [
                        f"index={index_label}",
                        f"qualifier={qualifier_label}",
                        f"direction={issue.direction}",
                        f"reason={issue.reason}",
                        f"attribute={issue.attribute_name}",
                        f"value={value_label}",
                    ],
                ),
            )
        header = f"Mapping failed with {len(self.issues)} issue(s):"
        return "\n".join([header, *issue_lines])

    def to_payload(self) -> list[dict[str, object | None]]:
        """Return mapping issues as JSON-serialisable dicts.

        Returns:
            A list of dicts, one per issue (see
            :meth:`MappingIssue.to_payload`).

        """
        return [issue.to_payload() for issue in self.issues]

issues = tuple(issues) instance-attribute

__init__(issues, message=None)

Initialize a mapping error with the captured issues.

Parameters:

Name Type Description Default
issues Sequence[MappingIssue]

One or more mapping issues that caused the failure.

required
message str | None

Optional override message. When None, a message is built automatically from the issues.

None
Source code in src/pymqrest/mapping.py
def __init__(self, issues: Sequence[MappingIssue], message: str | None = None) -> None:
    """Initialize a mapping error with the captured issues.

    Args:
        issues: One or more mapping issues that caused the failure.
        message: Optional override message. When ``None``, a message
            is built automatically from the issues.

    """
    self.issues = tuple(issues)
    if message is None:
        message = self._build_message()
    super().__init__(message)

_build_message()

Source code in src/pymqrest/mapping.py
def _build_message(self) -> str:
    if not self.issues:
        return "Mapping failed with no issues reported."
    issue_lines = []
    for issue in self.issues:
        index_label = "-"
        if issue.object_index is not None:
            index_label = str(issue.object_index)
        qualifier_label = issue.qualifier or "-"
        value_label = "-"
        if issue.attribute_value is not None:
            value_label = repr(issue.attribute_value)
        issue_lines.append(
            " | ".join(
                [
                    f"index={index_label}",
                    f"qualifier={qualifier_label}",
                    f"direction={issue.direction}",
                    f"reason={issue.reason}",
                    f"attribute={issue.attribute_name}",
                    f"value={value_label}",
                ],
            ),
        )
    header = f"Mapping failed with {len(self.issues)} issue(s):"
    return "\n".join([header, *issue_lines])

to_payload()

Return mapping issues as JSON-serialisable dicts.

Returns:

Type Description
list[dict[str, object | None]]

A list of dicts, one per issue (see

list[dict[str, object | None]]

meth:MappingIssue.to_payload).

Source code in src/pymqrest/mapping.py
def to_payload(self) -> list[dict[str, object | None]]:
    """Return mapping issues as JSON-serialisable dicts.

    Returns:
        A list of dicts, one per issue (see
        :meth:`MappingIssue.to_payload`).

    """
    return [issue.to_payload() for issue in self.issues]