Features: AI Rich snippet from url, AI product description writer
This commit is contained in:
@@ -7,7 +7,7 @@ Prompting is abstracted to get going sooner. Focus on your content quality, rath
|
|||||||
Alwrity gives hyper content personalization, factual web researched & SEO optimized content and tools for automating content & digital marketing.
|
Alwrity gives hyper content personalization, factual web researched & SEO optimized content and tools for automating content & digital marketing.
|
||||||
|
|
||||||
AI will help achieve Content Hyper-Personalization.
|
AI will help achieve Content Hyper-Personalization.
|
||||||

|

|
||||||
---
|
---
|
||||||
1). [Visit alwrity.com](https://www.alwrity.com/ai-writing-tools), You will find AI content writing tools, which are Free & No-Signup.
|
1). [Visit alwrity.com](https://www.alwrity.com/ai-writing-tools), You will find AI content writing tools, which are Free & No-Signup.
|
||||||
**Note:** Although, this is limited, as is our wallet & Resources.
|
**Note:** Although, this is limited, as is our wallet & Resources.
|
||||||
@@ -35,9 +35,10 @@ If you have 💻 Laptop + 🛜 Internet + 10 minutes, you will be generating blo
|
|||||||
3). streamlit run alwrity.py
|
3). streamlit run alwrity.py
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
**Still stuck, [Open issue here](https://github.com/AJaySi/AI-Writer/issues) & Someone will bail you out.
|
**Still stuck, [Open issue here](https://github.com/AJaySi/AI-Writer/issues) & Someone will bail you out.**
|
||||||
---
|
---
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### AI Tools & Features of Alwrity:
|
### AI Tools & Features of Alwrity:
|
||||||
| No. | Alwrity Tool | Description |
|
| No. | Alwrity Tool | Description |
|
||||||
@@ -67,7 +68,7 @@ If you have 💻 Laptop + 🛜 Internet + 10 minutes, you will be generating blo
|
|||||||
---
|
---
|
||||||
|
|
||||||
# AI Content Generation Toolkit - Alwrity
|
# AI Content Generation Toolkit - Alwrity
|
||||||

|

|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
|||||||
22
alwrity.py
22
alwrity.py
@@ -9,13 +9,13 @@ import base64
|
|||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
#from lib.chatbot_custom.chatbot_local_docqa import alwrity_chat_docqa
|
#from lib.chatbot_custom.chatbot_local_docqa import alwrity_chat_docqa
|
||||||
from lib.utils.alwrity_utils import (blog_from_keyword, ai_agents_team,
|
from lib.utils.alwrity_utils import (blog_from_keyword, ai_agents_team, essay_writer, ai_news_writer, ai_seo_tools,
|
||||||
essay_writer, ai_news_writer, ai_seo_tools,
|
|
||||||
ai_finance_ta_writer, ai_social_writer,
|
ai_finance_ta_writer, ai_social_writer,
|
||||||
do_web_research, competitor_analysis,
|
do_web_research, competitor_analysis,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lib.ai_writers.ai_story_writer.story_writer import story_input_section
|
from lib.ai_writers.ai_story_writer.story_writer import story_input_section
|
||||||
|
from lib.ai_writers.ai_product_description_writer import write_ai_prod_desc
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
@@ -334,9 +334,9 @@ def main():
|
|||||||
|
|
||||||
# Define the tabs
|
# Define the tabs
|
||||||
tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs(
|
tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs(
|
||||||
["AI Writers", "Content Planning", "Agents Teams", "AI SEO tools", "Alwrity Brain", "Ask Alwrity"])
|
["AI Writers", "Content Planning", "Agents Teams", "AI SEO tools", "AI Social Tools", "Ask Alwrity"])
|
||||||
with tab1:
|
with tab1:
|
||||||
write_blog()
|
ai_writers()
|
||||||
|
|
||||||
with tab2:
|
with tab2:
|
||||||
content_planning_tools()
|
content_planning_tools()
|
||||||
@@ -348,10 +348,10 @@ def main():
|
|||||||
ai_seo_tools()
|
ai_seo_tools()
|
||||||
|
|
||||||
with tab5:
|
with tab5:
|
||||||
alwrity_brain()
|
ai_social_writer()
|
||||||
|
|
||||||
with tab6:
|
with tab6:
|
||||||
st.info("Chatbot")
|
st.subheader("Chat with your Data, Chat with any Data.. COMING SOON !")
|
||||||
st.markdown("Create a collection by uploading files (PDF, MD, CSV, etc), or crawl a data source (Websites, more sources coming soon.")
|
st.markdown("Create a collection by uploading files (PDF, MD, CSV, etc), or crawl a data source (Websites, more sources coming soon.")
|
||||||
st.markdown("One can ask/chat, summarize and do semantic search over the uploaded data")
|
st.markdown("One can ask/chat, summarize and do semantic search over the uploaded data")
|
||||||
#alwrity_chat_docqa()
|
#alwrity_chat_docqa()
|
||||||
@@ -374,14 +374,14 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
# Functions for the main options
|
# Functions for the main options
|
||||||
def write_blog():
|
def ai_writers():
|
||||||
options = [
|
options = [
|
||||||
"AI Blog Writer",
|
"AI Blog Writer",
|
||||||
"Story Writer",
|
"Story Writer",
|
||||||
"Essay writer",
|
"Essay writer",
|
||||||
"Write News reports",
|
"Write News reports",
|
||||||
"Write Financial TA report",
|
"Write Financial TA report",
|
||||||
"AI Social writer (instagram, tweets, linkedin, facebook post)",
|
"AI Product Description Writer",
|
||||||
"AI Copywriter",
|
"AI Copywriter",
|
||||||
"Quit"
|
"Quit"
|
||||||
]
|
]
|
||||||
@@ -399,10 +399,10 @@ def write_blog():
|
|||||||
ai_news_writer()
|
ai_news_writer()
|
||||||
elif choice == "Write Financial TA report":
|
elif choice == "Write Financial TA report":
|
||||||
ai_finance_ta_writer()
|
ai_finance_ta_writer()
|
||||||
elif choice == "AI Social writer (instagram, tweets, linkedin, facebook post)":
|
elif choice == "AI Product Description Writer":
|
||||||
ai_social_writer()
|
write_ai_prod_desc()
|
||||||
elif choice == "Quit":
|
elif choice == "Quit":
|
||||||
st.write("Exiting, Getting Lost. But.... I have nowhere to go 🥹🥹")
|
st.subheader("Exiting, Getting Lost. But.... I have nowhere to go 🥹🥹")
|
||||||
|
|
||||||
|
|
||||||
def content_planning_tools():
|
def content_planning_tools():
|
||||||
|
|||||||
115
lib/ai_writers/ai_product_description_writer.py
Normal file
115
lib/ai_writers/ai_product_description_writer.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import streamlit as st
|
||||||
|
import json
|
||||||
|
|
||||||
|
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
|
||||||
|
|
||||||
|
|
||||||
|
def generate_product_description(title, details, audience, tone, length, keywords):
|
||||||
|
"""
|
||||||
|
Generates a product description using OpenAI's API.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
title (str): The title of the product.
|
||||||
|
details (list): A list of product details (features, benefits, etc.).
|
||||||
|
audience (list): A list of target audience segments.
|
||||||
|
tone (str): The desired tone of the description (e.g., "Formal", "Informal").
|
||||||
|
length (str): The desired length of the description (e.g., "short", "medium", "long").
|
||||||
|
keywords (str): Keywords related to the product (comma-separated).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The generated product description.
|
||||||
|
"""
|
||||||
|
prompt = f"""
|
||||||
|
Write a compelling product description for {title}.
|
||||||
|
|
||||||
|
Highlight these key features: {', '.join(details)}
|
||||||
|
|
||||||
|
Emphasize the benefits of these features for the target audience ({audience}).
|
||||||
|
Maintain a {tone} tone and aim for a length of approximately {length} words.
|
||||||
|
|
||||||
|
Use these keywords naturally throughout the description: {', '.join(keywords)}.
|
||||||
|
|
||||||
|
Remember to be persuasive and focus on the value proposition.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = llm_text_gen(prompt)
|
||||||
|
return response
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(f"Exit: Failed to get response from LLM: {err}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def display_inputs():
|
||||||
|
st.title("📝 AI Product Description Writer 🚀")
|
||||||
|
st.markdown("**Generate compelling and accurate product descriptions with AI.**")
|
||||||
|
|
||||||
|
col1, col2 = st.columns(2)
|
||||||
|
|
||||||
|
with col1:
|
||||||
|
product_title = st.text_input("🏷️ **Product Title**", placeholder="Enter the product title (e.g., Wireless Bluetooth Headphones)")
|
||||||
|
with col2:
|
||||||
|
product_details = st.text_area("📄 **Product Details**", placeholder="Enter features, benefits, specifications, materials, etc. (e.g., Noise Cancellation, Long Battery Life, Water Resistant, Comfortable Design)")
|
||||||
|
|
||||||
|
col3, col4 = st.columns(2)
|
||||||
|
|
||||||
|
with col3:
|
||||||
|
keywords = st.text_input("🔑 **Keywords**", placeholder="Enter keywords, comma-separated (e.g., wireless headphones, noise cancelling, Bluetooth 5.0)")
|
||||||
|
with col4:
|
||||||
|
target_audience = st.multiselect(
|
||||||
|
"🎯 **Target Audience**",
|
||||||
|
["Teens", "Adults", "Seniors", "Music Lovers", "Fitness Enthusiasts", "Tech Savvy", "Busy Professionals", "Travelers", "Casual Users"],
|
||||||
|
placeholder="Select target audience (optional)"
|
||||||
|
)
|
||||||
|
|
||||||
|
col5, col6 = st.columns(2)
|
||||||
|
|
||||||
|
with col5:
|
||||||
|
description_length = st.selectbox(
|
||||||
|
"📏 **Desired Description Length**",
|
||||||
|
["Short (1-2 sentences)", "Medium (3-5 sentences)", "Long (6+ sentences)"],
|
||||||
|
help="Select the desired length of the product description"
|
||||||
|
)
|
||||||
|
with col6:
|
||||||
|
brand_tone = st.selectbox(
|
||||||
|
"🎨 **Brand Tone**",
|
||||||
|
["Formal", "Informal", "Fun & Energetic"],
|
||||||
|
help="Select the desired tone for the description"
|
||||||
|
)
|
||||||
|
|
||||||
|
return product_title, product_details, target_audience, brand_tone, description_length, keywords
|
||||||
|
|
||||||
|
|
||||||
|
def display_output(description):
|
||||||
|
if description:
|
||||||
|
st.subheader("✨ Generated Product Description:")
|
||||||
|
st.write(description)
|
||||||
|
|
||||||
|
json_ld = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Product",
|
||||||
|
"name": product_title,
|
||||||
|
"description": description,
|
||||||
|
"audience": target_audience,
|
||||||
|
"brand": {
|
||||||
|
"@type": "Brand",
|
||||||
|
"name": "Your Brand Name"
|
||||||
|
},
|
||||||
|
"keywords": keywords.split(", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def write_ai_prod_desc():
|
||||||
|
product_title, product_details, target_audience, brand_tone, description_length, keywords = display_inputs()
|
||||||
|
|
||||||
|
if st.button("Generate Product Description 🚀"):
|
||||||
|
with st.spinner("Generating description..."):
|
||||||
|
description = generate_product_description(
|
||||||
|
product_title,
|
||||||
|
product_details.split(", "), # Split details into a list
|
||||||
|
target_audience,
|
||||||
|
brand_tone,
|
||||||
|
description_length.split(" ")[0].lower(), # Extract length from selectbox
|
||||||
|
keywords
|
||||||
|
)
|
||||||
|
display_output(description)
|
||||||
@@ -87,12 +87,6 @@ def facebook_post_writer():
|
|||||||
)
|
)
|
||||||
|
|
||||||
with col2:
|
with col2:
|
||||||
business_type = st.text_input(
|
|
||||||
"🏢 **What is your business type?**",
|
|
||||||
placeholder="e.g., Fitness coach",
|
|
||||||
help="Provide the type of your business. This will help tailor the post content."
|
|
||||||
)
|
|
||||||
|
|
||||||
post_tone_options = ["Informative", "Humorous", "Inspirational", "Upbeat", "Casual", "Customize"]
|
post_tone_options = ["Informative", "Humorous", "Inspirational", "Upbeat", "Casual", "Customize"]
|
||||||
post_tone = st.selectbox(
|
post_tone = st.selectbox(
|
||||||
"🎨 **What tone do you want to use?**",
|
"🎨 **What tone do you want to use?**",
|
||||||
@@ -108,6 +102,12 @@ def facebook_post_writer():
|
|||||||
help="Provide a specific tone if you selected 'Customize'."
|
help="Provide a specific tone if you selected 'Customize'."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
business_type = st.text_input(
|
||||||
|
"🏢 **What is your business type?**",
|
||||||
|
placeholder="e.g., Fitness coach",
|
||||||
|
help="Provide the type of your business. This will help tailor the post content."
|
||||||
|
)
|
||||||
|
|
||||||
avoid = st.text_input(
|
avoid = st.text_input(
|
||||||
"❌ **What elements do you want to avoid?**",
|
"❌ **What elements do you want to avoid?**",
|
||||||
placeholder="e.g., Long paragraphs",
|
placeholder="e.g., Long paragraphs",
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
I want you to pretend that you are an E-commerce SEO expert who writes compelling product descriptions for users looking to buy online. I am going to provide the title of one e-commerce product and I want you to come up with a minimum of three distinct content sections for the product description, each section about a unique subset of keywords relating to the product I provide you. Make sure that each of the unique content sections are labeled with an informative and eye-catching subheading describing the main focus of the content section. The main point of these commands is for you to developing a new keyword-rich, informative, and captivating product summary/description that is less than 1000 words. The purpose of product description is marketing the products to users looking to buy. Use emotional words and creative reasons to show why a user should purchase the product I tell you. After you generate the new product summary, please generate a bulleted list of 5 possible H1 headings for this product page, and make each H1 less than 7 words each. Please also include bulleted list of broad match keywords that were used to accomplish writing the product summary. Write a persuasive and professional sounding Meta Title and Description that integrates similar language present in the new product summary text. Make sure to include a numerical aspect in the Meta Title. Do not echo my prompt. Do not remind me what I asked you for. Do not apologize. Do not self-reference. Please use the following products:{Enter descriptive product name - 1 only}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
###############################################################################
|
|
||||||
#
|
|
||||||
# To use the module, simply create an instance of the AmazonAffiliateImages class,
|
|
||||||
# passing in your Amazon affiliate tag. Then, you can use the get_image_url() or
|
|
||||||
# get_image_html() methods to get the Amazon affiliate image URL or HTML for a product,
|
|
||||||
# passing in either the product ASIN or the product URL.
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
|
|
||||||
class AmazonAffiliateImages:
|
|
||||||
def __init__(self, associate_tag):
|
|
||||||
self.associate_tag = associate_tag
|
|
||||||
|
|
||||||
def get_product_asin(self, product_url):
|
|
||||||
"""Gets the Amazon product ASIN from a product URL.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
product_url: The Amazon product URL.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The Amazon product ASIN, or None if the product URL is not valid.
|
|
||||||
"""
|
|
||||||
|
|
||||||
soup = BeautifulSoup(requests.get(product_url).content, "html.parser")
|
|
||||||
asin = soup.find("input", type="hidden", name="ASIN")
|
|
||||||
if asin is not None:
|
|
||||||
return asin.get("value")
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_image_url(self, product_asin):
|
|
||||||
"""Gets the Amazon affiliate image URL for a product.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
product_asin: The Amazon product ASIN.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The Amazon affiliate image URL, or None if the product is not found.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url = f"https://images-na.ssl-images-amazon.com/images/I/{product_asin}.jpg"
|
|
||||||
response = requests.get(url)
|
|
||||||
if response.status_code == 200:
|
|
||||||
return url
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_image_html(self, product_asin):
|
|
||||||
"""Gets the Amazon affiliate image HTML for a product.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
product_asin: The Amazon product ASIN.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The Amazon affiliate image HTML, or None if the product is not found.
|
|
||||||
"""
|
|
||||||
|
|
||||||
image_url = self.get_image_url(product_asin)
|
|
||||||
if image_url is not None:
|
|
||||||
return f'<img src="{image_url}" alt="Amazon Affiliate Image" />'
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
#######################################################
|
|
||||||
|
|
||||||
import amazon_affiliate_images
|
|
||||||
|
|
||||||
affiliate_images = AmazonAffiliateImages("YOUR_ASSOCIATE_TAG")
|
|
||||||
image_html = affiliate_images.get_image_html("B00004CB54")
|
|
||||||
|
|
||||||
# Print the image HTML
|
|
||||||
print(image_html)
|
|
||||||
|
|
||||||
# Output : <img src="https://images-na.ssl-images-amazon.com/images/I/B00004CB54.jpg" alt="Amazon Affiliate Image" />
|
|
||||||
# You can then use this image HTML in your blog post.
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import openai
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
|
||||||
|
|
||||||
def gen_ecomm_product_desc(product_name):
|
|
||||||
"""Given a product name, generate relevant content for blogging.
|
|
||||||
"""
|
|
||||||
|
|
||||||
product_desc = openai.ChatCompletion.create(
|
|
||||||
model="gpt-3.5-turbo-16k",
|
|
||||||
messages=[
|
|
||||||
{"role": "system",
|
|
||||||
"content": """Act as an expert E-commerce copywriter specializing in content optimization for SEO. As an E-commerce SEO expert who writes compelling product descriptions for users looking to buy online. I am going to provide the title of one e-commerce product and I want you to come up with a minimum of three distinct content sections for the product description, each section about a unique subset of keywords relating to the product I provide you. Make sure that each of the unique content sections are labeled with an informative and eye-catching subheading describing the main focus of the content section. The main point of these commands is for you to developing a new keyword-rich, informative, and captivating product summary/description that is less than 1000 words. The purpose of product description is marketing the products to users looking to buy. Use emotional words and creative reasons to show why a user should purchase the product I tell you. After you generate the new product summary, please generate a bulleted list of 5 possible H1 headings for this product page, and make each H1 less than 7 words each. Please also include bulleted list of broad match keywords that were used to accomplish writing the product summary. Write a persuasive and professional sounding Meta Title and Description that integrates similar language present in the new product summary text. Make sure to include a numerical aspect in the Meta Title. Do not echo my prompt. Do not remind me what I asked you for. Do not apologize. Do not self-reference."""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": f"""Craft blog content for following e commerce product.
|
|
||||||
Product: {product_name}""",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
max_tokens=4096,
|
|
||||||
temperature=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
if "choices" in product_desc and len(product_desc["choices"]) > 0:
|
|
||||||
return product_desc["choices"][0]["message"]["content"]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
BIN
lib/utils/.alwrity_utils.py.swp
Normal file
BIN
lib/utils/.alwrity_utils.py.swp
Normal file
Binary file not shown.
BIN
lib/workspace/structured_data_seo.mp4
Normal file
BIN
lib/workspace/structured_data_seo.mp4
Normal file
Binary file not shown.
Reference in New Issue
Block a user