CoolFace
Apppublic

AiCodeCraft/Gemini-Interface-Deluxe

sourceHugging Facemitupdated 11mo agoView on Hugging Face
1likes
22222_app.py237 linesDownload Raw Back to root
1import streamlit as st2import google.generativeai as genai3from PIL import Image4import io5import base646import pandas as pd7import zipfile8import PyPDF29 10# Konfiguration der Seite11st.set_page_config(page_title="Gemini AI Chat", layout="wide")12 13st.title("🤖 Gemini AI Chat Interface")14st.markdown("""15**Welcome to the Gemini AI Chat Interface!**16Chat seamlessly with Google's advanced Gemini AI models, supporting multiple input types.17🔗 [GitHub Profile](https://github.com/volkansah) | 18📂 [Project Repository](https://github.com/volkansah/gemini-ai-chat) | 19💬 [Soon](https://aicodecraft.io)20""")21 22# Session State Management23if "messages" not in st.session_state:24    st.session_state.messages = []25if "uploaded_content" not in st.session_state:26    st.session_state.uploaded_content = None27 28# Funktionen zur Dateiverarbeitung29def encode_image(image):30    buffered = io.BytesIO()31    image.save(buffered, format="JPEG")32    return base64.b64encode(buffered.getvalue()).decode('utf-8')33 34def process_file(uploaded_file):35    """Verarbeitet die hochgeladene Datei und extrahiert den Inhalt."""36    file_type = uploaded_file.name.split('.')[-1].lower()37    38    # Text-basierte Erweiterungen für ZIP-Verarbeitung39    text_extensions = ('.txt', '.csv', '.py', '.html', '.js', '.css', 40                       '.php', '.json', '.xml', '.c', '.cpp', '.java', 41                       '.cs', '.rb', '.go', '.ts', '.swift', '.kt', '.rs', '.sh', '.sql', '.xlsx')42    43    if file_type in ["jpg", "jpeg", "png"]:44        return {"type": "image", "content": Image.open(uploaded_file).convert('RGB')}45    46    if file_type in ["txt"] + [ext.strip('.') for ext in text_extensions if ext not in ('.csv', '.xlsx')]:47        return {"type": "text", "content": uploaded_file.read().decode("utf-8", errors='ignore')}48    49    if file_type in ["csv", "xlsx"]:50        try:51            # Versuch, Datei als CSV oder Excel zu lesen52            if file_type == "csv":53                df = pd.read_csv(uploaded_file)54            else: # xlsx55                df = pd.read_excel(uploaded_file)56            return {"type": "text", "content": df.to_string()}57        except Exception as e:58            return {"type": "error", "content": f"Failed to read tabular data: {e}"}59    60    if file_type == "pdf":61        try:62            reader = PyPDF2.PdfReader(uploaded_file)63            return {"type": "text", "content": "".join(page.extract_text() for page in reader.pages if page.extract_text())}64        except Exception as e:65             return {"type": "error", "content": f"Failed to read PDF: {e}"}66    67    if file_type == "zip":68        try:69            with zipfile.ZipFile(uploaded_file) as z:70                newline = "\n"71                content = f"ZIP Contents (Processing text files only):{newline}"72                73                for file_info in z.infolist():74                    if not file_info.is_dir():75                        try:76                            # Prüfen, ob die Datei eine Text-Erweiterung hat77                            if file_info.filename.lower().endswith(text_extensions):78                                with z.open(file_info.filename) as file:79                                    # Decode mit 'ignore', falls es Probleme gibt80                                    file_content = file.read().decode('utf-8', errors='ignore')81                                    content += f"{newline}📄 {file_info.filename}:{newline}{file_content}{newline}"82                            else:83                                content += f"{newline}⚠️ Binärdatei/Unbekannte Datei ignoriert: {file_info.filename}{newline}"84                        except Exception as e:85                            content += f"{newline}❌ Fehler beim Lesen von {file_info.filename}: {str(e)}{newline}"86                87                return {"type": "text", "content": content}88        except Exception as e:89            return {"type": "error", "content": f"Failed to process ZIP: {e}"}90    91    return {"type": "error", "content": "Unsupported file format"}92 93# Sidebar für Einstellungen94with st.sidebar:95    api_key = st.text_input("Google AI API Key", type="password")96    97    # Modell-Liste bereinigt und auf die neuesten 2.5-Modelle fokussiert98    model_list = [99        # --- Aktuelle Flaggschiffe (Standard & Pro) ---100        "gemini-2.5-flash",       # Standard, schnell, multimodal (Vision-fähig)101        "gemini-2.5-pro",         # Flagship, bestes Reasoning, multimodal (Vision-fähig)102        103        # --- Vorherige Generation (als Fallback/Alternative) ---104        "gemini-1.5-flash",       105        "gemini-1.5-pro",         106        107        # --- Legacy-Modelle (Text-only oder ältere Endpunkte) ---108        "gemini-2.0-flash",       109        "gemini-1.0-pro",         # Älterer stabiler Endpunkt110    ]111    112    model = st.selectbox("Model", model_list)113    114    # Wichtiger Hinweis: 2.5er Modelle sind standardmäßig Vision-fähig115    st.caption("❗ Alle **2.5er** Modelle sind **Vision-fähig** (Bilder, Dateien).")116    117    temperature = st.slider("Temperature", 0.0, 1.0, 0.7)118    max_tokens = st.slider("Max Tokens", 1, 100000, 1000)119# Datei-Upload-Kontrolle120uploaded_file = st.file_uploader("Upload File (Image/Text/PDF/ZIP)", 121                                 type=["jpg", "jpeg", "png", "txt", "pdf", "zip", 122                                       "csv", "xlsx", "html", "css", "php", "js", "py"])123 124# Logik zur Dateiverarbeitung und Vorschau125if uploaded_file and st.session_state.uploaded_content is None:126    # Nur verarbeiten, wenn eine neue Datei hochgeladen wird und kein Inhalt im State ist127    processed = process_file(uploaded_file)128    st.session_state.uploaded_content = processed129 130# Vorschau anzeigen, wenn Inhalt vorhanden131if st.session_state.uploaded_content:132    processed = st.session_state.uploaded_content133    134    st.subheader("Current File Attachment:")135    136    if processed["type"] == "image":137        st.image(processed["content"], caption="Attached Image", use_container_width=False, width=300)138    elif processed["type"] == "text":139        st.text_area("File Preview", processed["content"], height=150)140    elif processed["type"] == "error":141         st.error(f"Error processing file: {processed['content']}")142    143    # NEU: Clear Button144    if st.button("❌ Clear Uploaded File Attachment"):145        st.session_state.uploaded_content = None146        # Da st.file_uploader selbst nicht einfach resettet,147        # informieren wir den Nutzer, dass der Zustand gelöscht ist.148        st.info("Attachment cleared! Reload the page to reset the upload field completely.")149 150 151# Chat-Historie anzeigen152for message in st.session_state.messages:153    with st.chat_message(message["role"]):154        st.markdown(message["content"])155 156# Chat-Eingabe verarbeiten157if prompt := st.chat_input("Your message..."):158    if not api_key:159        st.warning("API Key benötigt!")160        st.stop()161    162    # NEU: Spinner hinzugefügt163    with st.spinner("Gemini is thinking..."):164        try:165            # API konfigurieren166            genai.configure(api_key=api_key)167            168            # Modell auswählen169            model_instance = genai.GenerativeModel(model)170            171            # Inhalt vorbereiten172            content = [{"text": prompt}]173            174            # Dateiinhalt hinzufügen175            if st.session_state.uploaded_content:176                if st.session_state.uploaded_content["type"] == "image":177                    # Überprüfung, ob ein Vision-Modell ausgewählt ist178                    if "vision" not in model.lower() and "pro" not in model.lower():179                        st.error("Bitte ein Vision- oder Pro-Modell für Bilder auswählen!")180                        st.stop()181                    182                    content.append({183                        "inline_data": {184                            "mime_type": "image/jpeg",185                            "data": encode_image(st.session_state.uploaded_content["content"])186                        }187                    })188                elif st.session_state.uploaded_content["type"] == "text":189                    # Text-Inhalt dem Prompt hinzufügen190                    content[0]["text"] += f"\n\n[Attached File Content]\n{st.session_state.uploaded_content['content']}"191            192            # Nachricht zur Historie hinzufügen und anzeigen193            st.session_state.messages.append({"role": "user", "content": prompt})194            with st.chat_message("user"):195                st.markdown(prompt)196            197            # Antwort generieren198            response = model_instance.generate_content(199                content,200                generation_config=genai.types.GenerationConfig(201                    temperature=temperature,202                    max_output_tokens=max_tokens203                )204            )205            206            # Überprüfen, ob die Antwort gültig ist207            if not response.candidates:208                st.error("API Error: Keine gültige Antwort erhalten. Überprüfe die Eingabe oder das Modell.")209            else:210                # Antwort anzeigen und zur Historie hinzufügen211                response_text = response.text212                with st.chat_message("assistant"):213                    st.markdown(response_text)214                st.session_state.messages.append({"role": "assistant", "content": response_text})215            216        except Exception as e:217            st.error(f"API Error: {str(e)}")218            # Zusätzliche Überprüfung für Visionsfehler219            if st.session_state.uploaded_content and st.session_state.uploaded_content["type"] == "image" and "vision" not in model.lower() and "pro" not in model.lower():220                st.error("Detail-Fehler: Für Bilder MUSS ein Vision-fähiger Modell (z.B. 1.5 Pro) ausgewählt werden.")221 222# Instructions in the sidebar223with st.sidebar:224    st.markdown("""225    ---226    ## 📝 Instructions:227    1. Enter your Google AI API key228    2. Select a model (use **Pro/Vision** models for image analysis)229    3. Adjust parameters (Temperature/Tokens)230    4. Upload a file (optional, supports **Image, Text, PDF, ZIP, CSV/XLSX**)231    5. Type your message and press Enter232    233    ### About234    🔗 [GitHub Profile](https://github.com/volkansah) | 235    📂 [Project Repository](https://github.com/volkansah/gemini-ai-chat) | 236    💬 [Soon](https://aicodecraft.io)237    """)