jsakshi commited on
Commit
503c625
·
verified ·
1 Parent(s): 7c88afd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -178
app.py CHANGED
@@ -167,201 +167,116 @@ if __name__ == "__main__":
167
  import gradio as gr
168
  import os
169
  import time
 
170
  import requests
 
 
171
  import re
172
  from datetime import datetime
173
  from dotenv import load_dotenv
174
- from huggingface_hub import HfApi, upload_file
175
- import uuid
176
 
 
177
  load_dotenv()
178
 
179
- class BlogCreator:
180
- def __init__(self):
181
- self.hf_token = os.getenv("HF_TOKEN")
182
- self.api = HfApi(token=self.hf_token)
183
- self.headers = {"Authorization": f"Bearer {self.hf_token}"}
184
- self.username = "jsakshi" # Replace with your HF username
185
-
186
- def generate_blog(self, topic):
187
- try:
188
- # Generate unique space name
189
- space_name = f"{self.username}/blog-{uuid.uuid4().hex[:8]}"
190
-
191
- # Create blog space
192
- self.api.create_repo(
193
- repo_id=space_name,
194
- repo_type="space",
195
- space_sdk="static",
196
- private=False
197
- )
198
 
199
- # Generate content
200
- blog_text, image_urls = self._generate_content(topic, space_name)
201
-
202
- # Create HTML with design
203
- html_content = self._create_design(blog_text, image_urls, topic)
204
-
205
- # Upload files to space
206
- self._upload_to_space(space_name, html_content, image_urls)
207
-
208
- return f"https://huggingface.co/spaces/{space_name}", blog_text
209
-
210
- except Exception as e:
211
- return f"Error: {str(e)}", ""
212
 
213
- def _generate_content(self, topic, space_name):
214
- # Generate text
215
- text_response = requests.post(
216
- "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2",
217
- headers=self.headers,
218
- json={
219
- "inputs": f"Write a comprehensive blog about {topic} with markdown formatting and 3 image placeholders [IMAGE1], [IMAGE2], [IMAGE3]",
220
- "parameters": {"max_length": 2000}
221
- }
222
- )
223
- blog_text = text_response.json()[0]['generated_text']
224
 
225
- # Generate and upload images
226
- image_urls = []
227
- for idx in range(3):
228
- img_response = requests.post(
229
- "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
230
- headers=self.headers,
231
- json={"inputs": f"Colorful modern digital art about {topic}, vibrant colors, abstract patterns, 4k resolution"}
232
- )
233
- image_path = f"image_{idx}.png"
234
- upload_file(
235
- path_or_fileobj=img_response.content,
236
- path_in_repo=image_path,
237
- repo_id=space_name,
238
- repo_type="space"
239
- )
240
- image_urls.append(image_path)
241
- time.sleep(1)
242
 
243
- return blog_text, image_urls
 
 
 
 
 
 
 
 
 
 
 
 
244
 
245
- def _create_design(self, content, image_urls, topic):
246
- # Replace image placeholders
247
- for idx, url in enumerate(image_urls):
248
- content = content.replace(f"[IMAGE{idx+1}]", f'![Image {idx+1}]({url})')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
 
