Vault API

Overview

Through the Vault API, request validated pre-calculated returns and attribution data archived in Portfolio Vault to streamline your official performance and reporting workflows.

API Definition

swagger_file_format

API Documentation

SDK Library

Code Snippet

Building and running a calculation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;

using FactSet.AnalyticsAPI.Engines.v2.Api;
using FactSet.AnalyticsAPI.Engines.v2.Client;
using FactSet.AnalyticsAPI.Engines.v2.Model;

using FactSet.Protobuf.Stach;
using Google.Protobuf;

namespace FactSet.AnalyticsAPI.Engines.v2.Example.Examples
{
    public class VaultEngineExample
    {
        private static Configuration _engineApiConfiguration;
        private const string BASE_PATH = "https://api.factset.com";
        private const string USER_NAME = "<username-serial>";
        private const string PASSWORD = "<apiKey>";
        private const string VAULT_DEFAULT_DOCUMENT = "PA3_DOCUMENTS:DEFAULT";
        private const string VAULT_DEFAULT_ACCOUNT = "CLIENT:/ANALYTICS/DATA/NORDIC_EQUITY.ACCT";
        private const string VAULT_START_DATE = "FIRST_REPOSITORY";
        private const string VAULT_END_DATE = "LAST_REPOSITORY";
        private const string VAULT_FREQUENCY = "Monthly";

        private static Configuration GetEngineApiConfiguration()
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            if (_engineApiConfiguration != null)
            {
                return _engineApiConfiguration;
            }

            _engineApiConfiguration = new Configuration
            {
                BasePath = BASE_PATH,
                Username = USER_NAME,
                Password = PASSWORD
            };

            return _engineApiConfiguration;
        }

        public static void Main(string[] args)
        {
            try
            {
                var calculationParameters = new CalculationParameters
                {
                    Vault = new Dictionary<string, VaultCalculationParameters> { { "1", GetVaultCalculationParameters() } }
                };

                var calculationApi = new CalculationsApi(GetEngineApiConfiguration());

                var runCalculationResponse = calculationApi.RunCalculationWithHttpInfo(calculationParameters);

                var calculationId = runCalculationResponse.Headers["Location"][0].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last();
                ApiResponse<OutstandingCalculations> getStatus = null;

                while (getStatus == null || getStatus.Data.Status == OutstandingCalculations.StatusEnum.Queued || getStatus.Data.Status == OutstandingCalculations.StatusEnum.Executing)
                {
                    if (getStatus != null)
                    {
                        if (getStatus.Headers.ContainsKey("Cache-Control"))
                        {
                            var maxAge = getStatus.Headers["Cache-Control"][0];
                            if (string.IsNullOrWhiteSpace(maxAge))
                            {
                                Console.WriteLine("Sleeping for 2 seconds");
                                // Sleep for at least 2 seconds.
                                Thread.Sleep(2000);
                            }
                            else
                            {
                                var age = int.Parse(maxAge.Replace("max-age=", ""));
                                Console.WriteLine($"Sleeping for {age} seconds");
                                Thread.Sleep(age * 1000);
                            }
                        }
                    }

                    getStatus = calculationApi.GetCalculationByIdWithHttpInfo(calculationId);
                }
                Console.WriteLine("Calculation Completed");

                // Check for failed calculations
                foreach (var vaultCalculationParameters in getStatus.Data.Vault)
                {
                    if (vaultCalculationParameters.Value.Status == Calculation.StatusEnum.Failed)
                    {
                        Console.WriteLine($"CalculationId : {vaultCalculationParameters.Key} Failed!!!");
                        Console.WriteLine($"Error message : {vaultCalculationParameters.Value.Error}");
                    }
                }

                // Get result of successful calculations
                foreach (var vaultCalculationParameters in getStatus.Data.Vault)
                {
                    PrintResult(vaultCalculationParameters);
                }

                Console.ReadKey();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        private static VaultCalculationParameters GetVaultCalculationParameters()
        {
            // Build Vault Engine calculation parameters
            var componentsApi = new ComponentsApi(GetEngineApiConfiguration());

            var componentsResponse = componentsApi.GetVaultComponentsWithHttpInfo(VAULT_DEFAULT_DOCUMENT);

            if (componentsResponse.StatusCode != HttpStatusCode.OK)
            {
                LogError(componentsResponse);
                return null;
            }

            var vaultComponentId = componentsResponse.Data.First().Key;
            Console.WriteLine($"Vault Component Id : {vaultComponentId}");


            var vaultAccount = new VaultCalculationAccount(VAULT_DEFAULT_ACCOUNT);
            var vaultDates = new VaultDateParameters(VAULT_START_DATE, VAULT_END_DATE, VAULT_FREQUENCY);

            var configurationApi = new ConfigurationsApi(GetEngineApiConfiguration());

            var configurationResponse = configurationApi.GetVaultConfigurationsWithHttpInfo(vaultAccount.Id);
            if (configurationResponse.StatusCode != HttpStatusCode.OK)
            {
                LogError(componentsResponse);
                return null;
            }
            var vaultConfiguration = configurationResponse.Data.First().Key;

            var vaultCalculation = new VaultCalculationParameters(vaultComponentId, vaultAccount, vaultDates, vaultConfiguration);

            return vaultCalculation;
        }

        private static void PrintResult(KeyValuePair<string, Calculation> calculation)
        {
            if (calculation.Value.Status == Calculation.StatusEnum.Success)
            {
                ApiResponse<string> resultResponse = null;

                var utilityApi = new UtilityApi(GetEngineApiConfiguration());
                resultResponse = utilityApi.GetByUrlWithHttpInfo(calculation.Value.Result);

                if (resultResponse.StatusCode != HttpStatusCode.OK)
                {
                    LogError(resultResponse);
                    return;
                }

                Console.WriteLine($"CalculationId : {calculation.Key} Succeeded!!!");
                Console.WriteLine($"CalculationId : {calculation.Key} Result");
                Console.WriteLine("/****************************************************************/");
                

                // converting the data to Package object 
                var jpSettings = JsonParser.Settings.Default;
                var jp = new JsonParser(jpSettings.WithIgnoreUnknownFields(true));
                var package = jp.Parse<Package>(resultResponse.Data);

                // To convert package to 2D tables.
                var tables = package.ConvertToTableFormat();
                Console.WriteLine(tables[0]);

                // Uncomment the following line to generate an Excel file
                // package.GenerateCSV();
                Console.WriteLine("/****************************************************************/");
            }
        }

        private static void LogError<T>(ApiResponse<T> response)
        {
            Console.WriteLine("Error!!!");
            Console.WriteLine("Status Code: " + response.StatusCode);
            Console.WriteLine("Request Key: " + response.Headers["X-DataDirect-Request-Key"]);
            Console.WriteLine($"Reason: {response.Data}");
        }
    }
}

 

import java.util.List;
import java.util.Map;

import factset.analyticsapi.engines.v2.*;
import factset.analyticsapi.engines.v2.api.*;
import factset.analyticsapi.engines.v2.models.*;
import factset.analyticsapi.engines.v2.models.OutstandingCalculations.StatusEnum;

import com.google.protobuf.util.JsonFormat;
import com.google.protobuf.InvalidProtocolBufferException;
import com.factset.protobuf.stach.PackageProto.Package.Builder;
import com.factset.protobuf.stach.PackageProto.Package;

public class VaultEngineExample {
  private static ApiClient apiClient = null;
  private static final String BASE_PATH = "https://api.factset.com";
  private static final String USERNAME = "<username-serial>";
  private static final String PASSWORD = "<apiKey>";
  public static final String VAULT_DEFAULT_DOCUMENT = "PA3_DOCUMENTS:DEFAULT";
  public static final String VAULT_DEFAULT_ACCOUNT = "Client:/analytics/data/US_MID_CAP_CORE.ACTM";
  private static final String COMPONENT_NAME = "Exposures";
  private static final String COMPONENT_CATEGORY = "General / Positioning";

  public static void main(String[] args) throws InterruptedException {
    try {
      // Build Vault Calculation Parameters List

      // Get all component from VAULT_DEFAULT_DOCUMENT with Name COMPONENT_NAME & category COMPONENT_CATEGORY
      ComponentsApi componentsApi = new ComponentsApi(getApiClient());
      Map<String, ComponentListEntity> components = componentsApi.getVaultComponents(VAULT_DEFAULT_DOCUMENT);
      String componentId = components.entrySet().stream().filter(
          c -> c.getValue().getName().equals(COMPONENT_NAME) && c.getValue().getCategory().equals(COMPONENT_CATEGORY))
          .iterator().next().getKey();
      System.out.println("ID of component with Name '" + COMPONENT_NAME + "' and category '" + COMPONENT_CATEGORY
          + "' : " + componentId);

      ConfigurationsApi configurationsApi = new ConfigurationsApi(getApiClient());
      Map<String, ConfigurationItem> configurationsMap = configurationsApi
          .getVaultConfigurations(VAULT_DEFAULT_ACCOUNT);
      String configurationId = configurationsMap.entrySet().iterator().next().getKey();
      System.out.println("Configuration ID: " + configurationId);

      CalculationParameters parameters = new CalculationParameters();

      VaultCalculationParameters vaultItem = new VaultCalculationParameters();

      vaultItem.setComponentid(componentId);
      vaultItem.setConfigid(configurationId);

      VaultCalculationAccount account = new VaultCalculationAccount();
      account.setId(VAULT_DEFAULT_ACCOUNT);
      vaultItem.setAccount(account);

      VaultDateParameters dateParameters = new VaultDateParameters();
      dateParameters.setStartdate("FIRST_REPOSITORY");
      dateParameters.setEnddate("LAST_REPOSITORY");
      dateParameters.setFrequency("Monthly");
      vaultItem.setDates(dateParameters);

      parameters.putVaultItem("1", vaultItem);

      // Run Calculation Request
      CalculationsApi apiInstance = new CalculationsApi(getApiClient());
      ApiResponse<Void> createResponse = null;

      createResponse = apiInstance.runCalculationWithHttpInfo(parameters);

      String[] locationList = createResponse.getHeaders().get("Location").get(0).split("/");
      String requestId = locationList[locationList.length - 1];

      // Get Calculation Request Status
      ApiResponse<OutstandingCalculations> getStatus = null;

      while (getStatus == null || getStatus.getData().getStatus() == StatusEnum.QUEUED
          || getStatus.getData().getStatus() == StatusEnum.EXECUTING) {
        if (getStatus != null) {
          List<String> cacheControl = getStatus.getHeaders().get("Cache-Control");
          if (cacheControl != null) {
            int maxAge = Integer.parseInt(cacheControl.get(0).replaceAll("max-age=", ""));
            System.out.println("Sleeping for: " + maxAge + " seconds");
            Thread.sleep(maxAge * 1000);
          } else {
            System.out.println("Sleeping for: 2 seconds");
            Thread.sleep(2 * 1000);
          }
        }
        getStatus = apiInstance.getCalculationByIdWithHttpInfo(requestId);
      }

      System.out.println("Calculation Completed!!!");

      // Check for Failed Calculations
      for (Map.Entry<String, Calculation> calculationParameters : getStatus.getData().getVault().entrySet()) {
        if (calculationParameters.getValue().getStatus() == Calculation.StatusEnum.FAILED) {
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Failed!!!");
          System.out.println("Error message : " + calculationParameters.getValue().getError());
          return;
        }
      }

      // Get Result of Successful Caculations
      for (Map.Entry<String, Calculation> calculationParameters : getStatus.getData().getVault().entrySet()) {
        if (calculationParameters.getValue().getStatus() == Calculation.StatusEnum.SUCCESS) {
          UtilityApi utilityApiInstance = new UtilityApi(apiClient);
          ApiResponse<String> resultResponse = utilityApiInstance
              .getByUrlWithHttpInfo(calculationParameters.getValue().getResult());
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Succeeded!!!");
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Result");

          Builder builder = Package.newBuilder();
          try {
            JsonFormat.parser().ignoringUnknownFields().merge(resultResponse.getData(), builder);
          } catch (InvalidProtocolBufferException e) {
            System.out.println("Error while deserializing the response");
            e.printStackTrace();
          }

          Package result = (Package) builder.build();
          // To convert result to 2D tables.
          List<TableData> tables = StachExtensions.convertToTableFormat(result);
          System.out.println(tables.get(0)); // Prints the result in 2D table format.
          // Uncomment the following line to generate an Excel file
          // StachExtensions.generateExcel(result);
        }
      }
    } catch (ApiException e) {
      handleException("VaultEngineExample#Main", e);
      return;
    }
  }

