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
|
|
|
|
|
|
|
|
|
|
|
|