Spaces:
Paused
Paused
Create PPTX file, save it, and allow download
Browse files- .gitignore +1 -0
- .idea/misc.xml +3 -0
- app.py +24 -9
- examples/example_02_structured_output.json +44 -0
- global_config.py +1 -7
- pptx_helper.py +50 -0
- requirements.txt +2 -6
.gitignore
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
client_secret.json
|
2 |
credentials.json
|
3 |
token.json
|
|
|
4 |
|
5 |
|
6 |
### Python template
|
|
|
1 |
client_secret.json
|
2 |
credentials.json
|
3 |
token.json
|
4 |
+
*.pptx
|
5 |
|
6 |
|
7 |
### Python template
|
.idea/misc.xml
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<project version="4">
|
3 |
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (slides-wizard) (2)" project-jdk-type="Python SDK" />
|
|
|
|
|
|
|
4 |
</project>
|
|
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<project version="4">
|
3 |
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (slides-wizard) (2)" project-jdk-type="Python SDK" />
|
4 |
+
<component name="PythonCompatibilityInspectionAdvertiser">
|
5 |
+
<option name="version" value="3" />
|
6 |
+
</component>
|
7 |
</project>
|
app.py
CHANGED
@@ -1,14 +1,17 @@
|
|
1 |
import json
|
|
|
2 |
import streamlit as st
|
|
|
3 |
|
4 |
import llm_helper
|
|
|
5 |
from global_config import GlobalConfig
|
6 |
|
7 |
|
8 |
UI_BUTTONS = [
|
9 |
'Generate slides content',
|
10 |
'Generate JSON',
|
11 |
-
'Make the slides
|
12 |
]
|
13 |
|
14 |
|
@@ -18,7 +21,7 @@ def build_ui():
|
|
18 |
"""
|
19 |
|
20 |
st.title('Slides Wizard')
|
21 |
-
st.subheader('*:blue[Create your next slide deck using AI]*')
|
22 |
st.divider()
|
23 |
|
24 |
st.header('Step 1: Generate your content')
|
@@ -141,16 +144,28 @@ def process_slides_contents(text: str, progress_bar: st.progress):
|
|
141 |
|
142 |
# Now, step 3
|
143 |
st.divider()
|
144 |
-
st.header('Step 3: Create
|
145 |
st.caption('Let\'s now create the slides for you')
|
146 |
|
147 |
-
st.
|
148 |
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
|
156 |
def button_clicked(button):
|
|
|
1 |
import json
|
2 |
+
import time
|
3 |
import streamlit as st
|
4 |
+
import streamlit.runtime.scriptrunner as st_sr
|
5 |
|
6 |
import llm_helper
|
7 |
+
import pptx_helper
|
8 |
from global_config import GlobalConfig
|
9 |
|
10 |
|
11 |
UI_BUTTONS = [
|
12 |
'Generate slides content',
|
13 |
'Generate JSON',
|
14 |
+
'Make the slides'
|
15 |
]
|
16 |
|
17 |
|
|
|
21 |
"""
|
22 |
|
23 |
st.title('Slides Wizard')
|
24 |
+
st.subheader('*:blue[Create your next PowerPoint slide deck using AI]*')
|
25 |
st.divider()
|
26 |
|
27 |
st.header('Step 1: Generate your content')
|
|
|
144 |
|
145 |
# Now, step 3
|
146 |
st.divider()
|
147 |
+
st.header('Step 3: Create the slides')
|
148 |
st.caption('Let\'s now create the slides for you')
|
149 |
|
150 |
+
st.button(UI_BUTTONS[2], on_click=button_clicked, args=[2])
|
151 |
|
152 |
+
if st.session_state.clicked[2]:
|
153 |
+
progress_text = 'Creating...give it a moment'
|
154 |
+
progress_bar = st.progress(0, text=progress_text)
|
155 |
+
|
156 |
+
# Get a unique name for the file to save -- use the session ID
|
157 |
+
ctx = st_sr.get_script_run_ctx()
|
158 |
+
session_id = ctx.session_id
|
159 |
+
timestamp = time.time()
|
160 |
+
output_file_name = f'{session_id}_{timestamp}.pptx'
|
161 |
+
|
162 |
+
pptx_helper.generate_powerpoint_presentation(json_str, output_file_name)
|
163 |
+
st.progress(100, text='Done!')
|
164 |
+
|
165 |
+
# st.download_button('Download file', binary_contents) # Defaults to 'application/octet-stream'
|
166 |
+
|
167 |
+
with open(output_file_name, 'rb') as f:
|
168 |
+
st.download_button('Download PPTX file', f, file_name=output_file_name)
|
169 |
|
170 |
|
171 |
def button_clicked(button):
|
examples/example_02_structured_output.json
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"presentation_title": "Introduction to AI",
|
3 |
+
"slides": [
|
4 |
+
{
|
5 |
+
"slide_number": 1,
|
6 |
+
"slide_heading": "Introduction to AI",
|
7 |
+
"slide_contents": [
|
8 |
+
"What is AI?",
|
9 |
+
"History of AI",
|
10 |
+
"Benefits of AI",
|
11 |
+
"Challenges of AI",
|
12 |
+
"Examples of AI",
|
13 |
+
],
|
14 |
+
},
|
15 |
+
{
|
16 |
+
"slide_number": 2,
|
17 |
+
"slide_heading": "AI Pros and Cons",
|
18 |
+
"slide_contents": [
|
19 |
+
"Benefits of AI",
|
20 |
+
"Challenges of AI",
|
21 |
+
"Examples of AI",
|
22 |
+
],
|
23 |
+
},
|
24 |
+
{
|
25 |
+
"slide_number": 3,
|
26 |
+
"slide_heading": "Future Prospects of AI",
|
27 |
+
"slide_contents": [
|
28 |
+
"Advancements in AI",
|
29 |
+
"Job prospects in AI",
|
30 |
+
"Potential applications of AI",
|
31 |
+
"Ethical considerations in AI",
|
32 |
+
],
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"slide_number": 4,
|
36 |
+
"slide_heading": "Conclusion",
|
37 |
+
"slide_contents": [
|
38 |
+
"Summary of AI and its impact",
|
39 |
+
"Career opportunities in AI",
|
40 |
+
"Final thoughts on AI",
|
41 |
+
]
|
42 |
+
}
|
43 |
+
]
|
44 |
+
}
|
global_config.py
CHANGED
@@ -2,6 +2,7 @@ from dataclasses import dataclass
|
|
2 |
from dotenv import load_dotenv
|
3 |
import os
|
4 |
|
|
|
5 |
load_dotenv()
|
6 |
|
7 |
|
@@ -9,8 +10,6 @@ load_dotenv()
|
|
9 |
class GlobalConfig:
|
10 |
HUGGINGFACEHUB_API_TOKEN: str = os.getenv('HUGGINGFACEHUB_API_TOKEN')
|
11 |
|
12 |
-
# Flan-T5
|
13 |
-
# LLM_MODEL_NAME: str = 'google/flan-t5-xxl'
|
14 |
LLM_MODEL_NAME = 'tiiuae/falcon-7b-instruct'
|
15 |
# LLM_MODEL_NAME = 'h2oai/h2ogpt-gm-oasst1-en-2048-falcon-7b-v2'
|
16 |
# LLM_MODEL_NAME = 'garage-bAInd/Platypus2-70B-instruct'
|
@@ -19,11 +18,6 @@ class GlobalConfig:
|
|
19 |
LLM_MODEL_MAX_OUTPUT_LENGTH: int = 2000
|
20 |
LLM_MODEL_MAX_INPUT_LENGTH: int = 1000
|
21 |
|
22 |
-
# # Stable Diffusion
|
23 |
-
# DIFFUSION_MODEL_NAME: str = 'stabilityai/stable-diffusion-2-1'
|
24 |
-
# DIFFUSION_NUM_INFERENCE_STEPS: int = 3
|
25 |
-
|
26 |
PRELOAD_DATA_FILE = 'examples/example_02.json'
|
27 |
SLIDES_TEMPLATE_FILE = 'langchain_templates/template_07.txt'
|
28 |
|
29 |
-
GOOGLE_SLIDES_CREDENTIALS: str = os.getenv('GOOGLE_SLIDES_CREDENTIALS')
|
|
|
2 |
from dotenv import load_dotenv
|
3 |
import os
|
4 |
|
5 |
+
|
6 |
load_dotenv()
|
7 |
|
8 |
|
|
|
10 |
class GlobalConfig:
|
11 |
HUGGINGFACEHUB_API_TOKEN: str = os.getenv('HUGGINGFACEHUB_API_TOKEN')
|
12 |
|
|
|
|
|
13 |
LLM_MODEL_NAME = 'tiiuae/falcon-7b-instruct'
|
14 |
# LLM_MODEL_NAME = 'h2oai/h2ogpt-gm-oasst1-en-2048-falcon-7b-v2'
|
15 |
# LLM_MODEL_NAME = 'garage-bAInd/Platypus2-70B-instruct'
|
|
|
18 |
LLM_MODEL_MAX_OUTPUT_LENGTH: int = 2000
|
19 |
LLM_MODEL_MAX_INPUT_LENGTH: int = 1000
|
20 |
|
|
|
|
|
|
|
|
|
21 |
PRELOAD_DATA_FILE = 'examples/example_02.json'
|
22 |
SLIDES_TEMPLATE_FILE = 'langchain_templates/template_07.txt'
|
23 |
|
|
pptx_helper.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json5
|
2 |
+
import pptx
|
3 |
+
|
4 |
+
|
5 |
+
def generate_powerpoint_presentation(structured_contents: str, output_file_name: str):
|
6 |
+
"""
|
7 |
+
Create and save a PowerPoint presentation file containing the contents.
|
8 |
+
|
9 |
+
:param structured_contents: The presentation contents in "JSON" format (may contain trailing commas)
|
10 |
+
:param output_file_name: The name of the PPTX file to save as
|
11 |
+
"""
|
12 |
+
|
13 |
+
# The structured "JSON" contains trailing commas, so using json5
|
14 |
+
json_data = json5.loads(structured_contents)
|
15 |
+
|
16 |
+
presentation = pptx.Presentation()
|
17 |
+
|
18 |
+
# The title slide
|
19 |
+
title_slide_layout = presentation.slide_layouts[0]
|
20 |
+
slide = presentation.slides.add_slide(title_slide_layout)
|
21 |
+
title = slide.shapes.title
|
22 |
+
subtitle = slide.placeholders[1]
|
23 |
+
title.text = json_data['presentation_title']
|
24 |
+
subtitle.text = 'Generated by Slides Wizard AI :)'
|
25 |
+
|
26 |
+
# Add content in a loop
|
27 |
+
for a_slide in json_data['slides']:
|
28 |
+
bullet_slide_layout = presentation.slide_layouts[1]
|
29 |
+
slide = presentation.slides.add_slide(bullet_slide_layout)
|
30 |
+
shapes = slide.shapes
|
31 |
+
|
32 |
+
title_shape = shapes.title
|
33 |
+
body_shape = shapes.placeholders[1]
|
34 |
+
|
35 |
+
title_shape.text = a_slide['slide_heading']
|
36 |
+
|
37 |
+
text_frame = body_shape.text_frame
|
38 |
+
|
39 |
+
for an_item in a_slide['slide_contents']:
|
40 |
+
paragraph = text_frame.add_paragraph()
|
41 |
+
paragraph.text = an_item
|
42 |
+
paragraph.level = 0
|
43 |
+
|
44 |
+
# The thank-you slide
|
45 |
+
last_slide_layout = presentation.slide_layouts[0]
|
46 |
+
slide = presentation.slides.add_slide(last_slide_layout)
|
47 |
+
title = slide.shapes.title
|
48 |
+
title.text = 'Thank you!'
|
49 |
+
|
50 |
+
presentation.save(output_file_name)
|
requirements.txt
CHANGED
@@ -3,9 +3,5 @@ langchain~=0.0.268
|
|
3 |
huggingface_hub
|
4 |
streamlit~=1.25.0
|
5 |
|
6 |
-
|
7 |
-
|
8 |
-
# google-auth-httplib2
|
9 |
-
# google-auth-oauthlib
|
10 |
-
|
11 |
-
google-api-support
|
|
|
3 |
huggingface_hub
|
4 |
streamlit~=1.25.0
|
5 |
|
6 |
+
python-pptx
|
7 |
+
json5~=0.9.14
|
|
|
|
|
|
|
|