250
- # Create styled HTML
251
- return f"""
252
- <!DOCTYPE html>
253
- <html>
254
- <head>
255
- <title>{topic}</title>
256
- <style>
257
- :root {{
258
- --primary: #ff6b6b;
259
- --secondary: #4ecdc4;
260
- --accent: #ffe66d;
261
- }}
262
- body {{
263
- max-width: 800px;
264
- margin: 0 auto;
265
- padding: 40px;
266
- font-family: 'Segoe UI', sans-serif;
267
- background: linear-gradient(45deg, #f8f9fa, #ffffff);
268
- line-height: 1.6;
269
- }}
270
- .header {{
271
- text-align: center;
272
- padding: 40px 0;
273
- background: var(--primary);
274
- color: white;
275
- border-radius: 15px;
276
- margin-bottom: 40px;
277
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
278
- }}
279
- img {{
280
- width: 100%;
281
- border-radius: 15px;
282
- margin: 25px 0;
283
- border: 3px solid var(--secondary);
284
- transition: transform 0.3s ease;
285
- }}
286
- img:hover {{
287
- transform: scale(1.02);
288
- }}
289
- h1, h2, h3 {{
290
- color: var(--primary);
291
- margin-top: 30px;
292
- }}
293
- blockquote {{
294
- border-left: 4px solid var(--accent);
295
- padding: 15px 30px;
296
- margin: 20px 0;
297
- background: #fff9e6;
298
- border-radius: 4px;
299
- }}
300
- a {{
301
- color: var(--secondary);
302
- text-decoration: none;
303
- font-weight: bold;
304
- }}
305
- .content {{
306
- background: white;
307
- padding: 30px;
308
- border-radius: 15px;
309
- box-shadow: 0 2px 15px rgba(0,0,0,0.1);
310
- }}
311
- </style>
312
- </head>
313
- <body>
314
- <div class="header">
315
- <h1>{topic}</h1>
316
- <p>Generated on {datetime.now().strftime("%B %d, %Y")}</p>
317
- </div>
318
- <div class="content">
319
- {markdown.markdown(content)}
320
- </div>
321
- </body>
322
- </html>
323
- """
324
 
325
- def _upload_to_space(self, space_name, html_content, image_urls):
326
- # Upload HTML
327
- upload_file(
328
- path_or_fileobj=html_content.encode(),
329
- path_in_repo="index.html",
330
- repo_id=space_name,
331
- repo_type="space"
332
- )
 
 
333
 
334
- with gr.Blocks(theme=gr.themes.Soft()) as app:
335
- gr.Markdown("# 🎨 AI Blog Designer")
336
-
337
  with gr.Row():
338
  with gr.Column():
339
- topic_input = gr.Textbox(label="Blog Topic", placeholder="Enter your topic...")
340
- generate_btn = gr.Button("Create Beautiful Blog", variant="primary")
341
-
 
342
  with gr.Column():
343
- gr.Markdown("## Your Blog Link")
344
- blog_link = gr.Markdown("Waiting for generation...")
345
- blog_preview = gr.HTML()
346
- status = gr.Textbox(label="Status")
347
-
348
- def process_request(topic):
349
- creator = BlogCreator()
350
- try:
351
- url, content = creator.generate_blog(topic)
352
- return (
353
- f"[View Beautiful Blog]({url})",
354
- f"<iframe src='{url}' style='width:100%; height:600px; border:none;'></iframe>",
355
- "✅ Blog created successfully!"
356
- )
357
- except Exception as e:
358
- return "❌ Error", "", str(e)
359
-
360
- generate_btn.click(
361
- fn=process_request,
362
- inputs=topic_input,
363
- outputs=[blog_link, blog_preview, status]
364
- )
365
 
366
  if __name__ == "__main__":
367
- app.launch(share=True)
 
167
  import gradio as gr
168
  import os
169
  import time
170
+ import tempfile
171
  import requests
172
+ from PIL import Image
173
+ from io import BytesIO
174
  import re
175
  from datetime import datetime
176
  from dotenv import load_dotenv
 
 
177
 
178
+ # Load environment variables
179
  load_dotenv()
180
 
181
+ # Hugging Face configuration
182
+ HF_TOKEN = os.getenv("HF_TOKEN")
183
+ TEXT_API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2"
184
+ IMAGE_API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0"
185
+ HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
+ # Generate blog content
188
+ def generate_blog_content(topic, tone="professional", length="long"):
189
+ try:
190
+ current_date = datetime.now().strftime("%B %d, %Y")
191
+ prompt = f"""<s>[INST] Write a {tone} blog post about {topic} with:
192
+ - Title and subtitle
193
+ - Introduction with statistics
194
+ - 3-4 detailed sections with subheadings
195
+ - A conclusion with key takeaways
196
+ - Markdown formatting with colorful HTML & CSS
197
+ - Published date: {current_date}
198
+ - At least 1500 words [/INST]</s>"""
 
