Like what you see? Have a play with our trial version.

Error rendering macro 'rw-search'

null

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejava
titleJava
collapsetrue
package rest.code.examples;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Import a YFX file via the Yellowfin REST API
 */
public class ImportYFXFile {
    public static void main(String[] args) throws Exception {

        System.out.println(""Import YFX File"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String fileToImport = ""/Downloads/Test.yfx"";
        Path importFile = Paths.get(fileToImport);
        byte[] fileContents = Files.readAllBytes(importFile);
        String token = generateToken(host, restUsername, restPassword);

        // Upload File for initial analysis, and to fetch the number of import items.

        HttpEntity getImportFileContentMulitpartEntity = MultipartEntityBuilder
                .create()
                .setMode(HttpMultipartMode.LEGACY)
                .setCharset(Charset.forName(""UTF-8""))
                .addBinaryBody(""contentToProcess"", fileContents , ContentType.DEFAULT_BINARY, importFile.getFileName().toString())
                .build();

        System.out.println(""Getting Import File Contents"");

        Content getImportContentContent = Request.post(host + ""/api/rpc/import-export/get-import-content"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", getImportFileContentMulitpartEntity.getContentType())
                .addHeader(""cache-control"", ""no-cache"")
                .body(getImportFileContentMulitpartEntity)
                .execute()
                .returnContent();


        JsonObject jsonObject = new JsonParser().parse(getImportContentContent.asString()).getAsJsonObject();
        JsonElement itemList = jsonObject.get(""items"");
        JsonArray items = itemList.getAsJsonArray();

        // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD.

        String importOptions = """";

        for (int i=0; i < items.size(); i++ ) {
            JsonObject item = items.getAsJsonArray().get(i).getAsJsonObject();
            System.out.println(""Item "" + i + "" "" + item.get(""resourceType"").getAsString() + "" "" + item.get(""resourceName"").getAsString() + "" found"");
            if (i>0) {
                importOptions = importOptions + "","";
            }
            importOptions = importOptions + ""{ \""itemIndex\"": "" + i + "", \""optionKey\"": \""SKIP\"", \""optionValue\"": false }, { \""itemIndex\"": "" + i + "", \""optionKey\"": \""OPTION\"", \""optionValue\"": \""ADD\"" }"";
        }

        // Upload File for for import, with import options populated

        HttpEntity importContentMultipartEntity = MultipartEntityBuilder
                .create()
                .setMode(HttpMultipartMode.LEGACY)
                .setCharset(Charset.forName(""UTF-8""))
                .addBinaryBody(""contentToProcess"", fileContents , ContentType.DEFAULT_BINARY, importFile.getFileName().toString())
                .addTextBody(""importOptions"", ""["" + importOptions + ""]"", ContentType.APPLICATION_JSON)
                .build();

        System.out.println(""Importing Content"");
        Content importContentContent = Request.post(host + ""/api/rpc/import-export/import-content"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", importContentMultipartEntity.getContentType())
                .addHeader(""cache-control"", ""no-cache"")
                .body(importContentMultipartEntity)
                .execute()
                .returnContent();

        System.out.println(""Content Import Complete"");
        System.out.println(importContentContent.asString());

    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
Code Block
languagec#
titleC#
collapsetrue
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class ImportYFXFile
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine(""Import YFX File"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string fileToImport = ""/Downloads/Test.yfx"";
            byte[] fileContents = await File.ReadAllBytesAsync(fileToImport);
            string token = await GenerateToken(host, restUsername, restPassword);

            // Upload File for initial analysis, and to fetch the number of import items.
            var getImportFileContentMultipartContent = new MultipartFormDataContent
            {
                { new ByteArrayContent(fileContents), ""contentToProcess"", Path.GetFileName(fileToImport) }
            };

            Console.WriteLine(""Getting Import File Contents"");

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()} , nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var getImportContentResponse = await httpClient.PostAsync($""{host}/api/rpc/import-export/get-import-content"", getImportFileContentMultipartContent);
                string getImportContentResponseBody = await getImportContentResponse.Content.ReadAsStringAsync();

                JObject jsonObject = JObject.Parse(getImportContentResponseBody);
                JArray items = (JArray)jsonObject[""items""];

                // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD.
                StringBuilder importOptionsBuilder = new StringBuilder();

                for (int i = 0; i < items.Count; i++)
                {
                    JObject item = (JObject)items[i];
                    Console.WriteLine($""Item {i} {item[""resourceType""]} {item[""resourceName""]} found"");
                    if (i > 0)
                    {
                        importOptionsBuilder.Append("","");
                    }
                    importOptionsBuilder.Append($""{{ \""itemIndex\"": {i}, \""optionKey\"": \""SKIP\"", \""optionValue\"": false }}, {{ \""itemIndex\"": {i}, \""optionKey\"": \""OPTION\"", \""optionValue\"": \""ADD\"" }}"");
                }

                string importOptions = importOptionsBuilder.ToString();

                // Upload File for import, with import options populated
                var importContentMultipartContent = new MultipartFormDataContent
                {
                    { new ByteArrayContent(fileContents), ""contentToProcess"", Path.GetFileName(fileToImport) },
                    { new StringContent($""[{importOptions}]"", Encoding.UTF8, ""application/json""), ""importOptions"" }
                };

                Console.WriteLine(""Importing Content"");

                var importContentResponse = await httpClient.PostAsync($""{host}/api/rpc/import-export/import-content"", importContentMultipartContent);
                string importContentResponseBody = await importContentResponse.Content.ReadAsStringAsync();

                Console.WriteLine(""Content Import Complete"");
                Console.WriteLine(importContentResponseBody);
            }
        }

        /*
         * This function generates an access token for a user that will grant them access to
         * call REST API endpoints.
         */
        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, $""{host}/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", $""YELLOWFIN ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(JsonConvert.SerializeObject(new { userName = username, password = password }), Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JObject.Parse(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Code Block
titleGo
collapsetrue
package main

import (
            ""bytes""
            ""encoding/json""
            ""fmt""
            ""io/ioutil""
            ""math/rand""
            ""mime/multipart""
            ""net/http""
            ""path/filepath""
            ""strings""
            ""time""
)

func main() {
        fmt.Println(""Import YFX File"")

        host := ""http://localhost:8080/Yellowfin""
            restUsername := ""admin@yellowfin.com.au""
            restPassword := ""test""

            fileToImport := ""/Downloads/Test.yfx""
            fileContents, err := ioutil.ReadFile(fileToImport)
        if err != nil {
                fmt.Println(""Error reading file:"", err)
                return
        }

        token, err := generateToken(host, restUsername, restPassword)
        if err != nil {
                fmt.Println(""Error generating token:"", err)
                return
        }

        // Upload File for initial analysis, and to fetch the number of import items.
        var buf bytes.Buffer
        writer := multipart.NewWriter(&buf)

        part, err := writer.CreateFormFile(""contentToProcess"", filepath.Base(fileToImport))
        if err != nil {
                fmt.Println(""Error creating form file:"", err)
                return
        }
        part.Write(fileContents)
        writer.Close()

        req, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/rpc/import-export/get-import-content"", host), &buf)
        if err != nil {
                fmt.Println(""Error creating request:"", err)
                return
        }

        nonce := rand.Int63()
        req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
        req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
        req.Header.Set(""Content-Type"", writer.FormDataContentType())
        req.Header.Set(""cache-control"", ""no-cache"")

        client := &http.Client{}
        resp, err := client.Do(req)
        if err != nil {
                fmt.Println(""Error sending request:"", err)
                return
        }
        defer resp.Body.Close()

        getImportContentContent, err := ioutil.ReadAll(resp.Body)
        if err != nil {
                fmt.Println(""Error reading response body:"", err)
                return
        }

        var jsonObject map[string]interface{}
        if err := json.Unmarshal(getImportContentContent, &jsonObject); err != nil {
                fmt.Println(""Error parsing JSON response:"", err)
                return
        }

        items := jsonObject[""items""].([]interface{})
        var importOptions strings.Builder

        for i, item := range items {
                itemMap := item.(map[string]interface{})
                fmt.Printf(""Item %d %s %s found\n"", i, itemMap[""resourceType""].(string), itemMap[""resourceName""].(string))
                if i > 0 {
                        importOptions.WriteString("","")
                }
                importOptions.WriteString(fmt.Sprintf(`{ ""itemIndex"": %d, ""optionKey"": ""SKIP"", ""optionValue"": false }, { ""itemIndex"": %d, ""optionKey"": ""OPTION"", ""optionValue"": ""ADD"" }`, i, i))
        }

        // Upload File for import, with import options populated
        buf.Reset()
        writer = multipart.NewWriter(&buf)

        part, err = writer.CreateFormFile(""contentToProcess"", filepath.Base(fileToImport))
        if err != nil {
                fmt.Println(""Error creating form file:"", err)
                return
        }
        part.Write(fileContents)
        writer.WriteField(""importOptions"", fmt.Sprintf(""[%s]"", importOptions.String()))
        writer.Close()

        req, err = http.NewRequest(""POST"", fmt.Sprintf(""%s/api/rpc/import-export/import-content"", host), &buf)
        if err != nil {
                fmt.Println(""Error creating request:"", err)
                return
        }

        req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
        req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
        req.Header.Set(""Content-Type"", writer.FormDataContentType())
        req.Header.Set(""cache-control"", ""no-cache"")

        resp, err = client.Do(req)
        if err != nil {
                fmt.Println(""Error sending request:"", err)
                return
        }
        defer resp.Body.Close()

        importContentContent, err := ioutil.ReadAll(resp.Body)
        if err != nil {
                fmt.Println(""Error reading response body:"", err)
                return
        }

        fmt.Println(""Content Import Complete"")
        fmt.Println(string(importContentContent))
}

/*
 * This function generates an access token for a user that will grant them access to
 * call REST API endpoints.
 */
func generateToken(host, username, password string) (string, error) {
        nonce := rand.Int63()
        requestBody, err := json.Marshal(map[string]string{
                      "    "userName"": username,
                      "    "password"": password,
        })
        if err != nil {
                fmt.Println(""Error marshaling request body:"", err)
                return """", err
        }

        client := &http.Client{}
        request, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/refresh-tokens"", host), bytes.NewBuffer(requestBody))
        if err != nil {
                fmt.Println(""Error creating request:"", err)
                return """", err

        }

        request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
        request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
        request.Header.Set(""Content-Type"", ""application/json"")

        response, err := client.Do(request)
        if err != nil {
                fmt.Println(""Error sending request:"", err)
                return """", err
        }
        defer response.Body.Close()

        responseBody, err := ioutil.ReadAll(response.Body)
        if err != nil {
                fmt.Println(""Error reading response body:"", err)
                return """", err
        }

        var jsonResponse map[string]interface{}
        if err := json.Unmarshal(responseBody, &jsonResponse); err != nil {
                fmt.Println(""Error parsing JSON response:"", err)
                return """", err
        }

        accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
        if !ok {
                fmt.Println(""Token not retrieved"")
                return """", fmt.Errorf(""Token not retrieved successfully"")
        }

        fmt.Println(""Access Token:"", accessToken)
        return accessToken, nil
}
Code Block
languagejs
titleJavaScript
collapsetrue
const fetch = require(""node-fetch"");
const fs = require(""fs"");
const path = require(""path"");
const FormData = require(""form-data"");

async function main() {
    console.log(""Import YFX File"");

    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const fileToImport = ""/Downloads/Test.yfx"";
    const fileContents = fs.readFileSync(fileToImport);

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    // Upload File for initial analysis, and to fetch the number of import items
    const form1 = new FormData();
    form1.append(""contentToProcess"", fileContents, path.basename(fileToImport));

    const nonce1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers1 = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce1}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'cache-control': 'no-cache',
        ...form1.getHeaders()
    };

    try {
        console.log(""Getting Import File Contents"");
        const response1 = await fetch(`${host}/api/rpc/import-export/get-import-content`, {
            method: 'POST',
            headers: headers1,
            body: form1
        });

        if (!response1.ok) {
            throw new Error(`HTTP error! Status: ${response1.status}`);
        }

        const getImportContentContent = await response1.json();

        const items = getImportContentContent.items;

        // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD
        let importOptions = items.map((item, i) => {
            console.log(`Item ${i} ${item.resourceType} ${item.resourceName} found`);
            return [
                `{ ""itemIndex"": ${i}, ""optionKey"": ""SKIP"", ""optionValue"": false }`,
                `{ ""itemIndex"": ${i}, ""optionKey"": ""OPTION"", ""optionValue"": ""ADD"" }`
            ];
        }).flat().join("", "");

        // Upload File for import, with import options populated
        const form2 = new FormData();
        form2.append(""contentToProcess"", fileContents, path.basename(fileToImport));
        form2.append(""importOptions"", `[${importOptions}]`);

        const nonce2 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

        const headers2 = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce2}, token=${token}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'cache-control': 'no-cache',
            ...form2.getHeaders()
        };

        console.log(""Importing Content"");
        const response2 = await fetch(`${host}/api/rpc/import-export/import-content`, {
            method: 'POST',
            headers: headers2,
            body: form2
        });

        if (!response2.ok) {
            throw new Error(`HTTP error! Status: ${response2.status}`);
        }

        const importContentContent = await response2.text();
        console.log(""Content Import Complete"");
        console.log(importContentContent);

    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

/*
 * This function generates an access token for a user that will grant them access to
 * call REST API endpoints.
 */
async function generateToken(host, username, password) {
    // Generate nonce
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    // Create request headers
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    // Create request body
    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        // Make POST request
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        // Check if request was successful
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        // Parse JSON response
        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
Code Block
languagephp
titlePHP
collapsetrue
<?php
function main() {
    echo ""Import YFX File\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $fileToImport = ""/Downloads/Test.yfx"";
    $fileContents = file_get_contents($fileToImport);

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    // Upload File for initial analysis, and to fetch the number of import items.
    $getImportFileContentMultipartEntity = buildMultipartEntityForAnalysis($fileContents, basename($fileToImport));
    echo ""Getting Import File Contents\n"";

    try {
        $getImportContentContent = sendMultipartRequest($host, $token, $getImportFileContentMultipartEntity, ""/api/rpc/import-export/get-import-content"");
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
        return;
    }

    $jsonObject = json_decode($getImportContentContent, true);
    $items = $jsonObject['items'];

    // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD.
    $importOptions = [];
    foreach ($items as $i => $item) {
        echo ""Item $i "" . $item['resourceType'] . "" "" . $item['resourceName'] . "" found\n"";
        $importOptions[] = [
                "    "itemIndex"" => $i,
                "    "optionKey"" => ""SKIP"",
                  ""optionValue"" => false
        ];
        $importOptions[] = [
                "    "itemIndex"" => $i,
                "    "optionKey"" => ""OPTION"",
                  ""optionValue"" => ""ADD""
            ];
    }

    // Upload File for import, with import options populated
    $importContentMultipartEntity = buildMultipartEntity($fileContents, basename($fileToImport), json_encode($importOptions));
    echo ""Importing Content\n"";

    try {
        $importContentContent = sendMultipartRequest($host, $token, $importContentMultipartEntity, ""/api/rpc/import-export/import-content"");
        echo ""Content Import Complete\n"";
        echo $importContentContent;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

/*
 * This function generates an access token for a user that will grant them access to
 * call REST API endpoints.
 */
function generateToken($host, $username, $password) {
    // Generate nonce
    $nonce = mt_rand();

    // Create request headers
    $headers = [
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    ];

    // Create request body
    $body = json_encode([
            ""userName"" => $username,
            ""password"" => $password
    ]);

    // Make POST request
    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $body);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: $accessToken\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function buildMultipartEntityForAnalysis($fileContents, $fileName) {
    $boundary = uniqid();
    $multipartBody = ""--$boundary\r\n"";
    $multipartBody .= 'Content-Disposition: form-data; name=""contentToProcess""; filename=""' . $fileName . ""\""\r\n"";
    $multipartBody .= ""Content-Type: application/octet-stream\r\n\r\n"";
    $multipartBody .= $fileContents . ""\r\n"";
    $multipartBody .= ""--$boundary--"";

    return $multipartBody;
}

function buildMultipartEntity($fileContents, $fileName, $importOptions) {
    $boundary = uniqid();
    $multipartBody = ""--$boundary\r\n"";
    $multipartBody .= 'Content-Disposition: form-data; name=""contentToProcess""; filename=""' . $fileName . ""\""\r\n"";
    $multipartBody .= ""Content-Type: application/octet-stream\r\n\r\n"";
    $multipartBody .= $fileContents . ""\r\n"";
    $multipartBody .= ""--$boundary\r\n"";
    $multipartBody .= 'Content-Disposition: form-data; name=""importOptions""' . ""\r\n"";
    $multipartBody .= ""Content-Type: application/json\r\n\r\n"";
    $multipartBody .= $importOptions . ""\r\n"";
    $multipartBody .= ""--$boundary--"";

    return $multipartBody;
}

function sendMultipartRequest($host, $token, $multipartBody, $endpoint) {
    $boundary = substr($multipartBody, 2, strpos($multipartBody, ""\r\n"") - 2);
    $headers = [
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . mt_rand() . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: multipart/form-data; boundary=' . $boundary,
        'cache-control: no-cache'
    ];

    $response = httpRequest('POST', ""$host$endpoint"", $headers, $multipartBody);
    return $response;
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Code Block
languagepy
titlePython
collapsetrue
import json
import random
import time
import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
      rest_username = ""admin@yellowfin.com.au""
      rest_password = ""test""

      file_to_import = ""/Downloads/Test.yfx""

      try:
        with open(file_to_import, 'rb') as f:
            file_contents = f.read()
    except IOError as e:
        print(f""Error reading file: {e}"")
        return

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    # Upload File for initial analysis, and to fetch the number of import items
    files = {
        'contentToProcess': ('Test.yfx', file_contents, 'application/octet-stream')
    }

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={random.randint(0, 2**63 - 1)}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'cache-control': 'no-cache'
    }

    print(""Getting Import File Contents"")

    try:
        response = requests.post(f""{host}/api/rpc/import-export/get-import-content"", headers=headers, files=files)
        response.raise_for_status()
        import_content = response.json()
    except requests.RequestException as e:
        print(f""Error getting import file contents: {e}"")
        return

    items = import_content.get(""items"", [])
    import_options = []

    for i, item in enumerate(items):
        print(f""Item {i} {item['resourceType']} {item['resourceName']} found"")
        import_options.append({
                  ""itemIndex"": i,
                "    "optionKey"": ""SKIP"",
                "    "optionValue"": False
        })
        import_options.append({
                "    "itemIndex"": i,
                  ""optionKey"": ""OPTION"",
                "    "optionValue"": ""ADD""
            })

    import_options_json = json.dumps(import_options)

    # Upload File for import, with import options populated
    files = {
        'contentToProcess': ('Test.yfx', file_contents, 'application/octet-stream'),
        'importOptions': (None, import_options_json, 'application/json')
    }

    print(""Importing Content"")

    try:
        response = requests.post(f""{host}/api/rpc/import-export/import-content"", headers=headers, files=files)
        response.raise_for_status()
        print(""Content Import Complete"")
        print(response.text)
    except requests.RequestException as e:
        print(f""Error importing content: {e}"")

def generate_token(host, username, password):
    nonce = random.randint(0, 2**63 - 1)

    request_body = json.dumps({
            ""userName"": username,
            ""password"": password
    })

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)

    if response.status_code == 200:
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()