Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dotenv import load_dotenv
|
2 |
+
import streamlit as st
|
3 |
+
import os
|
4 |
+
import google.generativeai as genai
|
5 |
+
from PIL import Image
|
6 |
+
|
7 |
+
# Configure page
|
8 |
+
st.set_page_config(page_title="OtakuOracle ๐", layout="wide")
|
9 |
+
|
10 |
+
# Custom CSS for styling
|
11 |
+
st.markdown("""
|
12 |
+
<style>
|
13 |
+
.stApp {
|
14 |
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
15 |
+
color: #ffffff;
|
16 |
+
}
|
17 |
+
.stButton button {
|
18 |
+
background-color: #ff6b6b;
|
19 |
+
color: white;
|
20 |
+
border-radius: 10px;
|
21 |
+
transition: all 0.3s ease;
|
22 |
+
}
|
23 |
+
.stButton button:hover {
|
24 |
+
background-color: #ff8787;
|
25 |
+
transform: translateY(-2px);
|
26 |
+
box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4);
|
27 |
+
}
|
28 |
+
.sidebar .sidebar-content {
|
29 |
+
background: rgba(26, 26, 46, 0.9);
|
30 |
+
}
|
31 |
+
.stTextInput input {
|
32 |
+
border-radius: 8px;
|
33 |
+
border: 2px solid #4a90e2;
|
34 |
+
}
|
35 |
+
.css-1d391kg {
|
36 |
+
background-color: rgba(255, 255, 255, 0.05);
|
37 |
+
border-radius: 15px;
|
38 |
+
padding: 20px;
|
39 |
+
margin: 10px 0;
|
40 |
+
}
|
41 |
+
</style>
|
42 |
+
""", unsafe_allow_html=True)
|
43 |
+
|
44 |
+
# API Key input in sidebar
|
45 |
+
api_key = st.sidebar.text_input("Enter Google API Key ๐", type="password")
|
46 |
+
if not api_key:
|
47 |
+
st.warning("โ ๏ธ Please enter your Google API Key to use the app")
|
48 |
+
st.stop()
|
49 |
+
|
50 |
+
# Configure Gemini with provided API key
|
51 |
+
genai.configure(api_key=api_key)
|
52 |
+
|
53 |
+
def get_anime_recommendations(anime_title):
|
54 |
+
query = f"Give me 5 anime recommendations similar to {anime_title} with the following details: Anime, Genre, Main Protagonists, Summary."
|
55 |
+
response = chat.send_message(query, stream=True)
|
56 |
+
full_response = ""
|
57 |
+
for chunk in response:
|
58 |
+
full_response += chunk.text
|
59 |
+
return full_response
|
60 |
+
|
61 |
+
def format_anime_recommendation(text):
|
62 |
+
recommendations = text.split('\n\n')
|
63 |
+
formatted_recommendations = []
|
64 |
+
for rec in recommendations:
|
65 |
+
lines = rec.split('\n')
|
66 |
+
if len(lines) >= 4:
|
67 |
+
anime = lines[0].replace("Anime:", "").strip()
|
68 |
+
genre = lines[1].replace("Genre:", "").strip()
|
69 |
+
protagonists = lines[2].replace("Main Protagonists:", "").strip()
|
70 |
+
summary = lines[3].replace("Summary:", "").strip()
|
71 |
+
formatted_recommendations.append({
|
72 |
+
"Anime": anime,
|
73 |
+
"Genre": genre,
|
74 |
+
"Main Protagonists": protagonists,
|
75 |
+
"Summary": summary
|
76 |
+
})
|
77 |
+
return formatted_recommendations
|
78 |
+
|
79 |
+
def get_anime_character_response(character, question):
|
80 |
+
query = f"Respond to the following question in the style of the anime character {character}: {question}"
|
81 |
+
response = chat.send_message(query, stream=True)
|
82 |
+
full_response = ""
|
83 |
+
for chunk in response:
|
84 |
+
full_response += chunk.text
|
85 |
+
return full_response
|
86 |
+
|
87 |
+
def get_gemini_response(input, image, prompt):
|
88 |
+
model = genai.GenerativeModel('gemini-1.5-flash')
|
89 |
+
response = model.generate_content([input, image[0], prompt])
|
90 |
+
return response.text
|
91 |
+
|
92 |
+
def input_image_setup(uploaded_file):
|
93 |
+
if uploaded_file is not None:
|
94 |
+
bytes_data = uploaded_file.getvalue()
|
95 |
+
image_parts = [
|
96 |
+
{
|
97 |
+
"mime_type": uploaded_file.type,
|
98 |
+
"data": bytes_data
|
99 |
+
}
|
100 |
+
]
|
101 |
+
return image_parts
|
102 |
+
else:
|
103 |
+
raise FileNotFoundError("No file uploaded")
|
104 |
+
|
105 |
+
def load_animation():
|
106 |
+
with st.spinner('๐ Processing...'):
|
107 |
+
st.balloons()
|
108 |
+
|
109 |
+
# Initialize the Gemini Pro model
|
110 |
+
chat = genai.GenerativeModel("gemini-1.5-flash-002")
|
111 |
+
chat = chat.start_chat(history=[])
|
112 |
+
|
113 |
+
# Sidebar navigation
|
114 |
+
st.sidebar.markdown("## Navigation Menu ๐ฎ")
|
115 |
+
page = st.sidebar.selectbox("Select Service",
|
116 |
+
["Anime Recommender ๐", "Talk to Anime Character ๐ฃ๏ธ", "Anime Face Detect ๐"])
|
117 |
+
|
118 |
+
# Anime Recommender Page
|
119 |
+
if page == "Anime Recommender ๐":
|
120 |
+
st.markdown("# ๐ฌ Anime Recommender System")
|
121 |
+
st.markdown("---")
|
122 |
+
|
123 |
+
input_anime = st.text_input("Input Anime Title: ",
|
124 |
+
key="input_anime",
|
125 |
+
help="Enter the title of an anime you like!")
|
126 |
+
|
127 |
+
if st.button("Get Recommendations ๐"):
|
128 |
+
if input_anime:
|
129 |
+
load_animation()
|
130 |
+
response = get_anime_recommendations(input_anime)
|
131 |
+
recommendations = format_anime_recommendation(response)
|
132 |
+
|
133 |
+
st.subheader("Anime Recommendations ๐")
|
134 |
+
for rec in recommendations:
|
135 |
+
with st.container():
|
136 |
+
st.markdown(f"""
|
137 |
+
**Anime:** {rec['Anime']} ๐บ
|
138 |
+
**Genre:** {rec['Genre']} ๐ญ
|
139 |
+
**Main Protagonists:** {rec['Main Protagonists']} ๐งโ๐คโ๐ง
|
140 |
+
**Summary:** {rec['Summary']} ๐
|
141 |
+
---
|
142 |
+
""")
|
143 |
+
|
144 |
+
# Anime Character Chat Page
|
145 |
+
elif page == "Talk to Anime Character ๐ฃ๏ธ":
|
146 |
+
st.markdown("# ๐ฌ Chat with an Anime Character")
|
147 |
+
st.markdown("---")
|
148 |
+
|
149 |
+
character = st.text_input("Anime Character Name:",
|
150 |
+
help="Enter character name!")
|
151 |
+
question = st.text_input("Your Question:",
|
152 |
+
help="Ask your question!")
|
153 |
+
|
154 |
+
if st.button("Ask Character ๐จ๏ธ"):
|
155 |
+
if character and question:
|
156 |
+
load_animation()
|
157 |
+
response = get_anime_character_response(character, question)
|
158 |
+
st.markdown(f"### Response from {character} ๐ญ")
|
159 |
+
st.write(response)
|
160 |
+
|
161 |
+
# Anime Face Detect Page
|
162 |
+
elif page == "Anime Face Detect ๐":
|
163 |
+
st.markdown("# ๐ต๏ธ Anime Character Detector")
|
164 |
+
st.markdown("---")
|
165 |
+
|
166 |
+
input_prompt = """
|
167 |
+
You are an expert in the world of Anime where you need to see characters from the image and provide the details of every character in this below format:
|
168 |
+
|
169 |
+
1. Name of the Character(s):
|
170 |
+
2. Anime:
|
171 |
+
3. Role:
|
172 |
+
4. Favourite Habit:
|
173 |
+
|
174 |
+
If there are multiple characters then mention them separately in the above format
|
175 |
+
|
176 |
+
Note: If you don't find the character related to any Anime then kindly tell the user to provide an Anime character picture in this below format:
|
177 |
+
'Kindly provide a character from Anime'
|
178 |
+
"""
|
179 |
+
|
180 |
+
input_text = st.text_input("Input Prompt:",
|
181 |
+
help="Enter custom prompt!")
|
182 |
+
uploaded_file = st.file_uploader("Choose an image... ๐ท",
|
183 |
+
type=["jpg", "jpeg", "png"])
|
184 |
+
|
185 |
+
if uploaded_file:
|
186 |
+
image = Image.open(uploaded_file)
|
187 |
+
st.image(image, caption="Uploaded Image ๐ผ๏ธ", use_column_width=True)
|
188 |
+
|
189 |
+
if st.button("Analyze Character ๐"):
|
190 |
+
load_animation()
|
191 |
+
image_data = input_image_setup(uploaded_file)
|
192 |
+
response = get_gemini_response(input_text, image_data, input_prompt)
|
193 |
+
st.markdown("### Analysis Results ๐")
|
194 |
+
st.write(response)
|