I have a generator function that yields responses from a server (uses pexpect), and my flask app returns the Response after the user submits credentials. I tested it with this code and the Response appeared correctly:
@app.route('/clean', methods=['GET', 'POST'])
def clean_form():
if request.method == 'POST':
session['address'] = 'address'
session['username'] = request.form['username']
session['password'] = request.form['password']
session['tenant'] = request.form['tenant']
return Response(ssh_gen(address, username, password, cluster, client), content_type='text/event-stream')
return render_template('clean_form.html')
I want to instead have the response rendered in an html template (already tested Response appearing in new tab /clean-sse and that worked). My updated code is:
@app.route('/clean', methods=['GET', 'POST'])
def clean_form():
if request.method == 'POST':
session['address'] = 'address'
session['username'] = request.form['username']
session['password'] = request.form['password']
session['tenant'] = request.form['tenant']
return redirect(url_for('clean_sse'))
# Render the form if it's a GET request
return render_template('clean_form.html')
@app.route('/clean-sse')
def clean_sse():
if request.headers.get('Accept') == 'text/event-stream':
address = session.get('address')
username = session.get('username')
password = session.get('password')
tenant = session.get('tenant')
def stream_messages():
# Replace with actual SSH command execution logic
yield from ssh_gen(address, username, password, tenant)
return Response(stream_messages(), content_type='text/event-stream',
headers={
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
})
return render_template('clean_sse.html')
Here is some code from clean_sse.html:
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('Initializing EventSource');
const eventSource = new EventSource('/clean-sse', { headers: { Accept: 'text/event-stream' } });
eventSource.onopen = function() {
console.log('EventSource connection opened');
};
eventSource.onerror = function(error) {
console.error('EventSource error:', error);
};
eventSource.onmessage = (event) => {
console.log('Received event:', event);
const message = JSON.parse(event.data);
console.log('Parsed message:', message);
const formattedMessage = `<div class="sse-message">${message.data}</div>`;
const messageContainer = document.createElement('div');
messageContainer.innerHTML = formattedMessage;
const messagesContainer = document.getElementById('sse-messages-container');
messagesContainer.appendChild(messageContainer);
};
});
</script>
When inspecting, eventSource.onopen is called and the console shows the log. But EventStream is empty and no further logs appear. The html template is rendered but no data shows, and the Response when inspecting also is not functioning correctly.
Sorry if this is not enough info, I am new to using EventSource and frontend code in general. Any help or advice to display my Response on the frontend is greatly appreciated.
Note: I also made sure to format my message based on what I read. Here is an example yield from ssh_gen:
yield json.dumps({"data": "Started SSH session"}) + "nn"
I also did not give any of those messages an ‘event’ since I read that the default for onmessage has no event declared.
allie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.