Html and markdown are not being properly displayed and ui does not look good

Hey i am working with phidata AI Vedio summarizer project and i am not comfortable while using the html and css.i do not know whatโ€™s wrong, my output does not look good i think there is problem with markdown ot html while using this code. Please let me know how to fiz this i have provided the rest of details below.

  1. I am running this application locally.
  2. No application is not deployed anywhere i am just practicing the code.
  3. Python version == 3.11.1, streamlit version==1.41.1
  4. Here is github repository link
https://github.com/muhammadadilnaeem/AI-Agent-Smart-Video-Analyzer.git

It looks to me like itโ€™s doing the normal markdown behavior of treating indented code as code blocks. Hereโ€™s a playground showing how you can end up with some of your code being unintentionally indented, and also how you can fix this โ€“ just use st.html instead of st.markdown: playground

Code:

import streamlit as st


def get_content():
    content = "<p>Here is some content</p>"
    content2 = """
        <h1>Hello World</h1>

        <p>This is a paragraph</p>
        """
    return content + content2


st.subheader("With `st.markdown`:")

st.markdown(get_content(), unsafe_allow_html=True)

st.divider()

st.subheader("With `st.html`:")

st.html(get_content())
1 Like

Sir, itโ€™s still not working properly

Can you share a small reproducible script which shows the issue you are having?

1 Like

Sir After using st.html() now output loooks like this

here is source code

import os
import time
import tempfile
from pathlib import Path
from typing import Optional
from dotenv import load_dotenv
import streamlit as st
from phi.agent import Agent
from phi.model.google import Gemini
from phi.tools.duckduckgo import DuckDuckGo
import google.generativeai as genai
from google.generativeai import upload_file, get_file

# Load environment variables and configure API
load_dotenv()
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
if GOOGLE_API_KEY:
    genai.configure(api_key=GOOGLE_API_KEY)

def get_styled_html():
    """Return styled HTML content for the app"""
    return """
    <div class="app-container">
        <div class="title-section">
            <h1>โœจ Smart Video Analyzer</h1>
            <p class="subtitle">๐Ÿค– Powered by Advanced AI | ๐ŸŽฏ Precise Analysis | ๐ŸŒ Web Research</p>
        </div>
    </div>
    <style>
        .app-container {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        .title-section {
            background: linear-gradient(120deg, #2E3192 0%, #1BFFFF 100%);
            padding: 2rem;
            border-radius: 15px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            text-align: center;
            color: white;
            margin-bottom: 2rem;
        }
        .subtitle {
            font-size: 1.2rem;
            margin-top: 1rem;
            opacity: 0.9;
        }
    </style>
    """

def get_analysis_html(content: str) -> str:
    """Format analysis content as HTML"""
    return f"""
    <div class="analysis-container">
        <div class="analysis-header">
            <h2>โœจ Analysis Results</h2>
        </div>
        <div class="analysis-content">
            {content}
        </div>
    </div>
    <style>
        .analysis-container {{
            background: white;
            padding: 2rem;
            border-radius: 15px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            margin-top: 2rem;
        }}
        .analysis-header {{
            background: linear-gradient(120deg, #4E65FF 0%, #92EFFD 100%);
            color: white;
            padding: 1rem 2rem;
            border-radius: 10px;
            margin-bottom: 1.5rem;
        }}
        .analysis-content {{
            font-size: 16px;
            line-height: 1.6;
        }}
    </style>
    """

def format_analysis_response(content: str) -> str:
    """Format the analysis response with HTML structure"""
    sections = content.split('๐Ÿ“Š Relevant context and insights')
    main_points = sections[0].replace('๐ŸŽฏ Main points and key observations', '')
    
    formatted_content = f"""
    <div class="section">
        <h3>๐ŸŽฏ Key Observations</h3>
        <div class="content">{main_points}</div>
    </div>
    """
    
    if len(sections) > 1:
        insights = sections[1].split('๐Ÿ’ก Additional information')[0]
        web_research = sections[1].split('๐Ÿ’ก Additional information')[1]
        
        formatted_content += f"""
        <div class="section">
            <h3>๐Ÿ“Š Context & Insights</h3>
            <div class="content">{insights}</div>
        </div>
        <div class="section">
            <h3>๐Ÿ’ก Web Research Findings</h3>
            <div class="content">{web_research}</div>
        </div>
        """
    
    return get_analysis_html(formatted_content)

