30日間の無料評価版をお試しいただけます。

ISVクライアントがオンプレミスにインストールするシナリオでは、インストール自体に構築済みのコンテンツをバンドルする必要がある場合があります。構築済みのコンテンツは、通常コンテンツのマスターコピーが作成されたYellowfinの別のインスタンスからエクスポートされたYFXファイルの形式で存在します。

Yellowfinにコンテンツをインポートするにはいくつかの方法があります。UIから手動でインポートすることも、Yellowfinのインストールの一部として自動的にインストールすることもできます。自動インポートには、REST APIを使用する方法と、スタンドアローンインポーターを使用する方法の2つがあります。

スタンドアローンコマンドラインインポーターを使用したインポート

スタンドアローンインポーターは、実際にYellowfinを起動していなくても動作します。リポジトリデータベースに直接接続し、YFXファイルに含まれるコンテンツをインポートすることができます。

コマンドラインインポーターは、コマンドラインから以下のコマンドで実行できます。

java -cp "appserver/webapps/ROOT/WEB-INF/lib/*:appserver/lib/*" com.hof.standalone.ImportData <properties file> <import file>

クラスパス (-cp) パラメーターには、OSシステムによって異なる引用符が必要な場合があります。上記のコマンドには、Yellowfin ディレクトリでコマンドを実行するための正しいクラスパスが含まれています。

<properties> ファイルは、Yellowfin リポジトリデータベースの接続詳細を定義します。import.properties の例は、標準インストールのYellowfin/development/examples/standalone/import.properties にあります。

<import file> は、YellowfinからエクスポートされたYFXまたはXMLファイルです。

REST APIを使用したインポート

コンテンツは、POST /api/rpc/import-export/import-content エンドポイント Import Content を使用してYellowfinにインポートすることができます。初期コンテンツをインポートする場合は、Yellowfin サービスを開始する必要があります。これは、Yellowfin 自体をインストールした直後に実行できます。

以下のコード例では、REST APIを使用して指定したYFXファイルをインポートする方法を示しています。これらは、/api/rpc/import-export エンドポイントへの2つのリクエストで構成されています。最初のリクエストでは、エクスポートファイルに含まれるコンテンツが列挙されています。2番目のリクエストでは、最初のリクエストで作成されたimportOptions を使用してエクスポートファイルをインポートし、すべてのコンテンツを追加して、何もスキップしません。

Java
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();
 
    }
 
}
C#
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;
            }
        }
    }
}
Go
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
}
JavaScript
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();
PHP
<?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();
?>
Python
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()