kfahn/Generative_Art_Examples
0
1from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool2import datetime3import requests4import pytz5import yaml6import asyncio7import nest_asyncio8#import matplotlib9from playwright.async_api import async_playwright10from PIL import Image11import numpy as np12import subprocess13import json14from rapidfuzz import process15import gradio as gr16 17from tools.final_answer import FinalAnswerTool18 19from Gradio_UI import GradioUI20 21nest_asyncio.apply() # Ensure async works in a Jupyter/Colab/HF Spaces environment22 23subprocess.run(["apt-get", "update"])24subprocess.run(["apt-get", "install", "-y", "libnss3", "libatk1.0-0", "libatk-bridge2.0-0", "libxcomposite1",25"libxdamage1", "libcups2"])26 27 28subprocess.run(["playwright", "install", "chromium"])29 30# Below is an example of a tool that does nothing. Amaze us with your creativity !31@tool32def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type33 #Keep this format for the description / args / args description but feel free to modify the tool34 """A tool that does nothing yet 35 Args:36 arg1: the first argument37 arg2: the second argument38 """39 return "What magic will you build ?"40 41 42def load_image_sources():43 with open("expanded.json", "r") as file:44 # with open("image_sources.json", "r") as file:45 return json.load(file)46 47image_sources = load_image_sources()48 49 50def get_image_url(image_type: str, image_sources: dict):51 """Finds the best match for the given image type in a nested JSON structure."""52 53 choices = list(image_sources.keys()) # Get all available keys54 55 # Find the best match using `rapidfuzz`56 best_match, score, *_ = process.extractOne(image_type, choices, score_cutoff=60)57 58 if best_match:59 # Access the image_sources dictionary directly using the best_match string as the key60 print(f"Best match found: {best_match}") # Removed category access as it's not needed61 return image_sources[best_match] # Returns {'url', 'width', 'height', etc.}62 63 else:64 # Default return if no good match is found65 return {66 "url": "https://editor.p5js.org/kfahn/full/2XD5Y8MiV",67 "width": 800,68 "height": 80069 }70 71# def get_image_url(image_type: str):72# """Finds the best match for the given image type using fuzzy matching."""73# choices = list(image_sources.keys()) # Get all available keys74# best_match, score, *rest = process.extractOne(image_type, choices) 75 76# if score > 90: # Set a threshold to ensure a reasonable match77# print(best_match)78# return image_sources[best_match]79# else:80# #return None # No good match found81# return "https://editor.p5js.org/kfahn/full/2XD5Y8MiV"82 83# async def capture_screenshot(image_type: str):84# """Launches Playwright and uses user input, if any, to captures a screenshot of an image from p5.js."""85# print("Launching Playwright...")86# async with async_playwright() as p:87# browser = await p.chromium.launch(headless=True)88# page = await browser.new_page()89 90# #url = "https://openprocessing.org/sketch/2539973"91# url = "https://editor.p5js.org/kfahn/full/2XD5Y8MiV"92 93# if image_type: 94# image_url = get_image_url(image_type)95# else:96# image_url = url97 98# print(f"Opening image from p5 sketch: {image_url}")99# await page.goto(image_url, timeout=120000) # Wait for the image page to load100 101# print("Waiting for image element...")102# # await page.wait_for_selector("img", timeout=120000) # Wait for the <img> to be visible103# await page.wait_for_timeout(5000) # Allow sketch to fully render104# print("Capturing screenshot...")105# await page.set_viewport_size({"width": 800, "height": 800})106# await page.locator("iframe").screenshot(path="img.png")107# await browser.close()108# print("Screenshot saved!")109 110async def capture_screenshot(image_type: str):111 """Captures a screenshot of an image from p5.js."""112 print("Launching Playwright...")113 async with async_playwright() as p:114 browser = await p.chromium.launch(headless=True)115 page = await browser.new_page()116 117 # Load image sources from JSON118 image_sources = load_image_sources()119 image_data = get_image_url(image_type, image_sources)120 121 image_url = image_data["url"]122 width = image_data["width"]123 height = image_data["height"]124 125 print(f"Opening image: {image_url}")126 await page.goto(image_url, timeout=120000) # Load page127 128 print("Waiting for render...")129 await page.wait_for_timeout(5000)130 131 print(f"Setting viewport to {width}x{height}...")132 await page.set_viewport_size({"width": width, "height": height})133 134 print("Capturing screenshot...")135 await page.locator("iframe").screenshot(path="img.png")136 137 await browser.close()138 print("Screenshot saved!")139 140 141 142@tool143def grab_image(image_type: str) -> Image:144 """145 Fetches an user specified image or generative object from a p5.js sketch.146 This tool can be used to show a user what the generative art looks like.147 This function sends uses Playwright to launch a headless server and grab a screenshot of a p5.js sketch.148 Args:149 image_type: The art type or generative object. 150 151 Returns:152 image: The screen shot of the p5.js sketch as an image.153 """154 print("Running async Playwright screenshot...")155 156 loop = asyncio.new_event_loop() # Create a new event loop (Fixes issues on HF Spaces)157 asyncio.set_event_loop(loop)158 loop.run_until_complete(capture_screenshot(image_type))159 160 print("Loading image for Gradio...")161 162 img = Image.open("img.png")163 164 165 return img166 167@tool168def get_joke() -> str:169 """170 Fetches a random joke from the JokeAPI.171 This function sends a GET request to the JokeAPI to retrieve a random joke.172 It handles both single jokes and two-part jokes (setup and delivery).173 If the request fails or the response does not contain a joke, an error message is returned.174 Returns:175 str: The joke as a string, or an error message if the joke could not be fetched.176 """177 url = "https://v2.jokeapi.dev/joke/Any?type=single"178 179 try:180 response = requests.get(url)181 response.raise_for_status()182 183 data = response.json()184 185 if "joke" in data:186 return data["joke"]187 elif "setup" in data and "delivery" in data:188 return f"{data['setup']} - {data['delivery']}"189 else:190 return "Error: Unable to fetch joke."191 192 except requests.exceptions.RequestException as e:193 return f"Error fetching joke: {str(e)}"194 195#https://github.com/huggingface/smolagents/blob/main/examples/multiple_tools.py196@tool197def get_current_time_in_timezone(timezone: str) -> str:198 """A tool that fetches the current local time in a specified timezone.199 Args:200 timezone: A string representing a valid timezone (e.g., 'America/New_York').201 """202 try:203 # Create timezone object204 tz = pytz.timezone(timezone)205 # Get current time in that timezone206 local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")207 return f"The current local time in {timezone} is: {local_time}"208 except Exception as e:209 return f"Error fetching time for timezone '{timezone}': {str(e)}"210 211 212final_answer = FinalAnswerTool()213 214# If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:215# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud' 216 217model = HfApiModel(218max_tokens=2096,219temperature=0.5,220model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may be overloaded221custom_role_conversions=None,222)223 224 225# Import tool from Hub226image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)227 228with open("prompts.yaml", 'r') as stream:229 prompt_templates = yaml.safe_load(stream)230 231agent = CodeAgent(232 model=model,233 tools=[final_answer, get_joke, grab_image], ## add your tools here (don't remove final answer)234 max_steps=6,235 verbosity_level=1,236 grammar=None,237 planning_interval=None,238 name=None,239 description=None,240 prompt_templates=prompt_templates241)242 243 244GradioUI(agent).launch()