I'm trying to launch a python script on the backend when a user enters some numbers into a form using react.
I have Django as the main "shell" for my app handling the backend and is pointing to React properly for the frontend. The idea is to run all complex mathematical models, big data processing, and calculations on Python in the backend while node.js is used to run only front-end UI related scripts.
Django for logistics/substance.
React for the experience/aesthetics.
I am able to use SpawnSync child_process in Node.js to successfully execute when I type "node run_python.js" in the command line ("run_python.js" is the name of my function).
But when I run "npm run dev", that's when node is saying it can't find child_process. I checked node_modules and the childprocess library is there with keywords "child_process" included in the pacakge.json. I also tried referencing "child_process" in the main package.json file as a dependency.
Is there a better way to trigger a python script on the server through action in react?
here is the error message:
Example error message: ERROR in ./src/App.js 10:19-43 Module not found: Error: Can't resolve 'child_process' in '[my directory]'resolve 'child_process' in '[my private directory]' Parsed request is a module using description file: [my directory]/frontend/package.json (relative path: ./src) Field 'browser' doesn't contain a valid alias configuration resolve as module [my directory]/node_modules doesn't exist or is not a directory
Here is the code:
import React from 'react'
const App = () => {
//Function to call child_process in Node.js for python
const runPython = ()=>{
var user_inputted_data_from_react = {"revenue":6789086,"industry":"Financial Services"}
var python_input_data = JSON.stringify(user_inputted_data_from_react)
const { spawnSync } = require('child_process');
const python_response = spawnSync('python3', ['-c', `from python_app_library import python_script; python_script.run(${python_input_data});`], { encoding: "utf8" });
// Access stderr
console.log(python_response.stderr)
// Access stdout
return(python_response.stdout)
}
return (
<div>
<h3>Results from python:</h3>
<p>{runPython}</p>
</div>
)
}
export default App
CodePudding user response:
I figured this out myself watching YouTube videos.
The answer is to use Express and routers with APIs. Basically create a form element and place the url in the form action tag that that is then read by app.use() function in express.
Here is an example:
const runPython = require('./apps/runPython.js'); //<--Node function that calls a child process for python
app.use('/runPython/:appName',(req,res,next)=>{
var inputData = JSON.stringify(req.body);
var appName = req.params.appName //<--name of the python script file
const result = runPython.run_python_script(inputData, appName); //<--Python returns a text string
context = JSON.parse(result) //<-- conver test string to json
res.status(200).render('calculate_savings',{context}); //<--send python data back to browser
next
});
"runPython" Node script imported above for launching python child process..
function run_python_script(appName, inputData){
const { spawnSync } = require('child_process');
const python = spawnSync('python3', ['-c', `from apps import ${appName}; ${appName}.run(${inputData}); assert False`], { encoding: "utf8" });
// Access stdout
return(python.stdout)
// Access stderr
console.log(python.stderr)
}
module.exports = { run_python_script };
And finally, the form in html where python is called from...
<div>
<form action="/pythonApp/calculate_savings" method="POST">
<label for="revenue">Revenue</label>
<input name="revenue" value="123456789">
<button type="submit">Submit</button>
</form>
</div>