From aec2d6b4323204701d2fb944bd1e993b2c908e01 Mon Sep 17 00:00:00 2001 From: ajaysi Date: Mon, 22 Apr 2024 19:02:55 +0530 Subject: [PATCH] Create images for blogs - Stability AI --- ..env | 6 ++ alwrity.py | 13 +++- .../gen_stabl_diff_img.py | 71 +++++++++++------- ....py => main_generate_image_from_prompt.py} | 48 ++++++------ .../text_to_image_generation/save_image.py | 21 ++---- lib/utils/.alwrity_utils.py.swp | Bin 16384 -> 0 bytes lib/utils/alwrity_utils.py | 20 ++++- .../workspace}/audio_to_blog.gif | Bin .../workspace}/blogs_already_written_on.py | 0 {workspace => lib/workspace}/keyword_blog.gif | Bin {workspace => lib/workspace}/keyword_blog.png | Bin 11 files changed, 108 insertions(+), 71 deletions(-) create mode 100644 ..env rename lib/gpt_providers/text_to_image_generation/{generate_image_from_prompt.py => main_generate_image_from_prompt.py} (53%) delete mode 100644 lib/utils/.alwrity_utils.py.swp rename {workspace => lib/workspace}/audio_to_blog.gif (100%) rename {workspace => lib/workspace}/blogs_already_written_on.py (100%) rename {workspace => lib/workspace}/keyword_blog.gif (100%) rename {workspace => lib/workspace}/keyword_blog.png (100%) diff --git a/..env b/..env new file mode 100644 index 00000000..0807f5eb --- /dev/null +++ b/..env @@ -0,0 +1,6 @@ +STABILITY_API_KEY=sk-Jdu0BrFe4tta19PDpU1AlpVAtE3eJlmGZiAYx61bNUZkAl4d +STABILITY_API_KEY=sk-Jdu0BrFe4tta19PDpU1AlpVAtE3eJlmGZiAYx61bNUZkAl4d +STABILITY_API_KEY=asada +STABILITY_API_KEY=sk-Jdu0BrFe4tta19PDpU1AlpVAtE3eJlmGZiAYx61bNUZkAl4d +STABILITY_API_KEY=sdsa +STABILITY_API_KEY=sk-Jdu0BrFe4tta19PDpU1AlpVAtE3eJlmGZiAYx61bNUZkAl4d diff --git a/alwrity.py b/alwrity.py index 90fff985..3d93e228 100644 --- a/alwrity.py +++ b/alwrity.py @@ -69,6 +69,7 @@ def start_interactive_mode(): ("Competitor Analysis", "Competitor Analysis"), ("Create Blog Images", "Create Blog Images"), ("AI Social Media(TBD)", "AI Social Media(TBD)"), + ("AI Code Writer(TBD)", "AI Code Writer(TBD)"), ("Quit", "Quit") ] mode = radiolist_dialog(title="Choose an option:", values=choices).run() @@ -98,6 +99,9 @@ def start_interactive_mode(): #Linked-in posts """) raise typer.Exit() + elif mode == 'AI Code Writer(TBD)': + print("Coming soon, TBD") + raise typer.Exit() elif mode == 'Quit': typer.echo("Exiting, Getting Lost!") raise typer.Exit() @@ -178,7 +182,7 @@ def check_llm_environs(): # Load .env file load_dotenv(Path('.env')) gpt_provider = os.getenv("GPT_PROVIDER") - + # Disable unsupported GPT providers supported_providers = ['google', 'openai', 'mistralai'] if gpt_provider is None or gpt_provider.lower() not in map(str.lower, supported_providers): @@ -189,7 +193,7 @@ def check_llm_environs(): # Update .env file os.environ["GPT_PROVIDER"] = gpt_provider with open(".env", "a") as env_file: - env_file.write(f"GPT_PROVIDER=gpt_provider\n") + env_file.write(f"GPT_PROVIDER={gpt_provider}\n") print(f"βœ… API Key added to .env file.") if gpt_provider.lower() == "google": @@ -241,7 +245,8 @@ if __name__ == "__main__": os.system("clear" if os.name == "posix" else "cls") check_search_apis() check_llm_environs() - os.environ["SEARCH_SAVE_FILE"] = os.path.join(os.getcwd(), "workspace", - "web_research_report" + "_" + datetime.now().strftime("%Y-%m-%d_%H-%M-%S")) + os.environ["SEARCH_SAVE_FILE"] = os.path.join(os.getcwd(), "lib", "workspace") + "_" + datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + os.environ["IMG_SAVE_DIR"] = os.path.join(os.getcwd(), "lib", "workspace") + load_dotenv(Path('.env')) app() diff --git a/lib/gpt_providers/text_to_image_generation/gen_stabl_diff_img.py b/lib/gpt_providers/text_to_image_generation/gen_stabl_diff_img.py index ff4c5a51..0f801035 100644 --- a/lib/gpt_providers/text_to_image_generation/gen_stabl_diff_img.py +++ b/lib/gpt_providers/text_to_image_generation/gen_stabl_diff_img.py @@ -1,41 +1,56 @@ -from PIL import Image -import requests - # Ensure you sign up for an account to obtain an API key: # https://platform.stability.ai/ # Your API key can be found here after account creation: # https://platform.stability.ai/account/keys +import base64 +import os +import requests +from PIL import Image +from io import BytesIO + +from .save_image import save_generated_image + def generate_stable_diffusion_image(prompt): - """ - Generate images using Stable Diffusion API based on a given prompt. - - Args: - prompt (str): The prompt to generate the image. - image_dir (str): The directory where the image will be saved. - - Raises: - Warning: If the adult content classifier is triggered. - Exception: For any issues during image generation or saving. - """ - api_key = os.getenv('STABILITY_API_KEY') - + engine_id = "stable-diffusion-xl-1024-v1-0" + api_host = os.getenv('API_HOST', 'https://api.stability.ai') + api_key = os.getenv("STABILITY_API_KEY") + + if api_key is None: + raise Exception("Missing Stability API key.") + response = requests.post( - f"https://api.stability.ai/v2beta/stable-image/generate/sd3", + f"{api_host}/v1/generation/{engine_id}/text-to-image", headers={ - "authorization": f"Bearer {api_key}", - "accept": "image/*" + "Content-Type": "application/json", + "Accept": "application/json", + "Authorization": f"Bearer {api_key}" }, - files={"none": ''}, - data={ - "prompt": prompt, - "output_format": "webp", + json={ + "text_prompts": [ + { + "text": prompt + } + ], + "cfg_scale": 7, + "height": 1024, + "width": 1024, + "samples": 1, + "steps": 30, }, ) + + if response.status_code != 200: + raise Exception("Non-200 response: " + str(response.text)) + + data = response.json() + save_generated_image(data) - if response.status_code == 200: - with open("./dog-wearing-glasses.jpeg", 'wb') as file: - file.write(response.content) - else: - raise Exception(str(response.json())) + for i, image in enumerate(data["artifacts"]): + # Decode base64 image data + img_data = base64.b64decode(image["base64"]) + # Open image using PIL + img = Image.open(BytesIO(img_data)) + # Display the image + img.show() diff --git a/lib/gpt_providers/text_to_image_generation/generate_image_from_prompt.py b/lib/gpt_providers/text_to_image_generation/main_generate_image_from_prompt.py similarity index 53% rename from lib/gpt_providers/text_to_image_generation/generate_image_from_prompt.py rename to lib/gpt_providers/text_to_image_generation/main_generate_image_from_prompt.py index b2c8646c..602cf01d 100644 --- a/lib/gpt_providers/text_to_image_generation/generate_image_from_prompt.py +++ b/lib/gpt_providers/text_to_image_generation/main_generate_image_from_prompt.py @@ -23,9 +23,10 @@ logger.add(sys.stdout, #from .gen_dali2_images from .gen_dali3_images import generate_dalle3_images from .gen_stabl_diff_img import generate_stable_diffusion_image +from ..text_generation.main_text_generation import llm_text_gen -def generate_image(user_prompt, image_engine="dalle3"): +def generate_image(user_prompt, image_engine): """ The generation API endpoint creates an image based on a text prompt. @@ -41,15 +42,17 @@ def generate_image(user_prompt, image_engine="dalle3"): Must be one of "url" or "b64_json". Defaults to "url". --> user (str): A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. """ - img_prompt = generate_img_prompt(user_prompt) - # call the OpenAI API to generate image from prompt. - logger.info(f"Calling image.generate with prompt: {img_prompt}") - - if 'Dalle3' in image_engine: - image_stored_at = generate_dalle3_images(img_prompt) - elif 'Stable Diffusion' in image_engine: - image_stored_at = generate_stable_diffusion_image(img_prompt) - + try: + img_prompt = generate_img_prompt(user_prompt) + if 'Dalle3' in image_engine: + logger.info(f"Calling Dalle3 text-to-image with prompt: {img_prompt}") + image_stored_at = generate_dalle3_images(img_prompt) + elif 'Stability-Stable-Diffusion' in image_engine: + logger.info(f"Calling Stable diffusion text-to-image with prompt: \n{img_prompt}") + print("\n\n") + image_stored_at = generate_stable_diffusion_image(img_prompt) + except Exception as err: + logger.error(f"Failed to generate Image: {err}") return image_stored_at @@ -57,17 +60,16 @@ def generate_img_prompt(user_prompt): """ Given prompt, this functions generated a prompt for image generation. """ - # I want you to act as an artist advisor providing advice on various art styles such tips on utilizing - # light & shadow effects effectively in painting, shading techniques while sculpting etc. - # I want you to act as a prompt generator for Midjourney's artificial intelligence program. - # Your job is to provide detailed and creative descriptions that will inspire unique and interesting images from the AI. - # Here is your first prompt: "" - logger.info(f"Generate image prompt for : {user_prompt}") - prompt = f"""As an educationist and expert infographic artist, your tasked to create prompts that will be used for image generation. - Craft prompt for Openai Dall-e image generation program. Clearly describe the given text to represent it as image. - Make sure to avoid common image generation mistakes. - Advice for creating prompt for image from the given text(no more than 150 words). - Reply with only one answer and no descrition. Generate image prompt for the below text. - Text: {user_prompt}""" - response = (prompt) + prompt = f""" + As an expert prompt engineer and artist, I will provide you with 'text' for creating image. + I want you to act as a prompt generator for AI text to image models(no more than 150 words). + \n + Choose from various art styles, utilize light & shadow effects etc. + Make sure to avoid common image generation mistakes. + Reply with only one answer, no descrition and in plaintext. + Make sure your prompt is detailed and creative descriptions that will inspire unique and interesting images from the AI. + + \n\ntext:{user_prompt} """ + + response = llm_text_gen(prompt) return response diff --git a/lib/gpt_providers/text_to_image_generation/save_image.py b/lib/gpt_providers/text_to_image_generation/save_image.py index 89733b67..4bdd7a10 100644 --- a/lib/gpt_providers/text_to_image_generation/save_image.py +++ b/lib/gpt_providers/text_to_image_generation/save_image.py @@ -1,35 +1,28 @@ +import base64 import datetime import os import requests from PIL import Image import logging -def save_generated_image(img_generation_response, image_dir): +def save_generated_image(img_generation_response): """ Save generated images for blog, ensuring unique names for SEO. """ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) - generated_image_name = f"generated_image_{datetime.datetime.now():%Y-%m-%d-%H-%M-%S}.png" - generated_image_filepath = os.path.join(image_dir, generated_image_name) - generated_image_url = img_generation_response.data[0].url + generated_image_name = f"generated_image_{datetime.datetime.now():%Y-%m-%d-%H-%M-%S}.webp" + generated_image_filepath = os.path.join(os.getenv('IMG_SAVE_DIR'), generated_image_name) - logger.info(f"Fetch the image from url: {generated_image_url}") try: - response = requests.get(generated_image_url, stream=True) - response.raise_for_status() - with open(generated_image_filepath, "wb", encoding="utf-8") as image_file: - image_file.write(response.content) + for i, image in enumerate(img_generation_response["artifacts"]): + with open(generated_image_filepath, "wb") as f: + f.write(base64.b64decode(image["base64"])) except requests.exceptions.RequestException as e: logger.error(f"Failed to get generated image content: {e}") return None logger.info(f"Saved image at path: {generated_image_filepath}") - if os.environ.get('DISPLAY', ''): # Check if display is supported - img = Image.open(generated_image_filepath) - img.show() - return generated_image_filepath - diff --git a/lib/utils/.alwrity_utils.py.swp b/lib/utils/.alwrity_utils.py.swp deleted file mode 100644 index 715fe2b1334d520def21580ed829f44afe70e0fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 OZ78E|=P~mD diff --git a/lib/utils/alwrity_utils.py b/lib/utils/alwrity_utils.py index 19bc3f3c..e3857151 100644 --- a/lib/utils/alwrity_utils.py +++ b/lib/utils/alwrity_utils.py @@ -8,6 +8,8 @@ from prompt_toolkit import prompt from prompt_toolkit.completion import WordCompleter from prompt_toolkit.validation import Validator, ValidationError from prompt_toolkit.shortcuts import radiolist_dialog +import typer +from rich import print from lib.ai_web_researcher.gpt_online_researcher import gpt_web_researcher from lib.ai_web_researcher.metaphor_basic_neural_web_search import metaphor_find_similar @@ -15,7 +17,7 @@ from lib.ai_writers.keywords_to_blog import write_blog_from_keywords from lib.ai_writers.speech_to_blog.main_audio_to_blog import generate_audio_blog from lib.gpt_providers.text_generation.ai_story_writer import ai_story_generator from lib.gpt_providers.text_generation.ai_essay_writer import ai_essay_generator -from lib.gpt_providers.text_to_image_generation.generate_image_from_prompt import generate_image +from lib.gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image def blog_from_audio(): @@ -270,7 +272,21 @@ def image_generator(): print("Choose between:: Stable-Diffusion, Dalle2, Dalle3") img_model = prompt('Choose the image model to use for generation: ', completer=img_models, validator=ModelTypeValidator()) - print(f"{img_prompt}----{img_model}") + if 'Stability-Stable-Diffusion' in img_model: + api_key = 'STABILITY_API_KEY' + elif 'Dalle3' in img_model: + api_key = 'OPENAI_API_KEY' + + if os.getenv(api_key) is None: + print(f"\n\n[bold green] πŸ™‹ Get {api_key} Here:https://platform.stability.ai/docs/getting-started πŸ™‹ -- \n") + user_input = typer.prompt(f"πŸ’© -**Please Enter(copy/paste) {api_key} Key** - HereπŸ™‹:") + os.environ[api_key] = user_input + try: + with open(".env", "a") as env_file: + env_file.write(f"{api_key}={user_input}\n") + print(f"βœ… API Key added to .env file.") + except Exception as err: + print(f"Error: {err}") try: generate_image(img_prompt, img_model) except Exception as err: diff --git a/workspace/audio_to_blog.gif b/lib/workspace/audio_to_blog.gif similarity index 100% rename from workspace/audio_to_blog.gif rename to lib/workspace/audio_to_blog.gif diff --git a/workspace/blogs_already_written_on.py b/lib/workspace/blogs_already_written_on.py similarity index 100% rename from workspace/blogs_already_written_on.py rename to lib/workspace/blogs_already_written_on.py diff --git a/workspace/keyword_blog.gif b/lib/workspace/keyword_blog.gif similarity index 100% rename from workspace/keyword_blog.gif rename to lib/workspace/keyword_blog.gif diff --git a/workspace/keyword_blog.png b/lib/workspace/keyword_blog.png similarity index 100% rename from workspace/keyword_blog.png rename to lib/workspace/keyword_blog.png