  private static ApiClient getApiClient() throws ApiException {
    if (apiClient != null) {
      return apiClient;
    }

    apiClient = new ApiClient();
    apiClient.setConnectTimeout(30000);
    apiClient.setReadTimeout(30000);
    apiClient.setBasePath(BASE_PATH);
    apiClient.setUsername(USERNAME);
    apiClient.setPassword(PASSWORD);

    return apiClient;
  }

  private static void handleException(String method, ApiException e) {
    System.err.println("Exception when calling " + method);
    if (e.getResponseHeaders() != null && e.getResponseHeaders().containsKey("x-datadirect-request-key")) {
      System.out.println("x-datadirect-request-key: " + e.getResponseHeaders().get("x-datadirect-request-key").get(0));
    }
    System.out.println("Status code: " + e.getCode());
    System.out.println("Reason: " + e.getResponseBody());
    e.printStackTrace();
  }
}

 

import time
import json

from google.protobuf import json_format
from google.protobuf.json_format import MessageToJson
from google.protobuf.json_format import MessageToDict
from fds.protobuf.stach.Package_pb2 import Package

from fds.analyticsapi.engines.v2.configuration import Configuration;
from fds.analyticsapi.engines.v2.api_client import ApiClient;
from fds.analyticsapi.engines.v2.api.components_api import ComponentsApi
from fds.analyticsapi.engines.v2.api.configurations_api import ConfigurationsApi
from fds.analyticsapi.engines.v2.api.calculations_api import CalculationsApi
from fds.analyticsapi.engines.v2.api.utility_api import UtilityApi
from fds.analyticsapi.engines.v2.models.calculation_parameters import CalculationParameters
from fds.analyticsapi.engines.v2.models.vault_calculation_parameters import VaultCalculationParameters
from fds.analyticsapi.engines.v2.models.vault_calculation_account import VaultCalculationAccount
from fds.analyticsapi.engines.v2.models.vault_date_parameters import VaultDateParameters
from stach_extensions import StachExtensions

host = "https://api.factset.com"
username = "<username-serial>"
password = "<apiKey>"

vault_document_name = "PA3_DOCUMENTS:DEFAULT";
vault_default_account = "CLIENT:/ANALYTICS/DATA/NORDIC_EQUITY.ACCT";
vault_startdate = "FIRST_REPOSITORY";
vault_enddate = "LAST_REPOSITORY";
frequency = "Monthly";

config = Configuration()
config.host = host
config.username = username
config.password = password
# add proxy and/or disable ssl verification according to your development environment
# config.proxy = "<proxyUrl>"
# config.verify_ssl = False

api_client = ApiClient(config)

components_api = ComponentsApi(api_client);
components = components_api.get_vault_components_with_http_info(vault_document_name)
component_id = list(components[0].keys())[0]

vault_account_identifier = VaultCalculationAccount(vault_default_account)
vault_dates = VaultDateParameters(vault_startdate, vault_enddate, frequency)

configurations_api = ConfigurationsApi(api_client)
configurations = configurations_api.get_vault_configurations_with_http_info(vault_default_account)
configuration_id = list(configurations[0].keys())[0]

vault_calculation_parameters = {"1": VaultCalculationParameters(component_id, vault_account_identifier, vault_dates, configuration_id)}
calculations = CalculationParameters(vault=vault_calculation_parameters)
print(calculations)

calculations_api = CalculationsApi(api_client)
run_calculation_response = calculations_api.run_calculation_with_http_info(calculations=calculations)

if(run_calculation_response[1] != 202):
    print(batch_api_post_result[2].get("x-datadirect-request-key"))
    quit()

calculation_id = run_calculation_response[2].get("location").split("/")[-1]
print("Calculation Id: " + calculation_id)

calculation_status = calculations_api.get_calculation_by_id_with_http_info(calculation_id)
while (calculation_status[1] == 200 and (calculation_status[0].status == "Queued" or calculation_status[0].status == "Executing")):
    age_value = calculation_status[2].get("cache-control")
    if(age_value != None):
        max_age = age_value.replace("max-age=", "")
        print('Sleeping: ' + max_age)
        time.sleep(int(max_age))
    calculation_status = calculations_api.get_calculation_by_id_with_http_info(calculation_id)

if(calculation_status[1] != 200):
    print(calculation_status[2].get("x-datadirect-request-key"))
    quit()

print("Calculation Completed!!!");

for calculation_key, calculation_item in calculation_status[0].vault.items():
    if calculation_item.status == "Failed":
        print("Spar Calculation : " + calculation_key + " Failed!!!")
        print("Error Message : " + calculation_item.error)
    elif calculation_item.status == "Success":
        utility_api = UtilityApi(api_client)
        calculation_result = utility_api.get_by_url_with_http_info(calculation_item.result)

        if(calculation_result[1] != 200):
            print(calculation_result[2].get('x-datadirect-request-key'))
            quit()

        # converting the data to Package object
        result =  json_format.Parse(json.dumps(calculation_result[0]), Package())
        # print(MessageToJson(result)) # To print the result object as a JSON
        # print(MessageToDict(result)) # To print the result object as a Dictionary
        tables = StachExtensions.convert_to_table_format(result) # To convert result to 2D tables.
        print(tables[0]) # Prints the result in 2D table format.
        # StachExtensions.generate_excel(result) # To get the result in table format exported to excel file.

 

Converting API output to Table format
using System;
using System.Collections.Generic;
using System.Linq;
using FactSet.Protobuf.Stach;
using FactSet.Protobuf.Stach.Table;

namespace FactSet.AnalyticsAPI.Engines.v2.Example.Examples
{
    public static class StachExtensions
    {
        public static void GenerateCSV(this Package package)
        {
            foreach (var table in package.ConvertToTableFormat())
            {
                System.IO.File.WriteAllText($"{Guid.NewGuid():N}.csv", table.ToString());
            }
        }

        public static List<Table> ConvertToTableFormat(this Package package)
        {
            var tables = new List<Table>();
            foreach (var primaryTableId in package.PrimaryTableIds)
            {
                tables.Add(GenerateTable(package, primaryTableId));
            }

            return tables;
        }

        private static Table GenerateTable(Package package, string primaryTableId)
        {
            var primaryTable = package.Tables[primaryTableId];
            var headerId = primaryTable.Definition.HeaderTableId;
            var headerTable = package.Tables[headerId];
            var columnIds = primaryTable.Definition.Columns.Select(c => c.Id).ToList();
            var headerColumnIds = headerTable.Definition.Columns.Select(c => c.Id).ToList();
            var dimensionColumnsCount = primaryTable.Definition.Columns.Count(c => c.IsDimension);
            var rowCount = primaryTable.Data.Rows.Count;
            var headerRowCount = headerTable.Data.Rows.Count;

            var table = new Table
            {
                Rows = new List<Row>()
            };
            // Constructs the column headers by considering dimension columns and header rows
            foreach (var columnId in headerColumnIds)
            {
                var headerRow = new Row { Cells = new List<string>() };
                for (int j = 0; j < dimensionColumnsCount; j++)
                {
                    headerRow.Cells.Add("");
                }

                for (int i = 0; i < headerRowCount; i++)
                {
                    headerRow.Cells.Add(Convert.ToString(headerTable.Data.Columns[columnId]
                        .GetValueHelper(headerTable.Definition.Columns.First(c => c.Id == columnId).Type, i)));
                }
                table.Rows.Add(headerRow);
            }
            // Constructs the column data
            for (int i = 0; i < rowCount; i++)
            {
                var dataRow = new Row { Cells = new List<string>() };
                foreach (var columnId in columnIds)
                {
                    dataRow.Cells.Add(Convert.ToString(primaryTable.Data.Columns[columnId]
                        .GetValueHelper(primaryTable.Definition.Columns.First(c => c.Id == columnId).Type, i)));
                }
                table.Rows.Add(dataRow);
            }

            return table;
        }
    }

    public static class SeriesDataHelper
    {
        public static object GetValueHelper(this SeriesData seriesData, DataType dataType, int index)
        {
            switch (dataType)
            {
                case DataType.Bool:
                    {
                        return seriesData.BoolArray?.Values?[index];
                    }
                case DataType.Double:
                    {
                        return seriesData.DoubleArray?.Values?[index];
                    }
                case DataType.Duration:
                    {
                        var v = seriesData.DurationArray?.Values?[index];
                        return v?.ToTimeSpan();
                    }
                case DataType.Float:
                    {
                        return seriesData.FloatArray?.Values?[index];
                    }
                case DataType.Int32:
                    {
                        return seriesData.Int32Array?.Values?[index];
                    }
                case DataType.Int64:
                    {
                        return seriesData.Int64Array?.Values?[index];
                    }
                case DataType.String:
                    {
                        return seriesData.StringArray?.Values?[index];
                    }
                case DataType.Timestamp:
                    {
                        var v = seriesData.TimestampArray?.Values?[index];
                        return v?.ToDateTime();
                    }
                default:
                    throw new NotImplementedException($"{dataType} is not implemented");
            }
        }
    }

    public class Table
    {
        public List<Row> Rows { get; set; }

        public override string ToString()
        {
            return string.Join(Environment.NewLine, Rows);
        }
    }

    public class Row
    {
        public List<string> Cells { get; set; }

        public override string ToString()
        {
            return string.Join(",", Cells.Select(c => c.Replace(",", "")));
        }
    }
}

 

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.factset.protobuf.stach.NullValues;
import com.factset.protobuf.stach.PackageProto.Package;
import com.factset.protobuf.stach.table.DataTypeProto.DataType;
import com.factset.protobuf.stach.table.SeriesDataProto.SeriesData;
import com.factset.protobuf.stach.table.SeriesDefinitionProto.SeriesDefinition;
import com.factset.protobuf.stach.table.TableProto.Table;

import com.google.protobuf.Duration;
import com.google.protobuf.Timestamp;

public class StachExtensions {
  // The purpose of this class is to provide the helper methods for converting
  // stach to Tabular format.

  public static void generateExcel(Package packageObj) {
    for (TableData table : convertToTableFormat(packageObj)) {
      writeDataToExcel(table, UUID.randomUUID().toString() + ".xlsx");
    }
  }

  public static List<TableData> convertToTableFormat(Package packageObj) {
    List<TableData> tables = new ArrayList<TableData>();
    for (String primaryTableId : packageObj.getPrimaryTableIdsList()) {
      tables.add(generateTable(packageObj, primaryTableId));
    }
    return tables;
  }

  private static TableData generateTable(Package packageObj, String primaryTableId) {
    Map<String, Table> tablesMap = packageObj.getTablesMap();
    Table primaryTable = tablesMap.get(primaryTableId);
    String headerId = primaryTable.getDefinition().getHeaderTableId();
    Table headerTable = tablesMap.get(headerId);
    int headerRowCount = headerTable.getData().getRowsCount();
    int rowsCount = primaryTable.getData().getRowsCount();

    TableData table = new TableData();

    // Construct the column headers by considering dimension columns and header
    // rows.
    List<SeriesDefinition> headerTableSeriesDefinitions = headerTable.getDefinition().getColumnsList();
    List<SeriesDefinition> primaryTableSeriesDefinitions = primaryTable.getDefinition().getColumnsList();

    Map<String, SeriesData> headerTableColumns = headerTable.getData().getColumnsMap();
    Map<String, SeriesData> primaryTableColumns = primaryTable.getData().getColumnsMap();

    for (SeriesDefinition headerTableseriesDefinition : headerTableSeriesDefinitions) {
      Row headerRow = new Row();
      for (SeriesDefinition primaryTableSeriesDefinition : primaryTableSeriesDefinitions) {
        if (primaryTableSeriesDefinition.getIsDimension()) {
          headerRow.Cells.add(primaryTableSeriesDefinition.getDescription());
        }
      }

      String headerColumnId = headerTableseriesDefinition.getId();
      String nullFormat = headerTableseriesDefinition.getFormat().getNullFormat();
      for (int i = 0; i < headerRowCount; i++) {
        headerRow.Cells.add(SeriesDataHelper.getValueHelper(headerTableColumns.get(headerColumnId),
            headerTableseriesDefinition.getType(), i, nullFormat).toString());
      }
      table.Rows.add(headerRow);
    }

    // Construct the column data
    for (int i = 0; i < rowsCount; i++) {
      Row dataRow = new Row();
      for (SeriesDefinition primaryTableSeriesDefinition : primaryTableSeriesDefinitions) {
        String nullFormat = primaryTableSeriesDefinition.getFormat().getNullFormat();
        String primaryTableColumnId = primaryTableSeriesDefinition.getId();
        dataRow.Cells.add(SeriesDataHelper.getValueHelper(primaryTableColumns.get(primaryTableColumnId),
            primaryTableSeriesDefinition.getType(), i, nullFormat).toString());
      }
      table.Rows.add(dataRow);
    }
    return table;
  }

