MatteoScript commited on
Commit
c368803
·
verified ·
1 Parent(s): 2b7e894

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -18
app.py CHANGED
@@ -2,14 +2,85 @@ import streamlit as st
2
  import time
3
  import base64
4
  import io
 
5
  from PIL import Image
6
  from together import Together
7
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  # Funzione per generare le immagini, con gestione errori e retry dopo 10 secondi
10
  def generate_image(prompt, max_retries=5):
11
- api_key = os.getenv('API_REPLIACATE')
12
- client = Together(api_key = api_key)
13
  retries = 0
14
  while retries < max_retries:
15
  try:
@@ -30,40 +101,84 @@ def generate_image(prompt, max_retries=5):
30
  st.error("Numero massimo di tentativi raggiunto. Impossibile generare le immagini.")
31
  return None
32
 
33
- def generate_images(prompt, num_immagini):
 
 
 
 
 
 
34
  for numero in range(num_immagini):
35
  images_data = generate_image(prompt)
36
  if images_data is not None:
37
  for i, img_obj in enumerate(images_data):
38
  try:
39
  image_bytes = base64.b64decode(img_obj.b64_json)
40
- image = Image.open(io.BytesIO(image_bytes))
41
  st.image(image, caption="")
 
 
 
42
  except Exception as e:
43
  st.error(f"Errore nella visualizzazione dell'immagine {i+1}: {e}")
44
  else:
45
  st.error("Non è stato possibile generare le immagini. Riprova più tardi.")
46
  time.sleep(5)
47
- st.success("Immagini generate con successo!")
48
 
49
  def main():
50
- st.title("AI Imaging")
51
  st.sidebar.header("Impostazioni")
52
- stile_default = "Highly detailed, painterly style with a historical yet stylized aesthetic. Rich textures, ornate patterns, and a color palette dominated by imperial gold, deep red, and aged marble tones. Inspired by ancient Roman mosaics, frescoes, and classical sculpture, with a balanced mix of realism and stylization. Elegant, decorative card borders with intricate engravings and antique flourishes. Designed for a tabletop card game, ensuring clarity, readability, and a visually immersive experience."
 
 
 
 
 
53
  stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
54
- prompt_input = st.sidebar.text_area("Prompt Immagine")
55
- num_immagini = st.sidebar.slider("Variazioni", min_value=1, max_value=6, value=2)
56
- submit_button = st.sidebar.button(label="Genera Immagine", type = "primary", use_container_width=True)
57
- st.write("Inserisci il **Prompt** (che verrà unito allo stile) e clicca su *Genera Immagine*.")
 
 
 
 
 
58
  if submit_button:
59
- if not prompt_input.strip():
60
  st.error("Per favore, inserisci un prompt per l'immagine!")
 
 
 
 
 
 
 
 
 
 
61
  else:
62
- # Combiniamo il prompt inserito con lo stile fisso
63
- prompt_completo = f"{prompt_input}, {stile_immagine}"
64
-
65
- st.info("Generazione in corso, attendere...")
66
- generate_images(prompt_completo, num_immagini)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  if __name__ == "__main__":
69
- main()
 
 
2
  import time
3
  import base64
4
  import io
5
+ import zipfile
6
  from PIL import Image
7
  from together import Together
8
  import os
9
+ from dotenv import load_dotenv
10
+ from pydantic import BaseModel
11
+ from openai import OpenAI
12
+ import pandas as pd
13
+
14
+ load_dotenv()
15
+ api_together = os.getenv("TOGETHER_API_KEY")
16
+ api_gemini = os.getenv("API_GEMINI")
17
+ MODEL = "gemini-2.0-flash-exp"
18
+ clientOpenAI = OpenAI(
19
+ api_key=api_gemini,
20
+ base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
21
+ )
22
+
23
+ # Definizione dello schema Pydantic per un personaggio
24
+ class Character(BaseModel):
25
+ nome: str
26
+ classe: str
27
+ forza: int
28
+ destrezza: int
29
+ intelligenza: int
30
+ descrizione: str
31
+ english_description:str
32
+
33
+ # Definizione dello schema per la risposta contenente una lista di personaggi
34
+ class CharactersResponse(BaseModel):
35
+ personaggi: list[Character]
36
+
37
+ def generate_story(character: Character):
38
+ response = clientOpenAI.chat.completions.create(
39
+ model=MODEL,
40
+ n=1,
41
+ stream=True,
42
+ messages=[
43
+ {"role": "system", "content": "Tu sei un creatore di giochi di ruolo a CARTE. Crea un regolamento per un gioco di ruolo sul SACRO ROMANO IMPERO sulla base dei personaggi che ti fornirò"},
44
+ {
45
+ "role": "user",
46
+ "content": f"Ecco i personaggi del gioco di RUOLO a carte. Crea un regolamento!!! {character.model_dump_json()}"
47
+ }
48
+ ]
49
+ )
50
+ story = ""
51
+ st.subheader('Regole 📜')
52
+ placeholder = st.empty()
53
+ for chunk in response:
54
+ if chunk.choices[0].delta.content is not None:
55
+ text_chunk = chunk.choices[0].delta.content
56
+ story += text_chunk
57
+ placeholder.markdown(story)
58
+ print(story)
59
+ return story
60
+
61
+ def generate_ai(num_personaggi):
62
+ # Costruzione del prompt in italiano per generare i personaggi
63
+ prompt = (
64
+ f"Genera {num_personaggi} personaggi per un gioco di ruolo a carte ambientato nel Sacro Romano Impero. "
65
+ "Ogni personaggio deve avere i seguenti campi specificati nel modello. "
66
+ "Restituisci il risultato in formato JSON seguendo lo schema fornito")
67
+
68
+ # Esecuzione della chiamata all'API utilizzando il formato response_format
69
+ completion = clientOpenAI.beta.chat.completions.parse(
70
+ model=MODEL,
71
+ messages=[
72
+ {"role": "system", "content": "Sei un assistente utile per la generazione di personaggi per un gioco di RUOLO sul SACRO ROMANO IMPERO."},
73
+ {"role": "user", "content": prompt},
74
+ ],
75
+ response_format=CharactersResponse,
76
+ )
77
+ characters_response = completion.choices[0].message.parsed
78
+ print(characters_response)
79
+ return characters_response
80
 