199
 
200
+ payload = {
201
+ "inputs": prompt,
202
+ "parameters": {"max_new_tokens": 2048, "temperature": 0.7, "return_full_text": False}
203
+ }
 
 
 
 
 
 
 
204
 
205
+ response = requests.post(TEXT_API_URL, headers=HEADERS, json=payload)
206
+ response.raise_for_status()
207
+ return response.json()[0]['generated_text']
208
+ except Exception as e:
209
+ return f"Error generating content: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
+ # Generate feature image
212
+ def generate_featured_image(topic):
213
+ try:
214
+ prompt = f"A vibrant, eye-catching blog cover image about {topic}, ultra HD, artistic"
215
+ payload = {"inputs": prompt, "parameters": {"height": 1024, "width": 1024, "num_inference_steps": 30}}
216
+ response = requests.post(IMAGE_API_URL, headers=HEADERS, json=payload)
217
+ response.raise_for_status()
218
+ image = Image.open(BytesIO(response.content))
219
+ temp_img = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
220
+ image.save(temp_img.name)
221
+ return temp_img.name
222
+ except Exception as e:
223
+ return None
224
 
225
+ # Convert blog into a colorful web page
226
+ def generate_webpage(blog_content, title, author):
227
+ html_template = f"""
228
+ <html>
229
+ <head>
230
+ <style>
231
+ body {{ font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px; }}
232
+ .container {{ max-width: 800px; margin: auto; background: white; padding: 20px; border-radius: 10px; }}
233
+ h1 {{ color: #2c3e50; }}
234
+ h2, h3 {{ color: #2980b9; }}
235
+ p {{ color: #333; line-height: 1.6; }}
236
+ </style>
237
+ </head>
238
+ <body>
239
+ <div class='container'>
240
+ <h1>{title}</h1>
241
+ <h3>by {author}</h3>
242
+ {blog_content.replace("\n", "<br>")}
243
+ </div>
244
+ </body>
245
+ </html>
246
+ """
247
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".html", mode="w", encoding="utf-8")
248
+ temp_file.write(html_template)
249
+ temp_file.close()
250
+ return temp_file.name
251
 
252
+ # Generate blog
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
+ def generate_blog(topic, tone, author_name):
255
+ status_updates = ["🚀 Generating blog..."]
256
+ blog_content = generate_blog_content(topic, tone)
257
+ title = re.search(r'^#\s+(.+)$', blog_content, re.MULTILINE).group(1).strip() if re.search(r'^#\s+(.+)$', blog_content, re.MULTILINE) else topic
258
+ status_updates.append("🖼️ Generating featured image...")
259
+ image_path = generate_featured_image(topic)
260
+ status_updates.append("🌍 Generating website...")
261
+ web_page = generate_webpage(blog_content, title, author_name)
262
+ status_updates.append("✅ Blog Ready!")
263
+ return blog_content, title, "\n".join(status_updates), web_page
264
 
265
+ # Gradio UI
266
+ with gr.Blocks() as app:
267
+ gr.Markdown("# 🌟 AI Blog Generator & Web Designer")
268
  with gr.Row():
269
  with gr.Column():
270
+ topic_input = gr.Textbox(label="Blog Topic")
271
+ tone_input = gr.Dropdown(["professional", "casual", "technical", "storytelling"], label="Writing Style", value="professional")
272
+ author_input = gr.Textbox(label="Author Name")
273
+ generate_btn = gr.Button("Generate Blog")
274
  with gr.Column():
275
+ title_output = gr.Textbox(label="Generated Title")
276
+ blog_output = gr.Markdown()
277
+ status_output = gr.Textbox(label="Status")
278
+ web_page_output = gr.File(label="Download Website")
279
+ generate_btn.click(generate_blog, inputs=[topic_input, tone_input, author_input], outputs=[blog_output, title_output, status_output, web_page_output])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
  if __name__ == "__main__":
282
+ app.launch(share=True)