Accessible resources from webapps#

Web applications need access to various resources to function correctly. These resources can be internal (stored in Dataiku) or external (stored outside of Dataiku).

To access these resources, there are several strategies that developers can use depending on the specific use case. For example, the developer can use a JavaScript function to fetch the necessary data or assets if the resource is required during an event, such as when a button is clicked. Alternatively, the developer can use server-side code to retrieve the necessary information if the resource is needed when the web app is being built, for example. This tutorial will outline some of the most essential best practices for accessing resources in web apps.

At the end of the tutorial the complete code is provided for each framework. Each code highlights all different use cases for one dedicated framework.

External resources#

When creating a web application in Dataiku that requires accessing external resources, the process is similar to traditional web application development. In other words, you can use the standard HTML tags to access a resource on a specific URL. For instance, Code 1 below illustrates how to display an image using an external URL.

Code 1: How to use external resources#
<img src="https://picsum.photos/200/300" alt="Random picture from the internet"></img>

Or you can use Javascript to retrieve data.

Code 1.1: How to use external resources in Javasript#
/* Javascript function for external URL */
let externalImageJs = document.getElementById('externalImageJs')

fetch("https://picsum.photos/200/300")
    .then(response => response.blob())
    .then(image => externalImageJs.src = URL.createObjectURL(image))

Internal resources#

Web applications in Dataiku can use resources stored in Dataiku. There are various places where resources can be stored.

  • The section Internal resources stored in a managed folder explains how to use resources stored in a managed folder. Storing data in a managed folder is outside the scope of this tutorial, as there is nothing more than creating a managed folder and putting your data in it. These resources are tied to a project when storing resources in a managed folder. If you need to store resources for multiple project, consider storing them in the Global shared code or sharing the managed folder across projects.

  • The section Using resources stored in resources in project library explains how to use resources stored in the resources project library. These resources are tied to a project library. So you should consider this option, if your data are local to a project, do not want those data to appear in the flow, and you need the user to have a minimal set of permissions (defined by the project) to access or edit those data.

  • The section Internal resources stored in the global shared code explains how to store user resources stored in the Static web resources, defined in the Global shared code in the application menu. Suppose your resources are not dedicated to a project and are not sensitive data, or your web application is intended to be a public web app. In that case you should store these resources in the Static web resources.

  • The section Using resources stored in the Code Studios focuses on Code Studios and its usage when storing resources inside. You should store your resources in Code Studio. If you want your resources been between multiple projects within Code Studio templates, use the “Append to Dockerfile” block; see Preparing Code Studio templates.

The tutorial explains how to handle three different file types in each section. Depending on the framework, file usage can change depending on the file type. We have highlighted the most frequent usage of images, files, and CSS. Even though those resources are handled in the same way, the purpose of their usage changes.

Internal resources stored in a managed folder#

Displaying an image#

There are three steps to follow to load and use an image in a Dataiku web application:

  • Use the img tag in your HTML with the src attribute set to "" (Code 2.1).

  • In the Python backend, create a route to retrieve and serve the image file (Code 2.2).

  • In the JavaScript tab, dynamically set the image source to the route created in Code 2.2 (Code 2.3)

Code 2.1: Use the img tag#
<img id="getImageFromManageFolderImg" alt="image" class="container"></img>
Code 2.2: Backend route for serving an image#
import dataiku
import pandas as pd
from flask import request

# Definition of the various resources (This can be done programmatically)
# ## Name of the managed folder
folder = "Resources"
# ## Path name of the files
image = "/image.png"
pdf = "/document.pdf"
css = "/my-css.css"


def get_file_from_managed_folder(folder_name, file_name):
    """
    Retrieve the file from the managed folder
    Args:
        folder_name: name of the managed folder
        file_name: name of the file

    Returns:
        the file
    """
    folder = dataiku.Folder(folder_name)

    with folder.get_download_stream(file_name) as f:
        return (f.read())

@app.route('/get_image_from_managed_folder')
def get_image_from_managed_folder():
    return get_file_from_managed_folder(folder, image)
Code 2.3: Javascript for dynamically load the image#
let getImageFromManageFolderImg  = document.getElementById('getImageFromManageFolderImg')


getImageFromManageFolderImg.src  = getWebAppBackendUrl('/get_image_from_managed_folder')

Serving a file#

Serving a file for an end-user relies on the same principle. Except you don’t display it.

Code 3.1: Serving a file (HTML part)#
<p>The image is loaded within the javascript code</p>
<a id="getPDFFromManagedFolderA" href="" download="file.pdf">
    <span id="getPDFFromManagedFolder" onclick="" class="btn btn-primary">Get PDF file</span>
</a>
Code 3.2: Serving a file (Javascript part)#
let getPDFFromManagedFolder      = document.getElementById('getPDFFromManagedFolder')
let getPDFFromManagedFolderA     = document.getElementById('getPDFFromManagedFolderA')


getPDFFromManagedFolderA.href    = getWebAppBackendUrl('/get_pdf_from_managed_folder')
getPDFFromManagedFolder.addEventListener('click', () => {
    getWebAppBackendUrl('/get_pdf_from_managed_folder')
});
Code 3.3: Serving a file (Backend)#
def get_file_from_managed_folder(folder_name, file_name):
    """
    Retrieve the file from the managed folder
    Args:
        folder_name: name of the managed folder
        file_name: name of the file

    Returns:
        the file
    """
    folder = dataiku.Folder(folder_name)

    with folder.get_download_stream(file_name) as f:
        return (f.read())


@app.route('/get_pdf_from_managed_folder')
def get_pdf_from_managed_folder():
    return get_file_from_managed_folder(folder, pdf)

Using your own CSS#

If you need to use your own CSS, apply the same principle as in Serving a file.

Code 4.1 (part a): Declare your intention to use a personal CSS (HTML part)#
<link href="" rel="stylesheet" id="getCSSFromManagedFolder">
Code 4.1 (part b): Use your personal CSS (HTML part)#
<p>The image <span class="devadvocate-alert">is loaded</span> within the javascript code</p>
Code 4.2: Using your own CSS (Javascript part)#
let getCSSFromManagedFolder      = document.getElementById('getCSSFromManagedFolder')


getCSSFromManagedFolder.href     = getWebAppBackendUrl('/get_css_from_managed_folder')
Code 4.3: Using your own CSS (Backend)#
def get_file_from_managed_folder(folder_name, file_name):
    """
    Retrieve the file from the managed folder
    Args:
        folder_name: name of the managed folder
        file_name: name of the file

    Returns:
        the file
    """
    folder = dataiku.Folder(folder_name)

    with folder.get_download_stream(file_name) as f:
        return (f.read())

@app.route('/get_css_from_managed_folder')
def get_css_from_managed_folder():
    return get_file_from_managed_folder(folder, css)

Using resources stored in resources in project library#

If you want to store resources specific to a project, need the user to be authenticated and do not want to create a managed folder, you can rely on resources stored in the project library. Go to </> > Libraries and click on the Resources tab. Then create a static directory. Once the directory has been created, upload your files in this folder. All files in this folder will be accessible, by authenticated user, via the URL: http[s]://host:port/local/projects/PROJECT_KEY/resources/.

Alternatively, if you want to store project-related resources that are meant to be accessible to any unauthenticated user, you can create a local-static directory and upload your files in it. The files in this folder will be publicly accessible via the URL: http[s]://host:port/local/projects/PROJECT_KEY/public-resources/

Displaying an image#

Code 4.1: Use the img tag#
<img id="getImageFromProjectLibImg" alt="image" class="container"></img>
Code 4.2: Javascript for dynamically load the image#
let getImageFromProjectLibImg    = document.getElementById('getImageFromProjectLibImg')


getImageFromProjectLibImg.src  = `/local/projects/${dataiku.defaultProjectKey}/resources/image.jpg`

Serving a file#

Serving a file for an end-user relies on the same principle. Except you don’t display it.

Code 5.1: Serving a file (HTML part)#
<p>The pdf link is updated within the javascript code</p>
<a id="getPDFFromProjectLibA" href="" download="file.pdf">
    <span id="getPDFFromProjectLib" onclick="" class="btn btn-primary">Get PDF file</span>
