View pdf in streamlit

Hello Streamlit community, I’m trying to render a PDF file in my Streamlit app, but I can’t find a way to make the layout reactive.
I want it to be seen on one side of the chat, since when placing it it is being seen inside the sidebar. I hope for your help, thank you.

def main():
    st.set_page_config(page_title="ChatPDF",
                        # page_icon="static/img/stream.png",
                        )
    
    # Cargar estilos CSS desde un archivo externo
    with open("static/css/main.css") as source_des:
        st.markdown(f"<style>{source_des.read()}</style>", unsafe_allow_html=True)

    st.image("static/img/stream.png")
    
    if not "llm_chain" in st.session_state:
        st.session_state.llm_chain = None

    if not "chat_history" in st.session_state:
        st.session_state.chat_history = []

    if not "doc_len" in st.session_state:
        st.session_state.doc_len = 0

    user_input = st.chat_input("Envía un mensaje a CHAT ITP...")
    # Mensaje inicial
    if not user_input:
        # Select box para elegir el tipo de pregunta frecuente
        faq_type = st.selectbox(
            "Selecciona una categoría de preguntas frecuentes:",
            ("Estatuto Estudiantil", "Estatuto Docente", "Estatuto General")
        )
        
        # Mostrar preguntas frecuentes según la categoría seleccionada
        if faq_type == "Estatuto Estudiantil":
            col1, col2, col3 = st.columns(3)
            with col1:
                if st.button("¿Cómo puedo obtener mi certificado?"):
                    user_input = "¿Cómo puedo obtener mi certificado?"
                if st.button("¿Proceso para solicitar una copia de mi título?"):
                    user_input = "¿Proceso para solicitar una copia de mi título?"
            with col2:
                if st.button("¿Cuál es el proceso para solicitar mi título?"):
                    user_input = "¿Cuál es el proceso para solicitar mi título?"
                if st.button("Otra pregunta frecuente 2"):
                    user_input = "Otra pregunta frecuente 2"
            with col3:
                if st.button("Otra pregunta frecuente 3"):
                    user_input = "Otra pregunta frecuente 3"
                if st.button("Otra pregunta frecuente 4"):
                    user_input = "Otra pregunta frecuente 4"
        
        elif faq_type == "Estatuto Docente":
            col1, col2, col3 = st.columns(3)
            with col1:
                if st.button("¿Requisitos para obtener un título?"):
                    user_input = "¿Requisitos para obtener un título?"
                if st.button("¿Dónde puedo solicitar mi título?"):
                    user_input = "¿Dónde puedo solicitar mi título?"
            with col2:
                if st.button("¿Cuánto tiempo toma obtener un título?"):
                    user_input = "¿Cuánto tiempo toma obtener un título?"
                if st.button("¿Otra pregunta sobre títulos?"):
                    user_input = "¿Otra pregunta sobre títulos?"
            with col3:
                if st.button("¿Costos asociados al título?"):
                    user_input = "¿Costos asociados al título?"
                if st.button("¿Dudas generales sobre títulos?"):
                    user_input = "¿Dudas generales sobre títulos?"
        
        elif faq_type == "Estatuto General":
            col1, col2, col3 = st.columns(3)
            with col1:
                if st.button("¿Horarios de atención?"):
                    user_input = "¿Horarios de atención?"
                if st.button("¿Ubicación de oficinas?"):
                    user_input = "¿Ubicación de oficinas?"
            with col2:
                if st.button("¿Proceso de inscripción?"):
                    user_input = "¿Proceso de inscripción?"
                if st.button("¿Otra pregunta frecuente 2?"):
                    user_input = "¿Otra pregunta frecuente 2?"
            with col3:
                if st.button("¿Otra pregunta frecuente 3?"):
                    user_input = "¿Otra pregunta frecuente 3?"
                if st.button("¿Otra pregunta frecuente 4?"):
                    user_input = "¿Otra pregunta frecuente 4?"


    if user_input and st.session_state.llm_chain:
        bot_response = st.session_state.llm_chain({"question": user_input})
        st.session_state.memory = bot_response["chat_history"]
        for idx, msg in enumerate(st.session_state.memory):
            if idx % 2 == 0:
                with st.chat_message("user"):
                    st.write(msg.content)
            else:
                with st.chat_message("assistant"):
                    st.write(msg.content)



    elif user_input and not st.session_state.llm_chain:
        st.error("Cargue archivos y haga clic en continuar antes de hacer preguntas.")

    # Layout principal
    col1, col2 = st.columns([2, 3])

    with st.sidebar:
        st.subheader("Solo el administrador puede subir documentos 📄")

        # Input para la contraseña
        password_input = st.text_input("Contraseña", type="password")

        if password_input == "12345678":  # Reemplaza "12345678" con la contraseña real
            docs = st.file_uploader(
                "Sube el PDF y haz clic en continuar", type=["pdf"], accept_multiple_files=True
            )
            if docs and len(docs) > st.session_state.doc_len:
                st.session_state.doc_len = len(docs)
                with st.spinner("Procesando..."):
                    doc_text = get_text(docs)
                    doc_chunks = get_chunks(doc_text)
                    vectors = get_vector(doc_chunks)
                    st.session_state.llm_chain = get_llm_chain(vectors)
                
                # Visualización del PDF
                with col1:
                    displayPDF(docs[0])

    with col2:
        if st.session_state.llm_chain:
            for idx, msg in enumerate(st.session_state.chat_history):
                if idx % 2 == 0:
                    with st.chat_message("user"):
                        st.write(msg.content)
                else:
                    with st.chat_message("assistant"):
                        st.write(msg.content)