def stream_analysis(response_placeholder, agent, prompt, video_file):
    """Stream the AI analysis response"""
    response = agent.run(prompt, videos=[video_file])
    content = response.content
    
    with st.spinner("๐Ÿค– AI is analyzing your video..."):
        formatted_html = format_analysis_response(content)
        response_placeholder.html(formatted_html)

def main():
    st.set_page_config(page_title="โœจ Smart Video Analyzer", page_icon="๐ŸŽฅ", layout="wide")
    
    # Render main app HTML
    st.html(get_styled_html())
    
    # Initialize AI agent
    agent = create_agent()
    
    # File upload section
    st.html("""
        <div class="upload-section">
            <h3>๐Ÿ“ค Upload Your Video</h3>
            <style>
                .upload-section {
                    background: white;
                    padding: 2rem;
                    border-radius: 15px;
                    box-shadow: 0 4px 15px rgba(0,0,0,0.1);
                    margin: 1rem 0;
                }
            </style>
        </div>
    """)
    
    video_file = st.file_uploader(
        "Drop your video here โœจ",
        type=['mp4', 'mov', 'avi'],
        help="Supporting MP4, MOV, and AVI formats"
    )
    
    if video_file:
        video_path = process_video_file(video_file)
        st.video(video_path)
        
        st.html("""
            <div class="query-section">
                <h3>๐Ÿค” What would you like to know?</h3>
                <style>
                    .query-section {
                        background: white;
                        padding: 2rem;
                        border-radius: 15px;
                        box-shadow: 0 4px 15px rgba(0,0,0,0.1);
                        margin: 1rem 0;
                    }
                </style>
            </div>
        """)
        
        query = st.text_area(
            "",
            placeholder="๐Ÿ’ญ Ask anything about the video... I'll analyze it in detail!",
            help="Be specific for better results",
            value="Please provide a comprehensive analysis of this video including key points, insights, and relevant web research."
        )
        
        if st.button("๐Ÿ”ฎ Analyze Video", key="analyze_button"):
            if not query:
                st.warning("โš ๏ธ Please enter your question first!")
            else:
                try:
                    with st.spinner("๐ŸŽฌ Processing your video..."):
                        processed_file = upload_file(video_path)
                        while processed_file.state.name == "PROCESSING":
                            time.sleep(1)
                            processed_file = get_file(processed_file.name)
                        
                        prompt = f"""
                        Provide a detailed analysis of this video addressing:
                        "{query}"
                        
                        Structure your response with:
                        ๐ŸŽฏ Main points and key observations
                        ๐Ÿ“Š Relevant context and insights
                        ๐Ÿ’ก Additional information from web research
                        
                        Make it engaging and easy to understand.
                        """
                        
                        response_placeholder = st.empty()
                        stream_analysis(response_placeholder, agent, prompt, processed_file)
                
                except Exception as e:
                    st.error(f"โŒ Oops! Something went wrong: {str(e)}")
                finally:
                    Path(video_path).unlink(missing_ok=True)
    else:
        st.html("""
            <div class="welcome-section">
                <h2>๐Ÿ‘‹ Welcome to Smart Video Analyzer!</h2>
                <p>Upload a video to get started with AI-powered analysis</p>
                <p class="emoji-row">๐ŸŽฅ โœจ ๐Ÿค–</p>
                <style>
                    .welcome-section {
                        background: white;
                        padding: 2rem;
                        border-radius: 15px;
                        box-shadow: 0 4px 15px rgba(0,0,0,0.1);
                        text-align: center;
                        margin: 2rem 0;
                    }
                    .emoji-row {
                        font-size: 3rem;
                        margin: 1rem 0;
                    }
                </style>
            </div>
        """)

def create_agent() -> Agent:
    """Initialize AI agent with proper configuration"""
    return Agent(
        name="Smart Video Analyzer",
        model=Gemini(id="gemini-2.0-flash-exp"),
        tools=[DuckDuckGo()],
        markdown=True,
    )

def process_video_file(video_file) -> Optional[str]:
    """Process uploaded video file"""
    with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
        temp_file.write(video_file.read())
        return temp_file.name

if __name__ == "__main__":
    main()

It looks like you have two different things going on โ€“ one is some hard-coded HTML that you are generating โ€“ for that, I would recommend using st.html()

However, you also have the agent created with markdown=True, which I assume means that it will be returning markdown. So, for the output from the agent, you should use st.markdown().

1 Like

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