</a>
Code 5.2: Serving a file (Javascript part)#
let getPDFFromProjectLibA        = document.getElementById('getPDFFromProjectLibA')


getPDFFromProjectLibA.href     = `/local/projects/${dataiku.defaultProjectKey}/resources/file.pdf`

Using your own CSS#

If you need to use your own CSS, apply the same principle as in Serving a file.

Code 6.1 (part a): Declare your intention to use a personal CSS (HTML part)#
<link href="" rel="stylesheet" id="getCSSFromProjectLib">
Code 6.1 (part b): Use your personal CSS (HTML part)#
<p>The image <span class="devadvocate-alert">is loaded</span> within the javascript code</p>
Code 6.2: Using your own CSS (Javascript part)#
let getCSSFromProjectLib         = document.getElementById('getCSSFromProjectLib')


getCSSFromProjectLib.href      = `/local/projects/${dataiku.defaultProjectKey}/resources/my-css.css`

Internal resources stored in the global shared code#

If you want to store resources instance-wide and use them in a web app, consider storing them in the Global shared code. To store files in the Global shared code, click on Application menu > Global shared code > Static web resources. Save your files in the local-static folder, as shown in Figure 1. Once your files are uploaded to this folder, they will be accessible using the URL: {HOSTNAME}:{PORT}/local/static/.... So, all the codes using these resources are straightforward.

Important

The primary purpose of Static web resources is to serve files for public web applications, but they can also be used to store files for authenticated web applications. However, all files stored in this storage will be accessible without authentication.

Figure 1: Adding files to the Static Web Resources.

Figure 1: Adding files to the Static Web Resources#

Displaying an image#

Code 7.1: Use the img tag#
<img alt="image" src="/local/static/image.jpg" class="container"></img>

Serving a file#

If you need the user to be able to download the image, you can rely on the download attribute of the a tag.

Code 8.1: Serving a file#
<a href="/local/static/image.jpg" download="image.jpg">
    <img src="/local/static/image.jpg" alt="image" class="container"></img>
</a>

Using your own CSS#

If you need to use your own CSS, apply the same principle as in Serving a file.

Code 9.1: Using your own CSS#
<link href="/local/static/my-css.css" rel="stylesheet">
<p>The image <span class="devadvocate-alert">is loaded</span> within the javascript code</p>

Using resources stored in the Code Studios#

Code Studios does not allow editing Standard, Dash, and Bokeh web applications. Code Studios resources are stored inside the container, so to access a file in the resources, you need to fall back to classical file system operation. Depending on where the user stores its files, they will appear in different directories in Code Studio. Accessing to those files will remain the same regardless of the directory.

Displaying an image#

Not available

Serving a file#

Serving a file for an end-user relies on the same principle. Except you don’t display it.

Not available

Using your own CSS#

If you need to use your own CSS, apply the same principle as in Serving a file.

Not available

Complete code and conclusion#

Code 12 shows the complete code for using resources when developing web applications. This tutorial presents best practices for data storage according to your use case.

You will find the complete code for standard web application

Code 12: Code for standard web application (HTML part)#
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
        crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link href="" rel="stylesheet" id="getCSSFromManagedFolder">
<link href="" rel="stylesheet" id="getCSSFromProjectLib">

