""" Character Forge - Main Application Entry Point =============================================== License: GNU AGPL v3.0 Copyright (C) 2025 Gregor Hubert, Max Koch "cronos3k" This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Main entry point for the Character Forge Streamlit application. Run with: streamlit run app.py """ import streamlit as st from pathlib import Path # Import configuration from config.settings import Settings # Import components from ui.components.backend_selector import render_backend_selector from ui.components.status_display import render_status_display def initialize_session_state(): """ Initialize Streamlit session state with default values. Session state is Streamlit's way of persisting data across reruns. This function sets up all the global state our app needs. """ # Backend selection if 'backend' not in st.session_state: st.session_state.backend = "Gemini API (Cloud)" # API keys if 'gemini_api_key' not in st.session_state: st.session_state.gemini_api_key = Settings.get_gemini_api_key() # Output directory if 'output_dir' not in st.session_state: st.session_state.output_dir = Settings.OUTPUT_DIR # Generation history if 'history' not in st.session_state: st.session_state.history = [] def render_header(): """Render the application header and global controls.""" st.set_page_config( page_title="Character Forge - AI Image Generation", page_icon="🔥", layout="wide", initial_sidebar_state="expanded" ) st.title("🔥 Character Forge - AI Image Generation") st.markdown( """ **Professional character sheets and multi-image composition powered by AI** *Supports Gemini API, OmniGen2, and ComfyUI backends* """ ) # Show API key warning if not configured if not st.session_state.get('gemini_api_key'): st.warning( "⚠️ **API Key Required**: Please enter your Gemini API key in the sidebar to start generating. " "Get a free API key at [Google AI Studio](https://aistudio.google.com/app/apikey).", icon="🔑" ) st.divider() def render_global_backend_selector(): """ Render the global backend selector that applies to all pages. This is one of the key improvements over Gradio - no parameter drilling! The backend selection is stored in session_state and accessible everywhere. """ st.subheader("🔧 Generation Backend") col1, col2 = st.columns([2, 1]) with col1: # Render the backend selector component backend = render_backend_selector() st.session_state.backend = backend with col2: # Render status display if st.button("🔄 Refresh Status"): st.rerun() st.divider() def render_sidebar(): """Render the sidebar with navigation and settings.""" with st.sidebar: st.image("https://via.placeholder.com/150x150.png?text=🍌", width=150) st.markdown("## Navigation") st.page_link("pages/01_🔥_Character_Forge.py", label="🔥 Character Forge") st.page_link("pages/02_🎬_Composition_Assistant.py", label="🎬 Composition Assistant") st.page_link("pages/03_📸_Standard_Interface.py", label="📸 Standard Interface") st.divider() st.markdown("## Settings") # API Key input (for Gemini) st.markdown("### 🔑 API Key") st.info("Get your FREE API key at [Google AI Studio](https://aistudio.google.com/app/apikey)") api_key = st.text_input( "Gemini API Key", value=st.session_state.gemini_api_key or "", type="password", help="Enter your Google Gemini API key. Required for Gemini backend. Your key stays in YOUR session only.", placeholder="Enter your API key here..." ) if api_key != st.session_state.gemini_api_key: st.session_state.gemini_api_key = api_key # Output directory st.text_input( "Output Directory", value=str(st.session_state.output_dir), disabled=True, help="All generated images are saved here" ) st.divider() st.markdown("## About") st.markdown( """ **Character Forge** v1.0.0 Multi-backend AI image generation with specialized tools for: - Character sheet creation - Multi-image composition - Text/image-to-image generation --- **License:** GNU AGPL v3.0 **Privacy:** Your API key is stored only in YOUR session. It is never shared with other users. **Get Started:** - [Get API Key](https://aistudio.google.com/app/apikey) - [HuggingFace Space](https://huggingface.co/spaces/ghmk/character_forge) """ ) def main(): """Main application entry point.""" # Initialize session state initialize_session_state() # Render header render_header() # Render global backend selector render_global_backend_selector() # Render sidebar render_sidebar() # Main content area st.info( """ 👈 **Select a tool from the sidebar to get started:** - **🔥 Character Forge**: Create multi-angle character sheets automatically - **🎬 Composition Assistant**: Smart multi-image composition with auto-prompts - **📸 Standard Interface**: Direct text-to-image and image-to-image generation The backend selector above applies to all tools. """ ) # Show recent generations if st.session_state.history: st.subheader("📸 Recent Generations") cols = st.columns(4) for idx, item in enumerate(st.session_state.history[-4:]): with cols[idx]: st.image(item['image'], caption=item['name'], use_container_width=True) if __name__ == "__main__": main()