prasannahf commited on
Commit
7de5f0a
Β·
verified Β·
1 Parent(s): 57750fd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -0
app.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import traceback
4
+ import torch
5
+ from langgraph.graph import StateGraph, START, END
6
+ from langchain.schema import HumanMessage
7
+ from langchain_groq import ChatGroq
8
+ from langsmith import traceable # βœ… Added LangSmith for Debugging
9
+ from typing import TypedDict
10
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
11
+
12
+ # βœ… Load API keys from Hugging Face Secrets
13
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
14
+ LANGSMITH_API_KEY = os.getenv("LANGSMITH_API_KEY")
15
+
16
+ # βœ… Set LangSmith Debugging
17
+ os.environ["LANGCHAIN_TRACING_V2"] = "true"
18
+ os.environ["LANGCHAIN_API_KEY"] = LANGSMITH_API_KEY
19
+
20
+ # βœ… Initialize Groq LLM (for content generation)
21
+ llm = ChatGroq(groq_api_key=GROQ_API_KEY, model_name="mixtral-8x7b-32768")
22
+
23
+ # βœ… Define State for LangGraph
24
+ class State(TypedDict):
25
+ topic: str
26
+ titles: list
27
+ selected_title: str
28
+ content: str
29
+ summary: str
30
+ translated_content: str
31
+ tone: str
32
+ language: str
33
+
34
+ # βœ… Function to generate multiple blog titles using Groq
35
+ @traceable(name="Generate Titles") # βœ… Debugging with LangSmith
36
+ def generate_titles(data):
37
+ topic = data.get("topic", "")
38
+ prompt = f"Generate three short and catchy blog titles for the topic: {topic}. Each title should be under 10 words. Separate them with new lines."
39
+
40
+ response = llm([HumanMessage(content=prompt)])
41
+ titles = response.content.strip().split("\n")
42
+
43
+ return {"titles": titles, "selected_title": titles[0]}
44
+
45
+ # βœ… Function to generate blog content with tone using Groq
46
+ @traceable(name="Generate Content") # βœ… Debugging with LangSmith
47
+ def generate_content(data):
48
+ title = data.get("selected_title", "")
49
+ tone = data.get("tone", "Neutral")
50
+ prompt = f"Write a detailed and engaging blog post in a {tone} tone based on the title: {title}"
51
+
52
+ response = llm([HumanMessage(content=prompt)])
53
+ return {"content": response.content.strip()}
54
+
55
+ # βœ… Function to generate summary using Groq
56
+ @traceable(name="Generate Summary") # βœ… Debugging with LangSmith
57
+ def generate_summary(data):
58
+ content = data.get("content", "")
59
+ prompt = f"Summarize this blog post in a short and engaging way: {content}"
60
+
61
+ response = llm([HumanMessage(content=prompt)])
62
+ return {"summary": response.content.strip()}
63
+
64
+ # βœ… Load translation model (NLLB-200)
65
+ def load_translation_model():
66
+ model_name = "facebook/nllb-200-distilled-600M"
67
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
68
+ model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
69
+ return tokenizer, model
70
+
71
+ tokenizer, model = load_translation_model()
72
+
73
+ # βœ… Language codes for NLLB-200
74
+ language_codes = {
75
+ "English": "eng_Latn",
76
+ "Hindi": "hin_Deva",
77
+ "Telugu": "tel_Telu",
78
+ "Spanish": "spa_Latn",
79
+ "French": "fra_Latn"
80
+ }
81
+
82
+ # βœ… Function to translate blog content using NLLB-200
83
+ @traceable(name="Translate Content") # βœ… Debugging with LangSmith
84
+ def translate_content(data):
85
+ content = data.get("content", "")
86
+ language = data.get("language", "English")
87
+
88
+ if language == "English":
89
+ return {"translated_content": content}
90
+
91
+ tgt_lang = language_codes.get(language, "eng_Latn")
92
+
93
+ # βœ… Split content into smaller chunks (Avoids token limit issues)
94
+ max_length = 512
95
+ sentences = content.split(". ")
96
+ chunks = []
97
+ current_chunk = ""
98
+
99
+ for sentence in sentences:
100
+ if len(current_chunk) + len(sentence) < max_length:
101
+ current_chunk += sentence + ". "
102
+ else:
103
+ chunks.append(current_chunk.strip())
104
+ current_chunk = sentence + ". "
105
+
106
+ if current_chunk:
107
+ chunks.append(current_chunk.strip())
108
+
109
+ # βœ… Translate each chunk separately and combine results
110
+ translated_chunks = []
111
+ for chunk in chunks:
112
+ inputs = tokenizer(chunk, return_tensors="pt", padding=True, truncation=True)
113
+ translated_tokens = model.generate(**inputs, forced_bos_token_id=tokenizer.convert_tokens_to_ids(tgt_lang))
114
+ translated_text = tokenizer.decode(translated_tokens[0], skip_special_tokens=True)
115
+ translated_chunks.append(translated_text.strip())
116
+
117
+ full_translation = " ".join(translated_chunks)
118
+
119
+ return {"translated_content": full_translation}
120
+
121
+ # βœ… Create LangGraph Workflow
122
+ def make_blog_generation_graph():
123
+ """Create a LangGraph workflow for Blog Generation"""
124
+ graph_workflow = StateGraph(State)
125
+
126
+ # Define Nodes
127
+ graph_workflow.add_node("title_generation", generate_titles)
128
+ graph_workflow.add_node("content_generation", generate_content)
129
+ graph_workflow.add_node("summary_generation", generate_summary)
130
+ graph_workflow.add_node("translation", translate_content)
131
+
132
+ # Define Execution Order
133
+ graph_workflow.add_edge(START, "title_generation")
134
+ graph_workflow.add_edge("title_generation", "content_generation")
135
+ graph_workflow.add_edge("content_generation", "summary_generation")
136
+ graph_workflow.add_edge("content_generation", "translation")
137
+ graph_workflow.add_edge("summary_generation", END)
138
+ graph_workflow.add_edge("translation", END)
139
+
140
+ return graph_workflow.compile()
141
+
142
+ # βœ… Function to generate blog content (Fixed)
143
+ def generate_blog(topic, tone, language):
144
+ try:
145
+ if not topic:
146
+ return "⚠️ Please enter a topic.", "", "", "", ""
147
+
148
+ blog_agent = make_blog_generation_graph()
149
+ result = blog_agent.invoke({"topic": topic, "tone": tone, "language": language})
150
+
151
+ return result["titles"], result["selected_title"], result["content"], result["summary"], result["translated_content"]
152
+
153
+ except Exception as e:
154
+ error_message = f"⚠️ Error: {str(e)}\n{traceback.format_exc()}"
155
+ return error_message, "", "", "", ""
156
+
157
+ # βœ… Gradio UI
158
+ with gr.Blocks() as app:
159
+ gr.Markdown(
160
+ """
161
+ ### 🌍 Why Translate?
162
+ - πŸ—£οΈ **Multilingual Support**
163
+ - 🌎 **Expand Reach**
164
+ - βœ… **Better Understanding**
165
+ - πŸ€– **AI-Powered Accuracy**
166
+ """
167
+ )
168
+
169
+ gr.Interface(
170
+ fn=generate_blog,
171
+ inputs=[
172
+ gr.Textbox(label="Enter a topic for your blog"),
173
+ gr.Dropdown(["Neutral", "Formal", "Casual", "Persuasive", "Humorous"], label="Select Blog Tone", value="Neutral"),
174
+ gr.Dropdown(["English", "Hindi", "Telugu", "Spanish", "French"], label="Translate Blog To", value="English"),
175
+ ],
176
+ outputs=[
177
+ gr.Textbox(label="Suggested Blog Titles"),
178
+ gr.Textbox(label="Selected Blog Title"),
179
+ gr.Textbox(label="Generated Blog Content"),
180
+ gr.Textbox(label="Blog Summary"),
181
+ gr.Textbox(label="Translated Blog Content"),
182
+ ],
183
+ title="πŸš€ AI-Powered Blog Generator",
184
+ )
185
+
186
+ # βœ… Launch the Gradio App
187
+ app.launch(share=True)