Sunday, January 6, 2019

Einstein Analytics Dataflow REST API by example

The following link may be placed on your bookmarks bar and following the directions below you may view, start and stop dataflows. Please note there is no bullet proofing the script won't check if something is already running, etc. Also, it will acquire your SID, so please review the code carefully for any concerns.

data_flow

Basic instructions.

1) Log into Analytics Studio
2) Launch script
3) Look for popup in the upper left
4) View all the dataflows then select if you want to start, stop, etc.

The code.




/*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

(function () {

var JQ = null;
var JQ_VERSION = "3.2.1";
var API_STR = "v43.0/";
var PROTO_STR = "https://";
var BASE_PATH_STR = "/services/data/";
var CREDENTIALS_OBJ = getServerSid();
var DIV_DOM_ELEM = document.createElement("div");
var SELECT_DOM_ELEM = document.createElement("SELECT");
var MAX_TIMEOUTS = 15;

  function loadItem (u, i) {
      var d = document;
      if (!d.getElementById(i)) {
          var s = d.createElement('script');
          s.src = u;
          s.id = i;
          d.body.appendChild(s);
      }
setTimeout(checkJQueryVersion, 50);
console.info("waiting on timeout");
  }
  loadItem('//code.jquery.com/jquery-' + JQ_VERSION + '.min.js', 'jquery')

// There's a better way to do this, tired of trying to get onload to work
function checkJQueryVersion () {
function finishJQueryProcessing () {
JQ = jQuery.noConflict( true );
setupHTMLAdds();
}
if (MAX_TIMEOUTS < 0) {
console.warning("We did not detect the correct jquery version, but exceeded timeouts waiting. Could be slow network, or the requested jquery version was not configured correctly.");
finishJQueryProcessing();
return;
}
MAX_TIMEOUTS--;

if ($.fn.jquery == JQ_VERSION) {
console.info("Successfully loaded jquery version:", $.fn.jquery, ". FYI, timeouts remaining:", MAX_TIMEOUTS);
finishJQueryProcessing();
return;
}
setTimeout(checkJQueryVersion, 50);
}

function addBr (dom_elem, n) {
for (var i=0;i<n;i++) {
dom_elem.appendChild(document.createElement("br"));
}
}

function setupHTMLAdds () {
DIV_DOM_ELEM.appendChild(SELECT_DOM_ELEM);
var btns_arr = [
{label: "All Dataflows", proc: getDataflows},
{label: "Start Selected Dataflow", proc: startRunningDataflow},
{label: "Active Dataflows", proc: getRunningDataflows},
{label: "Stop Selected Dataflow", proc: stopRunningDataflow},
{label: "Close Me", proc: closeMe}
];

addBr (DIV_DOM_ELEM, 2);
for (var i=0; i<btns_arr.length; i++) {
var btn = document.createElement("button");
DIV_DOM_ELEM.appendChild(btn);
addBr(DIV_DOM_ELEM, 1);
btn.innerText = btns_arr[i].label;
btn.onclick = btns_arr[i].proc;
}

addBr(DIV_DOM_ELEM, 3);

if (document.body.firstChild) document.body.insertBefore(DIV_DOM_ELEM, document.body.firstChild);
else document.body.appendChild(DIV_DOM_ELEM);
}

function removeAllChildren (elem) {
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}

function closeMe () {
DIV_DOM_ELEM.parentNode.removeChild(DIV_DOM_ELEM);
}

function getServerSid () {
var server = window.location.href.replace(/https?:\/\//,"").split("/")[0];
var sid = document.cookie.match(/(^|;\s*)sid=(.+?);/)[2];
var shell_sid = sid.replace(/!/g,"\\!");
return {"server": server, "sid": sid, "shell_sid": shell_sid};
}

function secureHeaderPrepSf (sid) {
return function (xhr) {
xhr.setRequestHeader('Authorization', "OAuth " + sid);
}
}

function createAjaxErrorResponse (deco_text) {
return function (jqXHR, text_status, error_thrown ) {
console.error("Error (INFO:", deco_text, ")" , "'jqXHR':", jqXHR, "'text status':", text_status, "'error thrown':", error_thrown)
}
}

function startRunningDataflow () {
  var val = SELECT_DOM_ELEM.options[SELECT_DOM_ELEM.selectedIndex].value;
  var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflowjobs";
  var patch_data = {
command: "Start",
dataflowId: val
};
  JQ.ajax({
  type: "POST",
  data: JSON.stringify(patch_data),
  contentType: "application/json; charset=utf-8",
  url: url,
  beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
  error: createAjaxErrorResponse("starting dataflow"),
  success: function (data) {
  if (data.status) alert("Start request sent, status is currently: " + data.status);
  else alert("Start request sent, but no status indication was recieved");
  console.info("stopRunningDataflow data result:", data);
  }
  })
  }

 function stopRunningDataflow () {
var val = SELECT_DOM_ELEM.options[SELECT_DOM_ELEM.selectedIndex].value;
var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflowjobs/" + val ;
var patch_data = {command: "Stop"};
JQ.ajax({
type: "PATCH",
data: JSON.stringify(patch_data),
contentType: "application/json; charset=utf-8",
url: url,
beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
error: createAjaxErrorResponse("stopping dataflow"),
success: function (data) {
if (data.message) alert("Kill request sent and received message: " + data.message);
else alert("Kill request sent, but no message was recieved - likely the job was complete");
console.info("stopRunningDataflow data result:", data);
}
})
 }

function getRunningDataflows () {
var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflowjobs";
JQ.ajax({
type: "GET",
url: url,
beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
error: createAjaxErrorResponse("obtaining running dataflows"),
success: function (data) {
console.info("getRunningDataflows data result:", data);
removeAllChildren(SELECT_DOM_ELEM);
for (var i=0;i<data.dataflowJobs.length; i++) {
var duration = data.dataflowJobs[i].duration;
if (!duration) {
if (data.dataflowJobs[i].status == "Queued") duration = 0;
else {
duration = Math.round(( new Date() - new Date(data.dataflowJobs[i].startDate) ) / 1000);
}
}
var opt = document.createElement('option');
    opt.value = data.dataflowJobs[i].id;
opt.innerHTML = data.dataflowJobs[i].label + ", " + duration + " (s), " + data.dataflowJobs[i].status;
    SELECT_DOM_ELEM.appendChild(opt);
}
}
})
}

function getDataflows () {
var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflows";
JQ.ajax({
type: "GET",
url: url,
beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
error: createAjaxErrorResponse("getting dataflows"),
success: function (data) {
console.info("getDataflows data result:", data);
removeAllChildren(SELECT_DOM_ELEM);
for (var i=0;i<data.dataflows.length; i++) {
var opt = document.createElement('option');
    opt.value = data.dataflows[i].id;
opt.innerHTML = data.dataflows[i].label;
    SELECT_DOM_ELEM.appendChild(opt);
}
}
})
}

}());