Creating a Web App with React Frontend

Solved!
adamnieto
Creating a Web App with React Frontend

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!

2 Solutions
Andrey
Dataiker Alumni

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 Avtomonov
R&D Engineer @ Dataiku

View solution in original post

Andrey
Dataiker Alumni

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/backe...

 

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

Andrey Avtomonov
R&D Engineer @ Dataiku

View solution in original post

25 Replies
Andrey
Dataiker Alumni

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 Avtomonov
R&D Engineer @ Dataiku
adamnieto
Author

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? 

0 Kudos
Andrey
Dataiker Alumni

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/backe...

 

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

Andrey Avtomonov
R&D Engineer @ Dataiku
adamnieto
Author

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

0 Kudos
Suhail
Level 3

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
Dataiker Alumni

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

Andrey Avtomonov
R&D Engineer @ Dataiku
0 Kudos
adamnieto
Author

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

 

 

0 Kudos
Andrey
Dataiker Alumni

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

Andrey Avtomonov
R&D Engineer @ Dataiku
adamnieto
Author

Makes sense, thank you!

adamnieto
Author

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
Dataiker Alumni

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.

Andrey Avtomonov
R&D Engineer @ Dataiku
adamnieto
Author

Thank you for clarifying this! 

anuraa02
Level 1

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

0 Kudos
Andrey
Dataiker Alumni

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,

Andrey Avtomonov
R&D Engineer @ Dataiku
0 Kudos
err0w
Level 1

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!

0 Kudos
Andrey
Dataiker Alumni

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

Andrey Avtomonov
R&D Engineer @ Dataiku
0 Kudos
err0w
Level 1

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?

0 Kudos
Andrey
Dataiker Alumni

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.

 

Andrey Avtomonov
R&D Engineer @ Dataiku
0 Kudos
err0w
Level 1

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.

0 Kudos
Andrey
Dataiker Alumni

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

Andrey Avtomonov
R&D Engineer @ Dataiku
0 Kudos