maria355 commited on
Commit
e06303f
Β·
verified Β·
1 Parent(s): 15fe14f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +190 -190
app.py CHANGED
@@ -1,190 +1,190 @@
1
- import streamlit as st
2
- import os
3
- import requests
4
- from dotenv import load_dotenv
5
- from docx import Document
6
- from docx.shared import Pt
7
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
8
- from reportlab.lib.styles import getSampleStyleSheet
9
- from reportlab.lib.pagesizes import LETTER
10
- from io import BytesIO
11
- import markdown2
12
- import re
13
-
14
- # Load API Key
15
- load_dotenv()
16
- GROQ_API_KEY = os.getenv("GROQ_API_KEY")
17
- GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
18
- GROQ_MODEL = "llama3-70b-8192"
19
-
20
- # ---- Inject Custom CSS ----
21
- st.markdown("""
22
- <style>
23
- .stApp {
24
- background-color: #121212 !important;
25
- font-family: 'Segoe UI', sans-serif;
26
- color: #ffffff;
27
- }
28
- section[data-testid="stSidebar"] > div:first-child {
29
- background-color: #1f1f1f;
30
- padding: 30px 10px 20px 10px;
31
- }
32
- .sidebar-links a {
33
- font-size: 18px;
34
- color: #ffcc00;
35
- text-decoration: none;
36
- }
37
- .sidebar-links a:hover {
38
- color: #00ffff;
39
- text-decoration: underline;
40
- }
41
- h1, h3, h2, h4 {
42
- color: #ffd700;
43
- text-shadow: 1px 1px 3px rgba(0,0,0,0.4);
44
- }
45
- p {
46
- color: #f1f1f1;
47
- }
48
- .stButton button, .download-button button {
49
- background: linear-gradient(90deg, #f7971e, #ffd200) !important;
50
- color: #000000 !important;
51
- font-weight: bold;
52
- font-size: 18px !important;
53
- border-radius: 12px;
54
- padding: 10px 20px;
55
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
56
- }
57
- .stButton button:hover, .download-button button:hover {
58
- transform: scale(1.02);
59
- box-shadow: 0 6px 15px rgba(0, 0, 0, 0.4);
60
- }
61
- .connect-title {
62
- font-size: 24px;
63
- color: #32a852;
64
- font-weight: bold;
65
- margin-bottom: 10px;
66
- }
67
- </style>
68
- """, unsafe_allow_html=True)
69
-
70
- # ---- Sidebar ----
71
- st.sidebar.markdown("""<div class="connect-title">πŸ”— Connect With Me</div>""", unsafe_allow_html=True)
72
- st.sidebar.markdown("""<div class="sidebar-links">
73
- <a href="https://github.com/marianadeem755" target="_blank">🌐 GitHub</a><br>
74
- <a href="https://www.kaggle.com/marianadeem755" target="_blank">πŸ“Š Kaggle</a><br>
75
- <a href="mailto:marianadeem755@gmail.com">πŸ“§ Email</a><br>
76
- <a href="https://huggingface.co/maria355" target="_blank">πŸ€— Hugging Face</a>
77
- </div>""", unsafe_allow_html=True)
78
-
79
- st.sidebar.markdown("---")
80
- st.sidebar.markdown("""<span style='color: #32a852; font-size: 18px;'>πŸ“– About This App</span>""", unsafe_allow_html=True)
81
- st.sidebar.markdown("""
82
- This app uses the powerful LLaMA 3 AI model to generate high-quality blog posts in minutes.
83
- Simply enter a blog topic, select the tone, and choose your preferred download format (Markdown, PDF, or Word).
84
- """, unsafe_allow_html=True)
85
-
86
- # ---- Title and Inputs ----
87
- st.markdown("<h1>🌟 AI Blog Generator</h1>", unsafe_allow_html=True)
88
- st.markdown("<p style='font-size: 20px;'>Create blog posts in minutes using LLaMA 3 model.</p>", unsafe_allow_html=True)
89
- st.markdown("---")
90
-
91
- col1, col2 = st.columns(2)
92
- with col1:
93
- topic = st.text_input("πŸ“Œ Enter Blog Topic", placeholder="e.g., Future of AI in Education")
94
- with col2:
95
- tone = st.selectbox("πŸŽ™οΈ Select Tone", ["Informative", "Conversational", "Professional", "Casual"])
96
-
97
- format_choice = st.radio("πŸ’Ύ Choose Download Format", ["Markdown", "PDF", "Word (.docx)"], horizontal=True)
98
-
99
- # ---- Generate Button and Logic ----
100
- st.markdown("<br>", unsafe_allow_html=True)
101
- if st.button("πŸš€ Generate Blog Post", use_container_width=True):
102
- if not topic:
103
- st.warning("Please enter a blog topic.", icon="⚠️")
104
- elif not GROQ_API_KEY:
105
- st.error("GROQ_API_KEY not set. Please check your .env file.", icon="❌")
106
- else:
107
- with st.spinner("Crafting your blog with AI magic... ✨"):
108
- headers = {
109
- "Authorization": f"Bearer {GROQ_API_KEY}",
110
- "Content-Type": "application/json"
111
- }
112
- payload = {
113
- "model": GROQ_MODEL,
114
- "messages": [
115
- {"role": "system", "content": "You are a professional blog writer and researcher."},
116
- {"role": "user", "content": f"""
117
- Write a high-quality, well-structured blog post on the topic: "{topic}". The blog post should:
118
-
119
- 1. Be engaging, informative, and human-like in tone ({tone}).
120
- 2. Use Markdown-style headings and subheadings.
121
- 3. Be written in simple, reader-friendly language.
122
- 4. Be free of plagiarism and fluff.
123
- 5. Include facts, examples, and if appropriate, recent statistics or case studies.
124
-
125
- Start writing the blog now.
126
- """}
127
- ],
128
- "temperature": 0.7,
129
- "max_tokens": 1500
130
- }
131
-
132
- try:
133
- response = requests.post(GROQ_API_URL, headers=headers, json=payload)
134
- response.raise_for_status()
135
- blog = response.json()["choices"][0]["message"]["content"]
136
-
137
- st.markdown("### ✨ Generated Blog Post")
138
- st.markdown(blog)
139
-
140
- if format_choice == "Markdown":
141
- st.download_button("πŸ“₯ Download Markdown", blog, file_name="blog_post.md", key="md", type="primary", help="Download as Markdown")
142
-
143
- elif format_choice == "PDF":
144
- html = markdown2.markdown(blog)
145
- pdf_buffer = BytesIO()
146
- doc = SimpleDocTemplate(pdf_buffer, pagesize=LETTER)
147
- styles = getSampleStyleSheet()
148
- story = []
149
- for paragraph in html.split("\n"):
150
- if paragraph.strip():
151
- story.append(Paragraph(paragraph, styles["Normal"]))
152
- story.append(Spacer(1, 12))
153
- doc.build(story)
154
- pdf_buffer.seek(0)
155
- st.download_button("πŸ“₯ Download PDF", pdf_buffer, file_name="blog_post.pdf", key="pdf", type="primary", help="Download as PDF")
156
-
157
- elif format_choice == "Word (.docx)":
158
- doc = Document()
159
- style = doc.styles['Normal']
160
- font = style.font
161
- font.name = 'Segoe UI'
162
- font.size = Pt(11)
163
-
164
- for line in blog.split('\n'):
165
- line = line.strip()
166
- if not line or line in ['---', '===', '---', '___']:
167
- continue # Skip Markdown separators
168
-
169
- # Clean markdown formatting for Word
170
- line = re.sub(r'\*\*(.*?)\*\*', r'\1', line) # remove bold
171
- line = re.sub(r'\*(.*?)\*', r'\1', line) # remove italic
172
- line = re.sub(r'^-{3,}$', '', line) # remove --- lines
173
- line = re.sub(r'^={3,}$', '', line) # remove === lines
174
-
175
- if re.match(r"^#{1,6} ", line):
176
- level = line.count("#", 0, line.find(" "))
177
- heading = line.replace("#", "").strip()
178
- doc.add_heading(heading, level=min(level, 4))
179
- elif re.match(r"^[-*] ", line):
180
- doc.add_paragraph(line[2:], style='List Bullet')
181
- else:
182
- doc.add_paragraph(line)
183
-
184
- doc_buffer = BytesIO()
185
- doc.save(doc_buffer)
186
- doc_buffer.seek(0)
187
- st.download_button("πŸ“₯ Download Word", doc_buffer, file_name="blog_post.docx", key="docx", type="primary", help="Download as DOCX")
188
-
189
- except Exception as e:
190
- st.error(f"Failed to generate blog post: {e}", icon="❌")
 