<h1 class="display-1">Using resources in a web application</h1>
<p>Some code samples to demonstrate how we can use resources in web applications</p>
<div class="container">
    <h2 class="" dispaly-2>From external URL</h2>
    <div class="accordion" id="externalURL">
        <div class="accordion-item">
            <h2 class="accordion-header" id="headingExternalURL">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseExternalURL"
                        aria-expanded="false" aria-controls="collapseExternalURL">
                    Image
                </button>
            </h2>
            <div id="collapseExternalURL" class="accordion-collapse collapse" aria-labelledby="headingExternalURL"
                 data-bs-parent="#externalURL">
                <div class="accordion-body">
                    <p>You can use images comming from an URL by using the classical
                        <code>&lt;img scr="URL_TO_USE" alt="Description"/&gt;</code>
                    </p>
                    <img src="https://picsum.photos/200/300" alt="Random picture from the internet"></img>
                </div>
            </div>
        </div>
    </div>
    <div class="accordion" id="externalURLJs">
        <div class="accordion-item">
            <h2 class="accordion-header" id="headingExternalURLJs">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseExternalURLJs"
                        aria-expanded="false" aria-controls="collapseExternalURLJs">
                    Fetching resources from javascript
                </button>
            </h2>
            <div id="collapseExternalURLJs" class="accordion-collapse collapse" aria-labelledby="headingExternalURLJs"
                 data-bs-parent="#externalURLJs">
                <div class="accordion-body">
                    <p>Or you can use Javascript to fetch resources.</p>
                    <img src="" alt="Random picture from the internet" id="externalImageJs"></img>
                </div>
            </div>
        </div>
    </div>


    <h2>From managed folders</h2>

    <div class="accordion" id="accordion-managed-folder">
        <div class="accordion-item">
            <h2 class="accordion-header" id="displayInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapsedisplayInline"
                        aria-expanded="false" aria-controls="collapsedisplayInline">
                    Display an image
                </button>
            </h2>
            <div id="collapsedisplayInline" class="accordion-collapse collapse" aria-labelledby="displayInline"
                 data-bs-parent="#accordion-managed-folder">
                <div class="accordion-body">
                    <p>The image is loaded within the javascript code</p>
                    <img id="getImageFromManageFolderImg" alt="image" class="container"></img>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="displayAndDownloadInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapsedisplayAndDownloadInline" aria-expanded="false"
                        aria-controls="collapsedisplayAndDownloadInline">
                    Display an image and allow this image to be downloaded by clicking on it
                </button>
            </h2>
            <div id="collapsedisplayAndDownloadInline" class="accordion-collapse collapse"
                 aria-labelledby="displayAndDownloadInline" data-bs-parent="#accordion-managed-folder">
                <div class="accordion-body">
                    <p>The image is loaded within the javascript code</p>
                    <a id="getImageFromManageFolderA" href="" download="image.png">
                        <img id="getImageFromManageFolderAImg" alt="image" class="container"></img>
                    </a>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="DownloadPdfInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseDownloadPdfInline" aria-expanded="false"
                        aria-controls="collapseDownloadPdfInline">
                    PDF
                </button>
            </h2>
            <div id="collapseDownloadPdfInline" class="accordion-collapse collapse" aria-labelledby="DownloadPdfInline"
                 data-bs-parent="#accordion-managed-folder">
                <div class="accordion-body">
                    <p>The image is loaded within the javascript code</p>
                    <a id="getPDFFromManagedFolderA" href="" download="file.pdf">
                        <span id="getPDFFromManagedFolder" onclick="" class="btn btn-primary">Get PDF file</span>
                    </a>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="DownloadCSSInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseDownloadCSSInline" aria-expanded="false"
                        aria-controls="collapseDownloadCSSInline">
                    Local CSS
                </button>
            </h2>
            <div id="collapseDownloadCSSInline" class="accordion-collapse collapse" aria-labelledby="DownloadCSSInline"
                 data-bs-parent="#accordion-managed-folder">
                <div class="accordion-body">
                    <p>The image <span class="devadvocate-alert">is loaded</span> within the javascript code</p>
                </div>
            </div>
        </div>
    </div>

    <h2>From resources in project library </h2>

    <div class="accordion" id="accordion-project-lib">
        <div class="accordion-item">
            <h2 class="accordion-header" id="displayInlineProjectLib">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapsedisplayInlineProjectLib"
                        aria-expanded="false" aria-controls="collapsedisplayInlineProjectLib">
                    Display an image
                </button>
            </h2>
            <div id="collapsedisplayInlineProjectLib" class="accordion-collapse collapse" aria-labelledby="displayInlineProjectLib"
                 data-bs-parent="#accordion-project-lib">
                <div class="accordion-body">
                    <p>The image is loaded within the javascript code</p>
                    <img id="getImageFromProjectLibImg" alt="image" class="container"></img>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="displayAndDownloadInlineProjectLib">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapsedisplayAndDownloadInlineProjectLib" aria-expanded="false"
                        aria-controls="collapsedisplayAndDownloadInlineProjectLib">
                    Display an image and allow this image to be downloaded by clicking on it
                </button>
            </h2>
            <div id="collapsedisplayAndDownloadInlineProjectLib" class="accordion-collapse collapse"
                 aria-labelledby="displayAndDownloadInline" data-bs-parent="#accordion-project-lib">
                <div class="accordion-body">
                    <p>The image is loaded within the javascript code</p>
                    <a id="getImageFromProjectLibA" href="" download="image.png">
                        <img id="getImageFromProjectLibAImg" alt="image" class="container"></img>
                    </a>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="DownloadPdfInlineProjectLib">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseDownloadPdfInlineProjectLib" aria-expanded="false"
                        aria-controls="collapseDownloadPdfInlineProjectLib">
                    PDF
                </button>
            </h2>
            <div id="collapseDownloadPdfInlineProjectLib" class="accordion-collapse collapse" aria-labelledby="DownloadPdfInline"
                 data-bs-parent="#accordion-project-lib">
                <div class="accordion-body">
                    <p>The pdf link is updated within the javascript code</p>
                    <a id="getPDFFromProjectLibA" href="" download="file.pdf">
                        <span id="getPDFFromProjectLib" onclick="" class="btn btn-primary">Get PDF file</span>
                    </a>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="DownloadCSSInlineProjectLib">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseDownloadCSSInlineProjectLib" aria-expanded="false"
                        aria-controls="collapseDownloadCSSInlineProjectLib">
                    Local CSS
                </button>
            </h2>
            <div id="collapseDownloadCSSInlineProjectLib" class="accordion-collapse collapse" aria-labelledby="DownloadCSSInline"
                 data-bs-parent="#accordion-project-lib">
                <div class="accordion-body">
                    <p>The image <span class="devadvocate-alert2">is loaded</span> within the javascript code</p>
                </div>
            </div>
        </div>
    </div>

    <h2>Global shared Code (Static Web resources)</h2>
    <div class="accordion" id="accordion-global-share-code">
        <div class="accordion-item">
            <h2 class="accordion-header" id="globalDisplayInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseglobalDisplayInline" aria-expanded="false"
                        aria-controls="collapseglobalDisplayInline">
                    Display an image
                </button>
            </h2>
            <div id="collapseglobalDisplayInline" class="accordion-collapse collapse"
                 aria-labelledby="globalDisplayInline"
                 data-bs-parent="#accordion-global-share-code">
                <div class="accordion-body">
                    <img alt="image" src="/local/static/image.jpg" class="container"></img>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="globalDisplayAndDownloadInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#globalDollapsedisplayAndDownloadInline" aria-expanded="false"
                        aria-controls="globalDollapsedisplayAndDownloadInline">
                    Display an image and allow this image to be downloaded by clicking on it
                </button>
            </h2>
            <div id="globalDollapsedisplayAndDownloadInline" class="accordion-collapse collapse"
                 aria-labelledby="globalDisplayAndDownloadInline" data-bs-parent="#accordion-global-share-code">
                <div class="accordion-body">
                    <a href="/local/static/image.jpg" download="image.jpg">
                        <img src="/local/static/image.jpg" alt="image" class="container"></img>
                    </a>
                </div>
            </div>
        </div>


        <div class="accordion-item">
            <h2 class="accordion-header" id="globalDownloadPdfInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseglobalDownloadPdfInline" aria-expanded="false"
                        aria-controls="collapseglobalDownloadPdfInline">
                    PDF
                </button>
            </h2>
            <div id="collapseglobalDownloadPdfInline" class="accordion-collapse collapse"
                 aria-labelledby="globalDownloadPdfInline" data-bs-parent="#accordion-global-share-code">
                <div class="accordion-body">
                    <a href="/local/static/file.pdf" download="file.pdf">
                        <span class="btn btn-primary">Get PDF file</span>
                    </a>
                </div>
            </div>
        </div>

        <div class="accordion-item">
            <h2 class="accordion-header" id="globalDownloadCSSInline">
                <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#collapseglobalDownloadCSSInline" aria-expanded="false"
                        aria-controls="collapseglobalDownloadCSSInline">
                    Local CSS
                </button>
            </h2>
            <div id="collapseglobalDownloadCSSInline" class="accordion-collapse collapse"
                 aria-labelledby="globalDownloadCSSInline" data-bs-parent="#accordion-global-share-code">
                <div class="accordion-body">
                    <link href="/local/static/my-css.css" rel="stylesheet">
                    <p>The image <span class="devadvocate-alert">is loaded</span> within the javascript code</p>
                </div>
            </div>
        </div>
    </div>
