print("Welcome, Alwrity at your service..") import os from pathlib import Path import configparser from datetime import datetime import typer from prompt_toolkit import prompt from prompt_toolkit.shortcuts import radiolist_dialog from dotenv import load_dotenv import requests from rich import print from rich.text import Text load_dotenv(Path('.env')) print("Loading, required libraries..") app = typer.Typer() from lib.utils.alwrity_utils import blog_from_audio, blog_from_keyword, do_web_research, do_web_research, ai_news_writer from lib.utils.alwrity_utils import write_story, essay_writer, blog_tools, ai_finance_ta_writer, ai_content_team from lib.utils.alwrity_utils import content_planning_agents, competitor_analysis, image_to_text_writer, image_generator def prompt_for_time_range(): os.system("clear" if os.name == "posix" else "cls") print("\n๐Ÿ™‹ If you're researching keywords that are recent, use accordingly. Default is Anytime.\n") choices = [("anytime", "Anytime"), ("past year", "Past Year"), ("past month", "Past Month"), ("past week", "Past Week"), ("past day", "Past Day")] selected_time_range = radiolist_dialog(title="Select Search result time range:", values=choices).run() return selected_time_range[0] if selected_time_range else None def write_blog_options(): choices = [ ("Keywords", "Write from few keywords"), ("Audio To Blog", "Write from audio files"), ("AI Story Writer", "Story Writer"), ("AI Essay Writer", "Essay writer"), ("AI News Articles", "Write News reports"), ("AI Finance Writer", "Write Financial TA report"), ("Social", "AI Social writer(instagram, tweets, linkedin, facebook post)"), ("Copywriter", "AI Copywriter"), ("Quit", "Quit") ] selected_blog_type = radiolist_dialog(title="Choose Content creation Type:", values=choices).run() return selected_blog_type if selected_blog_type else None @app.command() def start_interactive_mode(): os.system("clear" if os.name == "posix" else "cls") text = "_______________________________________________________________________\n" text += "\nโš ๏ธ Alert! ๐Ÿ’ฅโ“๐Ÿ’ฅ\n" text += "Interactive tool, needs your attention/inputs, get off your mobile..'\n" text += "_______________________________________________________________________\n" print(text) choices = [ ("AI Writers", "Write with AI"), ("Content Planning", "Plan Content with AI"), ("Content Teams", "AI Content Agent Teams"), ("Quit", "Quit") ] mode = radiolist_dialog(title="Choose an option:", values=choices).run() if mode: if mode == 'AI Writers': write_blog() elif mode == 'Content Planning': content_planning_tools() elif mode == 'Content Teams': print("AI Content teams") ai_content_team() elif mode == 'Social Media': print(""" #whatsapp #instagram #youtube #twitter/X #Linked-in posts """) raise typer.Exit() elif mode == 'Quit': typer.echo("Exiting, Getting Lost!") raise typer.Exit() def content_planning_tools(): """ """ os.system("clear" if os.name == "posix" else "cls") text = "_______________________________________________________________________\n" text += "\nโš ๏ธ Alert! ๐Ÿ’ฅโ“๐Ÿ’ฅ\n" text += "ไฝœๅฎถ็š„้šœ็ข - Writer's block - Bloqueo de escritor - Schreibblockade\n" text += "Use Google Keyword planner, google ads instead. Better tools than below.\n" text += "Note: Who Cares, just give some titles, keywords to get started.. To Err is Human & AI..\n" text += "_______________________________________________________________________\n" print(text) choices = [ ("Do keyword Research", "Keywords web research - ๐Ÿค“ Will read & earn my bread.."), ("Competitor Analysis", "Competitor Analysis - ๐Ÿง What's my neighbour doing.."), ("Content Calender", "๐Ÿฅน๐Ÿฅน Just give me content calender ๐Ÿฅน๐Ÿฅน") ] mode = radiolist_dialog(title="Choose an option:", values=choices).run() if mode == 'Do keyword Research': if check_search_apis(): do_web_research() elif mode == 'Competitor Analysis': competitor_analysis() elif mode == 'Content Calender': content_planning_agents() def check_search_apis(): """ Check if necessary environment variables are present. Display messages with links on how to get them if not present. """ # Use rich.print for styling and hyperlinking print("Alwrity uses Basic, Semantic, Neural web search using above APIs for contextual blog generation.\n") api_keys = { "METAPHOR_API_KEY": "Metaphor AI Key (Get it here: [link=https://dashboard.exa.ai/login]Metaphor API[/link])", "TAVILY_API_KEY": "Tavily AI Key (Get it here: [link=https://tavily.com/#api]Tavily API[/link])", "SERPER_API_KEY": "Serper API Key (Get it here: [link=https://serper.dev/signup]SerperDev API[/link])", } missing_keys = [] with typer.progressbar(api_keys.items(), label="Checking API keys", length=len(api_keys)) as progress: for key, description in progress: if os.getenv(key) is None: # Use rich.print for styling and hyperlinking print(f"[bold red]โœ– ๐Ÿšซ {key} is missing:[/bold red] [blue underline]Get {key} API Key[/blue underline]") missing_keys.append((key, description)) if missing_keys: print("\nMost are Free APIs and really worth your while signing up for them.") print("๐Ÿ’ฉ๐Ÿ’ฉ๐Ÿ’ฉ: GO GET THEM, on above urls. [bold red]") #print("Note: They offer free/limited api calls, so we use most of them to have a lot of free api calls.") for key, description in missing_keys: get_api_key(key, description) else: return True def get_api_key(api_key: str, api_description: str): """ Ask the user to input the missing API key and add it to the .env file. Args: api_key (str): The name of the API key variable. api_description (str): The description of the API key. """ print("\n\n") print(f"[bold green] ๐Ÿ™‹ Attention Here: ๐Ÿ™‹ -- {api_description}") user_input = typer.prompt(f"๐Ÿ’ฉ -**Please Enter(copy/paste) {api_key} API Key** - Here๐Ÿ™‹:") with open(".env", "a") as env_file: env_file.write(f"{api_key}={user_input}\n") print(f"โœ… API Key added to .env file.") def write_blog(): blog_type = write_blog_options() if blog_type: if blog_type == 'Keywords': blog_from_keyword() elif blog_type == 'AI Story Writer': write_story() elif blog_type == 'AI Essay Writer': essay_writer() elif blog_type == 'Audio To Blog': blog_from_audio() elif blog_type == 'AI News Articles': ai_news_writer() elif blog_type == 'AI Finance Writer': ai_finance_ta_writer() elif blog_type == 'Quit': typer.echo("Exiting, Getting Lost..") raise typer.Exit() def check_llm_environs(): """ Function to check which LLM api is given. """ # 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): # Prompt user to select a provider gpt_provider = radiolist_dialog( title="Select your GPT Provider(llm) from 'google', 'openai', 'mistralai'", values=[("google", "Google Gemini Pro"), ("openai", "OpenAI- ChatGPT"), ("mistralai", "MistralAI/WIP")]).run() # 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") print(f"โœ… API Key added to .env file.") if gpt_provider.lower() == "google": api_key_var = "GEMINI_API_KEY" missing_api_msg = f"To get your {api_key_var}, please visit: https://aistudio.google.com/app/apikey" elif gpt_provider.lower() == "openai": api_key_var = "OPENAI_API_KEY" missing_api_msg = "To get your OpenAI API key, please visit: https://openai.com/blog/openai-api" elif gpt_provider.lower() == "mistralai": api_key_var = "MISTRAL_API_KEY" missing_api_msg = "To get your MistralAI API key, please visit: https://mistralai.com/api" if api_key_var not in os.environ: get_api_key(api_key_var, missing_api_msg) def check_internet(): try: response = requests.get("http://www.google.com", timeout=5) if not response.status_code == 200: print("๐Ÿ’ฅ๐Ÿคฏ WTFish, Internet is NOT available. Enjoy the wilderness..") exit(1) else: return except requests.ConnectionError: print("๐Ÿ’ฅ๐Ÿคฏ WTFish: Internet is NOT available. Enjoy the wilderness..") exit(1) except requests.Timeout: print("Request timed out. Internet might be slow.") exit(1) except Exception as e: print("Internet: An error occurred:", e) exit(1) def create_env_file(): env_file = Path('.env') if not env_file.is_file(): try: with open('.env', 'w') as f: f.write('# Alwrity will add your environment variables here\n') except Exception as e: print(f"๐Ÿ’ฅ๐ŸคฏError occurred while creating .env file: {e}") if __name__ == "__main__": print("Checking Internet..") check_internet() print("Creating .env file") create_env_file() print("Checking Search APIs..") check_search_apis() print("Checking LLM APIs..") check_llm_environs() # Export the paths and file names. Dont want alwrity to be chatty and prompt for inputs. os.environ["SEARCH_SAVE_FILE"] = os.path.join(os.getcwd(), "lib", "workspace", f"web_research_report_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}") os.environ["IMG_SAVE_DIR"] = os.path.join(os.getcwd(), "lib", "workspace") os.environ["CONTENT_SAVE_DIR"] = os.path.join(os.getcwd(), "lib", "workspace") os.environ["PROMPTS_DIR"] = os.path.join(os.getcwd(), "lib", "workspace", "prompts") load_dotenv(Path('.env')) app()