  private static void writeDataToExcel(TableData table, String fileLocation) {
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("PA Report");

    int rowsSize = table.Rows.size();
    for (int rowIndex = 0; rowIndex < rowsSize; rowIndex++) {
      XSSFRow xsswRow = sheet.createRow(rowIndex);
      List<String> cells = table.Rows.get(rowIndex).Cells;
      for (int cellIndex = 0; cellIndex < cells.size(); cellIndex++) {
        XSSFCell xssfCell = xsswRow.createCell(cellIndex);
        xssfCell.setCellValue(cells.get(cellIndex));
      }
    }

    try {
      FileOutputStream out = new FileOutputStream(new File(fileLocation));
      workbook.write(out);
      out.close();
      workbook.close();
    } catch (Exception e) {
      System.err.println("Failed to write data to excel");
      e.printStackTrace();
    }
  }
}

class SeriesDataHelper {
  public static Object getValueHelper(SeriesData seriesData, DataType dataType, int index, String nullFormat) {
    if (dataType == DataType.STRING) {
      String value = seriesData.getStringArray().getValues(index);
      return NullValues.STRING.equals(value) ? nullFormat : value;
    } else if (dataType == DataType.DOUBLE) {
      double value = seriesData.getDoubleArray().getValues(index);
      return Double.isNaN(value) ? nullFormat : value;
    } else if (dataType == DataType.BOOL) {
      return seriesData.getBoolArray().getValues(index);
    } else if (dataType == DataType.DURATION) {
      Duration value = seriesData.getDurationArray().getValues(index);
      return NullValues.DURATION.equals(value) ? nullFormat : value;
    } else if (dataType == DataType.FLOAT) {
      float value = seriesData.getFloatArray().getValues(index);
      return Float.isNaN(value) ? nullFormat : value;
    } else if (dataType == DataType.INT32) {
      int value = seriesData.getInt32Array().getValues(index);
      return NullValues.INT32 == value ? nullFormat : value;
    } else if (dataType == DataType.INT64) {
      long value = seriesData.getInt64Array().getValues(index);
      return NullValues.INT64 == value ? nullFormat : value;
    } else if (dataType == DataType.TIMESTAMP) {
      Timestamp value = seriesData.getTimestampArray().getValues(index);
      return NullValues.TIMESTAMP.equals(value) ? nullFormat : value;
    } else {
      throw new NotImplementedException(dataType + " is not implemented");
    }
  }
}

class TableData {
  List<Row> Rows = new ArrayList<Row>();

  public String toString() {
    return Rows.toString();
  }
}

class Row {
  List<String> Cells = new ArrayList<String>();

  public String toString() {
    return Cells.toString();
  }
}

 

import uuid
import math

import pandas as pd

from fds.protobuf.stach.Package_pb2 import Package
from fds.protobuf.stach.NullValues import NullValues
from fds.protobuf.stach.table.DataType_pb2 import DataType

class StachExtensions:
    """The purpose of this class is to provide the helper methods for converting Stach to Tabular format"""

    @staticmethod
    def generate_excel(package):
        for table in StachExtensions.convert_to_table_format(package):
            writer = pd.ExcelWriter(str(uuid.uuid1()) + ".xlsx")
            table.to_excel(excel_writer=writer)
            writer.save()
            writer.close()

    @staticmethod
    def convert_to_table_format(package):
        tables = list()
        for primary_table_id in package.primary_table_ids:
            tables.append(StachExtensions.generate_table(package, primary_table_id))
        return tables

    @staticmethod
    def generate_table(package_response, primary_table_id):

        if isinstance(package_response, Package):
            primary_table = package_response.tables[primary_table_id]
            header_id = primary_table.definition.header_table_id
            header_table = package_response.tables[header_id]
            dimension_columns = list(filter(lambda column_obj: column_obj.is_dimension, primary_table.definition.columns))
            dimension_columns_count = len(dimension_columns)
            row_count = len(primary_table.data.rows)
            header_row_count = len(header_table.data.rows)

            headers = list(list())
            # Constructs the column headers by considering dimension columns and header rows
            for series_definition_column in header_table.definition.columns:
                header_row = list()
                for i in range(0, dimension_columns_count, 1):
                    header_row.append(dimension_columns[i].description)

                for i in range(0, header_row_count, 1):
                    header_row.append(str(SeriesDataHelper.get_value_helper(header_table.data.columns[series_definition_column.id], series_definition_column.type, i, series_definition_column.format.null_format)))
                headers.append(header_row)

            data = list(list())
            # Constructs the column data
            for i in range(0, row_count, 1):
                data_row = list()
                for series_definition_column in primary_table.definition.columns:
                    data_row.append(str(SeriesDataHelper.get_value_helper(primary_table.data.columns[series_definition_column.id], series_definition_column.type, i, series_definition_column.format.null_format)))
                data.append(data_row)

            data_frame = pd.DataFrame(data=data)
            data_frame.columns = pd.MultiIndex.from_arrays(headers)
            return data_frame

        else:
            ValueError("Response data passed should be of package type.")


class SeriesDataHelper:

    @staticmethod
    def get_value_helper(series_data, datatype, index, null_format):
        if DataType.Name(datatype) == "STRING":
            return SeriesDataHelper.null_value_handler(datatype, series_data.string_array.values[index], null_format)
        elif DataType.Name(datatype) == "DOUBLE":
            return SeriesDataHelper.null_value_handler(datatype, series_data.double_array.values[index], null_format)
        elif DataType.Name(datatype) == "FLOAT":
            return SeriesDataHelper.null_value_handler(datatype, series_data.float_array.values[index], null_format)
        elif DataType.Name(datatype) == "INT32":
            return SeriesDataHelper.null_value_handler(datatype, series_data.int32_array.values[index], null_format)
        elif DataType.Name(datatype) == "INT64":
            return SeriesDataHelper.null_value_handler(datatype, series_data.int64_array.values[index], null_format)
        elif DataType.Name(datatype) == "BOOL":
            return SeriesDataHelper.null_value_handler(datatype, series_data.bool_array.values[index], null_format)
        elif DataType.Name(datatype) == "DURATION":
            return SeriesDataHelper.null_value_handler(datatype, series_data.duration_array.values[index], null_format)
        elif DataType.Name(datatype) == "TIMESTAMP":
            return SeriesDataHelper.null_value_handler(datatype, series_data.timestamp_array.values[index], null_format)
        else:
            ValueError("The datatype is not implemented")