</div>
Code 12.1: Code for standard web application (Javascript part)#
let getImageFromManageFolderA    = document.getElementById('getImageFromManageFolderA')
let getImageFromManageFolderImg  = document.getElementById('getImageFromManageFolderImg')
let getImageFromManageFolderAImg = document.getElementById('getImageFromManageFolderAImg')
let getPDFFromManagedFolder      = document.getElementById('getPDFFromManagedFolder')
let getPDFFromManagedFolderA     = document.getElementById('getPDFFromManagedFolderA')
let getCSSFromManagedFolder      = document.getElementById('getCSSFromManagedFolder')

let getImageFromProjectLibImg    = document.getElementById('getImageFromProjectLibImg')
let getImageFromProjectLibA      = document.getElementById('getImageFromProjectLibA')
let getImageFromProjectLibAImg   = document.getElementById('getImageFromProjectLibAImg')
let getPDFFromProjectLibA        = document.getElementById('getPDFFromProjectLibA')
let getCSSFromProjectLib         = document.getElementById('getCSSFromProjectLib')

// Dynamic setting of the various element
getCSSFromManagedFolder.href     = getWebAppBackendUrl('/get_css_from_managed_folder')
getImageFromManageFolderA.href   = getWebAppBackendUrl('/get_image_from_managed_folder')
getImageFromManageFolderImg.src  = getWebAppBackendUrl('/get_image_from_managed_folder')
getImageFromManageFolderAImg.src = getWebAppBackendUrl('/get_image_from_managed_folder')
getPDFFromManagedFolderA.href    = getWebAppBackendUrl('/get_pdf_from_managed_folder')

