Introduction to Machine Readable News with WebSocket API 

    Wasin Waeosri
    Developer Advocate

Introduction

Update: March 2025

This article shows how developers may use the Real-Time Websocket API aka Websocket API application to subscribe Machine Readable News (MRN) from Real-Time Distribution System (Advanced Data Hub and Real-Time Advanced Distribution Server), then assemble and decode MRN textual news message to display news in a console/Jupyter Notebook.

Machine Readable News (MRN) is an advanced service for automating the consumption and systematic analysis of news. It delivers deep historical news archives, ultra-low latency structured news, and news analytics directly to your applications. This enables algorithms to exploit the power of news to seize opportunities, capitalize on market inefficiencies, and manage event risk.

Update (As of March 2025): The GitHub example 's Main/Master branch now supports the Real-Time - Optimized (RTO) connection. You do not need to switch to the ERT-in-Cloud branch anymore.

WebSocket API Overview and Prerequisite

The WebSocket API is direct access that enables easy integration into a multitude of client technology environments such as scripting and web. This API runs directly on your Real-Time Distribution System infrastructure or the on the cloud and presents data in an open (JSON) readable format.

This example is focusing on the Machine Readable News (MRN) data processing only. I highly recommend you check the WebSocket API Tutorials page if you are not familiar with WebSocket API.

The Tutorials page provides a step-by-step guide (connect, log in, request data, parse data, etc) for developers who are interested in developing a WebSocket application to consume real-time data from Real-Time platform. The Tutorials also cover both Real-Time Optimized (RTO) and deployed Real-Time Distribution System (RTDS) infrastructure connection scenarios.

MRN Overview

MRN is published over Real-Time platform using an Open Message Model (OMM) envelope in News Text Analytics domain messages. The Real-time News content set is made available over MRN_STORY RIC. The content data is contained in a FRAGMENT field that has been compressed and potentially fragmented across multiple messages, to reduce bandwidth and message size.

A FRAGMENT field has a different data type based on a connection type:

  • RSSL connection (RTSDK C++/Java/C#): BUFFER type
  • WebSocket connection: Base64 ASCII string

The data goes through the following series of transformations:

  1. The core content data is a UTF-8 JSON string
  2. This JSON string is compressed using gzip
  3. The compressed JSON is split into several fragments (BUFFER or Base64 ASCII string) which each fit into a single update message
  4. The data fragments are added to an update message as the FRAGMENT field value in a FieldList envelope

Therefore, to parse the core content data, the application will need to reverse this process.

Data Model

Five fields, as well as the RIC itself, are necessary to determine whether the entire item has been received in its various fragments and how to concatenate the fragments to reconstruct the item:

  • MRN_SRC: identifier of the scoring/processing system that published the FRAGMENT;
  • GUID: globally unique identifier for the data item, all messages for this data item will have the same GUID value;
  • FRAGMENT: compressed data item fragment;
  • TOT_SIZE: total size in bytes of the fragmented data;
  • FRAG_NUM: sequence number of fragments within a data item, which is set to 1 for the first fragment of each item published

and is incremented for each subsequent fragment for the same item. A single MRN data item publication is uniquely identified by the combination of RIC name, MRN_SRC, and GUID.

Fragmentation

For a given RIC/MRN_SRC/GUID combination, when a data item requires only a single message, then TOT_SIZE will equal the number of bytes length in the FRAGMENT and FRAG_NUM will be 1.

When multiple messages are required, then the data item can be deemed as fully received once the sum of the number of bytes length of each FRAGMENT equals TOT_SIZE. The consumer will also observe that all FRAG_NUM range from 1 to the number of the fragment, with no intermediate integers skipped. In other words, a data item transmitted over three messages will contain FRAG_NUM values of 1, 2, and 3.

The WebSocket application also needs to convert the FRAGMENT field data from Base64 string to bytes data before further process this field. Python application can use the base64 module to decode Base64 string to bytes data.

Compression

The FRAGMENT field is compressed with gzip compression, thus requiring the consumer to decompress to reveal the JSON plain-text data in that FID.

When an MRN data item is sent in multiple messages, all the messages must be received and their FRAGMENTs concatenated before being decompressed. In other words, the FRAGMENTs should not be decompressed independently of each other.

The decompressed output is encoded in UTF-8 and formatted as JSON. Python application can uses zlib module to decompress JSON string.

How to process MRN data

Once the application has established a connection and requested MRN RIC data from Real-Time Distribution System, the application can process incoming MRN data message with the following flow:

Please see more detail in Code Walkthrough section below.

 

Code Walkthrough

Requesting data

The application can subscribe MRN data with the NewsTextAnalytics domain and the following MRN-specific RIC name:

  • MRN_STORY: Real-time News
  • MRN_TRNA: News Analytics: Company and C&E assets
  • MRN_TRNA_DOC: News Analytics: Macroeconomic News & events
  • MRN_TRSI: News Sentiment Indices

Handle Refresh Message

The MRN Refresh response message does not contain any news or fragment information. It contains the relevant feed-related or other static Fields. The application just prints out each incoming field data in a console for informational purposes.

Example result of MRN Refresh response message is following:

Handle Update Messages

The Update response messages contain news information and fragment(s) data. Firstly, the application gets FRAGMENT, FRAG_NUM, GUID, and MRN_SRC fields values from the Update message. We use Python's base64 module to decode a FRAGMENT field value from ASCII string to bytes data.

Process the first fragment/single fragment news

Next, we check if a FRAG_NUM = 1 which means it is the first fragment of this news message. The application then checks if a FRAGMENT bytes length = TOT_SIZE field.

  • If equal, this is a piece of single fragment news and this news message is completed
  • If not, this is the first fragment of multi-fragments news. We store this Update message's all fields data to the _news_envelopes list object and waiting for the next fragment(s).

Process multi-fragments news

When the application receives Update message with FRAG_NUM > 1, it means this message is multi-fragments news. We get the previous fragment(s) data from _news_envelopes list object via a GUID. Please note that Update messages with FRAG_NUM >1 will contain fewer fields as the metadata has been included in the first Update message (FRAG_NUM=1) for that news message.

The application also needs to check the validity of the received fragment by checking the MRN_SRC and FRAG_NUM order with previous fragments. If the received fragment is valid, the application assembles a received FRAGMENT bytes data with previous fragments and compares a total fragments byte length value with TOT_SIZE value.

  • If equal, it means this multi-fragments news message is completed
  • If not, we update current news Update message fields to the _news_envelopes list object and waiting for more fragment(s).

Handle a completed news FRAGMENT message

To unzip the content and get JSON string news message, we use Python's zlib module to unzip the gzip bytes data, then we parse it to JSON message.

Example Result

The example application supports console, Docker and classic Jupyter Notebook environments. Please check the README.md file in the source code project for more detail regarding how to run the application in each environment.

Note: The news message is in UTF-8 JSON string format. Some news messages that contain special Unicode characters may not be able to show in Windows OS console (cmd, git bash, powershell, etc) due to the OS limitation. Those messages will be print as UnicodeEncodeError exception. Cannot decode Unicode character message in a console instead.

Popular Topics