import os os.environ["XDG_CONFIG_HOME"] = os.path.join(os.getcwd(), ".config") import streamlit as st import pandas as pd import openai import time # --- CONFIG --- st.set_page_config(page_title="🖼️ Alt Text Generator", layout="wide") VALID_IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"] st.title("🖼️ Alt Text Generator") st.markdown("Generate SEO-friendly alt text for image URLs using GPT-4o Vision.\nMade by [Florian Potier](https://twitter.com/FloPots)") # --- INPUT API KEY --- api_key = st.text_input("🔑 Enter your OpenAI API key", type="password") if not api_key: st.stop() client = openai.OpenAI(api_key=api_key) # --- INPUT FILE --- uploaded_file = st.file_uploader("📁 Upload a CSV with image URLs", type=["csv"]) if uploaded_file: df = pd.read_csv(uploaded_file) st.success("✅ File uploaded successfully") st.dataframe(df.head()) # --- COLUMN SELECT --- image_col = st.selectbox("🧭 Select the column with image URLs", df.columns) # --- PROMPT INPUT --- prompt_instruction = st.text_area("📝 Enter the prompt to generate alt text", value="Write a concise, SEO-friendly alt text for the image below. Do not use brand names unless visible.") def is_valid_image_url(url: str): return any(url.lower().endswith(ext) for ext in VALID_IMAGE_EXTENSIONS) df["Valid Image"] = df[image_col].astype(str).apply(is_valid_image_url) valid_df = df[df["Valid Image"] == True] if valid_df.empty: st.error("❌ No valid image URLs found. Make sure URLs end with .jpg, .png, .webp, etc.") st.stop() st.info(f"🔍 {len(valid_df)} valid image URLs found. Invalid ones will be skipped.") # --- PROCESS --- if st.button("🚀 Start Processing"): progress = st.progress(0) results = [] urls = valid_df[image_col].tolist() for idx, url in enumerate(urls): try: response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "user", "content": [ {"type": "text", "text": prompt_instruction}, {"type": "image_url", "image_url": {"url": url}} ] } ] ) alt_text = response.choices[0].message.content.strip() except Exception as e: alt_text = f"ERROR: {e}" results.append(alt_text) progress.progress((idx + 1) / len(urls)) time.sleep(1) valid_df["Generated Alt Text"] = results output_df = df.copy() output_df.loc[valid_df.index, "Generated Alt Text"] = valid_df["Generated Alt Text"] st.success("✅ Done! Preview of the results:") st.dataframe(output_df[[image_col, "Generated Alt Text"]].head()) csv = output_df.to_csv(index=False).encode("utf-8") st.download_button("📥 Download CSV with Alt Text", csv, "alt_text_output.csv", "text/csv")