def displayPDF(upl_file):
    # Read file as bytes:
    bytes_data = upl_file.getvalue()

    # Convert to utf-8
    base64_pdf = base64.b64encode(bytes_data).decode("utf-8", 'ignore')

    # Embed PDF in HTML
    pdf_display = f'<iframe src="data:application/pdf;base64,{base64_pdf}" width="700" height="1000" type="application/pdf"></iframe>'

    # Display file
    st.markdown(pdf_display, unsafe_allow_html=True)

It is rendering outside the sidebar for me.

I think it was a previous code, only that it misconfigures the entire design since I want the left side to look like the following image and the pdf on the right side. Is there a way to prevent the PDF from being viewed on mobile devices?
I want it to look like this, when placing the pdf that way the input goes up and things like that.

I don’t understand the issue. You can put that in a column and the pdf in another column.

Yes, correct, but look, I don’t know why the chat column is deconfigured, since the input is passed to the top side and the messages start appearing at the bottom.

code:`def main():

st.set_page_config(page_title="ChatPDF",
                    initial_sidebar_state='collapsed',
                    layout="wide"
                    # page_icon="static/img/stream.png",
                    )

chat, pdf = st.columns([5 , 5])
    
with chat:
    # Cargar estilos CSS desde un archivo externo
    with open("static/css/main.css") as source_des:
        st.markdown(f"<style>{source_des.read()}</style>", unsafe_allow_html=True)

    st.image("static/img/stream.png")

    if not "llm_chain" in st.session_state:
        st.session_state.llm_chain = None

    if not "chat_history" in st.session_state:
        st.session_state.chat_history = []

    if not "doc_len" in st.session_state:
        st.session_state.doc_len = 0

    user_input = st.chat_input("Envía un mensaje a CHAT ITP...")

    # Mensaje inicial
    if not user_input:
        # Select box para elegir el tipo de pregunta frecuente
        faq_type = st.selectbox(
            "**Selecciona una categoría de preguntas frecuentes:**",
            ("Estatuto Estudiantil", "Estatuto Docente", "Estatuto General")
        )
        # Mostrar preguntas frecuentes según la categoría seleccionada
        if faq_type == "Estatuto Estudiantil":
            col1, col2, col3 = st.columns(3, gap="large")
            with col1:
                if st.button("¿Cómo puedo obtener mi certificado?"):
                    user_input = "¿Cómo puedo obtener mi certificado?"
                if st.button("¿Proceso para solicitar una copia de mi título?"):
                    user_input = "¿Proceso para solicitar una copia de mi título?"
            with col2:
                if st.button("¿Cuál es el proceso para solicitar mi título?"):
                    user_input = "¿Cuál es el proceso para solicitar mi título?"
                if st.button("Otra pregunta frecuente 2"):
                    user_input = "Otra pregunta frecuente 2"
            with col3:
                if st.button("Otra pregunta frecuente 3"):
                    user_input = "Otra pregunta frecuente 3"
                if st.button("Otra pregunta frecuente 4"):
                    user_input = "Otra pregunta frecuente 4"

        elif faq_type == "Estatuto Docente":
            col1, col2, col3 = st.columns(3, gap="large")
            with col1:
                if st.button("¿Requisitos para obtener un título?"):
                    user_input = "¿Requisitos para obtener un título?"
                if st.button("¿Dónde puedo solicitar mi título?"):
                    user_input = "¿Dónde puedo solicitar mi título?"
            with col2:
                if st.button("¿Cuánto tiempo toma obtener un título?"):
                    user_input = "¿Cuánto tiempo toma obtener un título?"
                if st.button("¿Otra pregunta sobre títulos?"):
                    user_input = "¿Otra pregunta sobre títulos?"
            with col3:
                if st.button("¿Costos asociados al título?"):
                    user_input = "¿Costos asociados al título?"
                if st.button("¿Dudas generales sobre títulos?"):
                    user_input = "¿Dudas generales sobre títulos?"

        elif faq_type == "Estatuto General":
            col1, col2, col3 = st.columns(3, gap="large")
            with col1:
                if st.button("¿Horarios de atención?"):
                    user_input = "¿Horarios de atención?"
                if st.button("¿Ubicación de oficinas?"):
                    user_input = "¿Ubicación de oficinas?"
            with col2:
                if st.button("¿Proceso de inscripción?"):
                    user_input = "¿Proceso de inscripción?"
                if st.button("¿Otra pregunta frecuente 2?"):
                    user_input = "¿Otra pregunta frecuente 2?"
            with col3:
                if st.button("¿Otra pregunta frecuente 3?"):
                    user_input = "¿Otra pregunta frecuente 3?"
                if st.button("¿Otra pregunta frecuente 4?"):
                    user_input = "¿Otra pregunta frecuente 4?"


    if user_input and st.session_state.llm_chain:
        bot_response = st.session_state.llm_chain({"question": user_input})
        st.session_state.memory = bot_response["chat_history"]
        for idx, msg in enumerate(st.session_state.memory):
            if idx % 2 == 0:
                with st.chat_message("user"):
                    st.write(msg.content)
            else:
                with st.chat_message("assistant"):
                    st.write(msg.content)

    elif user_input and not st.session_state.llm_chain:
        st.error("Cargue archivos y haga clic en continuar antes de hacer preguntas.")

    with st.sidebar:

        st.image("static/img/stream.png")

        tab1, tab2 = st.tabs(["Notas","Admin"])

        with tab1:
            # st.subheader("Solo el administrador puede subir documentos 📄")
            # Botón con un signo de pregunta que muestra información al pasar el mouse
            with st.popover("❓"):
                st.markdown("**Chat ITP** es un chatbot diseñado específicamente para mejorar la experiencia informativa de la comunidad del Instituto Tecnológico de Putumayo. Este software avanzado permite a docentes, estudiantes y personal administrativo realizar consultas interactivas y obtener respuestas inmediatas sobre una amplia gama de temas relacionados con el instituto. Con la capacidad de analizar y procesar información contenida en documentos PDF, Chat ITP facilita el acceso a datos cruciales como horarios de clases, detalles de cursos, información sobre el cuerpo docente y mucho más. Además, este chatbot inteligente está programado para entender y responder a una variedad de preguntas, asegurando que los usuarios puedan obtener la información que necesitan de manera rápida y eficiente.")

        with tab2:
        # Input para la contraseña
            password_input = st.text_input("Contraseña", type="password")

            if password_input == "12345678":  # Reemplaza "tu_contraseña" con la contraseña real
                docs = st.file_uploader(
                    "Sube el PDF y haz clic en continuar",type=["pdf"], accept_multiple_files=True
                )
                if len(docs) > st.session_state.doc_len:
                    st.session_state.doc_len = len(docs)
                    with st.spinner("Procesando..."):
                        doc_text = get_text(docs)
                        doc_chunks = get_chunks(doc_text)
                        vectors = get_vector(doc_chunks)
                        st.session_state.llm_chain = get_llm_chain(vectors)              
    st.sidebar.markdown('''
                        ---
                        By. Yan Cuaran - Maicol Jossa
                        ''')
with pdf:
    displayPDF(docs[0])

`

The chat_input widget no longer sticks itself to the bottom when it is inside a container, so you need to take care of its placement. Or maybe leave it outside the columns.

By leaving it out of the columns, it is displayed in both columns. I’ll see what solution I find. thank you
Do you know if there is documentation on how “colums” works?

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