# Python Microsoft Fabric API - Events

The Kafka and REST connections for an eventstream endpoint, and the KQL query request and response.

Events do not go through the Fabric connection. An eventstream's custom endpoint accepts Kafka and REST clients, and an eventhouse runs KQL queries sent over REST, so the connections below are Zato's Kafka and REST connections configured for Fabric. This page lists their fields, and the [sending](https://zato.io/docs/dev/examples/cloud/fabric/sending-events.html), [receiving](https://zato.io/docs/dev/examples/cloud/fabric/receiving-events.html) and [reading](https://zato.io/docs/dev/examples/cloud/fabric/reading-events.html) pages use them in services.

## Where the values come from {#where-the-values-come-from}

All values on this page come from the Keys tab of the eventstream's custom endpoint, whether it is a source (Zato sends) or a destination (Zato receives):

| On the Keys tab | Used as |
| --- | --- |
| Bootstrap server | The Kafka address, `<namespace>.servicebus.windows.net:9093` |
| Topic name | The Kafka topic, and the `<entity>` in the REST address |
| Connection string-primary key | The password of a Basic Auth definition for the `PLAIN` mechanism |
| Consumer group | The Kafka channel's consumer group, one created for Zato |

The namespace is the first part of the bootstrap server, up to `.servicebus.windows.net`.

## Security definitions {#security-definitions}

Two kinds of definition sign a Kafka connection in, and both are created under `Security` in the Dashboard:

| Mechanism | Definition | Fields |
| --- | --- | --- |
| `OAUTHBEARER` | Bearer token | Username the application (client) ID, Password the client secret, Auth endpoint `https://login.microsoftonline.com/<tenant ID>/oauth2/v2.0/token`, Scopes `https://<namespace>.servicebus.windows.net/.default` |
| `PLAIN` | Basic Auth | Username `$$ConnectionString`, Password the connection string |

The username is entered as `$$ConnectionString` because a value starting with a single `$` names an environment variable, and doubling the sign gives the literal `$ConnectionString` the endpoint expects.

## Kafka outgoing connection {#kafka-outgoing-connection}

Under `Connections → Message queues → Kafka → Outgoing connections`:

| Field | Value |
| --- | --- |
| Name | Any, used as `self.out.kafka[name]` |
| Address | The bootstrap server |
| Topic | The topic name |
| SSL | On |
| Security | The Bearer token or Basic Auth definition |
| SASL mechanism | `OAUTHBEARER` or `PLAIN`, matching the definition |

```yaml
outgoing_kafka:
  - name: Fabric Events
    address: <namespace>.servicebus.windows.net:9093
    topic: <topic name>
    security: Fabric Events Token
    sasl_mechanism: OAUTHBEARER
    ssl: true
```

A dict passed to `send` is JSON-encoded before it leaves:

```python
event = {
    'event_type': 'admission',
    'location': 'Riverside',
    'admission_id': 'ADM-1041',
}

self.out.kafka['Fabric Events'].send(event)
```

## Kafka channel {#kafka-channel}

Under `Connections → Message queues → Kafka → Channels`:

| Field | Value |
| --- | --- |
| Name | Any |
| Address | The bootstrap server |
| Topic | The topic name |
| Consumer group | The group created for Zato on the destination |
| Service | The service to run for each event |
| SSL | On |
| Security | The Bearer token or Basic Auth definition |
| SASL mechanism | `OAUTHBEARER` or `PLAIN`, matching the definition |

```yaml
channel_kafka:
  - name: Fabric Alerts
    address: <namespace>.servicebus.windows.net:9093
    topic: <topic name>
    group_id: zato
    service: stock.notify-purchasing
    security: Fabric Events Token
    sasl_mechanism: OAUTHBEARER
    ssl: true
```

The service receives the event's bytes in `self.request.raw_request`:

```python
event = json.loads(self.request.raw_request)
```

## REST alternative for sending {#rest-alternative-for-sending}

When Kafka is not an option, the same endpoint takes events over HTTPS. Under `Connections → REST → Outgoing connections`:

| Field | Value |
| --- | --- |
| Host | `https://<namespace>.servicebus.windows.net` |
| URL path | `/<topic name>/messages` |
| Data format | JSON |
| Security | A Bearer token definition with Scopes `https://eventhubs.azure.net/.default` |

The body is a list of events, each wrapped in `Body`, sent with the endpoint's own content type:

```python
body = json.dumps(event)
payload = [{'Body': body}]
headers = {'Content-Type': 'application/vnd.microsoft.servicebus.json'}

self.rest['Fabric Events REST'].post(self.cid, payload, headers=headers)
```

## KQL query over REST {#kql-query-over-rest}

An eventhouse accepts queries at `/v1/rest/query` on its Query URI, which is on the eventhouse's overview page. Under `Connections → REST → Outgoing connections`:

| Field | Value |
| --- | --- |
| Host | The Query URI, `https://<cluster>.kusto.fabric.microsoft.com` |
| URL path | `/v1/rest/query` |
| Data format | JSON |
| Security | A Bearer token definition with Scopes `https://kusto.kusto.windows.net/.default` |

The request names the database and carries the query:

```json
{"db": "Operations Events", "csl": "Events | where event_type == 'cancellation' | summarize cancelled = count() by location"}
```

The response is a list of tables. The first one is the query's result, with the columns described in `Columns` and the values in `Rows`, in the same order:

```json
{
  "Tables": [
    {
      "TableName": "Table_0",
      "Columns": [
        {"ColumnName": "location", "DataType": "String"},
        {"ColumnName": "cancelled", "DataType": "Int64"}
      ],
      "Rows": [
        ["Maple Grove", 1]
      ]
    }
  ]
}
```

Zipping each row with the column names gives one dict per row:

```python
tables = response.data['Tables']
result = tables[0]

column_names = []
for column in result['Columns']:
    column_names.append(column['ColumnName'])

rows = []
for values in result['Rows']:
    pairs = zip(column_names, values)
    row = dict(pairs)
    rows.append(row)
```

## See also {#see-also}

- [Sending events as they happen](https://zato.io/docs/dev/examples/cloud/fabric/sending-events.html) - A service sending events over Kafka and over REST
- [Receiving events as they happen](https://zato.io/docs/dev/examples/cloud/fabric/receiving-events.html) - A Kafka channel running a service for each event
- [Reading recent events](https://zato.io/docs/dev/examples/cloud/fabric/reading-events.html) - A KQL query run on demand and on a schedule
- [Connection](https://zato.io/docs/dev/examples/cloud/fabric/api/connection.html) - The app registration these definitions sign in as

## Learn more {#learn-more}

- [Development documentation](https://zato.io/docs/dev/) - Everything about writing services, in one place
- [Requests and responses](https://zato.io/docs/dev/request-response/) - What a service receives, what it returns and how to shape both
- [Integration examples](https://zato.io/docs/dev/examples/) - Ready-made code for the systems you are likely to connect to
- [IDE and debugging](https://zato.io/docs/dev/ide/) - Write services in the Dashboard or in your own editor
- [Data models](https://zato.io/docs/dev/model/) - Declare inputs and outputs and have them validated for you
- [In-depth API tutorial](https://zato.io/tutorials/main/01.html) - The full platform tutorial, from installation to production patterns