    @staticmethod
    def null_value_handler(datatype, value, null_format):
        if DataType.Name(datatype) == "STRING":
            if NullValues.STRING == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "DOUBLE":
            if math.isnan(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "FLOAT":
            if math.isnan(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "INT32":
            if NullValues.INT32 == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "INT64":
            if NullValues.INT64 == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "DURATION":
            if NullValues.DURATION.equals(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "TIMESTAMP":
            if NullValues.TIMESTAMP.equals(value):
                return null_format
            else:
                return value
        else:
            return value

 

Building and running a calculation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;

using FactSet.AnalyticsAPI.Engines.v2.Api;
using FactSet.AnalyticsAPI.Engines.v2.Client;
using FactSet.AnalyticsAPI.Engines.v2.Model;

using FactSet.Protobuf.Stach;
using Google.Protobuf;

namespace FactSet.AnalyticsAPI.Engines.v2.Example.Examples
{
    public class VaultEngineExample
    {
        private static Configuration _engineApiConfiguration;
        private const string BASE_PATH = "https://api.factset.com";
        private const string USER_NAME = "<username-serial>";
        private const string PASSWORD = "<apiKey>";
        private const string VAULT_DEFAULT_DOCUMENT = "PA3_DOCUMENTS:DEFAULT";
        private const string VAULT_DEFAULT_ACCOUNT = "CLIENT:/ANALYTICS/DATA/NORDIC_EQUITY.ACCT";
        private const string VAULT_START_DATE = "FIRST_REPOSITORY";
        private const string VAULT_END_DATE = "LAST_REPOSITORY";
        private const string VAULT_FREQUENCY = "Monthly";

        private static Configuration GetEngineApiConfiguration()
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            if (_engineApiConfiguration != null)
            {
                return _engineApiConfiguration;
            }

            _engineApiConfiguration = new Configuration
            {
                BasePath = BASE_PATH,
                Username = USER_NAME,
                Password = PASSWORD
            };

            return _engineApiConfiguration;
        }

        public static void Main(string[] args)
        {
            try
            {
                var calculationParameters = new CalculationParameters
                {
                    Vault = new Dictionary<string, VaultCalculationParameters> { { "1", GetVaultCalculationParameters() } }
                };

                var calculationApi = new CalculationsApi(GetEngineApiConfiguration());

                var runCalculationResponse = calculationApi.RunCalculationWithHttpInfo(calculationParameters);

                var calculationId = runCalculationResponse.Headers["Location"][0].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last();
                ApiResponse<OutstandingCalculations> getStatus = null;

                while (getStatus == null || getStatus.Data.Status == OutstandingCalculations.StatusEnum.Queued || getStatus.Data.Status == OutstandingCalculations.StatusEnum.Executing)
                {
                    if (getStatus != null)
                    {
                        if (getStatus.Headers.ContainsKey("Cache-Control"))
                        {
                            var maxAge = getStatus.Headers["Cache-Control"][0];
                            if (string.IsNullOrWhiteSpace(maxAge))
                            {
                                Console.WriteLine("Sleeping for 2 seconds");
                                // Sleep for at least 2 seconds.
                                Thread.Sleep(2000);
                            }
                            else
                            {
                                var age = int.Parse(maxAge.Replace("max-age=", ""));
                                Console.WriteLine($"Sleeping for {age} seconds");
                                Thread.Sleep(age * 1000);
                            }
                        }
                    }

                    getStatus = calculationApi.GetCalculationByIdWithHttpInfo(calculationId);
                }
                Console.WriteLine("Calculation Completed");

                // Check for failed calculations
                foreach (var vaultCalculationParameters in getStatus.Data.Vault)
                {
                    if (vaultCalculationParameters.Value.Status == Calculation.StatusEnum.Failed)
                    {
                        Console.WriteLine($"CalculationId : {vaultCalculationParameters.Key} Failed!!!");
                        Console.WriteLine($"Error message : {vaultCalculationParameters.Value.Error}");
                    }
                }

                // Get result of successful calculations
                foreach (var vaultCalculationParameters in getStatus.Data.Vault)
                {
                    PrintResult(vaultCalculationParameters);
                }

                Console.ReadKey();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        private static VaultCalculationParameters GetVaultCalculationParameters()
        {
            // Build Vault Engine calculation parameters
            var componentsApi = new ComponentsApi(GetEngineApiConfiguration());

            var componentsResponse = componentsApi.GetVaultComponentsWithHttpInfo(VAULT_DEFAULT_DOCUMENT);

            if (componentsResponse.StatusCode != HttpStatusCode.OK)
            {
                LogError(componentsResponse);
                return null;
            }

            var vaultComponentId = componentsResponse.Data.First().Key;
            Console.WriteLine($"Vault Component Id : {vaultComponentId}");


            var vaultAccount = new VaultCalculationAccount(VAULT_DEFAULT_ACCOUNT);
            var vaultDates = new VaultDateParameters(VAULT_START_DATE, VAULT_END_DATE, VAULT_FREQUENCY);

            var configurationApi = new ConfigurationsApi(GetEngineApiConfiguration());

            var configurationResponse = configurationApi.GetVaultConfigurationsWithHttpInfo(vaultAccount.Id);
            if (configurationResponse.StatusCode != HttpStatusCode.OK)
            {
                LogError(componentsResponse);
                return null;
            }
            var vaultConfiguration = configurationResponse.Data.First().Key;

            var vaultCalculation = new VaultCalculationParameters(vaultComponentId, vaultAccount, vaultDates, vaultConfiguration);

            return vaultCalculation;
        }

        private static void PrintResult(KeyValuePair<string, Calculation> calculation)
        {
            if (calculation.Value.Status == Calculation.StatusEnum.Success)
            {
                ApiResponse<string> resultResponse = null;

                var utilityApi = new UtilityApi(GetEngineApiConfiguration());
                resultResponse = utilityApi.GetByUrlWithHttpInfo(calculation.Value.Result);

                if (resultResponse.StatusCode != HttpStatusCode.OK)
                {
                    LogError(resultResponse);
                    return;
                }

                Console.WriteLine($"CalculationId : {calculation.Key} Succeeded!!!");
                Console.WriteLine($"CalculationId : {calculation.Key} Result");
                Console.WriteLine("/****************************************************************/");
                

                // converting the data to Package object 
                var jpSettings = JsonParser.Settings.Default;
                var jp = new JsonParser(jpSettings.WithIgnoreUnknownFields(true));
                var package = jp.Parse<Package>(resultResponse.Data);

                // To convert package to 2D tables.
                var tables = package.ConvertToTableFormat();
                Console.WriteLine(tables[0]);

                // Uncomment the following line to generate an Excel file
                // package.GenerateCSV();
                Console.WriteLine("/****************************************************************/");
            }
        }

        private static void LogError<T>(ApiResponse<T> response)
        {
            Console.WriteLine("Error!!!");
            Console.WriteLine("Status Code: " + response.StatusCode);
            Console.WriteLine("Request Key: " + response.Headers["X-DataDirect-Request-Key"]);
            Console.WriteLine($"Reason: {response.Data}");
        }
    }
}

 

import java.util.List;
import java.util.Map;

import factset.analyticsapi.engines.v2.*;
import factset.analyticsapi.engines.v2.api.*;
import factset.analyticsapi.engines.v2.models.*;
import factset.analyticsapi.engines.v2.models.OutstandingCalculations.StatusEnum;

import com.google.protobuf.util.JsonFormat;
import com.google.protobuf.InvalidProtocolBufferException;
import com.factset.protobuf.stach.PackageProto.Package.Builder;
import com.factset.protobuf.stach.PackageProto.Package;

public class VaultEngineExample {
  private static ApiClient apiClient = null;
  private static final String BASE_PATH = "https://api.factset.com";
  private static final String USERNAME = "<username-serial>";
  private static final String PASSWORD = "<apiKey>";
  public static final String VAULT_DEFAULT_DOCUMENT = "PA3_DOCUMENTS:DEFAULT";
  public static final String VAULT_DEFAULT_ACCOUNT = "Client:/analytics/data/US_MID_CAP_CORE.ACTM";
  private static final String COMPONENT_NAME = "Exposures";
  private static final String COMPONENT_CATEGORY = "General / Positioning";

  public static void main(String[] args) throws InterruptedException {
    try {
      // Build Vault Calculation Parameters List

      // Get all component from VAULT_DEFAULT_DOCUMENT with Name COMPONENT_NAME & category COMPONENT_CATEGORY
      ComponentsApi componentsApi = new ComponentsApi(getApiClient());
      Map<String, ComponentListEntity> components = componentsApi.getVaultComponents(VAULT_DEFAULT_DOCUMENT);
      String componentId = components.entrySet().stream().filter(
          c -> c.getValue().getName().equals(COMPONENT_NAME) && c.getValue().getCategory().equals(COMPONENT_CATEGORY))
          .iterator().next().getKey();
      System.out.println("ID of component with Name '" + COMPONENT_NAME + "' and category '" + COMPONENT_CATEGORY
          + "' : " + componentId);

      ConfigurationsApi configurationsApi = new ConfigurationsApi(getApiClient());
      Map<String, ConfigurationItem> configurationsMap = configurationsApi
          .getVaultConfigurations(VAULT_DEFAULT_ACCOUNT);
      String configurationId = configurationsMap.entrySet().iterator().next().getKey();
      System.out.println("Configuration ID: " + configurationId);

      CalculationParameters parameters = new CalculationParameters();

      VaultCalculationParameters vaultItem = new VaultCalculationParameters();

      vaultItem.setComponentid(componentId);
      vaultItem.setConfigid(configurationId);

      VaultCalculationAccount account = new VaultCalculationAccount();
      account.setId(VAULT_DEFAULT_ACCOUNT);
      vaultItem.setAccount(account);

      VaultDateParameters dateParameters = new VaultDateParameters();
      dateParameters.setStartdate("FIRST_REPOSITORY");
      dateParameters.setEnddate("LAST_REPOSITORY");
      dateParameters.setFrequency("Monthly");
      vaultItem.setDates(dateParameters);

      parameters.putVaultItem("1", vaultItem);

      // Run Calculation Request
      CalculationsApi apiInstance = new CalculationsApi(getApiClient());
      ApiResponse<Void> createResponse = null;

      createResponse = apiInstance.runCalculationWithHttpInfo(parameters);

      String[] locationList = createResponse.getHeaders().get("Location").get(0).split("/");
      String requestId = locationList[locationList.length - 1];

      // Get Calculation Request Status
      ApiResponse<OutstandingCalculations> getStatus = null;

      while (getStatus == null || getStatus.getData().getStatus() == StatusEnum.QUEUED
          || getStatus.getData().getStatus() == StatusEnum.EXECUTING) {
        if (getStatus != null) {
          List<String> cacheControl = getStatus.getHeaders().get("Cache-Control");
          if (cacheControl != null) {
            int maxAge = Integer.parseInt(cacheControl.get(0).replaceAll("max-age=", ""));
            System.out.println("Sleeping for: " + maxAge + " seconds");
            Thread.sleep(maxAge * 1000);
          } else {
            System.out.println("Sleeping for: 2 seconds");
            Thread.sleep(2 * 1000);
          }
        }
        getStatus = apiInstance.getCalculationByIdWithHttpInfo(requestId);
      }

      System.out.println("Calculation Completed!!!");

      // Check for Failed Calculations
      for (Map.Entry<String, Calculation> calculationParameters : getStatus.getData().getVault().entrySet()) {
        if (calculationParameters.getValue().getStatus() == Calculation.StatusEnum.FAILED) {
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Failed!!!");
          System.out.println("Error message : " + calculationParameters.getValue().getError());
          return;
        }
      }

      // Get Result of Successful Caculations
      for (Map.Entry<String, Calculation> calculationParameters : getStatus.getData().getVault().entrySet()) {
        if (calculationParameters.getValue().getStatus() == Calculation.StatusEnum.SUCCESS) {
          UtilityApi utilityApiInstance = new UtilityApi(apiClient);
          ApiResponse<String> resultResponse = utilityApiInstance
              .getByUrlWithHttpInfo(calculationParameters.getValue().getResult());
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Succeeded!!!");
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Result");

          Builder builder = Package.newBuilder();
          try {
            JsonFormat.parser().ignoringUnknownFields().merge(resultResponse.getData(), builder);
          } catch (InvalidProtocolBufferException e) {
            System.out.println("Error while deserializing the response");
            e.printStackTrace();
          }

          Package result = (Package) builder.build();
          // To convert result to 2D tables.
          List<TableData> tables = StachExtensions.convertToTableFormat(result);
          System.out.println(tables.get(0)); // Prints the result in 2D table format.
          // Uncomment the following line to generate an Excel file
          // StachExtensions.generateExcel(result);
        }
      }
    } catch (ApiException e) {
      handleException("VaultEngineExample#Main", e);
      return;
    }
  }

  private static ApiClient getApiClient() throws ApiException {
    if (apiClient != null) {
      return apiClient;
    }

    apiClient = new ApiClient();
    apiClient.setConnectTimeout(30000);
    apiClient.setReadTimeout(30000);
    apiClient.setBasePath(BASE_PATH);
    apiClient.setUsername(USERNAME);
    apiClient.setPassword(PASSWORD);

    return apiClient;
  }

  private static void handleException(String method, ApiException e) {
    System.err.println("Exception when calling " + method);
    if (e.getResponseHeaders() != null && e.getResponseHeaders().containsKey("x-datadirect-request-key")) {
      System.out.println("x-datadirect-request-key: " + e.getResponseHeaders().get("x-datadirect-request-key").get(0));
    }
    System.out.println("Status code: " + e.getCode());
    System.out.println("Reason: " + e.getResponseBody());
    e.printStackTrace();
  }
}

 

import time
import json

from google.protobuf import json_format
from google.protobuf.json_format import MessageToJson
from google.protobuf.json_format import MessageToDict
from fds.protobuf.stach.Package_pb2 import Package

from fds.analyticsapi.engines.v2.configuration import Configuration;
from fds.analyticsapi.engines.v2.api_client import ApiClient;
from fds.analyticsapi.engines.v2.api.components_api import ComponentsApi
from fds.analyticsapi.engines.v2.api.configurations_api import ConfigurationsApi
from fds.analyticsapi.engines.v2.api.calculations_api import CalculationsApi
from fds.analyticsapi.engines.v2.api.utility_api import UtilityApi
from fds.analyticsapi.engines.v2.models.calculation_parameters import CalculationParameters
from fds.analyticsapi.engines.v2.models.vault_calculation_parameters import VaultCalculationParameters
from fds.analyticsapi.engines.v2.models.vault_calculation_account import VaultCalculationAccount
from fds.analyticsapi.engines.v2.models.vault_date_parameters import VaultDateParameters
from stach_extensions import StachExtensions

host = "https://api.factset.com"
username = "<username-serial>"
password = "<apiKey>"

vault_document_name = "PA3_DOCUMENTS:DEFAULT";
vault_default_account = "CLIENT:/ANALYTICS/DATA/NORDIC_EQUITY.ACCT";
vault_startdate = "FIRST_REPOSITORY";
vault_enddate = "LAST_REPOSITORY";
frequency = "Monthly";

config = Configuration()
config.host = host
config.username = username
config.password = password
# add proxy and/or disable ssl verification according to your development environment
# config.proxy = "<proxyUrl>"
# config.verify_ssl = False

api_client = ApiClient(config)

components_api = ComponentsApi(api_client);
components = components_api.get_vault_components_with_http_info(vault_document_name)
component_id = list(components[0].keys())[0]

vault_account_identifier = VaultCalculationAccount(vault_default_account)
vault_dates = VaultDateParameters(vault_startdate, vault_enddate, frequency)

configurations_api = ConfigurationsApi(api_client)
configurations = configurations_api.get_vault_configurations_with_http_info(vault_default_account)
configuration_id = list(configurations[0].keys())[0]

vault_calculation_parameters = {"1": VaultCalculationParameters(component_id, vault_account_identifier, vault_dates, configuration_id)}
calculations = CalculationParameters(vault=vault_calculation_parameters)
print(calculations)

calculations_api = CalculationsApi(api_client)
run_calculation_response = calculations_api.run_calculation_with_http_info(calculations=calculations)

if(run_calculation_response[1] != 202):
    print(batch_api_post_result[2].get("x-datadirect-request-key"))
    quit()

calculation_id = run_calculation_response[2].get("location").split("/")[-1]
print("Calculation Id: " + calculation_id)

calculation_status = calculations_api.get_calculation_by_id_with_http_info(calculation_id)
while (calculation_status[1] == 200 and (calculation_status[0].status == "Queued" or calculation_status[0].status == "Executing")):
    age_value = calculation_status[2].get("cache-control")
    if(age_value != None):
        max_age = age_value.replace("max-age=", "")
        print('Sleeping: ' + max_age)
        time.sleep(int(max_age))
    calculation_status = calculations_api.get_calculation_by_id_with_http_info(calculation_id)

if(calculation_status[1] != 200):
    print(calculation_status[2].get("x-datadirect-request-key"))
    quit()

print("Calculation Completed!!!");

for calculation_key, calculation_item in calculation_status[0].vault.items():
    if calculation_item.status == "Failed":
        print("Spar Calculation : " + calculation_key + " Failed!!!")
        print("Error Message : " + calculation_item.error)
    elif calculation_item.status == "Success":
        utility_api = UtilityApi(api_client)
        calculation_result = utility_api.get_by_url_with_http_info(calculation_item.result)

        if(calculation_result[1] != 200):
            print(calculation_result[2].get('x-datadirect-request-key'))
            quit()

        # converting the data to Package object
        result =  json_format.Parse(json.dumps(calculation_result[0]), Package())
        # print(MessageToJson(result)) # To print the result object as a JSON
        # print(MessageToDict(result)) # To print the result object as a Dictionary
        tables = StachExtensions.convert_to_table_format(result) # To convert result to 2D tables.
        print(tables[0]) # Prints the result in 2D table format.
        # StachExtensions.generate_excel(result) # To get the result in table format exported to excel file.

 

Converting API output to Table format
using System;
using System.Collections.Generic;
using System.Linq;
using FactSet.Protobuf.Stach;
using FactSet.Protobuf.Stach.Table;

namespace FactSet.AnalyticsAPI.Engines.v2.Example.Examples
{
    public static class StachExtensions
    {
        public static void GenerateCSV(this Package package)
        {
            foreach (var table in package.ConvertToTableFormat())
            {
                System.IO.File.WriteAllText($"{Guid.NewGuid():N}.csv", table.ToString());
            }
        }

        public static List<Table> ConvertToTableFormat(this Package package)
        {
            var tables = new List<Table>();
            foreach (var primaryTableId in package.PrimaryTableIds)
            {
                tables.Add(GenerateTable(package, primaryTableId));
            }

            return tables;
        }

        private static Table GenerateTable(Package package, string primaryTableId)
        {
            var primaryTable = package.Tables[primaryTableId];
            var headerId = primaryTable.Definition.HeaderTableId;
            var headerTable = package.Tables[headerId];
            var columnIds = primaryTable.Definition.Columns.Select(c => c.Id).ToList();
            var headerColumnIds = headerTable.Definition.Columns.Select(c => c.Id).ToList();
            var dimensionColumnsCount = primaryTable.Definition.Columns.Count(c => c.IsDimension);
            var rowCount = primaryTable.Data.Rows.Count;
            var headerRowCount = headerTable.Data.Rows.Count;

            var table = new Table
            {
                Rows = new List<Row>()
            };
            // Constructs the column headers by considering dimension columns and header rows
            foreach (var columnId in headerColumnIds)
            {
                var headerRow = new Row { Cells = new List<string>() };
                for (int j = 0; j < dimensionColumnsCount; j++)
                {
                    headerRow.Cells.Add("");
                }

                for (int i = 0; i < headerRowCount; i++)
                {
                    headerRow.Cells.Add(Convert.ToString(headerTable.Data.Columns[columnId]
                        .GetValueHelper(headerTable.Definition.Columns.First(c => c.Id == columnId).Type, i)));
                }
                table.Rows.Add(headerRow);
            }
            // Constructs the column data
            for (int i = 0; i < rowCount; i++)
            {
                var dataRow = new Row { Cells = new List<string>() };
                foreach (var columnId in columnIds)
                {
                    dataRow.Cells.Add(Convert.ToString(primaryTable.Data.Columns[columnId]
                        .GetValueHelper(primaryTable.Definition.Columns.First(c => c.Id == columnId).Type, i)));
                }
                table.Rows.Add(dataRow);
            }

            return table;
        }
    }

    public static class SeriesDataHelper
    {
        public static object GetValueHelper(this SeriesData seriesData, DataType dataType, int index)
        {
            switch (dataType)
            {
                case DataType.Bool:
                    {
                        return seriesData.BoolArray?.Values?[index];
                    }
                case DataType.Double:
                    {
                        return seriesData.DoubleArray?.Values?[index];
                    }
                case DataType.Duration:
                    {
                        var v = seriesData.DurationArray?.Values?[index];
                        return v?.ToTimeSpan();
                    }
                case DataType.Float:
                    {
                        return seriesData.FloatArray?.Values?[index];
                    }
                case DataType.Int32:
                    {
                        return seriesData.Int32Array?.Values?[index];
                    }
                case DataType.Int64:
                    {
                        return seriesData.Int64Array?.Values?[index];
                    }
                case DataType.String:
                    {
                        return seriesData.StringArray?.Values?[index];
                    }
                case DataType.Timestamp:
                    {
                        var v = seriesData.TimestampArray?.Values?[index];
                        return v?.ToDateTime();
                    }
                default:
                    throw new NotImplementedException($"{dataType} is not implemented");
            }
        }
    }

    public class Table
    {
        public List<Row> Rows { get; set; }

        public override string ToString()
        {
            return string.Join(Environment.NewLine, Rows);
        }
    }

    public class Row
    {
        public List<string> Cells { get; set; }

        public override string ToString()
        {
            return string.Join(",", Cells.Select(c => c.Replace(",", "")));
        }
    }
}

 

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.factset.protobuf.stach.NullValues;
import com.factset.protobuf.stach.PackageProto.Package;
import com.factset.protobuf.stach.table.DataTypeProto.DataType;
import com.factset.protobuf.stach.table.SeriesDataProto.SeriesData;
import com.factset.protobuf.stach.table.SeriesDefinitionProto.SeriesDefinition;
import com.factset.protobuf.stach.table.TableProto.Table;

import com.google.protobuf.Duration;
import com.google.protobuf.Timestamp;

public class StachExtensions {
  // The purpose of this class is to provide the helper methods for converting
  // stach to Tabular format.

  public static void generateExcel(Package packageObj) {
    for (TableData table : convertToTableFormat(packageObj)) {
      writeDataToExcel(table, UUID.randomUUID().toString() + ".xlsx");
    }
  }

  public static List<TableData> convertToTableFormat(Package packageObj) {
    List<TableData> tables = new ArrayList<TableData>();
    for (String primaryTableId : packageObj.getPrimaryTableIdsList()) {
      tables.add(generateTable(packageObj, primaryTableId));
    }
    return tables;
  }

  private static TableData generateTable(Package packageObj, String primaryTableId) {
    Map<String, Table> tablesMap = packageObj.getTablesMap();
    Table primaryTable = tablesMap.get(primaryTableId);
    String headerId = primaryTable.getDefinition().getHeaderTableId();
    Table headerTable = tablesMap.get(headerId);
    int headerRowCount = headerTable.getData().getRowsCount();
    int rowsCount = primaryTable.getData().getRowsCount();

    TableData table = new TableData();

    // Construct the column headers by considering dimension columns and header
    // rows.
    List<SeriesDefinition> headerTableSeriesDefinitions = headerTable.getDefinition().getColumnsList();
    List<SeriesDefinition> primaryTableSeriesDefinitions = primaryTable.getDefinition().getColumnsList();

    Map<String, SeriesData> headerTableColumns = headerTable.getData().getColumnsMap();
    Map<String, SeriesData> primaryTableColumns = primaryTable.getData().getColumnsMap();

    for (SeriesDefinition headerTableseriesDefinition : headerTableSeriesDefinitions) {
      Row headerRow = new Row();
      for (SeriesDefinition primaryTableSeriesDefinition : primaryTableSeriesDefinitions) {
        if (primaryTableSeriesDefinition.getIsDimension()) {
          headerRow.Cells.add(primaryTableSeriesDefinition.getDescription());
        }
      }

      String headerColumnId = headerTableseriesDefinition.getId();
      String nullFormat = headerTableseriesDefinition.getFormat().getNullFormat();
      for (int i = 0; i < headerRowCount; i++) {
        headerRow.Cells.add(SeriesDataHelper.getValueHelper(headerTableColumns.get(headerColumnId),
            headerTableseriesDefinition.getType(), i, nullFormat).toString());
      }
      table.Rows.add(headerRow);
    }

    // Construct the column data
    for (int i = 0; i < rowsCount; i++) {
      Row dataRow = new Row();
      for (SeriesDefinition primaryTableSeriesDefinition : primaryTableSeriesDefinitions) {
        String nullFormat = primaryTableSeriesDefinition.getFormat().getNullFormat();
        String primaryTableColumnId = primaryTableSeriesDefinition.getId();
        dataRow.Cells.add(SeriesDataHelper.getValueHelper(primaryTableColumns.get(primaryTableColumnId),
            primaryTableSeriesDefinition.getType(), i, nullFormat).toString());
      }
      table.Rows.add(dataRow);
    }
    return table;
  }

  private static void writeDataToExcel(TableData table, String fileLocation) {
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("PA Report");

    int rowsSize = table.Rows.size();
    for (int rowIndex = 0; rowIndex < rowsSize; rowIndex++) {
      XSSFRow xsswRow = sheet.createRow(rowIndex);
      List<String> cells = table.Rows.get(rowIndex).Cells;
      for (int cellIndex = 0; cellIndex < cells.size(); cellIndex++) {
        XSSFCell xssfCell = xsswRow.createCell(cellIndex);
        xssfCell.setCellValue(cells.get(cellIndex));
      }
    }

    try {
      FileOutputStream out = new FileOutputStream(new File(fileLocation));
      workbook.write(out);
      out.close();
      workbook.close();
    } catch (Exception e) {
      System.err.println("Failed to write data to excel");
      e.printStackTrace();
    }
  }
}

class SeriesDataHelper {
  public static Object getValueHelper(SeriesData seriesData, DataType dataType, int index, String nullFormat) {
    if (dataType == DataType.STRING) {
      String value = seriesData.getStringArray().getValues(index);
      return NullValues.STRING.equals(value) ? nullFormat : value;
    } else if (dataType == DataType.DOUBLE) {
      double value = seriesData.getDoubleArray().getValues(index);
      return Double.isNaN(value) ? nullFormat : value;
    } else if (dataType == DataType.BOOL) {
      return seriesData.getBoolArray().getValues(index);
    } else if (dataType == DataType.DURATION) {
      Duration value = seriesData.getDurationArray().getValues(index);
      return NullValues.DURATION.equals(value) ? nullFormat : value;
    } else if (dataType == DataType.FLOAT) {
      float value = seriesData.getFloatArray().getValues(index);
      return Float.isNaN(value) ? nullFormat : value;
    } else if (dataType == DataType.INT32) {
      int value = seriesData.getInt32Array().getValues(index);
      return NullValues.INT32 == value ? nullFormat : value;
    } else if (dataType == DataType.INT64) {
      long value = seriesData.getInt64Array().getValues(index);
      return NullValues.INT64 == value ? nullFormat : value;
    } else if (dataType == DataType.TIMESTAMP) {
      Timestamp value = seriesData.getTimestampArray().getValues(index);
      return NullValues.TIMESTAMP.equals(value) ? nullFormat : value;
    } else {
      throw new NotImplementedException(dataType + " is not implemented");
    }
  }
}

class TableData {
  List<Row> Rows = new ArrayList<Row>();

  public String toString() {
    return Rows.toString();
  }
}

class Row {
  List<String> Cells = new ArrayList<String>();

  public String toString() {
    return Cells.toString();
  }
}

 

import uuid
import math

import pandas as pd

from fds.protobuf.stach.Package_pb2 import Package
from fds.protobuf.stach.NullValues import NullValues
from fds.protobuf.stach.table.DataType_pb2 import DataType

class StachExtensions:
    """The purpose of this class is to provide the helper methods for converting Stach to Tabular format"""

    @staticmethod
    def generate_excel(package):
        for table in StachExtensions.convert_to_table_format(package):
            writer = pd.ExcelWriter(str(uuid.uuid1()) + ".xlsx")
            table.to_excel(excel_writer=writer)
            writer.save()
            writer.close()

    @staticmethod
    def convert_to_table_format(package):
        tables = list()
        for primary_table_id in package.primary_table_ids:
            tables.append(StachExtensions.generate_table(package, primary_table_id))
        return tables

    @staticmethod
    def generate_table(package_response, primary_table_id):

        if isinstance(package_response, Package):
            primary_table = package_response.tables[primary_table_id]
            header_id = primary_table.definition.header_table_id
            header_table = package_response.tables[header_id]
            dimension_columns = list(filter(lambda column_obj: column_obj.is_dimension, primary_table.definition.columns))
            dimension_columns_count = len(dimension_columns)
            row_count = len(primary_table.data.rows)
            header_row_count = len(header_table.data.rows)

            headers = list(list())
            # Constructs the column headers by considering dimension columns and header rows
            for series_definition_column in header_table.definition.columns:
                header_row = list()
                for i in range(0, dimension_columns_count, 1):
                    header_row.append(dimension_columns[i].description)

                for i in range(0, header_row_count, 1):
                    header_row.append(str(SeriesDataHelper.get_value_helper(header_table.data.columns[series_definition_column.id], series_definition_column.type, i, series_definition_column.format.null_format)))
                headers.append(header_row)

            data = list(list())
            # Constructs the column data
            for i in range(0, row_count, 1):
                data_row = list()
                for series_definition_column in primary_table.definition.columns:
                    data_row.append(str(SeriesDataHelper.get_value_helper(primary_table.data.columns[series_definition_column.id], series_definition_column.type, i, series_definition_column.format.null_format)))
                data.append(data_row)

            data_frame = pd.DataFrame(data=data)
            data_frame.columns = pd.MultiIndex.from_arrays(headers)
            return data_frame

        else:
            ValueError("Response data passed should be of package type.")


class SeriesDataHelper:

    @staticmethod
    def get_value_helper(series_data, datatype, index, null_format):
        if DataType.Name(datatype) == "STRING":
            return SeriesDataHelper.null_value_handler(datatype, series_data.string_array.values[index], null_format)
        elif DataType.Name(datatype) == "DOUBLE":
            return SeriesDataHelper.null_value_handler(datatype, series_data.double_array.values[index], null_format)
        elif DataType.Name(datatype) == "FLOAT":
            return SeriesDataHelper.null_value_handler(datatype, series_data.float_array.values[index], null_format)
        elif DataType.Name(datatype) == "INT32":
            return SeriesDataHelper.null_value_handler(datatype, series_data.int32_array.values[index], null_format)
        elif DataType.Name(datatype) == "INT64":
            return SeriesDataHelper.null_value_handler(datatype, series_data.int64_array.values[index], null_format)
        elif DataType.Name(datatype) == "BOOL":
            return SeriesDataHelper.null_value_handler(datatype, series_data.bool_array.values[index], null_format)
        elif DataType.Name(datatype) == "DURATION":
            return SeriesDataHelper.null_value_handler(datatype, series_data.duration_array.values[index], null_format)
        elif DataType.Name(datatype) == "TIMESTAMP":
            return SeriesDataHelper.null_value_handler(datatype, series_data.timestamp_array.values[index], null_format)
        else:
            ValueError("The datatype is not implemented")

    @staticmethod
    def null_value_handler(datatype, value, null_format):
        if DataType.Name(datatype) == "STRING":
            if NullValues.STRING == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "DOUBLE":
            if math.isnan(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "FLOAT":
            if math.isnan(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "INT32":
            if NullValues.INT32 == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "INT64":
            if NullValues.INT64 == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "DURATION":
            if NullValues.DURATION.equals(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "TIMESTAMP":
            if NullValues.TIMESTAMP.equals(value):
                return null_format
            else:
                return value
        else:
            return value

 

Building and running a calculation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;

using FactSet.AnalyticsAPI.Engines.v2.Api;
using FactSet.AnalyticsAPI.Engines.v2.Client;
using FactSet.AnalyticsAPI.Engines.v2.Model;

using FactSet.Protobuf.Stach;
using Google.Protobuf;

namespace FactSet.AnalyticsAPI.Engines.v2.Example.Examples
{
    public class VaultEngineExample
    {
        private static Configuration _engineApiConfiguration;
        private const string BASE_PATH = "https://api.factset.com";
        private const string USER_NAME = "<username-serial>";
        private const string PASSWORD = "<apiKey>";
        private const string VAULT_DEFAULT_DOCUMENT = "PA3_DOCUMENTS:DEFAULT";
        private const string VAULT_DEFAULT_ACCOUNT = "CLIENT:/ANALYTICS/DATA/NORDIC_EQUITY.ACCT";
        private const string VAULT_START_DATE = "FIRST_REPOSITORY";
        private const string VAULT_END_DATE = "LAST_REPOSITORY";
        private const string VAULT_FREQUENCY = "Monthly";

        private static Configuration GetEngineApiConfiguration()
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            if (_engineApiConfiguration != null)
            {
                return _engineApiConfiguration;
            }

            _engineApiConfiguration = new Configuration
            {
                BasePath = BASE_PATH,
                Username = USER_NAME,
                Password = PASSWORD
            };

            return _engineApiConfiguration;
        }

        public static void Main(string[] args)
        {
            try
            {
                var calculationParameters = new CalculationParameters
                {
                    Vault = new Dictionary<string, VaultCalculationParameters> { { "1", GetVaultCalculationParameters() } }
                };

                var calculationApi = new CalculationsApi(GetEngineApiConfiguration());

                var runCalculationResponse = calculationApi.RunCalculationWithHttpInfo(calculationParameters);

                var calculationId = runCalculationResponse.Headers["Location"][0].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last();
                ApiResponse<OutstandingCalculations> getStatus = null;

                while (getStatus == null || getStatus.Data.Status == OutstandingCalculations.StatusEnum.Queued || getStatus.Data.Status == OutstandingCalculations.StatusEnum.Executing)
                {
                    if (getStatus != null)
                    {
                        if (getStatus.Headers.ContainsKey("Cache-Control"))
                        {
                            var maxAge = getStatus.Headers["Cache-Control"][0];
                            if (string.IsNullOrWhiteSpace(maxAge))
                            {
                                Console.WriteLine("Sleeping for 2 seconds");
                                // Sleep for at least 2 seconds.
                                Thread.Sleep(2000);
                            }
                            else
                            {
                                var age = int.Parse(maxAge.Replace("max-age=", ""));
                                Console.WriteLine($"Sleeping for {age} seconds");
                                Thread.Sleep(age * 1000);
                            }
                        }
                    }

                    getStatus = calculationApi.GetCalculationByIdWithHttpInfo(calculationId);
                }
                Console.WriteLine("Calculation Completed");

                // Check for failed calculations
                foreach (var vaultCalculationParameters in getStatus.Data.Vault)
                {
                    if (vaultCalculationParameters.Value.Status == Calculation.StatusEnum.Failed)
                    {
                        Console.WriteLine($"CalculationId : {vaultCalculationParameters.Key} Failed!!!");
                        Console.WriteLine($"Error message : {vaultCalculationParameters.Value.Error}");
                    }
                }

                // Get result of successful calculations
                foreach (var vaultCalculationParameters in getStatus.Data.Vault)
                {
                    PrintResult(vaultCalculationParameters);
                }

                Console.ReadKey();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        private static VaultCalculationParameters GetVaultCalculationParameters()
        {
            // Build Vault Engine calculation parameters
            var componentsApi = new ComponentsApi(GetEngineApiConfiguration());

            var componentsResponse = componentsApi.GetVaultComponentsWithHttpInfo(VAULT_DEFAULT_DOCUMENT);

            if (componentsResponse.StatusCode != HttpStatusCode.OK)
            {
                LogError(componentsResponse);
                return null;
            }

            var vaultComponentId = componentsResponse.Data.First().Key;
            Console.WriteLine($"Vault Component Id : {vaultComponentId}");


            var vaultAccount = new VaultCalculationAccount(VAULT_DEFAULT_ACCOUNT);
            var vaultDates = new VaultDateParameters(VAULT_START_DATE, VAULT_END_DATE, VAULT_FREQUENCY);

            var configurationApi = new ConfigurationsApi(GetEngineApiConfiguration());

            var configurationResponse = configurationApi.GetVaultConfigurationsWithHttpInfo(vaultAccount.Id);
            if (configurationResponse.StatusCode != HttpStatusCode.OK)
            {
                LogError(componentsResponse);
                return null;
            }
            var vaultConfiguration = configurationResponse.Data.First().Key;

            var vaultCalculation = new VaultCalculationParameters(vaultComponentId, vaultAccount, vaultDates, vaultConfiguration);

            return vaultCalculation;
        }

        private static void PrintResult(KeyValuePair<string, Calculation> calculation)
        {
            if (calculation.Value.Status == Calculation.StatusEnum.Success)
            {
                ApiResponse<string> resultResponse = null;

                var utilityApi = new UtilityApi(GetEngineApiConfiguration());
                resultResponse = utilityApi.GetByUrlWithHttpInfo(calculation.Value.Result);

                if (resultResponse.StatusCode != HttpStatusCode.OK)
                {
                    LogError(resultResponse);
                    return;
                }

                Console.WriteLine($"CalculationId : {calculation.Key} Succeeded!!!");
                Console.WriteLine($"CalculationId : {calculation.Key} Result");
                Console.WriteLine("/****************************************************************/");
                

                // converting the data to Package object 
                var jpSettings = JsonParser.Settings.Default;
                var jp = new JsonParser(jpSettings.WithIgnoreUnknownFields(true));
                var package = jp.Parse<Package>(resultResponse.Data);

                // To convert package to 2D tables.
                var tables = package.ConvertToTableFormat();
                Console.WriteLine(tables[0]);

                // Uncomment the following line to generate an Excel file
                // package.GenerateCSV();
                Console.WriteLine("/****************************************************************/");
            }
        }

        private static void LogError<T>(ApiResponse<T> response)
        {
            Console.WriteLine("Error!!!");
            Console.WriteLine("Status Code: " + response.StatusCode);
            Console.WriteLine("Request Key: " + response.Headers["X-DataDirect-Request-Key"]);
            Console.WriteLine($"Reason: {response.Data}");
        }
    }
}

 

import java.util.List;
import java.util.Map;

import factset.analyticsapi.engines.v2.*;
import factset.analyticsapi.engines.v2.api.*;
import factset.analyticsapi.engines.v2.models.*;
import factset.analyticsapi.engines.v2.models.OutstandingCalculations.StatusEnum;

import com.google.protobuf.util.JsonFormat;
import com.google.protobuf.InvalidProtocolBufferException;
import com.factset.protobuf.stach.PackageProto.Package.Builder;
import com.factset.protobuf.stach.PackageProto.Package;

public class VaultEngineExample {
  private static ApiClient apiClient = null;
  private static final String BASE_PATH = "https://api.factset.com";
  private static final String USERNAME = "<username-serial>";
  private static final String PASSWORD = "<apiKey>";
  public static final String VAULT_DEFAULT_DOCUMENT = "PA3_DOCUMENTS:DEFAULT";
  public static final String VAULT_DEFAULT_ACCOUNT = "Client:/analytics/data/US_MID_CAP_CORE.ACTM";
  private static final String COMPONENT_NAME = "Exposures";
  private static final String COMPONENT_CATEGORY = "General / Positioning";

  public static void main(String[] args) throws InterruptedException {
    try {
      // Build Vault Calculation Parameters List

      // Get all component from VAULT_DEFAULT_DOCUMENT with Name COMPONENT_NAME & category COMPONENT_CATEGORY
      ComponentsApi componentsApi = new ComponentsApi(getApiClient());
      Map<String, ComponentListEntity> components = componentsApi.getVaultComponents(VAULT_DEFAULT_DOCUMENT);
      String componentId = components.entrySet().stream().filter(
          c -> c.getValue().getName().equals(COMPONENT_NAME) && c.getValue().getCategory().equals(COMPONENT_CATEGORY))
          .iterator().next().getKey();
      System.out.println("ID of component with Name '" + COMPONENT_NAME + "' and category '" + COMPONENT_CATEGORY
          + "' : " + componentId);

      ConfigurationsApi configurationsApi = new ConfigurationsApi(getApiClient());
      Map<String, ConfigurationItem> configurationsMap = configurationsApi
          .getVaultConfigurations(VAULT_DEFAULT_ACCOUNT);
      String configurationId = configurationsMap.entrySet().iterator().next().getKey();
      System.out.println("Configuration ID: " + configurationId);

      CalculationParameters parameters = new CalculationParameters();

      VaultCalculationParameters vaultItem = new VaultCalculationParameters();

      vaultItem.setComponentid(componentId);
      vaultItem.setConfigid(configurationId);

      VaultCalculationAccount account = new VaultCalculationAccount();
      account.setId(VAULT_DEFAULT_ACCOUNT);
      vaultItem.setAccount(account);

      VaultDateParameters dateParameters = new VaultDateParameters();
      dateParameters.setStartdate("FIRST_REPOSITORY");
      dateParameters.setEnddate("LAST_REPOSITORY");
      dateParameters.setFrequency("Monthly");
      vaultItem.setDates(dateParameters);

      parameters.putVaultItem("1", vaultItem);

      // Run Calculation Request
      CalculationsApi apiInstance = new CalculationsApi(getApiClient());
      ApiResponse<Void> createResponse = null;

      createResponse = apiInstance.runCalculationWithHttpInfo(parameters);

      String[] locationList = createResponse.getHeaders().get("Location").get(0).split("/");
      String requestId = locationList[locationList.length - 1];

      // Get Calculation Request Status
      ApiResponse<OutstandingCalculations> getStatus = null;

      while (getStatus == null || getStatus.getData().getStatus() == StatusEnum.QUEUED
          || getStatus.getData().getStatus() == StatusEnum.EXECUTING) {
        if (getStatus != null) {
          List<String> cacheControl = getStatus.getHeaders().get("Cache-Control");
          if (cacheControl != null) {
            int maxAge = Integer.parseInt(cacheControl.get(0).replaceAll("max-age=", ""));
            System.out.println("Sleeping for: " + maxAge + " seconds");
            Thread.sleep(maxAge * 1000);
          } else {
            System.out.println("Sleeping for: 2 seconds");
            Thread.sleep(2 * 1000);
          }
        }
        getStatus = apiInstance.getCalculationByIdWithHttpInfo(requestId);
      }

      System.out.println("Calculation Completed!!!");

      // Check for Failed Calculations
      for (Map.Entry<String, Calculation> calculationParameters : getStatus.getData().getVault().entrySet()) {
        if (calculationParameters.getValue().getStatus() == Calculation.StatusEnum.FAILED) {
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Failed!!!");
          System.out.println("Error message : " + calculationParameters.getValue().getError());
          return;
        }
      }

      // Get Result of Successful Caculations
      for (Map.Entry<String, Calculation> calculationParameters : getStatus.getData().getVault().entrySet()) {
        if (calculationParameters.getValue().getStatus() == Calculation.StatusEnum.SUCCESS) {
          UtilityApi utilityApiInstance = new UtilityApi(apiClient);
          ApiResponse<String> resultResponse = utilityApiInstance
              .getByUrlWithHttpInfo(calculationParameters.getValue().getResult());
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Succeeded!!!");
          System.out.println("CalculationId : " + calculationParameters.getKey() + " Result");

          Builder builder = Package.newBuilder();
          try {
            JsonFormat.parser().ignoringUnknownFields().merge(resultResponse.getData(), builder);
          } catch (InvalidProtocolBufferException e) {
            System.out.println("Error while deserializing the response");
            e.printStackTrace();
          }

          Package result = (Package) builder.build();
          // To convert result to 2D tables.
          List<TableData> tables = StachExtensions.convertToTableFormat(result);
          System.out.println(tables.get(0)); // Prints the result in 2D table format.
          // Uncomment the following line to generate an Excel file
          // StachExtensions.generateExcel(result);
        }
      }
    } catch (ApiException e) {
      handleException("VaultEngineExample#Main", e);
      return;
    }
  }

  private static ApiClient getApiClient() throws ApiException {
    if (apiClient != null) {
      return apiClient;
    }

    apiClient = new ApiClient();
    apiClient.setConnectTimeout(30000);
    apiClient.setReadTimeout(30000);
    apiClient.setBasePath(BASE_PATH);
    apiClient.setUsername(USERNAME);
    apiClient.setPassword(PASSWORD);

    return apiClient;
  }

  private static void handleException(String method, ApiException e) {
    System.err.println("Exception when calling " + method);
    if (e.getResponseHeaders() != null && e.getResponseHeaders().containsKey("x-datadirect-request-key")) {
      System.out.println("x-datadirect-request-key: " + e.getResponseHeaders().get("x-datadirect-request-key").get(0));
    }
    System.out.println("Status code: " + e.getCode());
    System.out.println("Reason: " + e.getResponseBody());
    e.printStackTrace();
  }
}

 

import time
import json

from google.protobuf import json_format
from google.protobuf.json_format import MessageToJson
from google.protobuf.json_format import MessageToDict
from fds.protobuf.stach.Package_pb2 import Package

from fds.analyticsapi.engines.v2.configuration import Configuration;
from fds.analyticsapi.engines.v2.api_client import ApiClient;
from fds.analyticsapi.engines.v2.api.components_api import ComponentsApi
from fds.analyticsapi.engines.v2.api.configurations_api import ConfigurationsApi
from fds.analyticsapi.engines.v2.api.calculations_api import CalculationsApi
from fds.analyticsapi.engines.v2.api.utility_api import UtilityApi
from fds.analyticsapi.engines.v2.models.calculation_parameters import CalculationParameters
from fds.analyticsapi.engines.v2.models.vault_calculation_parameters import VaultCalculationParameters
from fds.analyticsapi.engines.v2.models.vault_calculation_account import VaultCalculationAccount
from fds.analyticsapi.engines.v2.models.vault_date_parameters import VaultDateParameters
from stach_extensions import StachExtensions

host = "https://api.factset.com"
username = "<username-serial>"
password = "<apiKey>"

vault_document_name = "PA3_DOCUMENTS:DEFAULT";
vault_default_account = "CLIENT:/ANALYTICS/DATA/NORDIC_EQUITY.ACCT";
vault_startdate = "FIRST_REPOSITORY";
vault_enddate = "LAST_REPOSITORY";
frequency = "Monthly";

config = Configuration()
config.host = host
config.username = username
config.password = password
# add proxy and/or disable ssl verification according to your development environment
# config.proxy = "<proxyUrl>"
# config.verify_ssl = False

api_client = ApiClient(config)

components_api = ComponentsApi(api_client);
components = components_api.get_vault_components_with_http_info(vault_document_name)
component_id = list(components[0].keys())[0]

vault_account_identifier = VaultCalculationAccount(vault_default_account)
vault_dates = VaultDateParameters(vault_startdate, vault_enddate, frequency)

configurations_api = ConfigurationsApi(api_client)
configurations = configurations_api.get_vault_configurations_with_http_info(vault_default_account)
configuration_id = list(configurations[0].keys())[0]

vault_calculation_parameters = {"1": VaultCalculationParameters(component_id, vault_account_identifier, vault_dates, configuration_id)}
calculations = CalculationParameters(vault=vault_calculation_parameters)
print(calculations)

calculations_api = CalculationsApi(api_client)
run_calculation_response = calculations_api.run_calculation_with_http_info(calculations=calculations)

if(run_calculation_response[1] != 202):
    print(batch_api_post_result[2].get("x-datadirect-request-key"))
    quit()

calculation_id = run_calculation_response[2].get("location").split("/")[-1]
print("Calculation Id: " + calculation_id)

calculation_status = calculations_api.get_calculation_by_id_with_http_info(calculation_id)
while (calculation_status[1] == 200 and (calculation_status[0].status == "Queued" or calculation_status[0].status == "Executing")):
    age_value = calculation_status[2].get("cache-control")
    if(age_value != None):
        max_age = age_value.replace("max-age=", "")
        print('Sleeping: ' + max_age)
        time.sleep(int(max_age))
    calculation_status = calculations_api.get_calculation_by_id_with_http_info(calculation_id)

if(calculation_status[1] != 200):
    print(calculation_status[2].get("x-datadirect-request-key"))
    quit()

print("Calculation Completed!!!");

for calculation_key, calculation_item in calculation_status[0].vault.items():
    if calculation_item.status == "Failed":
        print("Spar Calculation : " + calculation_key + " Failed!!!")
        print("Error Message : " + calculation_item.error)
    elif calculation_item.status == "Success":
        utility_api = UtilityApi(api_client)
        calculation_result = utility_api.get_by_url_with_http_info(calculation_item.result)

        if(calculation_result[1] != 200):
            print(calculation_result[2].get('x-datadirect-request-key'))
            quit()

        # converting the data to Package object
        result =  json_format.Parse(json.dumps(calculation_result[0]), Package())
        # print(MessageToJson(result)) # To print the result object as a JSON
        # print(MessageToDict(result)) # To print the result object as a Dictionary
        tables = StachExtensions.convert_to_table_format(result) # To convert result to 2D tables.
        print(tables[0]) # Prints the result in 2D table format.
        # StachExtensions.generate_excel(result) # To get the result in table format exported to excel file.

 

Converting API output to Table format
using System;
using System.Collections.Generic;
using System.Linq;
using FactSet.Protobuf.Stach;
using FactSet.Protobuf.Stach.Table;

namespace FactSet.AnalyticsAPI.Engines.v2.Example.Examples
{
    public static class StachExtensions
    {
        public static void GenerateCSV(this Package package)
        {
            foreach (var table in package.ConvertToTableFormat())
            {
                System.IO.File.WriteAllText($"{Guid.NewGuid():N}.csv", table.ToString());
            }
        }

        public static List<Table> ConvertToTableFormat(this Package package)
        {
            var tables = new List<Table>();
            foreach (var primaryTableId in package.PrimaryTableIds)
            {
                tables.Add(GenerateTable(package, primaryTableId));
            }

            return tables;
        }

        private static Table GenerateTable(Package package, string primaryTableId)
        {
            var primaryTable = package.Tables[primaryTableId];
            var headerId = primaryTable.Definition.HeaderTableId;
            var headerTable = package.Tables[headerId];
            var columnIds = primaryTable.Definition.Columns.Select(c => c.Id).ToList();
            var headerColumnIds = headerTable.Definition.Columns.Select(c => c.Id).ToList();
            var dimensionColumnsCount = primaryTable.Definition.Columns.Count(c => c.IsDimension);
            var rowCount = primaryTable.Data.Rows.Count;
            var headerRowCount = headerTable.Data.Rows.Count;

            var table = new Table
            {
                Rows = new List<Row>()
            };
            // Constructs the column headers by considering dimension columns and header rows
            foreach (var columnId in headerColumnIds)
            {
                var headerRow = new Row { Cells = new List<string>() };
                for (int j = 0; j < dimensionColumnsCount; j++)
                {
                    headerRow.Cells.Add("");
                }

                for (int i = 0; i < headerRowCount; i++)
                {
                    headerRow.Cells.Add(Convert.ToString(headerTable.Data.Columns[columnId]
                        .GetValueHelper(headerTable.Definition.Columns.First(c => c.Id == columnId).Type, i)));
                }
                table.Rows.Add(headerRow);
            }
            // Constructs the column data
            for (int i = 0; i < rowCount; i++)
            {
                var dataRow = new Row { Cells = new List<string>() };
                foreach (var columnId in columnIds)
                {
                    dataRow.Cells.Add(Convert.ToString(primaryTable.Data.Columns[columnId]
                        .GetValueHelper(primaryTable.Definition.Columns.First(c => c.Id == columnId).Type, i)));
                }
                table.Rows.Add(dataRow);
            }

            return table;
        }
    }

    public static class SeriesDataHelper
    {
        public static object GetValueHelper(this SeriesData seriesData, DataType dataType, int index)
        {
            switch (dataType)
            {
                case DataType.Bool:
                    {
                        return seriesData.BoolArray?.Values?[index];
                    }
                case DataType.Double:
                    {
                        return seriesData.DoubleArray?.Values?[index];
                    }
                case DataType.Duration:
                    {
                        var v = seriesData.DurationArray?.Values?[index];
                        return v?.ToTimeSpan();
                    }
                case DataType.Float:
                    {
                        return seriesData.FloatArray?.Values?[index];
                    }
                case DataType.Int32:
                    {
                        return seriesData.Int32Array?.Values?[index];
                    }
                case DataType.Int64:
                    {
                        return seriesData.Int64Array?.Values?[index];
                    }
                case DataType.String:
                    {
                        return seriesData.StringArray?.Values?[index];
                    }
                case DataType.Timestamp:
                    {
                        var v = seriesData.TimestampArray?.Values?[index];
                        return v?.ToDateTime();
                    }
                default:
                    throw new NotImplementedException($"{dataType} is not implemented");
            }
        }
    }

    public class Table
    {
        public List<Row> Rows { get; set; }

        public override string ToString()
        {
            return string.Join(Environment.NewLine, Rows);
        }
    }

    public class Row
    {
        public List<string> Cells { get; set; }

        public override string ToString()
        {
            return string.Join(",", Cells.Select(c => c.Replace(",", "")));
        }
    }
}

 

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.factset.protobuf.stach.NullValues;
import com.factset.protobuf.stach.PackageProto.Package;
import com.factset.protobuf.stach.table.DataTypeProto.DataType;
import com.factset.protobuf.stach.table.SeriesDataProto.SeriesData;
import com.factset.protobuf.stach.table.SeriesDefinitionProto.SeriesDefinition;
import com.factset.protobuf.stach.table.TableProto.Table;

import com.google.protobuf.Duration;
import com.google.protobuf.Timestamp;

public class StachExtensions {
  // The purpose of this class is to provide the helper methods for converting
  // stach to Tabular format.

  public static void generateExcel(Package packageObj) {
    for (TableData table : convertToTableFormat(packageObj)) {
      writeDataToExcel(table, UUID.randomUUID().toString() + ".xlsx");
    }
  }

  public static List<TableData> convertToTableFormat(Package packageObj) {
    List<TableData> tables = new ArrayList<TableData>();
    for (String primaryTableId : packageObj.getPrimaryTableIdsList()) {
      tables.add(generateTable(packageObj, primaryTableId));
    }
    return tables;
  }

  private static TableData generateTable(Package packageObj, String primaryTableId) {
    Map<String, Table> tablesMap = packageObj.getTablesMap();
    Table primaryTable = tablesMap.get(primaryTableId);
    String headerId = primaryTable.getDefinition().getHeaderTableId();
    Table headerTable = tablesMap.get(headerId);
    int headerRowCount = headerTable.getData().getRowsCount();
    int rowsCount = primaryTable.getData().getRowsCount();

    TableData table = new TableData();

    // Construct the column headers by considering dimension columns and header
    // rows.
    List<SeriesDefinition> headerTableSeriesDefinitions = headerTable.getDefinition().getColumnsList();
    List<SeriesDefinition> primaryTableSeriesDefinitions = primaryTable.getDefinition().getColumnsList();

    Map<String, SeriesData> headerTableColumns = headerTable.getData().getColumnsMap();
    Map<String, SeriesData> primaryTableColumns = primaryTable.getData().getColumnsMap();

    for (SeriesDefinition headerTableseriesDefinition : headerTableSeriesDefinitions) {
      Row headerRow = new Row();
      for (SeriesDefinition primaryTableSeriesDefinition : primaryTableSeriesDefinitions) {
        if (primaryTableSeriesDefinition.getIsDimension()) {
          headerRow.Cells.add(primaryTableSeriesDefinition.getDescription());
        }
      }

      String headerColumnId = headerTableseriesDefinition.getId();
      String nullFormat = headerTableseriesDefinition.getFormat().getNullFormat();
      for (int i = 0; i < headerRowCount; i++) {
        headerRow.Cells.add(SeriesDataHelper.getValueHelper(headerTableColumns.get(headerColumnId),
            headerTableseriesDefinition.getType(), i, nullFormat).toString());
      }
      table.Rows.add(headerRow);
    }

    // Construct the column data
    for (int i = 0; i < rowsCount; i++) {
      Row dataRow = new Row();
      for (SeriesDefinition primaryTableSeriesDefinition : primaryTableSeriesDefinitions) {
        String nullFormat = primaryTableSeriesDefinition.getFormat().getNullFormat();
        String primaryTableColumnId = primaryTableSeriesDefinition.getId();
        dataRow.Cells.add(SeriesDataHelper.getValueHelper(primaryTableColumns.get(primaryTableColumnId),
            primaryTableSeriesDefinition.getType(), i, nullFormat).toString());
      }
      table.Rows.add(dataRow);
    }
    return table;
  }

  private static void writeDataToExcel(TableData table, String fileLocation) {
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("PA Report");

    int rowsSize = table.Rows.size();
    for (int rowIndex = 0; rowIndex < rowsSize; rowIndex++) {
      XSSFRow xsswRow = sheet.createRow(rowIndex);
      List<String> cells = table.Rows.get(rowIndex).Cells;
      for (int cellIndex = 0; cellIndex < cells.size(); cellIndex++) {
        XSSFCell xssfCell = xsswRow.createCell(cellIndex);
        xssfCell.setCellValue(cells.get(cellIndex));
      }
    }

    try {
      FileOutputStream out = new FileOutputStream(new File(fileLocation));
      workbook.write(out);
      out.close();
      workbook.close();
    } catch (Exception e) {
      System.err.println("Failed to write data to excel");
      e.printStackTrace();
    }
  }
}

class SeriesDataHelper {
  public static Object getValueHelper(SeriesData seriesData, DataType dataType, int index, String nullFormat) {
    if (dataType == DataType.STRING) {
      String value = seriesData.getStringArray().getValues(index);
      return NullValues.STRING.equals(value) ? nullFormat : value;
    } else if (dataType == DataType.DOUBLE) {
      double value = seriesData.getDoubleArray().getValues(index);
      return Double.isNaN(value) ? nullFormat : value;
    } else if (dataType == DataType.BOOL) {
      return seriesData.getBoolArray().getValues(index);
    } else if (dataType == DataType.DURATION) {
      Duration value = seriesData.getDurationArray().getValues(index);
      return NullValues.DURATION.equals(value) ? nullFormat : value;
    } else if (dataType == DataType.FLOAT) {
      float value = seriesData.getFloatArray().getValues(index);
      return Float.isNaN(value) ? nullFormat : value;
    } else if (dataType == DataType.INT32) {
      int value = seriesData.getInt32Array().getValues(index);
      return NullValues.INT32 == value ? nullFormat : value;
    } else if (dataType == DataType.INT64) {
      long value = seriesData.getInt64Array().getValues(index);
      return NullValues.INT64 == value ? nullFormat : value;
    } else if (dataType == DataType.TIMESTAMP) {
      Timestamp value = seriesData.getTimestampArray().getValues(index);
      return NullValues.TIMESTAMP.equals(value) ? nullFormat : value;
    } else {
      throw new NotImplementedException(dataType + " is not implemented");
    }
  }
}

class TableData {
  List<Row> Rows = new ArrayList<Row>();

  public String toString() {
    return Rows.toString();
  }
}

class Row {
  List<String> Cells = new ArrayList<String>();

  public String toString() {
    return Cells.toString();
  }
}

 

import uuid
import math

import pandas as pd

from fds.protobuf.stach.Package_pb2 import Package
from fds.protobuf.stach.NullValues import NullValues
from fds.protobuf.stach.table.DataType_pb2 import DataType

class StachExtensions:
    """The purpose of this class is to provide the helper methods for converting Stach to Tabular format"""

    @staticmethod
    def generate_excel(package):
        for table in StachExtensions.convert_to_table_format(package):
            writer = pd.ExcelWriter(str(uuid.uuid1()) + ".xlsx")
            table.to_excel(excel_writer=writer)
            writer.save()
            writer.close()

    @staticmethod
    def convert_to_table_format(package):
        tables = list()
        for primary_table_id in package.primary_table_ids:
            tables.append(StachExtensions.generate_table(package, primary_table_id))
        return tables

    @staticmethod
    def generate_table(package_response, primary_table_id):

        if isinstance(package_response, Package):
            primary_table = package_response.tables[primary_table_id]
            header_id = primary_table.definition.header_table_id
            header_table = package_response.tables[header_id]
            dimension_columns = list(filter(lambda column_obj: column_obj.is_dimension, primary_table.definition.columns))
            dimension_columns_count = len(dimension_columns)
            row_count = len(primary_table.data.rows)
            header_row_count = len(header_table.data.rows)

            headers = list(list())
            # Constructs the column headers by considering dimension columns and header rows
            for series_definition_column in header_table.definition.columns:
                header_row = list()
                for i in range(0, dimension_columns_count, 1):
                    header_row.append(dimension_columns[i].description)

                for i in range(0, header_row_count, 1):
                    header_row.append(str(SeriesDataHelper.get_value_helper(header_table.data.columns[series_definition_column.id], series_definition_column.type, i, series_definition_column.format.null_format)))
                headers.append(header_row)

            data = list(list())
            # Constructs the column data
            for i in range(0, row_count, 1):
                data_row = list()
                for series_definition_column in primary_table.definition.columns:
                    data_row.append(str(SeriesDataHelper.get_value_helper(primary_table.data.columns[series_definition_column.id], series_definition_column.type, i, series_definition_column.format.null_format)))
                data.append(data_row)

            data_frame = pd.DataFrame(data=data)
            data_frame.columns = pd.MultiIndex.from_arrays(headers)
            return data_frame

        else:
            ValueError("Response data passed should be of package type.")


class SeriesDataHelper:

    @staticmethod
    def get_value_helper(series_data, datatype, index, null_format):
        if DataType.Name(datatype) == "STRING":
            return SeriesDataHelper.null_value_handler(datatype, series_data.string_array.values[index], null_format)
        elif DataType.Name(datatype) == "DOUBLE":
            return SeriesDataHelper.null_value_handler(datatype, series_data.double_array.values[index], null_format)
        elif DataType.Name(datatype) == "FLOAT":
            return SeriesDataHelper.null_value_handler(datatype, series_data.float_array.values[index], null_format)
        elif DataType.Name(datatype) == "INT32":
            return SeriesDataHelper.null_value_handler(datatype, series_data.int32_array.values[index], null_format)
        elif DataType.Name(datatype) == "INT64":
            return SeriesDataHelper.null_value_handler(datatype, series_data.int64_array.values[index], null_format)
        elif DataType.Name(datatype) == "BOOL":
            return SeriesDataHelper.null_value_handler(datatype, series_data.bool_array.values[index], null_format)
        elif DataType.Name(datatype) == "DURATION":
            return SeriesDataHelper.null_value_handler(datatype, series_data.duration_array.values[index], null_format)
        elif DataType.Name(datatype) == "TIMESTAMP":
            return SeriesDataHelper.null_value_handler(datatype, series_data.timestamp_array.values[index], null_format)
        else:
            ValueError("The datatype is not implemented")

    @staticmethod
    def null_value_handler(datatype, value, null_format):
        if DataType.Name(datatype) == "STRING":
            if NullValues.STRING == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "DOUBLE":
            if math.isnan(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "FLOAT":
            if math.isnan(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "INT32":
            if NullValues.INT32 == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "INT64":
            if NullValues.INT64 == value:
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "DURATION":
            if NullValues.DURATION.equals(value):
                return null_format
            else:
                return value
        elif DataType.Name(datatype) == "TIMESTAMP":
            if NullValues.TIMESTAMP.equals(value):
                return null_format
            else:
                return value
        else:
            return value

 

Change Logs

v2
Summary
  • v2.0.0 - Released on 08/15/19
Functionality Additions
  • Initial release [v2.0.0]
Changes
  • No changes
Bug Fixes
  • No changes
v1 (Retired)
Summary
  • v1.1.0 - Released on 07/25/19
  • v1.0.0 - Released on 06/13/19
Functionality Additions
  • Added format parameter to Get Result Endpoint to switch between different output formats [v1.1.0]
  • Made document extension optional when using Component Lookup endpoint [v1.1.0]
  • Added ability to create, fetch, and delete multiple Vault calculations [v1.0.0]
  • Initial release [v1.0.0]
Changes
  • No changes
Bug Fixes
  • No bug fixes