St.write_stream with formatted html text

Hi experts.

Is there a way to use st.write_stream to stream formatted HTML text? Tried the following and it correctly applies the HTML format, but displays a NONE tag after each line (see attached screenshot).

import time
import streamlit as st

def stream_html_text():
    for header in ["<h1>Header1</h1>", "<h2>Header2</h2>", "<h3>Header3</h3>"]:
        yield st.write(header, unsafe_allow_html=True)
        time.sleep(0.02)

if st.button("Stream HTML text"):
    with st.spinner("Working really hard..."):
        st.write_stream(stream_html_text)
    st.success('Done!')

Thanks for your help,
Stefan

st.write returns None, so that is what your generator yields and what write_stream writes.

If you want to yield text chunks then just do yield header. But then, according to my tests, write_stream won’t parse it as html (it will parse and render markdown though).

Or if you want to st.write each text chunk, then you don’t need write_stream.

Are there plans to make st.write_stream support formatted HTML text?

Sorry, no idea.

Here is a naive implementation that works well for your example. The argument must be an iterable.

import time
import streamlit as st


def write_stream(stream):
    result = ""
    container = st.empty()
    for chunk in stream:
        result += chunk
        container.write(result, unsafe_allow_html=True)


def get_stream():
    for chunk in ["<h1>Header1</h1>", "<h2>Header2</h2>", "<h3>Header3</h3>"]:
        time.sleep(1)
        yield chunk


if st.button("Stream HTML text"):
    with st.spinner("Working really hard..."):
        write_stream(stream=get_stream())
    st.success('Done!')

Your solution works great :slight_smile:

Thank you.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.