> ## Documentation Index
> Fetch the complete documentation index at: https://iso8583sim.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Mock host

> Mock issuer host: an asyncio TCP server that answers ISO 8583 requests by rules.

`iso8583sim.net.host`

## `Rule`

```python theme={null}
Rule(
    mti: list[str] = list(),
    pan_prefix: list[str] = list(),
    amount_gt: int | None = None,
    amount_lt: int | None = None,
    network: str | None = None,
    fields: dict[int, str] = dict(),
    respond: str = '00',
    action: str = 'respond',
    delay_ms: int = 0,
)
```

One response rule. The first rule whose conditions all match is used.

**Attributes**

<ResponseField name="mti" type="list[str]">
  Request MTIs this rule applies to (any when empty)
</ResponseField>

<ResponseField name="pan_prefix" type="list[str]">
  Only match cards whose PAN starts with one of these
</ResponseField>

<ResponseField name="amount_gt" type="int | None">
  Only match when field 4 is greater than this (minor units)
</ResponseField>

<ResponseField name="amount_lt" type="int | None">
  Only match when field 4 is less than this (minor units)
</ResponseField>

<ResponseField name="network" type="str | None">
  Only match this card network (e.g. "VISA")
</ResponseField>

<ResponseField name="fields" type="dict[int, str]">
  Only match when these fields have exactly these values
</ResponseField>

<ResponseField name="respond" type="str">
  Response code for field 39
</ResponseField>

<ResponseField name="action" type="str">
  "respond" (default), "drop" (never answer, to test timeouts) or
  "close" (close the connection)
</ResponseField>

<ResponseField name="delay_ms" type="int">
  Wait this long before answering
</ResponseField>

### `from_dict()`

```python theme={null}
def from_dict(data: dict[str, Any]) -> Rule
```

Build a rule from a rules-file entry: \{"match": \{...}, "respond": "51", ...}.

### `matches()`

```python theme={null}
def matches(request: ISO8583Message) -> bool
```

## `HostStats`

```python theme={null}
HostStats(
    received: int = 0,
    responded: int = 0,
    dropped: int = 0,
    errors: int = 0,
    response_codes: Counter[str] = Counter(),
)
```

Counters for what the mock host has seen and done.

## `MockHost`

```python theme={null}
MockHost(
    rules: list[Rule] | None = None,
    wire_format: WireFormat | None = None,
    framing: Framing | None = None,
    version: ISO8583Version = ISO8583Version.V1987,
)
```

A mock issuer host for testing acquirer and switch software.

**Example**

```python theme={null}
host = MockHost(rules=[Rule(amount_gt=100000, respond="51"), Rule()])
server = await host.start("127.0.0.1", 8583)
```

### `rule_for()`

```python theme={null}
def rule_for(request: ISO8583Message) -> Rule
```

### `build_response()`

```python theme={null}
def build_response(request: ISO8583Message, code: str) -> ISO8583Message
```

Build the response to a request with the given response code.

### `start()`

```python theme={null}
async def start(host: str = '127.0.0.1', port: int = 8583) -> asyncio.Server
```

Start listening. Returns the asyncio server (port 0 picks a free port).

### `stop()`

```python theme={null}
async def stop() -> None
```

### `port`

The port the host is listening on.

## Functions

### `load_rules()`

```python theme={null}
def load_rules(path: str | Path) -> list[Rule]
```

Load rules from a JSON or YAML file with a top-level "rules" list.

### `response_mti()`

```python theme={null}
def response_mti(mti: str) -> str
```

0100 -> 0110, 0200 -> 0210, 0400 -> 0410, 0800 -> 0810, 0120 -> 0130.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.