nlp-ca / app.py
danielle2003's picture
Update app.py
379877a verified
import streamlit as st
import streamlit.components.v1 as components
import os
from PIL import Image
# Set the page layout
st.set_page_config(layout="wide")
import json
import base64
import time
from dotenv import load_dotenv
import os
import requests
# Try loading environment variables locally
try:
from dotenv import load_dotenv
load_dotenv()
except:
pass
# Get the token from environment variables
HF_TOKEN = os.environ.get("HF_TOKEN")
if "framework" not in st.session_state:
st.session_state.framework = "gen"
# Initialize state
if "menu" not in st.session_state:
st.session_state.menu = "class"
if "show_overlay" not in st.session_state:
st.session_state.show_overlay = True
if "models" not in st.session_state:
st.session_state.models = []
if "save_path" not in st.session_state:
st.session_state.save_path = ""
# Initialize message storage
if "messages" not in st.session_state:
st.session_state.messages = []
if "input_text" not in st.session_state:
st.session_state.input_text = ""
if "input_task" not in st.session_state:
st.session_state.input_task = ""
if "generate_response" not in st.session_state:
st.session_state.generate_response = False
if st.session_state.show_overlay == False:
left = -9
top = -10
else:
top= -6.75
left =-5
# Folder to store chat histories
CHAT_DIR = "chat_histories"
os.makedirs(CHAT_DIR, exist_ok=True)
# Set default chat_id if not set
if "chat_id" not in st.session_state:
st.session_state.chat_id = "chat_1"
# Save messages to a file
def save_chat_history():
if st.session_state.messages: # Only save if there's at least one message
with open(f"{CHAT_DIR}/{st.session_state.chat_id}.json", "w", encoding="utf-8") as f:
json.dump(st.session_state.messages, f, ensure_ascii=False, indent=4)
#####################################################################################################
# Function to load data
def query_huggingface_model(selected_model: dict, input_data, input_type="text",max_tokens=512,task="text-classification",temperature=0.7, top_p=0.9 ):
API_URL = selected_model.get("url")
headers = {"Authorization": f"Bearer {HF_TOKEN}"}
try:
if input_type == "text":
if task == "text-generation":
payload = {
"messages": [
{
"role": "user",
"content": input_data
}
],
"max_tokens": max_tokens,
"temperature": temperature,
"top_p": top_p,
"model":selected_model.get("model")
}
else:
payload = {
"inputs": input_data ,
}
response = requests.post(API_URL, headers=headers, json=payload)
elif input_type == "image":
with open(input_data, "rb") as f:
data = f.read()
response = requests.post(API_URL, headers=headers, data=data)
else:
return {"error": f"Unsupported input_type: {input_type}"}
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {"error": str(e)}
def extract_response_content(response):
print(f"Response is: {response}")
# For text generation or image captioning
if isinstance(response, list):
if response and isinstance(response[0], dict) and "generated_text" in response[0]:
return response[0]["generated_text"]
elif response and isinstance(response[0], list) and "label" in response[0][0]:
# For text classification
return [(item["label"], round(item["score"], 3)) for item in response[0]]
# For OpenAI-style chat responses
elif isinstance(response, dict):
if "choices" in response and isinstance(response["choices"], list):
try:
return response["choices"][0]["message"]["content"]
except (KeyError, IndexError, TypeError):
return "Error: Could not extract message from choices"
elif "error" in response:
return f"Error: {response['error']}"
return "Unknown response format"
# Load a specific chat
def load_chat_history(chat_id):
file_path = f"{CHAT_DIR}/{chat_id}.json"
if os.path.exists(file_path):
with open(file_path, "r", encoding="utf-8") as f:
st.session_state.messages = json.load(f)
st.session_state.chat_id = chat_id
else:
st.warning(f"No history found for {chat_id}.")
st.session_state.show_overlay = False
st.session_state.models = [
{
"model": "distilbert-base-uncased-finetuned-sst-2-english",
"url": "https://router.huggingface.co/hf-inference/models/distilbert/distilbert-base-uncased-finetuned-sst-2-english"
},
{
"model": "openai-community/roberta-base-openai-detector",
"url": "https://router.huggingface.co/hf-inference/models/openai-community/roberta-base-openai-detector"
},
{
"model": "nlptown/bert-base-multilingual-uncased-sentiment",
"url": "https://router.huggingface.co/hf-inference/models/nlptown/bert-base-multilingual-uncased-sentiment"
},
{
"model": "BAAI/bge-reranker-base",
"url": "https://router.huggingface.co/hf-inference/models/BAAI/bge-reranker-base"
},
{
"model": "SamLowe/roberta-base-go_emotions",
"url": "https://router.huggingface.co/hf-inference/models/SamLowe/roberta-base-go_emotions"
}
]
if st.session_state.framework == "gen":
encoded_logo = "hugging.png"
main_bg_ext = "png"
main_bg = "picturebg.jfif"
st.markdown(
f"""
<style>
/* Container for logo and text */
/* Container for logo and text */
.logo-text-container {{
position: fixed;
top: 20px; /* Adjust vertical position */
left: 30px; /* Align with sidebar */
display: flex;
align-items: center;
gap: 15px;
width: 70%;
z-index:1000;
}}
/* Logo styling */
.logo-text-container img {{
width: 60px; /* Adjust logo size */
border-radius: 10px; /* Optional: round edges */
margin-left:-5px;
margin-top: -15px;
}}
/* Bold text styling */
.logo-text-container h1 {{
font-family: Nunito;
color: #0175C2;
font-size: 25px;
font-weight: bold;
margin-right :100px;
padding:0px;
top:0;
margin-top: 10px;
}}
.logo-text-container i{{
font-family: Nunito;
color: orange;
font-size: 15px;
margin-right :10px;
padding:0px;
margin-left:-15.5%;
margin-top:2% !important;
}}
/* Sidebar styling */
section[data-testid="stSidebar"][aria-expanded="true"] {{
margin-top: 100px !important; /* Space for the logo */
border-radius: 0 60px 0px 60px !important; /* Top-left and bottom-right corners */
width: 300px !important; /* Sidebar width */
background: none; /* No background */
color: white !important;
}}
header[data-testid="stHeader"] {{
background: transparent !important;
margin-right: 100px !important;
margin-top: 1px !important;
z-index: 1 !important;
color: blue; /* White text */
font-family: "Times New Roman " !important; /* Font */
font-size: 18px !important; /* Font size */
font-weight: bold !important; /* Bold text */
padding: 10px 20px; /* Padding for buttons */
border: none; /* Remove border */
transition: all 0.3s ease-in-out; /* Smooth transition */
display: flex;
align-items: center;
justify-content: center;
margin: 10px 0;
width:90% !important;
left:5.5%;
height:60px;
margin-top:70px;
backdrop-filter: blur(10px);
}}
div[data-testid="stDecoration"] {{
background-image: none;
}}
div[data-testid="stApp"] {{
background: url(data:image/{main_bg_ext};base64,{base64.b64encode(open(main_bg, "rb").read()).decode()});
background-size: cover; /* Ensure the image covers the full page */
background-position: center;
background-repeat:no-repeat;
height: 98vh;
width: 99.3%;
border-radius: 20px !important;
margin-left: 5px;
margin-right: 20px;
margin-top: 10px;
overflow: hidden;
backdrop-filter: blur(10px); /* Glass effect */
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2); /* Light border */
}}
section[data-testid="stMain"] {{
overflow:hidden !important;
}}
div[data-testid="stSlider"] {{
margin-top:45px;
}}
label[data-testid="stWidgetLabel"]{{
margin-left:20px !important;
}}
div[data-baseweb="slider"] {{
border-radius: 30px;
padding-right:40px;
z-index: 1;
/* Glass effect background */
backdrop-filter: blur(2px);
-webkit-backdrop-filter: blur(12px);
/* Shiny blue borders (left & right) */
border-top: 2px solid rgba(255, 255, 155, 0.4); /* Light border */
margin-left:13px;
border-bottom: 2px solid rgba(255, 255, 155, 0.4); /* Light border */
}}
div[data-baseweb="slider"] > :nth-child(1)> div {{
margin-left:20px !important;
margin-top:10px;
}}
div[data-testid="stSliderTickBarMin"]{{
background:none !important;
margin-left:20px !important;
font-size:12px;
margin-bottom:5px;
font-family: "Times New Roman " !important; /* Font */
}}
div[data-testid="stSliderTickBarMax"]{{
background:none !important;
font-size:12px;
margin-bottom:5px;
font-family: "Times New Roman " !important; /* Font */
}}
div[data-testid="stSliderThumbValue"]{{
font-size:12px;
font-family: "Times New Roman " !important; /* Font */
}}
div[data-testid="stProgress"]{{
margin-right:25px;
margin-top:-70px;
height:10px !important;
}}
[class*="st-key-content-container-3"] {{
margin-top: 50px; /* Adjust top margin */
margin-left:500px !important;
color:orange;
font-size:2.2rem;
}}
/* Button row styling */
.button-row {{
display: flex;
justify-content: flex-start;
gap: 20px;
margin-bottom: 20px;
}}
.custom-button:hover {{
background-color: #0056b3;
}}
div.stButton > button p{{
color: orange !important;
font-weight:bold;
}}
div.stButton > button {{
color: orange !important; /* White text */
font-family: "Times New Roman " !important; /* Font */
font-size: 18px !important; /* Font size */
font-weight: bold !important; /* Bold text */
padding: 10px 20px; /* Padding for buttons */
border: none; /* Remove border */
border-radius: 35px; /* Rounded corners */
transition: all 0.3s ease-in-out; /* Smooth transition */
display: flex;
align-items: center;
transform: scale(1.05); /* Slightly enlarge button */
transform: scale(1.1); /* Slight zoom on hover */
justify-content: center;
}}
/* Hover effect */
div.stButton > button:hover {{
background: rgba(255, 255, 255, 0.2);
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.4); /* Enhanced shadow on hover */
transform: scale(1.05); /* Slightly enlarge button */
transform: scale(1.1); /* Slight zoom on hover */
box-shadow: 0px 4px 12px rgba(255, 255, 255, 0.4); /* Glow effect */
}}
div[data-testid="stMarkdownContainer"] p {{
font-family: "Times New Roman" !important; /* Elegant font for title */
color:black !important;
}}
.titles{{
margin-top:-90px !important;
margin-left:40px;
text-align:center;
align-items:center;
font-family: "Times New Roman" !important;
}}
.header {{
align-items: center;
gap: 20px; /* Optional: adds space between image and text */
}}
/* Title styling */
.header h1{{
font-size: 5rem;
font-weight: bold;
margin-left: 5px;
/* margin-top:-50px;*/
margin-bottom:30px;
padding: 0;
color: black; /* Neutral color for text */
}}
.header h1 span{{
font-size: 6rem;
font-weight: bold;
margin-left: 5px;
/* margin-top:-50px;*/
margin-bottom:30px;
background: orange;
padding:5px;
border-radius:15px ;
color: black; /* Neutral color for text */
}}
.titles .content{{
font-family: "Times New Roman" !important; /* Elegant font for title */
font-size: 1.1rem;
margin-bottom:1px;
padding: 0;
color:black; /* Neutral color for text */
}}
</style>
""",
unsafe_allow_html=True,
)
# Overlay container
st.markdown(
f"""
<style>
.logo-text-containers {{
position: absolute;
top: -60px;
right: 40px;
background-color: rgba(255, 255, 255, 0.9);
padding: 15px;
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
z-index: 10;
width:80vw;
height:620px;
}}
.logo-text-containers img {{
height: 40px;
right:0;
}}
.logo-text-containers h1 {{
display: inline;
font-size: 20px;
vertical-align: middle;
}}
.logo-text-containers i {{
display: block;
margin-top: 5px;
font-size: 14px;
color: #333;
}}
div[class*="st-key-try"] >div>button > div >p{{
top: 5px;
font-size: 30px !important;
font-weight: bold !important;
cursor: pointer;
color:orange !important;
z-index:1000;
}}
div[class*="st-key-try"] >div>button {{
height:70px !important;
width:250px !important;
background: rgba(255, 255, 255, 0.2) !important;
backdrop-filter: blur(10px) !important;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2); /* Shadow effect */
margin-left:20px;
}}
[class*="st-key-close-btn"]:hover {{
color: #f00;
}}
[class*="st-key-divider-col"] {{
border-left: 3px solid rgba(255, 255, 155, 0.5); /* Light border */
border-radius: 35px; /* Rounded corners */
margin-top:-15px;
margin-left:3px;
}}
[class*="st-key-col1"] {{
border-right: 3px solid rgba(255, 255, 155, 0.5); /* Light border */
border-radius: 35px; /* Rounded corners */
margin-left:20px;
margin-top:-15px;
}}
[class*="st-key-logo-text-containers"] {{
margin: 10px; /* Set a margin inside the container */
max-width: 100%;
overflow: hidden;
position: absolute;
top:-43px;
left:10px;
overflow: hidden;
background-color: tansparent;
padding: 15px;
border-radius: 30px;
padding-right:40px;
z-index: 1;
width:88vw;
height:660px;
/* Glass effect background */
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
/* Shiny blue borders (left & right) */
border-left: 3px solid rgba(255, 255, 255, 0.9); /* Light border */
border-right: 3px solid rgba(255, 255, 255, 0.9); /* Light border */
}}
@media (max-width: 768px) {{
.logo-text-container h1 {{
font-size: 12px;
}}
.logo-text-container i {{
font-size: 10px;
ma
}}
.logo-text-container img {{
width: 30px; /* Adjust logo size */
border-radius: 10px; /* Optional: round edges */
margin-left:15px;
margin-top: -35px;
}}
}}
</style>
""",
unsafe_allow_html=True,
)
st.markdown(
f""" <div class="logo-text-container">
<img src="data:image/png;base64,{base64.b64encode(open("hugging.png","rb").read()).decode()}" alt="Uploaded Image">
<h1>Hugging face<br></h1>
<i>transformers pipeline</i>
</div>
""",
unsafe_allow_html=True,
)
st.markdown(
f""" <div class="titles">
<div class = "header">
<h1></br><span>Frame the </span> Prompt </br> Where Words Become Art
</h1>
</div>
<div class="content">
This intelligent assistant enables you to generate insightful text and vivid imagery description from simple prompts.
Whether you're brainstorming ideas, <br>drafting content, or visualizing concepts — everything is saved, so your creative flow never skips a beat.
</div>
</div>
""",
unsafe_allow_html=True,
)
with st.container(key="content-container-3"):
if st.button("Try it now ",key="try"):
st.session_state.framework = "dash"
st.session_state.show_overlay = True
st.rerun()
if st.session_state.framework == "dash":
if st.session_state.menu == "class":
choice1 = '"Win a free vacation to the Bahamas! Click the link below to claim your prize.This is an exclusive offer for a limited time only, don’t miss out!"'
choice2 = '"I can’t believe my phone just died right before an important call. Ugh! Now I have to wait for hours to get it fixed and miss out on everything."'
choice3 = '"Apple unveils a new AI chip with groundbreaking technology in the latest iPhone.This innovation is set to redefine the way we use smartphones in everyday life."'
choice4 = '"I made a delicious homemade food last night with fresh ingredients. It was so good, I can’t wait to make it again for dinner tomorrow."'
text_h1 = "🏷️ Text Classification"
images="images.png"
images="images.png"
image1 = 'images.png'
image2 = 'images.png'
image3 = 'images.png'
margin = 0
margintop = "-20"
display = "none"
st.session_state.models = [
{
"model": "distilbert-base-uncased-finetuned-sst-2-english",
"url": "https://router.huggingface.co/hf-inference/models/distilbert/distilbert-base-uncased-finetuned-sst-2-english"
},
{
"model": "openai-community/roberta-base-openai-detector",
"url": "https://router.huggingface.co/hf-inference/models/openai-community/roberta-base-openai-detector"
},
{
"model": "nlptown/bert-base-multilingual-uncased-sentiment",
"url": "https://router.huggingface.co/hf-inference/models/nlptown/bert-base-multilingual-uncased-sentiment"
},
{
"model": "BAAI/bge-reranker-base",
"url": "https://router.huggingface.co/hf-inference/models/BAAI/bge-reranker-base"
},
{
"model": "SamLowe/roberta-base-go_emotions",
"url": "https://router.huggingface.co/hf-inference/models/SamLowe/roberta-base-go_emotions"
}
]
task = "text-classification"
if st.session_state.menu == "gen":
choice1 = 'Write a poem about the ocean at night. Include imagery and emotion to bring it to life.'
choice2 = 'Generate a product description for a futuristic smartwatch with health monitoring features.'
choice3 = 'Complete this sentence: "As she opened the old journal, she found..."'
choice4 = 'Write a motivational quote that could be used in a fitness app.'
text_h1 = "✍️ Text Generation"
images = 'images.png'
image1 = 'images.png'
image2 = 'images.png'
image3 = 'images.png'
margin = 0
margintop = -20
task = "text-generation"
display = "block"
st.session_state.models = [
{
"model": "deepseek-ai/DeepSeek-V3",
"url": "https://router.huggingface.co/nebius/v1/chat/completions"
},
{
"model": "mistralai/mistral-7b-instruct",
"url": "https://router.huggingface.co/novita/v3/openai/chat/completions"
},
{
"model": "meta-llama/llama-3.1-8b-instruct",
"url":"https://router.huggingface.co/novita/v3/openai/chat/completions"
},
{
"model": "qwen/qwq-32b",
"url": "https://router.huggingface.co/novita/v3/openai/chat/completions"
},
{
"model": "google/gemma-2-2b-it-fast",
"url": "https://router.huggingface.co/nebius/v1/chat/completions"
}
]
st.session_state.model = "best_bilstm_model.h5"
if st.session_state.menu == "image":
choice1 = ''
choice2 = ''
choice3 = ''
choice4 = ''
text_h1 = "🖼️ Image to Text "
images = 'images.jfif'
image1 = 'logo2.png'
image2 = 'hugging.png'
margintop = -90
image3 = 'Captured.png'
display = "none"
st.session_state.models = [
{
"model": "Salesforce/blip-image-captioning-large",
"url": "https://router.huggingface.co/hf-inference/models/Salesforce/blip-image-captioning-large"
},
{
"model": "nlpconnect/vit-gpt2-image-captioning",
"url": "https://router.huggingface.co/hf-inference/models/nlpconnect/vit-gpt2-image-captioning"
}
]
task = "image-to-text"
margin = 120
st.session_state.model = "best_bilstm_model.h5"
st.markdown(
"""
<style>
section[data-testid="stSidebar"] {
scrollbar-width: thin;
scrollbar-color: #888 #f1f1f1;
}
section[data-testid="stSidebar"] ::-webkit-scrollbar {
width: 4px;
}
section[data-testid="stSidebar"] ::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 10px;
}
</style>
""",
unsafe_allow_html=True
)
st.markdown(
f"""
<style>
/* Sidebar styling */
section[data-testid="stSidebar"][aria-expanded="true"] {{
margin-top: 0px !important; /* Space for the logo */
width: 300px !important; /* Sidebar width */
/* box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); /* Shadow effect */
/* border: 1px solid #FFD700; /* Shiny golden border */
margin-bottom: 1px !important;
color:white !important;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
background:#f9f9f9;
}}
*, html {{scroll-behavior: smooth !important;}}
div[data-testid="stSidebarContent"]{{
overflow-x:hidden !important;
}}
/* Style for the upload button */
[class*="st-key-upload-btn"] {{
top: -31px; /* Position from the top of the inner circle */
left: 150px; /* Position horizontally at the center */
padding: 10px 20px;
color: red;
border: none;
border-radius: 15px;
cursor: pointer;
font-size: 35px !important;
z-index:10000000;
width:300px;
}}
[class*="st-key-upload-btns"] {{
top: 106px; /* Position from the top of the inner circle */
left: 390px; /* Position horizontally at the center */
padding: 10px 20px;
color: red;
border: none;
border-radius: 10px;
cursor: pointer;
font-size: 35px !important;
z-index:10000000000000000000000;
width:300px;
}}
.upload-btn:hover {{
background-color: rgba(0, 123, 255, 1);
}}
div[data-testid="stFileUploader"] label > div > p {{
display:none;
color:white !important;
}}
div[data-testid="stFileUploader"] > div {{
color:blue !important;
margin-top:-110px;
margin-left:150px;
width:300px;
height:110px;
}}
section[data-testid="stFileUploaderDropzone"] {{
width:900px;
height: 120px;
border-radius: 30px;
display: flex;
justify-content: center;
align-items: center;
margin-top:-10px;
margin:20px;
background-color:#f0f2f6; /* Transparent blue background */
color:white;
}}
div[data-testid="stFileUploaderDropzoneInstructions"] div > small{{
color:white !important;
display:none;
}}
div[data-testid="stFileUploaderDropzoneInstructions"] span{{
margin-left:65px;
color:black;
}}
div[data-testid="stFileUploaderDropzoneInstructions"] div{{
display:none;
}}
section[data-testid="stFileUploaderDropzone"] button{{
display:none;
}}
div[data-testid="stMarkdownContainer"] p {{
font-family: "Times New Roman" !important; /* Elegant font for title */
color:black !important;
}}
div[class*="st-key-user-"]{{
margin-left:510px;
width:550px;
}}
div[class*="st-key-assistant-"]{{
margin-left:100px;
}}
.highlight {{
border: 4px solid lime;
font-weight: bold;
background: radial-gradient(circle, rgba(0,255,0,0.3) 0%, rgba(0,0,0,0) 70%);
box-shadow: 0px 0px 30px 10px rgba(0, 255, 0, 0.9),
0px 0px 60px 20px rgba(0, 255, 0, 0.6),
inset 0px 0px 15px rgba(0, 255, 0, 0.8);
transition: all 0.3s ease-in-out;
}}
.highlight:hover {{
transform: scale(1.05);
background: radial-gradient(circle, rgba(0,255,0,0.6) 0%, rgba(0,0,0,0) 80%);
box-shadow: 0px 0px 40px 15px rgba(0, 255, 0, 1),
0px 0px 70px 30px rgba(0, 255, 0, 0.7),
inset 0px 0px 20px rgba(0, 255, 0, 1);
}}
header[data-testid="stHeader"] {{
/* border-radius: 1px !important;*/
background: white !important; /* Gradient background */
/*: 3px solid #FFD700; /* Shiny golden border */
/*border-bottom:none !important;*/
margin-right: 300px !important;
margin-top: 12.5px !important;
border-bottom:1px solid #ccc;
width:48%;
height:85px;
margin-left:770px;
z-index:1000000;
}}
div[data-testid="stDecoration"]{{
background-image:none;
}}
button[data-testid="stBaseButton-secondary"]{{
background:transparent;
border:none;
}}
div[data-testid="stApp"]{{
background:white;
height: 98.9vh; /* Full viewport height */
width: 99%;
border-radius: 10px !important;
margin-left:5px;
margin-right:10px;
margin-top:5px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);
overflow: hidden;
}}
div[data-testid="stChatMessage"]{{
z-index:1;
border-radius:50px;
}}
section[data-testid="stAppScrollToBottomContainer"]{{
margin-top:50px !important;
padding-right:5px !important;
margin-right:10px;
}}
div[data-testid="stChatMessageAvatarUser"]{{
display:none;
}}
div[data-testid="stChatMessageAvatarAssistant"]{{
display:none;
}}
div[data-testid="stChatInput"]{{
height:120px !important;
}}
div[data-testid="stChatInput"]>div{{
max-height:200px !important;
}}
div[class*="st-key-upload"] > div[data-testid="stChatInput"]> div > div:nth-child(4) {{
top: 85px;
right: 50px;
}}
div[class*="st-key-upload"] > div[data-testid="stChatInput"] > div > div {{
margin-top:10px !important;
height: 0px;
width: -0px;
}}
div[data-testid ="stSidebarCollapsedControl"]> div > button{{
background-image: url(data:image/png;base64,{base64.b64encode(open("close.png", "rb").read()).decode()});
background-size: cover; /* size of the image */
background-repeat: no-repeat;
width:30px !important;
margin-left: -15px !important;
display: block !important;
width: 41px !important;
height: 40px;
}}
div[data-testid ="stSidebarCollapsedControl"]> div > button > svg{{
display:none !important;
}}
div[data-testid="stSidebarCollapseButton"] > button >svg{{
display:none !important;
}}
div[data-testid="stSidebarCollapseButton"] {{
display:block !important;
}}
div[data-testid ="stSidebarCollapseButton"]> button{{
background-image: url(data:image/png;base64,{base64.b64encode(open("close.png", "rb").read()).decode()});
background-size: cover; /* size of the image */
background-repeat: no-repeat;
display:block !important;
display: block !important;
width: 40px;
height: 40px;
position:relative;
margin-left:-250px !important;
margin-top:-20px;
}}
[class*="st-key-content_1"] {{
background: transparent;
border-radius: 10px;
/* box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);*/
width: 90%;
margin-left: -100px;
/* margin-top: -90px;*/
margin-bottom: 20px;
margin-right:10px;
margin-top:5px !important;
padding:100px;
overflow-y: auto; /* Enable vertical scrolling for the content */
position: fixed; /* Fix the position of the container */
top: 1%; /* Adjust top offset */
left: 15%; /* Adjust left offset */
overflow-x:hidden;
overflow-y:hidden;
display: flex;
z-index:10000;
}}
div[data-testid="stSidebarHeader"]{{
height:40px !important;
position:fixed;
z-index:10000;
background:#f9f9f9;
width:300px;
}}
section[data-testid="stMain"]{{
margin-left:-70px !important;
}}
section[data-testid="stSidebar"]{{
background:#f7f7f8;
}}
[class*="st-key-center-box"] {{
background-color: transparent;
border-radius: 60px;
width: 100%;
margin-top:30px;
top:20% !important; /* Adjust top offset */
left: 1%; /* Adjust left offset */
}}
[class*="st-key-side"] {{
background-color: transparent;
border-radius: 60px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.5);
width: 5%;
/* margin-top: 100px;*/
margin-bottom: 10px;
margin-right:10px;
padding:30px;
display: flex;
justify-content: center;
align-items: center;
overflow-y: auto; /* Enable vertical scrolling for the content */
position: fixed; /* Fix the position of the container */
top: 17%; /* Adjust top offset */
left: 16%; /* Adjust left offset */
height:50vh; /* Full viewport height */
}}
[class*="st-key-button_"] .stButton p > img {{
max-width: 100%;
vertical-align: top;
height:130px !important;
object-fit: cover;
padding: 10px;
width:250px !important;
border-radius:10px !important;
max-height: 2em !important;
}}
div.stButton > button {{
color: orange !important; /* White text */
font-family: "Times New Roman " !important; /* Font */
font-size: 18px !important; /* Font size */
font-weight: bold !important; /* Bold text */
padding: 1px 2px; /* Padding for buttons */
border: none; /* Remove border */
border-radius: 5px; /* Rounded corners */
transition: all 0.3s ease-in-out; /* Smooth transition */
display: flex;
align-items: left;
justify-content: left;
margin-left:-15px ;
width:200px;
height:50px;
z-index:1000;
text-align: left; /* Align text to the left */
padding-left: 50px;
}}
div.stButton > button p{{
color: black !important; /* White text */
}}
/* Hover effect */
div.stButton > button:hover {{
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.4); /* Enhanced shadow on hover */
transform: scale(0.05); /* Slightly enlarge button */
transform: scale(1.01); /* Slight zoom on hover */
box-shadow: 0px 4px 12px rgba(255, 255, 255, 0.4); /* Glow effect */
}}
div.stButton > button:active {{
background: none;
}}
div.stDownloadButton > button:active,
div.stDownloadButton > buttonfocus {{
outline: none; /* Remove the focus outline if you want */
}}
[class*="st-key-button_"] .stButton p > img {{
max-width: 100%;
vertical-align: top;
height:130px !important;
object-fit: cover;
padding: 10px;
width:250px !important;
border-radius:10px !important;
max-height: 2em !important;
}}
div.stDownloadButton > button > div > p {{
font-size:15px !important;
font-weight:bold;
}}
[class*="st-key-button_"] .stButton p{{
font-family: "Times New Roman " !important; /* Font */
font-size:100px !important;
height:150px !important;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
font-weight: bold;
margin-top:5px;
margin-left:5px;
color:black;
border-radius:10px;
}}
[class*="st-key-button_"]:hover {{
}}
[class*="st-key-nav-"] .stButton p{{
font-family: "Times New Roman " !important; /* Font */
font-size:1rem !important;
font-weight: bold;
}}
[class*="st-key-create"]>div > button
{{
background-image: url(data:image/png;base64,{base64.b64encode(open("side.png", "rb").read()).decode()});
width: 130px !important;
background-size: contain;
background-repeat: no-repeat;
margin-top: -88px !important;
margin-left: -100px !important;
z-index: 100000000000000;
pointer-events: auto; /* Ensure the button is clickable */
border-radius:0px;
}}
.user-image{{
height:100px ;
margin:20px;
}}
/******************************************************/
/* * *choices*************/
[class*="st-key-choices"]{{
margin-left:220px;
padding:30px;
margin-top:{margintop}px !important;
}}
[class*="st-key-choice-1"]{{
background:white !important;
border-radius:15px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
width:350px;
}}
[class*="st-key-choice-1"]>div >button{{
background-image: url(data:image/png;base64,{base64.b64encode(open(images, "rb").read()).decode()}) !important;
background-size: 100% 100%;
background-repeat: no-repeat;
background-position:center;
}}
[class*="st-key-choice-1"]>div >button p{{
margin-left:{margin}px !important;
}}
[class*="st-key-choice-"]>div >button p{{
margin-right:10px !important;
}}
[class*="st-key-choice-2"]>div >button{{
background-image: url(data:image/png;base64,{base64.b64encode(open(image1, "rb").read()).decode()}) !important;
background-repeat: no-repeat;
background-position:center;
background-size: contain;
}}
[class*="st-key-choice-2"]>div >button p{{
margin-left:{margin}px !important;
}}
[class*="st-key-choice-5"]>div >button{{
background-image: url(data:image/png;base64,{base64.b64encode(open(image2, "rb").read()).decode()}) !important;
background-size: contain;
background-position:center;
background-repeat: no-repeat;
}}
[class*="st-key-choice-5"]>div >button p{{
margin-left:{margin}px !important;
}}
[class*="st-key-choice-6"]>div >button{{
background-image: url(data:image/png;base64,{base64.b64encode(open(image3, "rb").read()).decode()}) !important;
background-size: contain;
background-position:center;
background-repeat: no-repeat;
}}
[class*="st-key-choice-6"]>div >button p{{
margin-left:{margin}px !important;
}}
[class*="st-key-choice-"] > div.stButton > button{{
padding-left: 25px !important;
height: 130px !important;
margin-left: 0px !important;
max-width: 400px;
width: 350px;
}}
[class*="st-key-choice-2"]{{
background:white !important;
border-radius:15px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
width:350px;
}}
[class*="st-key-choice-5"]{{
background:white !important;
border-radius:15px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
width:350px;
}}
[class*="st-key-choice-6"]{{
background:white !important;
border-radius:15px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
width:350px;
}}
/*************************************************************/
div[data-testid="stSelectbox"]
{{
width: 297px !important;
background-color: white !important;
margin-top: -118px !important;
position: relative;
margin-left: -8px !important;
z-index:10000000000000000000;
position:fixed;
border-bottom:1px solid #ccc;
border-radius:0px;
height:87px;
padding:15px;
padding-left:100px;
}}
div[data-testid="stExpander"]
{{
width: 250px !important;
background-color: white !important;
margin-top: -102px !important;
position: relative;
margin-left: 289px !important;
z-index:10000000000000000000;
position:fixed;
border-bottom:1px solid #ccc;
border-radius:0px;
height:87px;
padding-top:35px;
padding-left:10px;
=
}}
div[data-testid="stExpander"]>details{{
z-index:10000000000000000000;
display:{display} !important;
background:white;
}}
div[data-testid="stTextInput"]
{{
background-color: transparent; /* White background */
z-index:100000000;
margin-top: -10px !important;
margin-left: 200px !important;
}}
div[data-testid="stHeading"]
{{
margin-top: 10px !important;
position: relative;
margin-left: 300px !important;
}}
div[data-testid="stTextInput"]>div
{{
width: 900px; /* Full width inside the container */
z-index:10000000000000000;
height:120px;
border-radius:30px;
border:0.5px solid white;
}}
[class*="st-key-btn-new"]>div > button{{
width:40px !important;
margin-top:{top}% !important;
margin-left:{left}% !important;
z-index:1000000000000;
background-image: url(data:image/png;base64,{base64.b64encode(open("side.png", "rb").read()).decode()});
background-size: contain; /* size of the image */
background-repeat: no-repeat;
position:fixed;
}}
[class*="st-key-input-base"]>div{{
z-index:1000000000000000;
}}
[class*="st-key-base-content"]>div{{
background:transparent !important;
z-index:1000000000000000;
margin-top: 440px !important;
position:fixed;
}}
[class*="st-key-answers"]{{
height:200px !important;
overflow-y:scroll;
overflow-x:hidden;
scroll-behavior: smooth !important;
max-height:300px;
}}
[class*="st-key-uploads"]{{
margin:50px;
margin-top: 10px;
margin-left: 150px;
margin-bottom:80px;
}}
[class*="st-key-imupload"]{{
margin-left: 150px;
}}
[class*="st-key---hist_"]{{
margin-top:-20px !important;
margin-left:-30px;
}}
[class*="st-key---hist_"]>div >button p{{
margin-top:-20px !important;
font-size:16px;
font-family: "Times New Roman" !important; /* Elegant font for title */
color:black !important;
}}
[class*="st-key---hist_"]>div >button {{
padding-left:15px;
width:300px !important;
text-overflow: ellipsis;
}}
[class*="st-key-hist_"]{{
overflow:hidden;
text-overflow: ellipsis;
max-width: 300px;
margin-left:-35px;
}}
h3{{
color:black !important;
font-family: "Times New Roman" !important; /* Elegant font for title */
font-size:18px;
}}
[class*="st-key-nav-"]>div >button{{
width:350px !important;
height:20px !important;
}}
[class*="st-key-nav-"]{{
margin-left:-20px !important;
}}
[class*="st-key-nav-1"]{{
border-radius:80px !important;
border-radius:80px !important;
width:280px !important;
margin-top:50px !important;
background-image: url(data:image/png;base64,{base64.b64encode(open("img.png", "rb").read()).decode()});
background-size: contain; /* size of the image */
background-repeat: no-repeat;
color :black !important;
padding:10px;
padding-left:25px;
}}
[class*="st-key-nav-2"] .stButton p{{
margin-left:-10px !important;
}}
[class*="st-key-nav-2"]{{
border-radius:80px !important;
border-radius:80px !important;
width:280px !important;
margin-top:-20px !important;
background-image: url(data:image/png;base64,{base64.b64encode(open("side.png", "rb").read()).decode()});
background-size: contain; /* size of the image */
background-repeat: no-repeat;
color :black !important;
padding:10px;
margin-left:-10px !important;
padding-left:25px;
}}
[class*="st-key-nav-3"]{{
border-radius:80px !important;
border-radius:80px !important;
width:280px !important;
margin-top:-22px !important;
background-image: url(data:image/png;base64,{base64.b64encode(open("gen.png", "rb").read()).decode()});
background-size: contain; /* size of the image */
background-repeat: no-repeat;
color :black !important;
padding:10px;
padding-left:20px;
margin-left:-10px !important;
height:51px !important;
}}
[class*="st-key-nav-6"] {{
border: none; /* Remove border */
background: transparent !important;
border-radius:80px !important;
backdrop-filter: blur(10px) !important;
border-radius:80px !important;
width:190px !important;
margin-top:35px !important;
}}
</style>
""",
unsafe_allow_html=True
)
loading_html = """
<style>
.loader {
border: 8px solid #f3f3f3;
border-top: 8px solid #0175C2; /* Blue color */
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin: auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<div class="loader"></div>
"""
# Sort chat files by last modified time (most recent first)
chat_files = sorted(
os.listdir(CHAT_DIR),
key=lambda x: os.path.getmtime(os.path.join(CHAT_DIR, x)),
reverse=True
)
# Sidebar buttons
with st.sidebar:
if st.button(" &nbsp;&nbsp; Text Classification",key="nav-1"):
st.session_state.menu ="class" # Store state
st.rerun()
if st.button(" &nbsp;&nbsp; Text Generation",key="nav-2"):
st.session_state.menu ="gen" # Store state
st.rerun()
if st.button(" &nbsp;&nbsp; Image to text Generator",key="nav-3"):
st.session_state.menu ="image" # Store state
st.rerun()
st.markdown("### 💬 Previous Chats")
# List existing chats as buttons
# List existing chats as buttons with a delete icon
for chat_file in chat_files:
chat_id = chat_file.replace(".json", "")
file_path = os.path.join(CHAT_DIR, chat_file)
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
if data:
# Get first user message
first_user_message = next(
(msg["content"] for msg in data if msg["role"] == "user"), "🆕 New Chat"
)
preview_line = first_user_message.strip().split("\n")[0]
truncated_preview = preview_line[:50] + ("..." if len(preview_line) > 50 else "")
# Generate keys
val = f"hist_{chat_id}"
delete_key = f"del_{chat_id}"
# Create side-by-side buttons
col1, col2 = st.columns([5, 1])
key = f"col_{chat_id}"
with st.container(key=key):
with col1:
if st.button(f"🗂 {truncated_preview}", key=val):
load_chat_history(chat_id)
st.session_state.show_overlay = False
st.rerun()
except (json.JSONDecodeError, FileNotFoundError):
pass # Skip invalid files
# Add your model description logic here
if st.button("",key ="btn-new"):
st.session_state.show_overlay = True
# Set new ID based on existing files
new_id = f"chat_{len(os.listdir(CHAT_DIR)) + 1}"
st.session_state.chat_id = new_id
st.session_state.messages = []
save_chat_history() # Save empty history to create the file
st.rerun()
with st.container(key="content_1"):
if st.button("",key ="create"):
st.session_state.show_overlay = True
st.rerun()
model_names = [m["model"] for m in st.session_state.models]
selected_model_name = st.selectbox(task, model_names)
selected_model = next((m for m in st.session_state.models if m["model"] == selected_model_name), None)
with st.expander("⚙️ Advanced Settings"):
temperature = st.slider("Temperature", 0.0, 2.0, 0.7, step=0.1)
top_p = st.slider("Top-p ", 0.0, 1.0, 0.9, step=0.05)
max_tokens = st.slider("Max tokens", 50, 1024, 512, step=50)
if st.session_state.show_overlay == True:
st.header(f"{text_h1} – What can I help you with?")
user_input = ''
if st.session_state.menu != "image":
if user_input := st.chat_input("Ask anything",key="imupload"):
st.session_state.user_input = user_input
st.session_state.show_overlay = False
# Add user message
# Add user message to history
st.session_state.messages.append({
"role": "user",
"content": user_input,
"image": st.session_state.save_path if st.session_state.menu == "image" else ""
})
# Simulate assistant response (replace with real AI later)
# Indicate that a response should be generated on the chat page
st.session_state.input_text = st.session_state.user_input
st.session_state.input_task = "text"
st.session_state.generate_response = True
st.rerun()
if st.session_state.menu == "image":
if prompts := st.chat_input(
"Say something and/or attach an image",
accept_file=True,
file_type=["jpg", "jpeg", "png"],key = "uploads"
): # Step 3: Open the image using PIL
files = prompts["files"]
text_input = prompts["text"]
# Optional image handling
image_path = ""
if files:
file = files[0]
image = Image.open(file)
save_dir = "saved_images"
os.makedirs(save_dir, exist_ok=True)
save_path = os.path.join(save_dir, file.name)
image.save(save_path)
st.session_state.save_path = save_path
image_path = save_path # So you can add it to messages
#st.session_state.show_overlay = False
st.session_state.show_overlay = False
# Add user message
st.session_state.messages.append({
"role": "user",
"content": image_path,
"image": st.session_state.save_path
})
st.session_state.input_text = st.session_state.save_path
st.session_state.input_task = "image"
# assistant response
# Indicate that a response should be generated on the chat page
st.session_state.generate_response = True
st.rerun()
with st.container(key="choices"):
col1,col2,col3,col4 = st.columns([1.5,0.1,1.5,1])
with col1:
if st.button(choice1,key="choice-1"):
st.session_state.user_input = choice1
if st.session_state.menu == "image":
st.session_state.messages.append({
"role": "user",
"content": images,
"image": images
})
st.session_state.input_task = "image"
st.session_state.input_text = images
# assistant response
# Indicate that a response should be generated on the chat page
else:
st.session_state.input_text = choice1
st.session_state.input_task = "text"
st.session_state.messages.append({
"role": "user",
"content": choice1,
"image":""
})
st.session_state.show_overlay = False
st.session_state.generate_response = True
st.rerun()
if st.button(choice2,key="choice-2"):
st.session_state.user_input = choice2
if st.session_state.menu == "image":
st.session_state.input_task = "image"
st.session_state.input_text = image1
st.session_state.messages.append({
"role": "user",
"content": image1,
"image": image1
})
else:
st.session_state.input_text = choice2
st.session_state.input_task = "text"
st.session_state.messages.append({
"role": "user",
"content": choice2,
"image":""
})
st.session_state.generate_response = True
st.session_state.show_overlay = False
st.rerun()
with col3:
if st.button(choice3,key="choice-5"):
st.session_state.user_input = choice3
if st.session_state.menu == "image":
st.session_state.input_task = "image"
st.session_state.input_text = image2
st.session_state.messages.append({
"role": "user",
"content": image2,
"image": image2
})
else:
st.session_state.input_text = choice3
st.session_state.input_task = "text"
st.session_state.messages.append({
"role": "user",
"content": choice3,
"image":""
})
st.session_state.generate_response = True
st.session_state.show_overlay = False
st.rerun()
if st.button(choice4,key="choice-6"):
st.session_state.user_input = choice4
if st.session_state.menu == "image":
st.session_state.input_task = "image"
st.session_state.input_text = image3
st.session_state.messages.append({
"role": "user",
"content": image3,
"image": image3
})
else:
st.session_state.input_text = choice4
st.session_state.input_task = "text"
st.session_state.messages.append({
"role": "user",
"content": choice4,
"image":""
})
st.session_state.generate_response = True
st.session_state.show_overlay = False
st.rerun()
if st.session_state.show_overlay == False:
def generate_stream_response(text):
# Yield the string one character at a time (for streaming)
for char in text:
yield char
time.sleep(0.02)
# Display chat messages from history on app rerun
if st.session_state.get("generate_response", True):
with st.spinner("generating output..."):
response = query_huggingface_model(
selected_model,
st.session_state.input_text,
input_type=st.session_state.input_task,
task=task,
temperature=temperature,top_p=top_p,max_tokens=max_tokens
)
if st.session_state.menu == "gen":
temper = temperature,
topp = top_p
else:
temper = "",
topp = ""
st.session_state.messages.append({
"role": "assistant",
"content": extract_response_content(response),
"image": "",
"model": selected_model['model'],
"temp":temper,
"top_p" : topp,
})
st.session_state.generate_response = False # Reset the flag
save_chat_history()
st.rerun()
for i, message in enumerate(st.session_state.messages):
con = message["role"]
container_key = f"{con}-{i}"
with st.container(key=container_key):
with st.chat_message(message["role"]):
if message["role"] == "assistant":
st.markdown(
f"**Model:** `{message['model']}`"
+ (
f"&nbsp;&nbsp;**Temperature:** `{message['temp']}`&nbsp;&nbsp;**Top-p:** `{message['top_p']}`"
if message.get('temp') and message.get('top_p') else ""
),
unsafe_allow_html=True
)
if message["image"] != "":
st.markdown(f"""<img src="data:image/png;base64,{base64.b64encode(open(message["image"],"rb").read()).decode()}" class="user-image" alt="Uploaded Image"> """,unsafe_allow_html=True,)
st.markdown(message["content"])
if st.session_state.menu == "image":
if prompts := st.chat_input(
"Say something and/or attach an image",
accept_file=True,
file_type=["jpg", "jpeg", "png"],key = "upload"
):
files = prompts["files"]
text_input = prompts["text"]
# Optional image handling
image_path = ""
if files:
file = files[0]
image = Image.open(file)
save_dir = "saved_images"
os.makedirs(save_dir, exist_ok=True)
save_path = os.path.join(save_dir, file.name)
image.save(save_path)
st.session_state.save_path = save_path
image_path = save_path # So you can add it to messages
# Show in chat window
with st.container(key="user-k"):
with st.chat_message("user"):
st.markdown(text_input)
if image_path:
st.markdown(f"""<img src="data:image/png;base64,{base64.b64encode(open(image_path,"rb").read()).decode()}" class="user-image" alt="Uploaded Image"> """,unsafe_allow_html=True,)
with st.container(key="assistant-k"):
# Display assistant response in chat message container
with st.chat_message("assistant"):
with st.spinner("Model is generating a response..."):
# Add message to history
result = query_huggingface_model(selected_model, st.session_state.save_path , input_type="image")
st.session_state.messages.append({
"role": "user",
"content": text_input,
"image": image_path
})
response = extract_response_content(result)
st.markdown(
f"**Model:** `{selected_model['model'] if isinstance(selected_model, dict) else selected_model}`"
f"{': temperature' + str(temperature) if st.session_state.menu == 'gen' else ''} "
f"{ 'Top-p:'+str( top_p) if st.session_state.menu == 'gen' else ''}"
)
print(response)
st.write_stream(generate_stream_response(response)) # This will stream the text one character at a time
# Add assistant response to chat history
if st.session_state.menu == "gen":
temper = temperature,
topp = top_p
else:
temper = "",
topp = ""
st.session_state.messages.append({"role": "assistant", "content": response,"image":"","model":selected_model['model'],"temp":temper,"top_p":topp})
save_chat_history()
else:
# Accept user input
if prompt := st.chat_input("Ask anything"):
# Display user message in chat message container
with st.container(key="user-k"):
with st.chat_message("user"):
st.markdown(prompt)
# Add user message to chat history
with st.container(key="assistant-k"):
# Display assistant response in chat message container
with st.chat_message("assistant"):
with st.spinner("Model is generating a response..."):
st.session_state.messages.append({"role": "user", "content": prompt,"image":""})
result = query_huggingface_model(selected_model, prompt , input_type="text",task=task,temperature=temperature,top_p=top_p,max_tokens=max_tokens)
st.markdown(
f"**Model:** `{selected_model['model'] if isinstance(selected_model, dict) else selected_model}`"
f"{':temperature ' + str(temperature) if st.session_state.menu == 'gen' else ''} "
f"{ 'Top-p:'+str( top_p) if st.session_state.menu == 'gen' else ''}"
)
response = extract_response_content(result)
st.write_stream(generate_stream_response(response)) # Add assistant response to chat history
if st.session_state.menu == "gen":
temper = temperature,
topp = top_p
else:
temper = "",
topp = ""
st.session_state.messages.append({"role": "assistant", "content": response,"image":"","model":selected_model['model'],"temp":temper,"top_p":topp})
save_chat_history()