As described in this Github issue, it is very easy to write unsafe apps when developers have the ability to code in HTML. The idea is that users should always be able to trust Streamlit apps. So we have turned HTML off by default in Streamlit and will be removing the option to turn it on at some point in the future.(Update: We heard you, and have no plans to deprecate allow_unsafe_html! )
However, there are some legitimate use cases for writing HTML today to get around limitations in Streamlit’s current feature set. Some examples are:
Layout: laying items side by side, changing margin/padding/alignment properties, at.
Text-based diagrams: see this example from a user working on NLP.
(Rest assured, we are currently working on solutions to the use-cases above. You will hear about them very soon!)
If you’re using HTML in Streamlit, we would like to hear from you! Let us know:
Why are you using it?
Any thoughts on what you’d like to see in Streamlit if you did not have the ability to use HTML?
I am working in NLP and want to highlight passages of text in different ways.
E.g. highlight negated words in red. Afaik is this not possible in markdown and when introducing custom HTML elements as text they get moved into their own span objects even with allow_unsave_html turned on.
It is possible to do this, we just can’t use quotes or style tags in the element. The solution was to also print the css in tags and avoid styling individual elements.
Hi Streamlit team! First, thank you very much for creating Streamlit. I can’t begin to express how much this helps with my day-to-day challenges. I have completely moved off of my custom Flask/React tool that I created to manage my workflow.
My current area of focus is OCR from highly quantized images. My models require copious amount of tuning and adjustments along with combinations of multiple feature extractors to work. To this end, when I’m processing my image or video sources, I need to be able to see how all the feature extractions work side-by-side. My solution within Streamlit was to create a Dataframe with embedded PIL Images, that I use a custom formatter on. I got the idea from here:
I would prefer to be able to simply use the Pandas Styler, but unfortunately their format does not allow the embedding of HTML currently, though it is mentioned as a possible future enhancement.
The other way I could work around this is by creating a custom Jinja2 template the Styler uses and repurpose the current Pandas html.tpl, see here:
This would in my opinion be a complete abuse of the Styler as I would have to override the displaying of the table elements in the TR block, with the undocumented r & c values which could easily be renamed in the future.
Here is a sample of the code I use to display images within a Pandas table:
def get_thumbnail(path):
i = Image.open(path)
i.thumbnail((150, 150), Image.LANCZOS)
return i
def image_base64(im):
base64Image = None
if isinstance(im, str):
im = get_thumbnail(im)
with BytesIO() as buffer:
im.save(buffer, 'jpeg')
base64Image = base64.b64encode(buffer.getvalue()).decode()
return base64Image
def image_formatter(im):
return f'<img src="data:image/jpeg;base64,{image_base64(im)}">'
def run_the_app():
...
df = pd.DataFrame(data)
st.markdown(df.to_html(formatters={'image': image_formatter}, escape=False), unsafe_allow_html=True)
...
As you can see I perform a to_html() on the DataFrame with a custom formatter, and then pass the result to st.markdown. While this solution meets my needs it is not ideal, as I cannot leverage the Pandas Styler as its render method will not allow disabling of escaping HTML tags.
I hope this helps better understand my personal need of HTML. If I may make a recommendation, remove html from markdown and make st.html() a first-class citizen. Or make PIL Images a valid type in Streamlit dataframes which get rendered in the browser.
Based on what you’re saying, I think when we add support for horizontal layouts we should probably also support grid layouts. So I created a feature request here: https://github.com/streamlit/streamlit/issues/309 .
Please follow the feature there to be notified when we implement it. And help us come up with a nice API for it too!
def video_youtube(src: str, width="100%", height=315):
"""An extension of the video widget
Arguments:
src {str} -- A youtube url like https://www.youtube.com/embed/B2iAodr0fOo
Keyword Arguments:
width {str} -- The width of the video (default: {"100%"})
height {int} -- The height of the video (default: {315})
"""
st.write(
f'<iframe width="{width}" height="{height}" src="{src}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
unsafe_allow_html=True,
)
I guess I will be developing more extensions using html as I continue. You can find them in for inspiration
I would like to create a tooltip to provide more info related to an item on my app. So, once a user hovers over it, the tooltip should be displayed. Is there a way to achieve this at the moment?
One more question that is related to HTML:
Is there a way to customize the HTML of the default index page and add custom CSS styling as well, etc.?
Thanks for the amazing app. It’s really amazing, and speeds up everything. Thanks a million!
Hi. The use case that came to my mind (and actually how I found this page) is embedding an interactive code/text editor like this one: https://ace.c9.io/
I would like to embed graph visualisations based on d3js (e.g. based on this library https://github.com/vasturiano/force-graph) in my streamlit app. Is this even possible?
Thanks @thiago for the fast response! I’ll track the feature request
I am still wondering about a temporary workaround. So far, I need to run a separate local python server to access the visualisation htmls (because of the browser’s same-origin policy). Would it be possible for me to copy the vis-htmls to the local streamlit folder, in order to access them from the same port as streamlit (8501 for instance)?
EDIT: Found the static html folder, I’ll just symlink my generated htmls inside it for the time being. It’s a bit of a sketchy workaround, but it’s okay for now! Being able to embed js in streamlit at some point would be awesome!
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.