cancel
Showing results for 
Search instead for 
Did you mean: 
intapiuser
Community Team Member
Community Team Member
In Sisense Linux distribution you are able to upload files to the Sisense environment via the file management Interface. This article describes few ways for uploading files programmatically using bash, Powershell and python.

Powershell Script for uploading a file via rest api for Sisense version greater than L2021.5

# ------- Config -------

# Sisense base DNS
# For example http://23.50.45.130:30845
$baseUrl="<Sisense DNS>" 

# Destination location on sisense server - must be accessible via Sisense file management interface
$remoteLocation="/test1/data.csv"

# Local file path 
$filePath="data.csv"

# admin api token
$apiToken="<Admin API Token>"

# Should the new file override existing files with the same name
$shouldOverride="true"

# ------- End Of Config -------

# File Management URL
$uploadPathUrl="/app/explore/api/resources/data"

# Create URL to send file to
$url=$baseUrl+$uploadPathUrl+$remoteLocation + "?override=" + $shouldOverride
#Write-Output $url

# Create authorization bearer header
$authorization="Bearer $apiToken"
#Write-Output $authorization

# In order to add files via the file explorer, one requires also x-auth token. the next part fetchs x-auth using the admin api token
$xauthpath="/app/explore/api/login"
$xauthurl=$baseUrl+$xauthpath
#Write-Output $xauthurl

$headers = @{
    'Authorization' = $authorization
}

# Send request to get xauth
# For https remove -AllowUnencryptedAuthentication
$xauth = Invoke-RestMethod -Uri $xauthurl -Method Post -Headers $headers -AllowUnencryptedAuthentication
#Write-Output $xauth

$headers += @{
    'X-Auth' = $xauth
}

# Send a request to upload a file
# For https remove -AllowUnencryptedAuthentication
$res = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -AllowUnencryptedAuthentication -ContentType 'text/csv' -InFile $filePath

# Print response
Write-Output $res

Bash Script for uploading a file via rest api (using cUrl) for Sisense version greater than L2021.5

#!/bin/bash          

# ------- Config -------

# Sisense base DNS
# For example http://23.50.45.130:30845
baseUrl="<Sisense DNS>"

# Destination location on sisense server - must be accessible via droppy
remoteLocation="/test1/data.csv"

# Local file path 
filePath="data.csv"

# admin api token
apiToken="<Admin API Token>"

# Should the new file override existing files with the same name
shouldOverride="true"

# ------- End Of Config -------

# File Management URL
uploadPathUrl="/app/explore/api/resources/data"

# Create URL to send file to
url=$baseUrl$uploadPathUrl$remoteLocation"?override="$shouldOverride

echo $url

# Create authorization bearer header
authorization="Bearer $apiToken"

# In order to add files via the file explorer, one requires also x-auth token. the next part fetchs x-auth using the admin api token
xauthpath="/app/explore/api/login"
xauthurl=$baseUrl$xauthpath
echo $xauthurl

# Send request to get xauth
xauth=$(curl -H "Authorization: $authorization"  $xauthurl)
echo $xauth

# Send a request to upload a file
res=$(curl -H "Authorization: $authorization" -H "X-Auth: $xauth" -H "Content-Type: text/csv" -d @$filePath $url)

# Print response
echo $res

Power-Shell 1 file upload Example - Version <=L20121.3

The script below will allow the user to upload files programmatically, using REST command. The script itself is written in Powershell.
Change the first 4 parameters
dns - The URL you use for your Sisense site
RemoteLocation - The location of the target file within File Manager
FilePath - The local location of the file from the Local Server
AUTH_TOEN - Generate a token and replace it with <token>
$dns= 'https://myhost.sisense.com'
$RemoteLocation= 'data/Test'
$FilePath = 'C:\myfolder\myfile.csv';
$AUTH_TOKEN = 'Bearer <Token>'

###############################################################
$pos = $FilePath.LastIndexOf("\")
$URL = $dns+'/app/explore/!/upload?vId=0&rename=0&to=/'+$RemoteLocation;
$filename = $FilePath.Substring($pos+1)
$fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
$fileEnc = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes);
$boundary = [System.Guid]::NewGuid().ToString(); 
$LF = "`r`n";
$Headers = @{'Authorization'=$AUTH_TOKEN};

$bodyLines = ( 
 "--$boundary",
 "Content-Disposition: form-data; name=`"filename`"; filename=`"$filename`"",
 "Content-Type: application/octet-stream$LF",
 $fileEnc,
 "--$boundary--$LF" 
) -join $LF

Invoke-RestMethod -Uri $URL -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -headers $Headers -Body $bodyLines

Python Example For Folder Syncing (Upload Only)

In this example you can set a local folder with sub-folders to sync with a File Management virtual library.
First run will upload and update all files and create a lastRunTime.json file for reference of last run.
On the next run only files that the update date is larger than the last run time of the application will be uploaded/updated
Config.ini file sample:
[DEFAULT]

# Sisense URL
host = https://test.sisense.com

# Path to store files on target machine
remoteLocation= data/Test

# Path to folder or file which should be transferred 
# If folder is specifeed, all subfolders will be also proccessed
path = C:\Users\Documents\Test\

# Sisense API token
token = Bearer TOKEN


# Script will store last modified time for each processed file. This will allow it to upload only modified files on next executions
lastRunFilename = lastRunTime.json
Droppy.py file sample:

Droppy.py example Version <=L2021.3

import uuid
import requests
import io
import json
import os
import time
from datetime import datetime
import configparser


config = configparser.ConfigParser()
config.read('config.ini')

lastRunFilename = config.get('DEFAULT','lastRunFilename')
host = config.get('DEFAULT','host')
remoteLocation = config.get('DEFAULT','remoteLocation')
path = config.get('DEFAULT','path')
token = config.get('DEFAULT','token')