getImageFromProjectLibImg.src  = `/local/projects/${dataiku.defaultProjectKey}/resources/image.jpg`
getImageFromProjectLibA.href   = `/local/projects/${dataiku.defaultProjectKey}/resources/image.jpg`
getImageFromProjectLibAImg.src = `/local/projects/${dataiku.defaultProjectKey}/resources/image.jpg`
getPDFFromProjectLibA.href     = `/local/projects/${dataiku.defaultProjectKey}/resources/file.pdf`
getCSSFromProjectLib.href      = `/local/projects/${dataiku.defaultProjectKey}/resources/my-css.css`


//
getPDFFromManagedFolder.addEventListener('click', () => {
    getWebAppBackendUrl('/get_pdf_from_managed_folder')
});

/* Javascript function for external URL */
let externalImageJs = document.getElementById('externalImageJs')

fetch("https://picsum.photos/200/300")
    .then(response => response.blob())
    .then(image => externalImageJs.src = URL.createObjectURL(image))
Code 12.2: Code for standard web application (Python part)#
import dataiku
import pandas as pd
from flask import request

# Definition of the various resources (This can be done programmatically)
# ## Name of the managed folder
folder = "Resources"
# ## Path name of the files
image = "/image.png"
pdf = "/document.pdf"
css = "/my-css.css"


def get_file_from_managed_folder(folder_name, file_name):
    """
    Retrieve the file from the managed folder
    Args:
        folder_name: name of the managed folder
        file_name: name of the file

    Returns:
        the file
    """
    folder = dataiku.Folder(folder_name)

    with folder.get_download_stream(file_name) as f:
        return (f.read())

@app.route('/get_image_from_managed_folder')
def get_image_from_managed_folder():
    return get_file_from_managed_folder(folder, image)

@app.route('/get_pdf_from_managed_folder')
def get_pdf_from_managed_folder():
    return get_file_from_managed_folder(folder, pdf)

@app.route('/get_css_from_managed_folder')
def get_css_from_managed_folder():
    return get_file_from_managed_folder(folder, css)