Arrcus commited on
Commit
119f656
·
1 Parent(s): fe3560b

kits using

Browse files
Files changed (2) hide show
  1. app copy.py +105 -0
  2. genai copy 2.py +116 -0
app copy.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Tuple, Optional
2
+ from PIL import Image, ImageDraw, ImageFont
3
+
4
+
5
+ WEATHER_PNG_PATH = None # disk fallback removed
6
+ GENERATED_PNG_PATH = None # disk fallback removed
7
+
8
+ def _placeholder_image(size: Tuple[int, int], text: str, bg=(230, 230, 230)) -> Image.Image:
9
+ # Always create a simple placeholder; don't try to read a file here
10
+ img = Image.new("RGB", size, color=bg)
11
+ draw = ImageDraw.Draw(img)
12
+ try:
13
+ font = ImageFont.load_default()
14
+ except Exception:
15
+ font = None
16
+ w, h = draw.textbbox((0, 0), text, font=font)[2:]
17
+ draw.text(((size[0] - w) / 2, (size[1] - h) / 2), text, fill=(80, 80, 80), font=font)
18
+ return img
19
+
20
+
21
+ def load_weather_plot(size: Tuple[int, int] = (1024, 1024), kit_id: Optional[int] = None) -> Image.Image:
22
+ """Load the weather plot image for a given kit.
23
+
24
+ Tries to generate in-memory via weather_data_visualisation(); falls back to
25
+ a placeholder if unavailable.
26
+ """
27
+ try:
28
+ # Prefer calling the function to get a PIL image directly
29
+ from weather_data_visualisation import weather_data_visualisation
30
+ # Coerce kit_id to int, defaulting to 1001 if not provided/invalid
31
+ kit = 1001
32
+ if kit_id is not None:
33
+ try:
34
+ kit = int(kit_id)
35
+ except Exception:
36
+ kit = 1001
37
+
38
+ img = weather_data_visualisation(kit=kit, save_to_disk=False)
39
+ if isinstance(img, Image.Image):
40
+ if img.size != size:
41
+ img = img.resize(size, Image.LANCZOS)
42
+ return img
43
+ except Exception as e:
44
+ print(f"Weather plot generation failed: {e}")
45
+
46
+ return _placeholder_image(size, "Weather plot unavailable")
47
+
48
+
49
+ def load_genai_output(size: Tuple[int, int] = (1024, 1024), kit_id: Optional[int] = None) -> Image.Image:
50
+ """Load the GenAI output image for a given kit if available; otherwise a placeholder.
51
+
52
+ Uses the selected kit's weather plot as the guiding input for the GenAI image.
53
+ """
54
+ try:
55
+ from genai import generate_genai_image
56
+
57
+ # Provide the latest weather image if possible to guide the GenAI
58
+ base_img = None
59
+ try:
60
+ base_img = load_weather_plot(size, kit_id=kit_id)
61
+ except Exception:
62
+ base_img = None
63
+
64
+ img = generate_genai_image(input_image=base_img, save_to_disk=False)
65
+ if isinstance(img, Image.Image):
66
+ if img.size != size:
67
+ img = img.resize(size, Image.LANCZOS)
68
+ return img
69
+ except Exception as e:
70
+ print(f"genai.py not usable yet: {e}")
71
+
72
+ return _placeholder_image(size, "GenAI image pending")
73
+
74
+
75
+ def get_both_images(kit_id: Optional[int] = None, size: Tuple[int, int] = (1024, 1024)) -> Tuple[Image.Image, Image.Image]:
76
+ left = load_weather_plot(size, kit_id=kit_id)
77
+ right = load_genai_output(size, kit_id=kit_id)
78
+ return left, right
79
+
80
+
81
+ def create_app():
82
+ """Creates and returns the Gradio app with two side-by-side images."""
83
+ import gradio as gr
84
+
85
+ with gr.Blocks(title="Weather × GenAI") as app:
86
+ gr.Markdown("# Weather visualization and GenAI output")
87
+ with gr.Row():
88
+ kit_input = gr.Number(label="Kit ID", value=1001, precision=0)
89
+ with gr.Row():
90
+ left_img = gr.Image(label="Weather plot", type="pil")
91
+ right_img = gr.Image(label="GenAI output", type="pil")
92
+
93
+ # Load both images on app start
94
+ app.load(fn=get_both_images, inputs=[kit_input], outputs=[left_img, right_img])
95
+
96
+ # Manual refresh button
97
+ refresh_btn = gr.Button("Refresh")
98
+ refresh_btn.click(fn=get_both_images, inputs=[kit_input], outputs=[left_img, right_img])
99
+
100
+ return app
101
+
102
+
103
+ if __name__ == "__main__":
104
+ app = create_app()
105
+ app.launch()
genai copy 2.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ from PIL import Image
3
+ from typing import Optional
4
+ from io import BytesIO
5
+ import time
6
+
7
+ load_dotenv() # take environment variables from .env.
8
+
9
+ from google import genai
10
+
11
+ client = genai.Client()
12
+
13
+ # Default creative prompt
14
+ DEFAULT_PROMPT = (
15
+ "Turn the provided data visualization into a painting using an eastern art style."
16
+ )
17
+
18
+
19
+ def generate_genai_image(
20
+ input_image: Optional[Image.Image] = None,
21
+ prompt: Optional[str] = None,
22
+ model: str = "gemini-2.5-flash-image-preview",
23
+ save_to_disk: bool = False,
24
+ ) -> Optional[Image.Image]:
25
+ """Generate a stylized image from an input PIL image using Google GenAI.
26
+
27
+ Args:
28
+ input_image: Source PIL image. If None, calls weather_data_visualisation() to generate in-memory.
29
+ prompt: Optional text prompt; falls back to DEFAULT_PROMPT.
30
+ model: Model name to use.
31
+ save_to_disk: When True, saves to output/generated_image.png (no disk reads occur).
32
+
33
+ Returns:
34
+ A PIL.Image on success, or None if generation failed.
35
+ """
36
+
37
+ # Resolve input image strictly in-memory
38
+ img = input_image
39
+ if img is None:
40
+ try:
41
+ from weather_data_visualisation import weather_data_visualisation
42
+
43
+ img = weather_data_visualisation(save_to_disk=False)
44
+ except Exception:
45
+ img = None
46
+
47
+ if img is None:
48
+ return None
49
+
50
+ # Prepare prompt
51
+ ptxt = prompt or DEFAULT_PROMPT
52
+
53
+ output_image = None
54
+ last_error = None
55
+
56
+ # Retry up to 5 times, waiting 2 seconds between failed attempts
57
+ for attempt in range(1, 6):
58
+ try:
59
+ response = client.models.generate_content(
60
+ model=model,
61
+ contents=[ptxt, img],
62
+ )
63
+ except Exception as e:
64
+ last_error = e
65
+ # If not last attempt, wait and retry
66
+ if attempt < 5:
67
+ time.sleep(2)
68
+ continue
69
+ else:
70
+ print(f"GenAI request failed (attempt {attempt}/5): {e}")
71
+ break
72
+
73
+ try:
74
+ # Reset on each attempt
75
+ output_image = None
76
+ for part in response.candidates[0].content.parts:
77
+ if getattr(part, "text", None) is not None:
78
+ # Optional: print any textual response
79
+ print(part.text)
80
+ elif getattr(part, "inline_data", None) is not None:
81
+ output_image = Image.open(BytesIO(part.inline_data.data)).convert("RGB")
82
+ # Success condition
83
+ if output_image is not None:
84
+ break
85
+ except Exception as e:
86
+ last_error = e
87
+ # Parsing failed; if not last attempt, wait and retry
88
+ if attempt < 5:
89
+ time.sleep(2)
90
+ continue
91
+ else:
92
+ print(f"Failed to parse GenAI response (attempt {attempt}/5): {e}")
93
+ break
94
+
95
+ # If we reached here with no image, wait then try again (unless last attempt)
96
+ if output_image is None and attempt < 5:
97
+ time.sleep(2)
98
+
99
+ # Optional save without using as a future fallback
100
+ if output_image is not None and save_to_disk:
101
+ try:
102
+ import os
103
+
104
+ os.makedirs("output", exist_ok=True)
105
+ output_image.save("output/generated_image.png")
106
+ except Exception:
107
+ pass
108
+
109
+ if output_image is None and last_error is not None:
110
+ # Keep return type unchanged; logging already printed above
111
+ pass
112
+
113
+ return output_image
114
+
115
+ if __name__ == "__main__":
116
+ generate_genai_image()