I am a very beginner with Streamlit (just simple apps ) and I’ am trying to display a PDF inside an iframe when a link is clicked. I’m using the chat_input component for user interactions.
When a user interacts using the chat_input component, I provide them a list of PDF URLs. Upon clicking these links, I want the PDFs to be displayed inside iframes in the Streamlit app.
Expected behavior:
When a user clicks on one of the provided PDF links, the corresponding PDF should be displayed inside an iframe within the Streamlit app.
Actual behavior:
Currently, clicking the link opens the PDF in a new browser tab and download it directly because I don’t know how to interact with an iframe using the chat_input.
I found few examples about how to use iframe and I tested them however none of them are integrated with chat_input and I’m kinda lost DOH
You may want to consider using the components.iframe function, which is used to render an iframe. This function takes a URL as its input and can be used to include an entire page within a Streamlit app. You could use this function to display the PDF inside an iframe within your Streamlit app when a link is clicked
I tried that approach earlier but encountered an issue in a specific scenario.
I aim to display the response in this format:
Text with answer
[link1] [link2] [link3]
Note: The links could alternatively be represented as buttons.
While I managed to integrate the iframe component, I’m struggling to send the response within the same message.
Here’s a snippet of the relevant code segment (refer to the TODO comments) and I welcome any recommendations for improvement.
import streamlit as st
import streamlit.components.v1 as components
def clicked(url):
st.session_state.show_url = url
if "show" not in st.session_state:
st.session_state["show_url"] = None
if st.session_state.show_url is not None:
# embed url in a streamlit app
components.iframe(st.session_state.show, height=600, scrolling=True)
if "messages" not in st.session_state:
st.session_state["messages"] = [
{"role": "assistant", "content": "How can I help you?"}
]
for msg in st.session_state.messages:
st.chat_message(msg["role"]).markdown(msg["content"], unsafe_allow_html=True)
if prompt := st.chat_input():
st.session_state.messages.append({"role": "user", "content": prompt})
st.chat_message("user").markdown(prompt, unsafe_allow_html=True)
# do something with the prompt
message = "You said: " + prompt
st.chat_message("assistant").markdown(message, unsafe_allow_html=True)
# TODO: find a way to write button in the same line as the message
st.chat_message("assistant").button(
"Streamlit Doc", on_click=clicked("https://docs.streamlit.io/en/stable/")
)
st.chat_message("assistant").button(
"Streamlit Doc 2", on_click=clicked("https://docs.streamlit.io/en/stable/")
)
st.session_state.messages.append({"role": "assistant", "content": message})
Just a heads up: I’m aware that clicking on the buttons causes them to disappear, and I’ll address this later