Creating a Web App with React Frontend

adamnieto
adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

Hi Community ,

Does anyone know if it is possible or even recommended to use React for the frontend of a web app in DSS? If so, can you please share how you accomplished setting this up with the Flask backend.

Thank You!

Tagged:

Best Answers

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭
    Answer ✓

    Hi Adam!

    React webapps are not natively supported by DSS, that's why the creation process may look a bit tricky, but here's what you could do:

    1) Create a dev plugin on your DSS instance:

    Screenshot 2020-06-02 at 13.35.48.png

     2) create the following file structure:

    Screenshot 2020-06-02 at 13.44.22.png

    where

    - resource/my-app - your react application directory

    - webapps/react/app.js - an empty file required by DSS

    - webapps/react/body.html - a symlink to the resource/my-app/build/index.html

    - webapps/react/webapp.json - a webapp config, for example

    {
    "meta": {
    "label": "Test react app",
    "description": "",
    "icon": "icon-puzzle-piece"
    },

    "baseType": "STANDARD", // WARNING: do not change
    "hasBackend": "false",
    "noJSSecurity": "false",
    "standardWebAppLibraries": ["jquery","dataiku"],

    "params": [],

    "roles": [
    /* {"type": "DATASET", "targetParamsKey": "input_dataset"} */
    ]
    }

    3) Add "homepage": "../../resource/my-app/build" to your resource/my-app/package.json

    That's it, now you just need to reload the webapp from the plugin actions dropdown and

    considering that your React app is built you can create a new visual webapp in your project.

    Hope this helps. Don't hesitate to let us know if you have questions.

    Regards,

    Andrey Avtomonov

    R&D Engineer

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭
    Answer ✓

    Here's the plugin code I was using:

    https://github.com/andreybavt/demo-dss-react-plugin

    To answer your questions:

    1) You can use JSX to develop your app, however, you'd need to build it first so that the build directory contains js files.

    Also note that you won't be able to leverage Webpack dev server, but to recompile the webapp after changes.

    The build should be run manually from the $DATADIR/plugins/dev/YOUR_PLUGIN_NAME/resource/YOUR_WEBAPP_NAME

    2) python-lib is a directory that may contain python code that is shared between different webapps backends. In my case it's empty so you can ignore it to reduce confusion.

    In general if you need a python backend for your webapp you need to create a backend.py file defining the endpoints. Here's an example how it can be done

    https://github.com/dataiku/dss-plugin-reinforcement-learning/blob/master/webapps/vizualisation/backend.py

    3) Not necessarily, you can have multiple webapps in one plugin. Just create another directory next to webapps/react with a similar structure. (Make sure you don't forget to add a webapp.json and at least modify meta property in it)

    For the development process I'd recommend creating a plugin first and adding a simple react webapp into it. Then you're not limited to only coding inside DSS, you can either

    - open $DATADIR/plugins/dev/YOUR_PLUGIN_NAME/resource/YOUR_WEBAPP_NAME with your favourite IDE and continue developing the app from it

    - or use our VSCode integration to edit your plugin code

    https://marketplace.visualstudio.com/items?itemName=dataiku.dataiku-dss

    In both cases you are free to develop the webapp completely outside of DSS (just by starting the devserver manually from the webapp dir). But to test the API requests served by the python backend you'd need to compile the app and open it from DSS.

    Regards,

    Andrey

Answers

  • adamnieto
    adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

    Hi Andrey!

    Thank you so much for putting this together. This was very helpful! Is it possible for you to share this plugin that you have with the community?

    I also have some follow up questions:

    1. Does this method allow for JSX? If not, does that mean I would need to develop the web application outside of DSS and then compile to get the static files?

    2. I saw that there is a python-lib folder, is this empty or does this also have some flask modules in it?

    3. Does this method mean that each webapp that is made using react will need to be its own plugin?

    Also what do you think of this idea:

    Does it make sense to develop the web app outside of DSS and then maybe we can develop some sort of script that takes the regular react web app repo and transforms it into a plugin like this? What are your thoughts on this?

  • adamnieto
    adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

    This is really helpful @Andrey
    ! Thank you for your help!

  • Suhail
    Suhail Registered Posts: 18 ✭✭✭✭

    Hi @Andrey
    ,

    I am working on a similar use case and I followed all the steps mentioned by you. However, when I load the webapp, I can only see the path to the index.html as a text.

    When I replace the link with the actual html from index.html file, the app is working as expected . It seems that the symlink is not working. Can you please shed some information as-to how the symlink is created here.

    Thanks

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭

    Hi @Suhail
    ,

    Did you also try the plugin from the demo repo: https://github.com/andreybavt/demo-dss-react-plugin.git ?

    In order to try it, you'd need to run

    npm install && npm run build

    in the $DATADIR/plugins/installed/react/resource/my-app

    (if you've installed the plugin in dev mode, you'd have to change "installed" to "dev" in the path)

    After that, you may open a project and create a visual webapp to test it.

    If it doesn't work, could you tell your DSS version?

    Otherwise, as a workaround you could also delete the body.html symlink and add the following line to the package.json of the react app:

    "postbuild": "cp build/index.html ../../webapps/react/body.html",
    (it needs to be added to the "scripts" section)
    Then run
    npm run build
    from $DATADIR/plugins/installed/react/resource/my-app

    Regards,

    Andrey

  • adamnieto
    adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

    Hi @Andrey
    ,

    Just as a follow up, does your repo require a specific version of NodeJS, React and or any other dependencies? If so could you list them?

    Additionally, on a side note, does DSS have NodeJS as a dependency? I know DSS is using Angular but wasn't sure of the exact implementation. I just want to know because I don't want to screw up anything when downloading NodeJS and React on my workplace's collaboratively used DSS server.

    Thank you for your help!

    Best,

    Adam

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭

    Hi Adam,

    The react app in a demo mainly requires just react as a dependency, an exact list can be found here:

    https://github.com/andreybavt/demo-dss-react-plugin/blob/master/resource/my-app/package.json

    However this is just a demo app, you are free to use any framework and any dependency you want for your webapp. In the end, you're just required to build it to generate static files that DSS would serve when the webapp is opened. At this stage there's no difference whether the webapp was originally developed with React or Angular, plain JS or Typescript, the webapp is just serving the built files that are simply html+js+styles+resources.

    By default DSS doesn't rely on NodeJS. (There's only PDF export feature that will require Node, but it's not enabled by default)

    I was using NodeJs v13.3.0 for testing the demo plugin, but again since there's no difference from DSS point of view you can install other versions.

    Regards,

    Andrey

  • adamnieto
    adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

    Makes sense, thank you!

  • adamnieto
    adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

    Hi @Andrey
    ,

    I was curious your thoughts on this. Do you have any workarounds for developers who want to use React to build their web app but do not have terminal access to their DSS server (for instance, cannot run "npm install && npm run build" in $DATADIR/plugins/installed/react/resource/my-app)?

    In this case these developers would develop the visual web app plugin locally on their computer using React. Do you know what their workaround would be or development process would look like to get this plugin up and running on their DSS instance? Or is it not possible to accomplish this without terminal access?

    Thank you for your help!

    Best,
    Adam

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭

    Hi Adam,

    No, for the process described above in this thread you indeed need SSH access to the server and there's no easy workaround.

    As you said, you could develop an app locally, build it, and then copy the content of the "build" directory to DSS via the web UI.

  • adamnieto
    adamnieto Neuron 2020, Neuron, Registered, Neuron 2021, Neuron 2022, Neuron 2023 Posts: 88 Neuron

    Thank you for clarifying this!

  • anuraa02
    anuraa02 Registered Posts: 2 ✭✭✭

    Hi Andrey,

    I am trying to host a REACT based webapp on DSS using the methods suggested by you above. However, my webapp contains some visualizations that needs to use data from within DSS. We referred to this link to create a CallPythonDo function in our app to refer to a python file in a webapp to fetch the data. However, since, we have to first build the app locally and then copy the content to DSS, we are getting a compilation error as the above mentioned function is defined (or imported) and so is not recognized while building.
    Do you know what the workaround would be to get it working?

    Thanks in advance!

    Adarsh

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭
    edited July 17

    Hi @anuraa02
    ,

    If you'd like to have a backend for your react webapp here are the steps you'd need to take:(I assume you've followed the instructions above and created a plugin, however you can follow the same steps even if you've just created a webapp without a plugin)

    1) modify $DATADIR/plugins/installed/PLUGIN/webapps/WEBAPP/webapp.json to contain:

    "hasBackend": "true"

    2) Add $DATADIR/plugins/installed/PLUGIN/webapps/WEBAPP/backend.py, for example:

    import dataiku
    from flask import request
    
    @app.route('/first_api_call')
    def first_call():
        return json.dumps({"status": "ok", "data": 123})
    

    if you need to contact DSS API, you can use the dataiku library imported in the beginning

    3) Modify your react component to send AJAX requests (not the part around first_api_call)

    import React from 'react';
    import logo from './logo.svg';
    import './App.css';
    
    function App() {
      function handleClick(e) {
        console.log('The link was clicked.');
    
        window.$.getJSON(window.getWebAppBackendUrl('first_api_call'), function(data) {
          const output = window.$('<pre />').text('Backend reply: ' + JSON.stringify(data));
          window.$('body').append(output)
        });
    
      }
    
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React
            </a>
            <code onClick={handleClick}>Click me!</code>
          </header>
        </div>
      );
    }
    
    export default App;
    

    jQuery and getWebAppBackendUrl are added to your page automatically by DSS, in order to overcome the React compilation issues you'd have to refer to them from a window object.

    Don't forget to restart DSS after applying all of the modifications and start the newly created backend when running the webapp.

    Regards,

  • err0w
    err0w Registered Posts: 6 ✭✭✭

    Hi Andrey,

    I tried following the steps given here. And I am facing an error with getWebAppBackendUrl. The error I am getting is "window.getWebAppBackendUrl" is not defined. Can you please tell me if this function is part of some library? Sorry if it's something basic, I am really new to dataiku & react.

    Thanks!

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭

    Hi @err0w
    ,

    When Datiaku serves your webapp it adds some utility code on top of it, part if this code is a definition of a getWebAppBackendUrl function. So it should be available to the React application at the application runtime.

    I've recorded a small tutorial on how to configure a backend for a React webapp that I previously used for demo in this thread

    https://youtu.be/Q4InTCTAtRk

    let me know if some parts of it are still not clear.

    P.S.

    If after following all of the steps in a video the /first_api_call is still failing, you may need to adjust your instance security settings:

    Administration -> Settings -> Login (LDAP, SSO) & Security > Webapps -> Authentication mode -> Allow webapp authors to decide

    Screenshot 2020-08-20 at 13.15.50.png

  • err0w
    err0w Registered Posts: 6 ✭✭✭

    Hi Andrey!

    We do not have terminal access in DSS. We build it on our local machine & then upload the built code to DSS. Is there any workaround it?

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭

    Building a webapp locally doesn't really change a process much, just instead of running the npm commands I ran on the same server do it locally and copy the results.

  • err0w
    err0w Registered Posts: 6 ✭✭✭

    Hi Andrey!

    As additional utility code served by DSS is not present on our local machine. The build fails with an error, getWebAppBackendUrl is not defined.

    I tried using "window.getWebAppBackendUrl" which threw an error on runtime, however, the build was successful in this case(getWebAppBackendUrl is not defined)

    In both cases, I ran "npm run build" on my local machine only.

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭
    edited July 17

    Could you tell me if there's any difference (except for building locally and not on DSS server) between your case and tutorial here?
    https://youtu.be/Q4InTCTAtRk

    You can also try to access this function by

    window.dataiku.getWebAppBackendUrl

    Normally both of this ways should work.

    Since this function is added by DSS at the runtime, there's no difference between building the webapp locally or on DSS server

  • err0w
    err0w Registered Posts: 6 ✭✭✭

    There is no difference in building. I'll try using window.dataiku.getWebAppBackendUrl

    Thanks!

  • err0w
    err0w Registered Posts: 6 ✭✭✭
    edited July 17

    Hi Andrey!

    There is no difference (except for building on DSS & locally). I'll try using

    window.dataiku.getWebAppBackendUrl

    Thanks!

  • err0w
    err0w Registered Posts: 6 ✭✭✭

    Hi Andrey!

    I tried doing this & printed the window object in the console. It had both window.dataiku.getWebAppBackendUrl & window.getWebAppBackendUrl but during runtime it throws an error stating that getWebAppBackendUrl is not a function

    Additionally, when I tried making a call to the function in console, I was able to get a response. I have attached the screenshot for reference.

    Thanks!

  • Andrey
    Andrey Dataiker Alumni Posts: 119 ✭✭✭✭✭✭✭

    Hmm, could you send me your plugin code to andrey.avtomonov@dataiku.com

    You can download the whole contents by navigating to Plugins -> Development -> click on 3 dots on the left of the plugin name and then click on Download.

  • CoreyS
    CoreyS Dataiker Alumni, Dataiku DSS Core Designer, Dataiku DSS Core Concepts, Registered Posts: 1,150 ✭✭✭✭✭✭✭✭✭

    Thank you everyone for your questions. In the interest of knowledge sharing @Andrey
    was kind enough to put this topic together as a Knowledge Base article:

  • villander
    villander Registered Posts: 1 ✭✭

    @Andrey I'm using React with Dataiku and there are some weird issues like I can't find the "window.getWebAppBackendUrl("main")" into user effect. And sometimes the "useState" does not work in Dataiku environment. Have you seen these issues before? What's the status of Dataiku JS API with React framework integration?

Setup Info
    Tags
      Help me…