Last active
December 18, 2025 11:53
-
-
Save originalankur/c199e04eab0561bb85a37d02fa0b71b8 to your computer and use it in GitHub Desktop.
DSPy Signature -> Prompt -> Nano Banana
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| from google import genai | |
| from google.genai import types | |
| import dspy | |
| # --- Configuration --- | |
| DEFAULT_MODEL_NAME = 'gemini/gemini-2.0-flash' | |
| IMAGE_MODEL_NAME = 'gemini-3-pro-image-preview' | |
| # do create the directory | |
| DEFAULT_SAVE_PATH = os.path.expanduser("~/image_generator/img/") | |
| # --- Setup --- | |
| def configure_dspy(model_name: str = DEFAULT_MODEL_NAME) -> None: | |
| """Configures the DSPy language model globally.""" | |
| lm = dspy.LM(model_name) | |
| dspy.configure(lm=lm) | |
| # --- Signatures --- | |
| class OpArtSignature(dspy.Signature): | |
| """ | |
| Generates an art prompt in the style of Op Art (Optical Art). | |
| Focus: Optical illusions, vibrating patterns, visual tricks. | |
| """ | |
| visual_effect = dspy.InputField(desc="Visual effect: Vibrating colors, warping planes, motion, flashing") | |
| patterns = dspy.InputField(desc="Patterns: Repeating lines, concentric circles, moiré patterns, distorting grids") | |
| color_palette = dspy.InputField(desc="Color palette: High-contrast black and white, or intensely clashing bright colors") | |
| precision = dspy.InputField(desc="Precision: Meticulous, machine-like exactitude") | |
| image_generation_prompt = dspy.OutputField(desc="A detailed description suitable for generating an image in the Op Art style. Generated image shouldn't go in a frame or on a wall.") | |
| class ImpossibleGeometrySignature(dspy.Signature): | |
| """ | |
| Generates an art prompt in the style of Impossible Geometry (Optical Illusion). | |
| Focus: Visual paradoxes, spatial ambiguities, and objects that defy physics (e.g., M.C. Escher). | |
| """ | |
| illusion_concept = dspy.InputField(desc="Concept: The specific paradox (e.g., Penrose triangle, infinite staircase, waterfall, tessellation)") | |
| perspective_trick = dspy.InputField(desc="Technique: Isometric projection, forced perspective, or dual-plane interpretation") | |
| forms = dspy.InputField(desc="Forms: Polyhedra, interlocking architectural elements, connected loops") | |
| rendering_style = dspy.InputField(desc="Rendering: Realistic shading and texture (stone, wood) to make the impossibility convincing") | |
| image_generation_prompt = dspy.OutputField(desc="A detailed description suitable for generating an image of impossible geometry.") | |
| # --- Core Logic --- | |
| class ImageGenerator: | |
| """Encapsulates image generation logic using Google GenAI.""" | |
| def __init__(self, model_name: str = IMAGE_MODEL_NAME): | |
| self.client = genai.Client() | |
| self.model_name = model_name | |
| def generate(self, prompt: str, filename: str, save_path: str = DEFAULT_SAVE_PATH, | |
| aspect_ratio: str = "16:9", image_size: str = "4k", show: bool = True) -> None: | |
| """ | |
| Generates an image from a prompt and saves it to the specified path. | |
| """ | |
| print(f"Generating image for prompt: '{prompt}'...") | |
| try: | |
| response = self.client.models.generate_content( | |
| model=self.model_name, | |
| contents=prompt, | |
| config=types.GenerateContentConfig( | |
| tools=[{"google_search": {}}], | |
| image_config=types.ImageConfig( | |
| aspect_ratio=aspect_ratio, | |
| image_size=image_size | |
| ) | |
| ) | |
| ) | |
| image_parts = [part for part in response.parts if part.inline_data] | |
| if image_parts: | |
| image = image_parts[0].as_image() | |
| os.makedirs(save_path, exist_ok=True) | |
| full_path = os.path.join(save_path, filename) | |
| image.save(full_path) | |
| print(f"Image saved successfully to: {full_path}") | |
| if show: | |
| image.show() | |
| else: | |
| print("Warning: No image data found in response.") | |
| except Exception as e: | |
| print(f"Error during image generation: {e}") | |
| # wrapper for backward compatibility or simple usage | |
| def generate_image(prompt, filename, save_path=DEFAULT_SAVE_PATH, aspect_ratio="16:9", image_size="4k", show=True): | |
| generator = ImageGenerator() | |
| generator.generate(prompt, filename, save_path, aspect_ratio, image_size, show) | |
| def test_generate_image(): | |
| """Test function for generating a simple infographic.""" | |
| generate_image( | |
| "Generate an infographic of the current weather in Bengaluru.", | |
| "weather_bengaluru.png", | |
| "." | |
| ) | |
| # --- Main Execution --- | |
| if __name__ == "__main__": | |
| configure_dspy() | |
| # Example usage with DSPy | |
| impossible_geometry_prog = dspy.ChainOfThought(ImpossibleGeometrySignature) | |
| # We pass only the relevant fields for Impossible Geometry | |
| prediction = impossible_geometry_prog( | |
| illusion_concept="infinite staircase", | |
| perspective_trick="dual-plane interpretation", | |
| forms="connected loops", | |
| rendering_style="blank and white lines" | |
| ) | |
| prompt = prediction.image_generation_prompt | |
| print(f"Generated Prompt: {prompt}") | |
| # Generate the image | |
| generate_image(prompt, "impossible_geometry_test_4.png", ".") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment