No matter what I try, I cannot get my data to print as it comes in. I tried this tutorial:
https://jakearchibald.com/2016/streams-ftw/
This SO post: How to handle streaming data using fetch? (and a several other SO posts I can't recall) And, tried reading the docs: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams
test.py
import time
import sys
for i in range(1,10):
print('test', i)
time.sleep(.5)
sys.stdout.flush()
server.js
firmwareRouter.get('/run_test', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-control': 'no-cache' });
const pathToExample = '/server/path/to/test.py';
const { spawn } = require('child_process');
const pythonProcess = spawn('python', [pathToExample]);
pythonProcess.stdout.on('data', (data) => {
// console.log(data.toString());
res.write(data);
});
pythonProcess.on('close', (code) => {
res.end('Process has ended');
});
});
Firmware.js (Version 1)
export default function Firmware(props) {
const [data, setData] = useState('');
async function runTest() {
try {
const url = 'api/firmware/run_test'
const request = {
method: 'GET',
headers: {
'Content-Type': 'text/event-stream'
},
}
const res = await fetch(url, request);
const reader = res.body.getReader();
const chunks = [];
const decoder = new TextDecoder('utf-8');
let done, value;
while (!done) {
({ value, done } = await reader.read());
value = decoder.decode(value);
if (done) {
return chunks;
}
console.log(value);
chunks.push(value);
setData(value);
}
} catch (err) {
console.log('frontend:Firmware', err);
}
}
return (
<Fragment>
{data}
<button onClick={() => runTest()}>Run Test </button>
</Fragment >
)
}
Firmware.js (Version 2)
export default function Firmware(props) {
const [data, setData] = useState('');
async function runTest() {
const url = 'api/firmware/run_test'
const request = {
method: 'GET',
headers: {
'Content-Type': 'text/event-stream'
},
}
fetch(url, request).then((res) => {
let reader = res.body.getReader();
let decoder = new TextDecoder();
reader.read().then(function processResult(result) {
if (result.done) return;
console.log(decoder.decode(result.value, { stream: true }))
return reader.read().then(processResult);
})
})
}
// return ()
No matter what, it only prints to the browser once the process has finished. I need it to print as the python script prints. What am I missing here?