'''import gradio as gr
import os
import time
import requests
import re
import uuid
import markdown
from datetime import datetime
from dotenv import load_dotenv
from huggingface_hub import HfApi, upload_file
load_dotenv()
# Configuration
HF_TOKEN = os.getenv("HF_TOKEN")
HF_USERNAME = "jsakshi"
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
def generate_blog_content(topic):
try:
prompt = f"""Create a detailed, professional blog post about {topic} including:
- A compelling title and subtitle
- An introduction
- 3 main sections with descriptive headings
- Key points and data examples in each section
- A conclusion
Use an informative, professional tone."""
response = requests.post(
"https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2",
headers=HEADERS,
json={"inputs": prompt, "parameters": {"max_length": 2000}}
)
if response.status_code != 200:
return None, f"API Error: {response.text}"
blog_text = response.json()[0]['generated_text']
# Extract title (assuming first line contains the title)
lines = blog_text.split('\n')
title = topic
subtitle = "A comprehensive analysis and exploration"
for line in lines[:5]:
if line.strip() and not line.startswith('#'):
title = line.strip()
break
# Look for a possible subtitle
for line in lines[1:10]:
if line.strip() and line != title and not line.startswith('#'):
subtitle = line.strip()
break
return {
"title": title,
"subtitle": subtitle,
"content": blog_text
}, None
except Exception as e:
return None, f"Error: {str(e)}"
def create_hosted_blog(topic):
try:
# Generate blog content first
content_data, error = generate_blog_content(topic)
if error or not content_data:
return f"Error generating content: {error}", ""
# Create unique space
space_id = f"blog-{uuid.uuid4().hex[:8]}"
space_name = f"{HF_USERNAME}/{space_id}"
# Initialize Hub API
api = HfApi(token=HF_TOKEN)
api.create_repo(
repo_id=space_name,
repo_type="space",
space_sdk="static",
private=False
)
# Generate and upload images
image_paths = []
image_prompts = [
f"Professional illustration about {topic}, integrating real-world images with clean design and minimalist style. "
f"Include conceptual diagrams, flowcharts, or graphs alongside real-world elements to enhance understanding. "
f"Use subtle colors, modern typography, and a well-structured layout for clarity and engagement.",
f"Data visualization or concept diagram related to {topic}, combining infographic elements with real-world scenarios. "
f"Ensure a balance of artistic design and informative content, making it suitable for presentations or reports. "
f"Include 3D renders or photorealistic overlays to improve visualization."
]
for idx, img_prompt in enumerate(image_prompts):
response = requests.post(
"https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
headers=HEADERS,
json={"inputs": img_prompt}
)
if response.status_code == 200:
img_filename = f"image_{idx}.png"
upload_file(
path_or_fileobj=response.content,
path_in_repo=img_filename,
repo_id=space_name,
repo_type="space"
)
image_paths.append(img_filename)
time.sleep(2) # Add delay to prevent rate limiting
# Format the current date
current_date = datetime.now().strftime("%B %d, %Y")
# Create HTML using the modern template from the example
title = content_data.get("title", topic)
subtitle = content_data.get("subtitle", "A comprehensive analysis")
content = content_data.get("content", "")
# Process the content to get sections for TOC
sections = []
section_pattern = re.compile(r'^##?\s+(.+)$', re.MULTILINE)
section_matches = section_pattern.findall(content)
for i, section in enumerate(section_matches[:6]):
section_id = section.lower().replace(' ', '-').replace(':', '')
sections.append({
"title": section,
"id": section_id
})
# Convert markdown content to HTML with proper section IDs
html_content = content
for section in sections:
pattern = f"## {section['title']}"
replacement = f"
{f'' if image_paths else ''}
{html_content}
{f'' if len(image_paths) > 1 else ''}
Key Takeaways
This article explores the essential aspects of {topic}, providing insights into current trends, challenges, and future opportunities in this field.
"""
# Upload HTML file
upload_file(
path_or_fileobj=complete_html.encode(),
path_in_repo="index.html",
repo_id=space_name,
repo_type="space"
)
return f"https://huggingface.co/spaces/{space_name}", content_data.get("content", "")
except Exception as e:
return f"Error: {str(e)}", ""
# Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as app:
gr.Markdown("# 📄 Professional Blog Generator")
gr.Markdown("Create well-structured, professional blog posts with just a topic")
with gr.Row():
with gr.Column():
topic_input = gr.Textbox(label="Enter Blog Topic",
placeholder="e.g., Future of AI in Healthcare")
generate_btn = gr.Button("Generate Blog", variant="primary")
status = gr.Textbox(label="Status", interactive=False)
with gr.Column():
gr.Markdown("### Blog URL")
blog_link = gr.Markdown("Your blog link will appear here...")
gr.Markdown("### Preview")
blog_output = gr.Markdown()
generate_btn.click(
fn=create_hosted_blog,
inputs=topic_input,
outputs=[blog_link, blog_output]
)
if __name__ == "__main__":
app.launch(share=True)'''
import gradio as gr
import os
import time
import requests
import re
import uuid
import markdown
from datetime import datetime
from dotenv import load_dotenv
from huggingface_hub import HfApi, upload_file
import json
from functools import partial
import logging
# Set up logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
load_dotenv()
# Configuration
HF_TOKEN = os.getenv("HF_TOKEN")
if not HF_TOKEN:
logger.error("HF_TOKEN not found in .env file")
HF_USERNAME = "jsakshi"
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
# Simulated user authentication (replace with proper auth in production)
AUTHORIZED_USERS = {"admin": "password123"} # username: password
# Store edit history for undo/redo
edit_history = []
current_history_index = -1
def generate_initial_content(topic):
"""Generate initial blog content using Hugging Face API."""
logger.info(f"Generating content for topic: {topic}")
try:
prompt = f"""Create a detailed blog post about {topic} including:
- A compelling title and subtitle
- An introduction
- 3 main sections with descriptive headings
- A conclusion
Use an informative tone."""
response = requests.post(
"https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2",
headers=HEADERS,
json={"inputs": prompt, "parameters": {"max_length": 2000}}
)
if response.status_code != 200:
logger.error(f"API request failed: {response.status_code} - {response.text}")
return f"Error: API request failed with status {response.status_code}"
return response.json()[0]['generated_text']
except Exception as e:
logger.error(f"Error generating content: {str(e)}")
return f"Error generating content: {str(e)}"
def generate_image(prompt):
"""Generate an image using Stable Diffusion API."""
try:
response = requests.post(
"https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
headers=HEADERS,
json={"inputs": prompt}
)
if response.status_code == 200:
return response.content
logger.error(f"Image generation failed: {response.status_code} - {response.text}")
return None
except Exception as e:
logger.error(f"Error generating image: {str(e)}")
return None
def create_or_update_space(content_data, space_name=None, images=[]):
"""Create or update a Hugging Face Space with editable content."""
try:
api = HfApi(token=HF_TOKEN)
if not space_name:
space_id = f"blog-{uuid.uuid4().hex[:8]}"
space_name = f"{HF_USERNAME}/{space_id}"
api.create_repo(repo_id=space_name, repo_type="space", space_sdk="static", private=False)
logger.info(f"Created new space: {space_name}")
# Process content into editable sections
sections = re.split(r'(## .+)', content_data)
html_content = '
'
current_section = ""
for part in sections:
if part.strip():
if part.startswith('## '):
if current_section:
html_content += f'
{markdown.markdown(current_section)}
'
html_content += f'
{part[3:]}
'
current_section = ""
else:
current_section += part
if current_section:
html_content += f'
{markdown.markdown(current_section)}
'
html_content += ''
# Add images
image_html = ""
for i, img_path in enumerate(images):
image_html += f'
'
# Complete HTML with editing features
complete_html = f"""
Editable Blog
{html_content}
{image_html}
"""
# Upload HTML
upload_file(
path_or_fileobj=complete_html.encode(),
path_in_repo="index.html",
repo_id=space_name,
repo_type="space"
)
# Upload images if provided as bytes
for i, img in enumerate(images):
if isinstance(img, bytes):
upload_file(
path_or_fileobj=img,
path_in_repo=f"image_{i}.png",
repo_id=space_name,
repo_type="space"
)
images[i] = f"image_{i}.png"
logger.info(f"Updated space: {space_name}")
return f"https://huggingface.co/spaces/{space_name}"
except Exception as e:
logger.error(f"Error creating/updating space: {str(e)}")
return None
def authenticate(username, password):
"""Authenticate user against hardcoded credentials."""
if not username or not password:
logger.warning("Empty username or password provided")
return False
is_valid = username in AUTHORIZED_USERS and AUTHORIZED_USERS[username] == password
logger.info(f"Authentication attempt for {username}: {'Success' if is_valid else 'Failed'}")
return is_valid
def generate_and_edit(topic, username, password):
"""Generate blog and create editable space."""
logger.info(f"Starting generate_and_edit for topic: {topic}")
# Check authentication
if not authenticate(username, password):
return "Authentication failed: Incorrect username or password", "", "Error"
# Check HF_TOKEN
if not HF_TOKEN:
return "Authentication failed: HF_TOKEN not set in .env", "", "Error"
# Generate content
initial_content = generate_initial_content(topic)
if "Error" in initial_content:
return "Failed to generate content", initial_content, "Error"
# Generate images
image_prompts = [
f"Professional illustration about {topic}, clean design, minimalist style.",
f"Data visualization related to {topic}, infographic style."
]
images = []
for prompt in image_prompts:
img_data = generate_image(prompt)
if img_data:
images.append(img_data)
time.sleep(2) # Prevent rate limiting
# Create space
space_url = create_or_update_space(initial_content, images=images)
if not space_url:
return "Failed to create space", initial_content, "Error"
return space_url, initial_content, "Blog generated successfully"
# Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as app:
gr.Markdown("# 📝 Blog Editor")
gr.Markdown("Generate and edit professional blog posts with an intuitive interface")
with gr.Row():
with gr.Column():
username = gr.Textbox(label="Username", placeholder="admin")
password = gr.Textbox(label="Password", type="password", placeholder="password123")
topic_input = gr.Textbox(label="Blog Topic", placeholder="e.g., Future of AI")
generate_btn = gr.Button("Generate & Edit", variant="primary")
with gr.Column():
status = gr.Textbox(label="Status", interactive=False)
blog_link = gr.Markdown("Blog link will appear here...")
blog_preview = gr.Markdown(label="Preview", value="Content preview will appear here...")
generate_btn.click(
fn=generate_and_edit,
inputs=[topic_input, username, password],
outputs=[blog_link, blog_preview, status]
)
if __name__ == "__main__":
app.launch(share=True, debug=True)