Update app.py
Browse files
app.py
CHANGED
@@ -341,7 +341,7 @@ if __name__ == "__main__":
|
|
341 |
app.launch(share=True)'''
|
342 |
|
343 |
|
344 |
-
import gradio as gr
|
345 |
import os
|
346 |
import time
|
347 |
import requests
|
@@ -730,7 +730,7 @@ def create_hosted_blog(topic):
|
|
730 |
|
731 |
<div class="sidebar-section">
|
732 |
<h3 class="sidebar-title">About the Author</h3>
|
733 |
-
<p>This article was created by
|
734 |
</div>
|
735 |
|
736 |
<div class="sidebar-section">
|
@@ -803,5 +803,199 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
|
|
803 |
outputs=[blog_link, blog_output]
|
804 |
)
|
805 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
806 |
if __name__ == "__main__":
|
807 |
app.launch(share=True)
|
|
|
341 |
app.launch(share=True)'''
|
342 |
|
343 |
|
344 |
+
'''import gradio as gr
|
345 |
import os
|
346 |
import time
|
347 |
import requests
|
|
|
730 |
|
731 |
<div class="sidebar-section">
|
732 |
<h3 class="sidebar-title">About the Author</h3>
|
733 |
+
<p>This article was created by Sakshi Jadhav that combines research, writing, and design capabilities to produce comprehensive, informative content on cutting-edge topics.</p>
|
734 |
</div>
|
735 |
|
736 |
<div class="sidebar-section">
|
|
|
803 |
outputs=[blog_link, blog_output]
|
804 |
)
|
805 |
|
806 |
+
if __name__ == "__main__":
|
807 |
+
app.launch(share=True)'''
|
808 |
+
|
809 |
+
import gradio as gr
|
810 |
+
import os
|
811 |
+
import time
|
812 |
+
import requests
|
813 |
+
import re
|
814 |
+
import uuid
|
815 |
+
import markdown
|
816 |
+
from datetime import datetime
|
817 |
+
from dotenv import load_dotenv
|
818 |
+
from huggingface_hub import HfApi, upload_file
|
819 |
+
|
820 |
+
load_dotenv()
|
821 |
+
|
822 |
+
# Configuration
|
823 |
+
HF_TOKEN = os.getenv("HF_TOKEN")
|
824 |
+
HF_USERNAME = "jsakshi"
|
825 |
+
AUTHOR_NAME = "Sarah Johnson" # Add your name here
|
826 |
+
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
|
827 |
+
|
828 |
+
def generate_blog_content(topic, seo_keywords):
|
829 |
+
try:
|
830 |
+
prompt = f"""Write a high-quality, well-researched blog post on {topic} that sounds completely human-written.
|
831 |
+
Requirements:
|
832 |
+
- Engaging, conversational tone (avoid AI-sounding phrases)
|
833 |
+
- Start with a strong hook in the introduction
|
834 |
+
- Use subheadings, bullet points, and real-world examples
|
835 |
+
- Bold 3-5 key terms using **bold** formatting
|
836 |
+
- Include: "This article was written by {AUTHOR_NAME}, combining research and industry expertise"
|
837 |
+
- SEO keywords: {', '.join(seo_keywords)}
|
838 |
+
- Length: 1500-2000 words
|
839 |
+
- Structure:
|
840 |
+
1. Introduction with surprising statistic/anecdote
|
841 |
+
2. 3-5 main sections with clear subheadings
|
842 |
+
3. Practical advice/actionable takeaways
|
843 |
+
4. Conclusion with thought-provoking question
|
844 |
+
|
845 |
+
Make it flow naturally with varied sentence structure. Avoid markdown formatting except for bolding."""
|
846 |
+
|
847 |
+
response = requests.post(
|
848 |
+
"https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2",
|
849 |
+
headers=HEADERS,
|
850 |
+
json={"inputs": prompt, "parameters": {"max_length": 2500}}
|
851 |
+
)
|
852 |
+
|
853 |
+
if response.status_code != 200:
|
854 |
+
return None, f"API Error: {response.text}"
|
855 |
+
|
856 |
+
blog_text = response.json()[0]['generated_text']
|
857 |
+
|
858 |
+
# Post-processing
|
859 |
+
blog_text = re.sub(r'\n{3,}', '\n\n', blog_text) # Remove extra newlines
|
860 |
+
blog_text = add_author_byline(blog_text, AUTHOR_NAME)
|
861 |
+
|
862 |
+
return extract_metadata(blog_text), None
|
863 |
+
|
864 |
+
except Exception as e:
|
865 |
+
return None, f"Error: {str(e)}"
|
866 |
+
|
867 |
+
def add_author_byline(content, author_name):
|
868 |
+
byline = f"\n\n---\n\n*This article was meticulously researched and written by {author_name}, " \
|
869 |
+
"combining hands-on industry experience with academic insights. All content is human-created.*"
|
870 |
+
return content + byline
|
871 |
+
|
872 |
+
def extract_metadata(blog_text):
|
873 |
+
# Extract title and subtitle
|
874 |
+
lines = blog_text.split('\n')
|
875 |
+
title = lines[0].strip().replace('#', '').strip()
|
876 |
+
subtitle = next((line.strip() for line in lines[1:10] if line.strip() and not line.startswith('#')), "In-Depth Analysis")
|
877 |
+
|
878 |
+
# Find key points for bold formatting
|
879 |
+
bold_terms = list(set(re.findall(r'\*\*(.*?)\*\*', blog_text)))
|
880 |
+
|
881 |
+
return {
|
882 |
+
"title": title,
|
883 |
+
"subtitle": subtitle,
|
884 |
+
"content": blog_text,
|
885 |
+
"bold_terms": bold_terms[:5]
|
886 |
+
}
|
887 |
+
|
888 |
+
def create_hosted_blog(topic, seo_keywords):
|
889 |
+
try:
|
890 |
+
# Generate blog content
|
891 |
+
content_data, error = generate_blog_content(topic, seo_keywords)
|
892 |
+
if error:
|
893 |
+
return f"Error: {error}", ""
|
894 |
+
|
895 |
+
# Create space and upload content (same as before)
|
896 |
+
# ... [keep previous space creation and image upload code] ...
|
897 |
+
|
898 |
+
# Enhanced HTML template with SEO
|
899 |
+
complete_html = f"""<!DOCTYPE html>
|
900 |
+
<html lang="en">
|
901 |
+
<head>
|
902 |
+
<meta charset="UTF-8">
|
903 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
904 |
+
<title>{content_data['title']}</title>
|
905 |
+
<meta name="description" content="{content_data['subtitle']}">
|
906 |
+
<meta name="keywords" content="{', '.join(seo_keywords)}">
|
907 |
+
<meta name="author" content="{AUTHOR_NAME}">
|
908 |
+
<!-- Keep previous styles, add these enhancements -->
|
909 |
+
<style>
|
910 |
+
.author-bio {{
|
911 |
+
display: flex;
|
912 |
+
align-items: center;
|
913 |
+
gap: 1rem;
|
914 |
+
padding: 1.5rem;
|
915 |
+
background: #f8f9fa;
|
916 |
+
border-radius: 8px;
|
917 |
+
margin: 2rem 0;
|
918 |
+
}}
|
919 |
+
.author-img {{
|
920 |
+
width: 80px;
|
921 |
+
height: 80px;
|
922 |
+
border-radius: 50%;
|
923 |
+
object-fit: cover;
|
924 |
+
}}
|
925 |
+
.key-terms {{
|
926 |
+
background: #fff3cd;
|
927 |
+
padding: 1rem;
|
928 |
+
border-left: 4px solid #ffc107;
|
929 |
+
margin: 1.5rem 0;
|
930 |
+
}}
|
931 |
+
/* Keep previous styles */
|
932 |
+
</style>
|
933 |
+
</head>
|
934 |
+
<body>
|
935 |
+
<header><!-- Same header --></header>
|
936 |
+
|
937 |
+
<div class="container">
|
938 |
+
<div class="blog-content">
|
939 |
+
<article class="main-content">
|
940 |
+
<div class="author-bio">
|
941 |
+
<img src="author-placeholder.png" alt="{AUTHOR_NAME}" class="author-img">
|
942 |
+
<div>
|
943 |
+
<h4>{AUTHOR_NAME}</h4>
|
944 |
+
<p>Industry expert with 10+ years experience in {topic.split()[-1]}</p>
|
945 |
+
</div>
|
946 |
+
</div>
|
947 |
+
|
948 |
+
<div class="key-terms">
|
949 |
+
<h4>Key Terms in This Article:</h4>
|
950 |
+
<p>{', '.join(content_data['bold_terms'])}</p>
|
951 |
+
</div>
|
952 |
+
|
953 |
+
<!-- Content sections -->
|
954 |
+
{process_content(content_data['content'])}
|
955 |
+
|
956 |
+
<!-- Keep footer and other elements -->
|
957 |
+
</article>
|
958 |
+
</div>
|
959 |
+
</div>
|
960 |
+
</body>
|
961 |
+
</html>
|
962 |
+
"""
|
963 |
+
# Upload and return
|
964 |
+
# ... [keep previous upload code] ...
|
965 |
+
|
966 |
+
except Exception as e:
|
967 |
+
return f"Error: {str(e)}", ""
|
968 |
+
|
969 |
+
def process_content(content):
|
970 |
+
# Convert markdown bold to HTML and add anchor links
|
971 |
+
content = content.replace('**', '<strong>').replace('**', '</strong>')
|
972 |
+
return markdown.markdown(content)
|
973 |
+
|
974 |
+
# Enhanced Gradio UI
|
975 |
+
with gr.Blocks(theme=gr.themes.Soft()) as app:
|
976 |
+
gr.Markdown("# ✍️ Human-Written Blog Generator")
|
977 |
+
gr.Markdown("Create authentic, SEO-optimized articles that read like human-written content")
|
978 |
+
|
979 |
+
with gr.Row():
|
980 |
+
with gr.Column():
|
981 |
+
topic_input = gr.Textbox(label="Main Topic",
|
982 |
+
placeholder="e.g., Sustainable AI Practices in Modern Tech")
|
983 |
+
seo_input = gr.Textbox(label="SEO Keywords (comma-separated)",
|
984 |
+
placeholder="AI sustainability, green tech, eco-friendly AI")
|
985 |
+
generate_btn = gr.Button("Create Article", variant="primary")
|
986 |
+
|
987 |
+
with gr.Column():
|
988 |
+
gr.Markdown("### Live Blog URL")
|
989 |
+
blog_link = gr.Markdown()
|
990 |
+
gr.Markdown("### Content Preview")
|
991 |
+
blog_output = gr.Markdown()
|
992 |
+
status = gr.Textbox(label="Generation Status")
|
993 |
+
|
994 |
+
generate_btn.click(
|
995 |
+
fn=create_hosted_blog,
|
996 |
+
inputs=[topic_input, seo_input],
|
997 |
+
outputs=[blog_link, blog_output]
|
998 |
+
)
|
999 |
+
|
1000 |
if __name__ == "__main__":
|
1001 |
app.launch(share=True)
|