1
+ import streamlit as st
2
+ import os
3
+ import requests
4
+ from dotenv import load_dotenv
5
+ from docx import Document
6
+ from docx.shared import Pt
7
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
8
+ from reportlab.lib.styles import getSampleStyleSheet
9
+ from reportlab.lib.pagesizes import LETTER
10
+ from io import BytesIO
11
+ import markdown2
12
+ import re
13
+
14
+ # Load API Key
15
+ load_dotenv()
16
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
17
+ GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
18
+ GROQ_MODEL = "llama3-70b-8192"
19
+
20
+ # ---- Inject Custom CSS ----
21
+ st.markdown("""
22
+ <style>
23
+ .stApp {
24
+ background-color: #121212 !important;
25
+ font-family: 'Segoe UI', sans-serif;
26
+ color: #ffffff;
27
+ }
28
+ section[data-testid="stSidebar"] > div:first-child {
29
+ background-color: #1f1f1f;
30
+ padding: 30px 10px 20px 10px;
31
+ }
32
+ .sidebar-links a {
33
+ font-size: 18px;
34
+ color: #ffcc00;
35
+ text-decoration: none;
36
+ }
37
+ .sidebar-links a:hover {
38
+ color: #00ffff;
39
+ text-decoration: underline;
40
+ }
41
+ h1, h3, h2, h4 {
42
+ color: #ffd700;
43
+ text-shadow: 1px 1px 3px rgba(0,0,0,0.4);
44
+ }
45
+ p {
46
+ color: #f1f1f1;
47
+ }
48
+ .stButton button, .download-button button {
49
+ background: linear-gradient(90deg, #f7971e, #ffd200) !important;
50
+ color: #000000 !important;
51
+ font-weight: bold;
52
+ font-size: 18px !important;
53
+ border-radius: 12px;
54
+ padding: 10px 20px;
55
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
56
+ }
57
+ .stButton button:hover, .download-button button:hover {
58
+ transform: scale(1.02);
59
+ box-shadow: 0 6px 15px rgba(0, 0, 0, 0.4);
60
+ }
61
+ .connect-title {
62
+ font-size: 24px;
63
+ color: #32a852;
64
+ font-weight: bold;
65
+ margin-bottom: 10px;
66
+ }
67
+ </style>
68
+ """, unsafe_allow_html=True)
69
+
70
+ # ---- Sidebar ----
71
+ st.sidebar.markdown("""<div class="connect-title">πŸ”— Connect With Me</div>""", unsafe_allow_html=True)
72
+ st.sidebar.markdown("""<div class="sidebar-links">
73
+ <a href="https://github.com/marianadeem755" target="_blank">🌐 GitHub</a><br>
74
+ <a href="https://www.kaggle.com/marianadeem755" target="_blank">πŸ“Š Kaggle</a><br>
75
+ <a href="mailto:marianadeem755@gmail.com">πŸ“§ Email</a><br>
76
+ <a href="https://huggingface.co/maria355" target="_blank">πŸ€— Hugging Face</a>
77
+ </div>""", unsafe_allow_html=True)
78
+
79
+ st.sidebar.markdown("---")
80
+ st.sidebar.markdown("""<span style='color: #32a852; font-size: 18px;'>πŸ“– About This App</span>""", unsafe_allow_html=True)
81
+ st.sidebar.markdown("""
82
+ This app uses the powerful LLaMA 3 AI model to generate high-quality blog posts in minutes.
83
+ Simply enter a blog topic, select the tone, and choose your preferred download format (Markdown, PDF, or Word).
84
+ """, unsafe_allow_html=True)
85
+
86
+ # ---- Title and Inputs ----
87
+ st.markdown("<h1>🌟 AI Blog Generator</h1>", unsafe_allow_html=True)
88
+ st.markdown("<p style='font-size: 20px;'>Create blog posts in minutes using LLaMA 3 model.</p>", unsafe_allow_html=True)
89
+ st.markdown("---")
90
+
91
+ col1, col2 = st.columns(2)
92
+ with col1:
93
+ topic = st.text_input("πŸ“Œ Enter Blog Topic", placeholder="e.g., Future of AI in Education")
94
+ with col2:
95
+ tone = st.selectbox("πŸŽ™οΈ Select Tone", ["Informative", "Conversational", "Professional", "Casual"])
96
+
97
+ format_choice = st.radio("πŸ’Ύ Choose Download Format", ["Markdown", "PDF", "Word (.docx)"], horizontal=True)
98
+
99
+ # ---- Generate Button and Logic ----
100
+ st.markdown("<br>", unsafe_allow_html=True)
101
+ if st.button("πŸš€ Generate Blog Post", use_container_width=True):
102
+ if not topic:
103
+ st.warning("Please enter a blog topic.", icon="⚠️")
104
+ elif not GROQ_API_KEY:
105
+ st.error("GROQ_API_KEY not set. Please check your .env file.", icon="❌")
106
+ else:
107
+ with st.spinner("Crafting your blog with AI magic... ✨"):
108
+ headers = {
109
+ "Authorization": f"Bearer {GROQ_API_KEY}",
110
+ "Content-Type": "application/json"
111
+ }
112
+ payload = {
113
+ "model": GROQ_MODEL,
114
+ "messages": [
115
+ {"role": "system", "content": "You are a professional blog writer and researcher."},
116
+ {"role": "user", "content": f"""
117
+ Write a high-quality, well-structured blog post on the topic: "{topic}". The blog post should:
118
+
119
+ 1. Be engaging, informative, and human-like in tone ({tone}).
120
+ 2. Use Markdown-style headings and subheadings.
121
+ 3. Be written in simple, reader-friendly language.
122
+ 4. Be free of plagiarism and fluff.
123
+ 5. Include facts, examples, and if appropriate, recent statistics or case studies.
124
+
125
+ Start writing the blog now.
126
+ """}
127
+ ],
128
+ "temperature": 0.7,
129
+ "max_tokens": 1500
130
+ }
131
+
132
+ try:
133
+ response = requests.post(GROQ_API_URL, headers=headers, json=payload)
134
+ response.raise_for_status()
135
+ blog = response.json()["choices"][0]["message"]["content"]
136
+
137
+ st.markdown("### ✨ Generated Blog Post")
138
+ st.markdown(blog)
139
+
140
+ if format_choice == "Markdown":
141
+ st.download_button("πŸ“₯ Download Markdown", blog, file_name="blog_post.md", key="md", type="primary", help="Download as Markdown")
142
+
143
+ elif format_choice == "PDF":
144
+ html = markdown2.markdown(blog)
145
+ pdf_buffer = BytesIO()
146
+ doc = SimpleDocTemplate(pdf_buffer, pagesize=LETTER)
147
+ styles = getSampleStyleSheet()
148
+ story = []
149
+ for paragraph in html.split("\n"):
150
+ if paragraph.strip():
151
+ story.append(Paragraph(paragraph, styles["Normal"]))
152
+ story.append(Spacer(1, 12))
153
+ doc.build(story)
154
+ pdf_buffer.seek(0)
155
+ st.download_button("πŸ“₯ Download PDF", pdf_buffer, file_name="blog_post.pdf", key="pdf", type="primary", help="Download as PDF")
156
+
157
+ elif format_choice == "Word (.docx)":
158
+ doc = Document()
159
+ style = doc.styles['Normal']
160
+ font = style.font
161
+ font.name = 'Segoe UI'
162
+ font.size = Pt(11)
163
+
164
+ for line in blog.split('\n'):
165
+ line = line.strip()
166
+ if not line or line in ['---', '===', '---', '___']:
167
+ continue # Skip Markdown separators
168
+
169
+ # Clean markdown formatting for Word
170
+ line = re.sub(r'\*\*(.*?)\*\*', r'\1', line) # remove bold
171
+ line = re.sub(r'\*(.*?)\*', r'\1', line) # remove italic
172
+ line = re.sub(r'^-{3,}$', '', line) # remove --- lines
173
+ line = re.sub(r'^={3,}$', '', line) # remove === lines
174
+
175
+ if re.match(r"^#{1,6} ", line):
176
+ level = line.count("#", 0, line.find(" "))
177
+ heading = line.replace("#", "").strip()
178
+ doc.add_heading(heading, level=min(level, 4))
179
+ elif re.match(r"^[-*] ", line):
180
+ doc.add_paragraph(line[2:], style='List Bullet')
181
+ else:
182
+ doc.add_paragraph(line)
183
+
184
+ doc_buffer = BytesIO()
185
+ doc.save(doc_buffer)
186
+ doc_buffer.seek(0)
187
+ st.download_button("πŸ“₯ Download Word", doc_buffer, file_name="blog_post.docx", key="docx", type="primary", help="Download as DOCX")
188
+
189
+ except Exception as e:
190
+ st.error(f"Failed to generate blog post: {e}", icon="❌")