WIP - Streamlit UI, firecrawl - V0.5

This commit is contained in:
ajaysi
2024-06-12 22:46:41 +05:30
parent bebca6612d
commit 8dfcb1f536
8 changed files with 60 additions and 71711 deletions

View File

@@ -22,11 +22,11 @@ from lib.utils.alwrity_utils import (
# Function to check if API keys are present and prompt user to input if not # Function to check if API keys are present and prompt user to input if not
def check_api_keys(): def check_api_keys():
api_keys = { api_keys = {
"METAPHOR_API_KEY": "Metaphor AI Key (Get it here: https://dashboard.exa.ai/login)", "METAPHOR_API_KEY": "[Get Metaphor AI Key](https://dashboard.exa.ai/login)",
"TAVILY_API_KEY": "Tavily AI Key (Get it here: https://tavily.com/#api)", "TAVILY_API_KEY": "[Get Tavily AI Key](https://tavily.com/#api)",
"SERPER_API_KEY": "Serper API Key (Get it here: https://serper.dev/signup)", "SERPER_API_KEY": "[Get Serper API Key](https://serper.dev/signup)",
"STABILITY_API_KEY": "Stability API Key (Get it here: https://platform.stability.ai/)", "STABILITY_API_KEY": "[Get Stability API Key Here](https://platform.stability.ai/)",
"FIRECRAWL_API_KEY": "Firecrawl API key (Get it here: https://www.firecrawl.dev/account)" "FIRECRAWL_API_KEY": "[Get Firecrawl API key Here](https://www.firecrawl.dev/account)"
} }
missing_keys = [] missing_keys = []
@@ -35,14 +35,21 @@ def check_api_keys():
missing_keys.append((key, description)) missing_keys.append((key, description))
if missing_keys: if missing_keys:
st.warning(f"API keys are missing. Please provide them below:{missing_keys}") st.warning("🚨 Some API keys are missing! Please provide them below: 🚨")
new_keys = []
for key, description in missing_keys: for key, description in missing_keys:
api_key = st.text_input(f"Enter {key}:", placeholder=description, help=description) api_key = st.text_input(f"Enter 🔏 {key}: 👉{description}👈", placeholder=description, help=description)
if api_key: if api_key:
with open(".env", "a") as env_file: new_keys.append((key, api_key))
if new_keys:
with open(".env", "a") as env_file:
for key, api_key in new_keys:
env_file.write(f"{key}={api_key}\n") env_file.write(f"{key}={api_key}\n")
os.environ[key] = api_key os.environ[key] = api_key
st.success(f"{key} added successfully! Enter to Continue..") st.success(f"{key} added successfully! Press Enter to continue.")
return False return False
return True return True
@@ -317,7 +324,6 @@ def main():
sidebar_configuration() sidebar_configuration()
else: else:
st.error("Error loading Environment variables.") st.error("Error loading Environment variables.")
st.stop()
# Define the tabs # Define the tabs
tab1, tab2, tab3, tab4, tab5 = st.tabs( tab1, tab2, tab3, tab4, tab5 = st.tabs(

View File

@@ -74,11 +74,11 @@ def write_blog_from_keywords(search_keywords, url=None):
if blog_markdown_str and tavily_search_result: if blog_markdown_str and tavily_search_result:
logger.info(f"\n\n######### Blog content after Tavily AI research: ######### \n\n") logger.info(f"\n\n######### Blog content after Tavily AI research: ######### \n\n")
blog_markdown_str = write_blog_google_serp(search_keywords, tavily_search_result) blog_markdown_str = write_blog_google_serp(search_keywords, tavily_search_result)
status.update(label="Finished Writing Blog From Tavily Results:{blog_markdown_str}") status.update(label="Finished Writing Blog From Tavily Results:{blog_markdown_str}", expanded=True)
except Exception as err: except Exception as err:
logger.error(f"Failed to do Tavily AI research: {err}") logger.error(f"Failed to do Tavily AI research: {err}")
status.update(label="🙎 Generating - Title, Meta Description, Tags, Categories for the content.") status.update(label="🙎 Generating - Title, Meta Description, Tags, Categories for the content.", expanded=True)
try: try:
blog_title, blog_meta_desc, blog_tags, blog_categories = blog_metadata(blog_markdown_str) blog_title, blog_meta_desc, blog_tags, blog_categories = blog_metadata(blog_markdown_str)
except Exception as err: except Exception as err:
@@ -87,21 +87,14 @@ def write_blog_from_keywords(search_keywords, url=None):
try: try:
generated_image_filepath = generate_image(f"{blog_title} + ' ' + {blog_meta_desc}") generated_image_filepath = generate_image(f"{blog_title} + ' ' + {blog_meta_desc}")
except Exception as err: except Exception as err:
st.error(f"Failed in Image generation: {err}") st.warning(f"Failed in Image generation: {err}")
saved_blog_to_file = save_blog_to_file(blog_markdown_str, blog_title, blog_meta_desc, saved_blog_to_file = save_blog_to_file(blog_markdown_str, blog_title, blog_meta_desc,
blog_tags, blog_categories, generated_image_filepath) blog_tags, blog_categories, generated_image_filepath)
status.update(label=f"Saved the content in this file: {saved_blog_to_file}") status.update(label=f"Saved the content in this file: {saved_blog_to_file}")
blog_frontmatter = dedent(f"""
\n---------------------------------------------------------------------
title: {blog_title.strip()}\n
categories: [{blog_categories.strip()}]\n
tags: [{blog_tags.strip()}]\n
Meta description: {blog_meta_desc.replace(":", "-").strip()}\n
---------------------------------------------------------------------\n
""")
logger.info(f"\n\n --------- Finished writing Blog for : {search_keywords} -------------- \n") logger.info(f"\n\n --------- Finished writing Blog for : {search_keywords} -------------- \n")
st.markdown(f"{blog_frontmatter}")
# Render the result on streamlit UI
st.image(generated_image_filepath) st.image(generated_image_filepath)
st.markdown(f"{blog_markdown_str}") st.markdown(f"{blog_markdown_str}")
status.update(label=f"Finished, Review & Use your Original Content Below: {saved_blog_to_file}") status.update(label=f"Finished, Review & Use your Original Content Below: {saved_blog_to_file}", state="complete")

View File

@@ -1,28 +1,52 @@
import sys import sys
import streamlit as st import streamlit as st
from loguru import logger from loguru import logger
import random
import time
logger.remove() logger.remove()
logger.add(sys.stdout, logger.add(sys.stdout,
colorize=True, colorize=True,
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}" format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
) )
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
def blog_metadata(blog_article): def blog_metadata(blog_article):
""" Common function to get blog metadata """ """ Common function to get blog metadata """
logger.info(f"Generating Content MetaData\n") logger.info(f"Generating Content MetaData\n")
progress_bar = st.progress(0)
total_steps = 4
# Step 1: Generate blog title
time.sleep(random.uniform(1, 3))
blog_title = generate_blog_title(blog_article) blog_title = generate_blog_title(blog_article)
progress_bar.progress(1 / total_steps)
# Step 2: Generate blog meta description
time.sleep(random.uniform(1, 3))
blog_meta_desc = generate_blog_description(blog_article) blog_meta_desc = generate_blog_description(blog_article)
progress_bar.progress(2 / total_steps)
# Step 3: Generate blog tags
time.sleep(random.uniform(1, 3))
blog_tags = get_blog_tags(blog_article) blog_tags = get_blog_tags(blog_article)
progress_bar.progress(3 / total_steps)
# Step 4: Generate blog categories
time.sleep(random.uniform(1, 3))
blog_categories = get_blog_categories(blog_article) blog_categories = get_blog_categories(blog_article)
progress_bar.progress(4 / total_steps)
# Present the result in a table format
st.table({
"Metadata": ["Blog Title", "Meta Description", "Tags", "Categories"],
"Value": [blog_title, blog_meta_desc, blog_tags, blog_categories]
})
return blog_title, blog_meta_desc, blog_tags, blog_categories return blog_title, blog_meta_desc, blog_tags, blog_categories
def generate_blog_title(blog_article): def generate_blog_title(blog_article):
""" """
Given a blog title generate an outline for it Given a blog title generate an outline for it
@@ -43,7 +67,6 @@ def generate_blog_title(blog_article):
logger.error(f"Failed to get response from LLM: {err}") logger.error(f"Failed to get response from LLM: {err}")
raise err raise err
def generate_blog_description(blog_content): def generate_blog_description(blog_content):
""" """
Prompt designed to give SEO optimized blog descripton Prompt designed to give SEO optimized blog descripton
@@ -62,7 +85,6 @@ def generate_blog_description(blog_content):
logger.error(f"Failed to get response from LLM:{err}") logger.error(f"Failed to get response from LLM:{err}")
raise err raise err
def get_blog_categories(blog_article): def get_blog_categories(blog_article):
""" """
Function to generate blog categories for given blog content. Function to generate blog categories for given blog content.
@@ -80,12 +102,10 @@ def get_blog_categories(blog_article):
except Exception as err: except Exception as err:
logger.error(f"get_blog_categories:Failed to get response from LLM: {err}") logger.error(f"get_blog_categories:Failed to get response from LLM: {err}")
def get_blog_tags(blog_article): def get_blog_tags(blog_article):
""" """
Function to suggest tags for the given blog content Function to suggest tags for the given blog content
""" """
# Suggest at least 5 tags for the following blog post [Enter your blog post text here].
prompt = f"""As an expert SEO and blog writer, suggest only 2 relevant and specific blog tags prompt = f"""As an expert SEO and blog writer, suggest only 2 relevant and specific blog tags
for the given blog content. Only reply with comma separated values. for the given blog content. Only reply with comma separated values.
Blog content: {blog_article}.""" Blog content: {blog_article}."""
@@ -96,3 +116,4 @@ def get_blog_tags(blog_article):
except Exception as err: except Exception as err:
logger.error(f"Failed to get response from LLM: {err}") logger.error(f"Failed to get response from LLM: {err}")
raise err raise err

View File

@@ -2,6 +2,7 @@
import os import os
import sys import sys
from pathlib import Path from pathlib import Path
import streamlit as st
import google.generativeai as genai import google.generativeai as genai
from dotenv import load_dotenv from dotenv import load_dotenv
@@ -44,6 +45,7 @@ def gemini_text_response(prompt, temperature, top_p, n, max_tokens):
for chunk in response: for chunk in response:
# text_response.append(chunk.text) # text_response.append(chunk.text)
print(chunk.text) print(chunk.text)
#st.write(chunk.text)
else: else:
print(response) print(response)
logger.info(f"Number of Token in Prompt Sent: {model.count_tokens(prompt)}") logger.info(f"Number of Token in Prompt Sent: {model.count_tokens(prompt)}")

File diff suppressed because one or more lines are too long

View File

@@ -95,7 +95,7 @@ input[type="text"] {
} }
/* Custom button styling */ /* Custom button styling */
button { div.stButton > button:first-child {
background: #1565C0; /* Match tab color */ background: #1565C0; /* Match tab color */
color: white; color: white;
border: none; border: none;
@@ -112,8 +112,8 @@ button {
font-weight: bold; font-weight: bold;
} }
button:hover { div.stButton > button:hover:first-child {
background-color: #1976D2; /* Match tab hover color */ background-color: #1976A2; /* Match tab hover color */
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3); box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 KiB

View File

@@ -5,6 +5,7 @@ python-dotenv
loguru loguru
openai openai
crewai[tools] crewai[tools]
crewai_tools
google.generativeai google.generativeai
mistralai mistralai
tenacity tenacity