Spaces:
Sleeping
Sleeping
File size: 6,309 Bytes
5b6e956 c078ea1 5b6e956 c078ea1 5b6e956 c078ea1 5b6e956 c078ea1 5b6e956 c078ea1 5b6e956 c078ea1 5b6e956 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
"""
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()
|