81
  # Funzione per generare le immagini, con gestione errori e retry dopo 10 secondi
82
  def generate_image(prompt, max_retries=5):
83
+ client = Together(api_key=api_together)
 
84
  retries = 0
85
  while retries < max_retries:
86
  try:
 
101
  st.error("Numero massimo di tentativi raggiunto. Impossibile generare le immagini.")
102
  return None
103
 
104
+ def generate_images(character: Character, stile_immagine, num_immagini):
105
+ # Lista per salvare le immagini generate come tuple (nome_file, bytes)
106
+ prompt = f"{character.english_description} {stile_immagine}"
107
+ images_bytes_list = []
108
+ if character.nome != "":
109
+ st.subheader(f"{character.nome} 🦸‍♂️")
110
+ st.markdown(f"- **Classe:** {character.classe}\n- **Forza:** {character.forza}\n- **Destrezza:** {character.destrezza}\n- **Intelligenza:** {character.intelligenza}\n- **Descrizione:** {character.descrizione}", unsafe_allow_html=True)
111
  for numero in range(num_immagini):
112
  images_data = generate_image(prompt)
113
  if images_data is not None:
114
  for i, img_obj in enumerate(images_data):
115
  try:
116
  image_bytes = base64.b64decode(img_obj.b64_json)
117
+ image = Image.open(io.BytesIO(image_bytes))
118
  st.image(image, caption="")
119
+ img_byte_arr = io.BytesIO()
120
+ image.save(img_byte_arr, format='PNG')
121
+ images_bytes_list.append((f"image_{numero+1}_{i+1}.png", img_byte_arr.getvalue()))
122
  except Exception as e:
123
  st.error(f"Errore nella visualizzazione dell'immagine {i+1}: {e}")
124
  else:
125
  st.error("Non è stato possibile generare le immagini. Riprova più tardi.")
126
  time.sleep(5)
127
+ return images_bytes_list
128
 
129
  def main():
130
+ st.title("Imperium AI 🏰")
131
  st.sidebar.header("Impostazioni")
132
+ stile_default = ("Highly detailed, painterly style with a historical yet stylized aesthetic. "
133
+ "Rich textures, ornate patterns, and a color palette dominated by imperial gold, "
134
+ "deep red, and aged marble tones. Inspired by ancient Roman mosaics, frescoes, "
135
+ "and classical sculpture, with a balanced mix of realism and stylization. "
136
+ "Elegant, decorative card borders with intricate engravings and antique flourishes. "
137
+ "Designed for a tabletop card game, ensuring clarity, readability, and a visually immersive experience.")
138
  stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
139
+ auto = False
140
+ prompt_input = st.sidebar.text_input("Prompt Immagine (in inglese)", value="Roman Soldier", disabled=auto)
141
+ auto = st.sidebar.toggle(label= 'Generazione automatica')
142
+ num_personaggi = st.sidebar.slider("Personaggi", min_value=1, max_value=30, value=5, disabled=not auto)
143
+ num_immagini = st.sidebar.slider("Variazioni Immagini", min_value=1, max_value=6, value=2)
144
+ submit_button = st.sidebar.button(label="Genera Immagine", type="primary", use_container_width=True)
145
+
146
+ st.write("Forgia il tuo **destino nell'Impero**: crea, combatti e domina con nel più grande gioco di ruolo a carte generato dall'AI")
147
+
148
  if submit_button:
149
+ if not prompt_input.strip() and not auto:
150
  st.error("Per favore, inserisci un prompt per l'immagine!")
151
+ return
152
+ if auto:
153
+ with st.spinner('Generazione Personaggi'):
154
+ characters = generate_ai(num_personaggi)
155
+ st.subheader('Personaggi 🎭')
156
+ df = pd.DataFrame([{k: v for k, v in character.model_dump().items() if k != "english_description"} for character in characters.personaggi])
157
+ st.dataframe(df, hide_index=True)
158
+ st.divider()
159
+ generate_story(characters)
160
+ st.divider()
161
  else:
162
+ characters = CharactersResponse(personaggi=[Character(nome="", classe="Guerriero", forza=10, destrezza=8, intelligenza=6, descrizione="Un forte guerriero", english_description=prompt_input)])
163
+ with st.spinner('Generazione Immagini'):
164
+ images = []
165
+ for character in characters.personaggi:
166
+ images.extend(generate_images(character, stile_immagine, num_immagini))
167
+ if images:
168
+ zip_buffer = io.BytesIO()
169
+ with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
170
+ for file_name, file_bytes in images:
171
+ zip_file.writestr(file_name, file_bytes)
172
+ zip_buffer.seek(0)
173
+ st.download_button(
174
+ label="Download All Images",
175
+ data=zip_buffer,
176
+ file_name="images.zip",
177
+ mime="application/zip",
178
+ type='primary'
179
+ )
180
+ st.success("Immagini generate con successo!")
181
 
182
  if __name__ == "__main__":
183
+ st.set_page_config(page_title="Imperium AI", page_icon="🏰", layout="wide")
184
+ main()