# Cut slashes at the end of paths if they are exist
if path[-1] == '\\':
 path = path[:-1]
if remoteLocation[-1] == '/':
 remoteLocation = remoteLocation[:-1]

# Function to compare stored and file last modified time
def compareModificationTime(filePath):

 if (filePath in lastRunTime and os.path.getmtime(filePath)>int(lastRunTime.get(filePath))) or (filePath not in lastRunTime):
  return True
 else:
  return False

# Function to upload file to Droppy via Sisense API
def uploadFile (filesNames, folderPath):
 if os.path.isfile(path):
  globalFolderPath = os.path.dirname(path)
 else:
  globalFolderPath = path

 if folderPath != globalFolderPath:
  remotePath = remoteLocation + folderPath.replace(globalFolderPath,'')
 else:
  remotePath = remoteLocation

 remotePath = remotePath.replace('\\','/')
 url = host +'/app/explore/!/upload?vId=0&rename=0&to=/'+remotePath
 files = []
 header = {'Authorization': token}
 notSentFiles = []
 for filename in filesNames:
  filePath = '%s\\%s'%(folderPath, filename)
  if compareModificationTime(filePath):
   files.append( ("file", ( open(filePath, "rb"))))
   lastRunTime [filePath] = int(time.time())
  else:
   notSentFiles.append(filePath)
 if files:
  
  r = requests.post(url, files=files, headers=header)

  for filename in filesNames:
   print(remotePath+'/'+filename, r.status_code, r.reason)
 return notSentFiles


try:
 f = open(lastRunFilename, "r")
 timestamp = f.read()
 lastRunTime = json.loads(timestamp)
except:
 lastRunTime = {}



notSentFiles=[]
if ( os.path.isdir(path)):

 for root, subdirs, files in os.walk(path):
  if files:

   notSentFiles += uploadFile (files, root)

   time.sleep(0.1)
elif ( os.path.isfile(path)):

 notSentFiles += uploadFile ([os.path.basename(path)], path.rsplit('\\', 1)[0])

 
elif not os.path.exists(path):
 print ("Specified path doesn't exist")

if notSentFiles:
 print ('These files were not uploaded because they were not modified:')
 for file in notSentFiles:
  print (file)


with open(lastRunFilename, 'w') as f:
    json.dump(lastRunTime, f)

Version >= L2021.5

import uuid
import requests
import io
import json
import os
import time
from datetime import datetime
import configparser
​
​
config = configparser.ConfigParser()
config.read('config.ini')
​
lastRunFilename = config.get('DEFAULT','lastRunFilename')
host = config.get('DEFAULT','host')
remoteLocation = config.get('DEFAULT','remoteLocation')
path = config.get('DEFAULT','path')
token = config.get('DEFAULT','token')
​
# Cut slashes at the end of paths if they are exist
if path[-1] == '\\':
 path = path[:-1]
if remoteLocation[-1] == '/':
 remoteLocation = remoteLocation[:-1]
​
# Function to compare stored and file last modified time
def compareModificationTime(filePath):
​
 if (filePath in lastRunTime and os.path.getmtime(filePath)>int(lastRunTime.get(filePath))) or (filePath not in lastRunTime):
  return True
 else:
  return False
​
# Function to upload file to Droppy via Sisense API
def uploadFile (filesNames, folderPath):
 def get_auth(token):
  headers = {
  'Authorization': token,
  }
​
​
  x_auth = requests.post(f'{host}/app/explore/api/login', headers=headers)
  if x_auth.status_code==200:
   return x_auth.text
  else:
   print ('Cannot get x-auth token. Check API token validity')
   return False
  
 # # SERVICE FUNCTION
 # # Do NOT modify
 x_auth = get_auth(token)
 if os.path.isfile(path):
  globalFolderPath = os.path.dirname(path)
 else:
  globalFolderPath = path
​
 if folderPath != globalFolderPath:
  remotePath = remoteLocation + folderPath.replace(globalFolderPath,'')
 else:
  remotePath = remoteLocation
​
 remotePath = remotePath.replace('\\','/')
​
 files = []
 header = {'Authorization': token, 'x-auth': x_auth,}
 notSentFiles = []
 for filename in filesNames:
  filePath = '%s\\%s'%(folderPath, filename)
  if compareModificationTime(filePath):
   files.append(filePath)
   lastRunTime [filePath] = int(time.time())
  else:
   notSentFiles.append(filePath)
 if files:
  for file in files:
   with open(file,'rb') as ff:
    file=os.path.basename(file)
    r = requests.post(f'{host}/app/explore/api/resources/{remotePath}/{file}?override=true', headers=header,data=ff)
    print(remotePath+'/'+file, r.status_code, r.reason)
​
 return notSentFiles
​
​
try:
 f = open(lastRunFilename, "r")
 timestamp = f.read()
 lastRunTime = json.loads(timestamp)
except:
 lastRunTime = {}
​
​
​
notSentFiles=[]
if ( os.path.isdir(path)):
​
 for root, subdirs, files in os.walk(path):
  if files:
​
   notSentFiles += uploadFile (files, root)
​
   time.sleep(0.1)
elif ( os.path.isfile(path)):
​
 notSentFiles += uploadFile ([os.path.basename(path)], path.rsplit('\\', 1)[0])
​
 
elif not os.path.exists(path):
 print ("Specified path doesn't exist")
​
if notSentFiles:
 print ('These files were not uploaded because they were not modified:')
 for file in notSentFiles:
  print (file)
​
​
with open(lastRunFilename, 'w') as f:
    json.dump(lastRunTime, f)
Rate this article:
Version history
Last update:
‎03-02-2023 09:51 AM
Updated by:
Contributors