refactoring pour que l'application soit plus facile à entretenir
This commit is contained in:
parent
e8b82a1f3d
commit
a50bf9e598
10 changed files with 239 additions and 197 deletions
|
@ -9,7 +9,7 @@ COPY requirements.txt .
|
|||
RUN pip install -r requirements.txt
|
||||
|
||||
# Copy the app's code
|
||||
COPY main.py .
|
||||
COPY *.py .
|
||||
|
||||
# Set the entrypoint to run the app
|
||||
ENTRYPOINT [ "streamlit", "run" ]
|
||||
|
|
16
app_tab1.py
Normal file
16
app_tab1.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
import mdformat
|
||||
import streamlit as st
|
||||
|
||||
from demo_text import demo_text
|
||||
|
||||
|
||||
def app_tab1():
|
||||
def button1_callback():
|
||||
st.session_state['markdown'] = mdformat.text(st.session_state['markdown'],
|
||||
options={"number": True})
|
||||
|
||||
st.session_state['content'] = st.text_area(
|
||||
"Entre ton texte ici. Les images sont dans ./images/", demo_text,
|
||||
height=450,
|
||||
key='markdown')
|
||||
st.button("Formater le texte", on_click=button1_callback)
|
6
app_tab2.py
Normal file
6
app_tab2.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import streamlit as st
|
||||
|
||||
|
||||
def app_tab2():
|
||||
st.write("Aperçu")
|
||||
st.markdown(st.session_state['content'])
|
104
app_tab3.py
Normal file
104
app_tab3.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
import datetime
|
||||
|
||||
import requests
|
||||
import streamlit as st
|
||||
|
||||
from models import DocumentSpecs
|
||||
|
||||
|
||||
def app_tab3():
|
||||
st.header("Paramètres")
|
||||
http_headers = {"Authorization": f"Bearer {st.session_state['bearer_token']}"}
|
||||
# Styles
|
||||
response_styles = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/styles/", headers=http_headers).json()
|
||||
styles = response_styles.get("styles")
|
||||
selected_style = st.selectbox("Select a style:", styles)
|
||||
# Formats
|
||||
response_formats = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/formats/{selected_style}/", headers=http_headers).json()
|
||||
formats = response_formats.get("formats")
|
||||
selected_format = st.selectbox("Select a format:", formats)
|
||||
|
||||
# Autres paramètres
|
||||
response_format_parameters = requests.get(
|
||||
f"{st.session_state['fabriquedoc_endpoint']}/format_parameters/{selected_style}/{selected_format}/", headers=http_headers).json()
|
||||
linkcolor = st.text_input("Link color:",
|
||||
value=response_format_parameters.get("linkcolor"))
|
||||
tocdepth = st.number_input("Table of Contents depth:",
|
||||
value=int(response_format_parameters.get("tocdepth")),
|
||||
min_value=1,
|
||||
max_value=5,
|
||||
step=1)
|
||||
pdfengine = st.text_input("PDF engine:",
|
||||
value=response_format_parameters.get("pdfengine"))
|
||||
fontsize = st.number_input("Font size:",
|
||||
value=int(response_format_parameters.get("fontsize")),
|
||||
step=1)
|
||||
paperwidth = st.number_input("Paper width:",
|
||||
value=int(response_format_parameters.get("paperwidth")),
|
||||
step=30)
|
||||
paperheight = st.number_input("Paper height:",
|
||||
value=int(response_format_parameters.get("paperheight")),
|
||||
step=30)
|
||||
ratio = st.number_input("Ratio:",
|
||||
value=int(response_format_parameters.get("ratio")),
|
||||
step=10)
|
||||
margin = st.number_input("Margin:",
|
||||
value=int(response_format_parameters.get("margin")),
|
||||
step=10)
|
||||
vmargin = st.number_input("Vertical margin:",
|
||||
value=int(response_format_parameters.get("vmargin")),
|
||||
step=10)
|
||||
extension = st.selectbox("Extension:", ["jpg", "pdf", "mp4"])
|
||||
if extension == "mp4":
|
||||
fps = st.number_input("FPS:",
|
||||
value=int(response_format_parameters.get("fps")),
|
||||
step=1)
|
||||
stilltime = st.number_input("Still time:",
|
||||
value=int(response_format_parameters.get("stilltime")),
|
||||
step=1)
|
||||
else:
|
||||
fps = 0
|
||||
stilltime = 0
|
||||
|
||||
# Envoi
|
||||
if st.button("Generate post"):
|
||||
document_specs = DocumentSpecs(
|
||||
format=selected_format,
|
||||
style=selected_style,
|
||||
linkcolor=linkcolor,
|
||||
tocdepth=tocdepth,
|
||||
pdfengine=pdfengine,
|
||||
content=st.session_state['content'],
|
||||
fontsize=fontsize,
|
||||
paperwidth=paperwidth,
|
||||
paperheight=paperheight,
|
||||
ratio=ratio,
|
||||
margin=margin,
|
||||
vmargin=vmargin,
|
||||
extension=extension,
|
||||
fps=fps,
|
||||
stilltime=stilltime
|
||||
)
|
||||
|
||||
post_headers = http_headers | {"Content-Type": "application/json"}
|
||||
# Send the POST request with the JSON data in the request body
|
||||
response = requests.post(f"{st.session_state['fabriquedoc_endpoint']}/generer/",
|
||||
json=document_specs.model_dump(),
|
||||
headers=post_headers)
|
||||
# Check the response status code
|
||||
if 200 <= response.status_code <= 299:
|
||||
# If the request is successful, get the file data from the response
|
||||
file_data = response.content
|
||||
datef = datetime.datetime.now().strftime("%m-%d-%Y")
|
||||
|
||||
if document_specs.extension in ["jpg"]:
|
||||
extn = "zip"
|
||||
else:
|
||||
extn = document_specs.extension
|
||||
|
||||
file_name = f"{document_specs.style}-{document_specs.format}-{datef}-output.{extn}"
|
||||
|
||||
st.download_button('Télécharger', file_data, file_name=file_name)
|
||||
else:
|
||||
# If the request is unsuccessful, display the error status code and message
|
||||
st.error(f"Request failed with status code {response.status_code}: {response.text}")
|
35
app_tab4.py
Normal file
35
app_tab4.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
import requests
|
||||
import streamlit as st
|
||||
|
||||
|
||||
def app_tab4():
|
||||
st.header("Images")
|
||||
http_headers = {"Authorization": f"Bearer {st.session_state['bearer_token']}"}
|
||||
|
||||
st.write("Images disponibles")
|
||||
# list uploaded files with a request to the GET /images endpoint
|
||||
response = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/images/", headers=http_headers)
|
||||
images = response.json()["images"]
|
||||
selected_image = st.selectbox("Choisis une image:", images)
|
||||
image_response = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/images/{selected_image}", headers=http_headers)
|
||||
image_data = image_response.content
|
||||
st.image(image_data)
|
||||
|
||||
st.write("Envoyer une image")
|
||||
uploaded_files = st.file_uploader("Choisis un fichier image",
|
||||
type=["jpg", "jpeg"],
|
||||
accept_multiple_files=True)
|
||||
if uploaded_files is not None:
|
||||
for uploaded_file in uploaded_files:
|
||||
url = f"{st.session_state['fabriquedoc_endpoint']}/images/"
|
||||
# Create a FormData object
|
||||
files = {"file": uploaded_file}
|
||||
|
||||
# Submit the file to the endpoint
|
||||
response = requests.post(url, files=files, headers=http_headers)
|
||||
|
||||
# Check the response status
|
||||
if response.status_code < 300:
|
||||
st.write(f"File {uploaded_file.name} sent successfully!")
|
||||
else:
|
||||
st.write(f"File {uploaded_file.name} upload failed.")
|
9
demo_text.py
Normal file
9
demo_text.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
demo_text = """
|
||||
# Ceci est un titre\n
|
||||
## Ceci est un sous-titre\n\n
|
||||
Ceci est un paragraphe\n\n
|
||||
## Ceci est un autre sous-titre\n\n
|
||||
> Ceci est du code\n\n
|
||||
Ceci est un emoji :heart_eyes:\n\n
|
||||
::: {.center}\nCeci est centré\n:::
|
||||
"""
|
23
login_form.py
Normal file
23
login_form.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
import streamlit as st
|
||||
import requests
|
||||
|
||||
|
||||
def login_form():
|
||||
with st.form(key='authentication'):
|
||||
username = st.text_input("Username")
|
||||
password = st.text_input("Password", type="password")
|
||||
submit_button = st.form_submit_button(label='Login')
|
||||
if submit_button:
|
||||
# Send a POST request to your authentication endpoint
|
||||
response = requests.post(f"{st.session_state['fabriquedoc_endpoint']}/token/",
|
||||
data={"username": username, "password": password})
|
||||
if response.status_code == 200:
|
||||
st.write("Connexion réussie!")
|
||||
bearer_token = response.json()["access_token"]
|
||||
# Store the bearer token in the session state
|
||||
st.session_state['bearer_token'] = bearer_token
|
||||
st.session_state['logged_in'] = True
|
||||
else:
|
||||
st.error("Connexion échouée!")
|
||||
st.session_state['bearer_token'] = ""
|
||||
st.session_state['logged_in'] = False
|
220
main.py
220
main.py
|
@ -16,214 +16,44 @@
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import dotenv
|
||||
import streamlit as st
|
||||
import requests
|
||||
from pydantic import BaseModel
|
||||
import mdformat
|
||||
import dotenv
|
||||
import os
|
||||
import app_tab1
|
||||
import app_tab2
|
||||
import app_tab3
|
||||
import app_tab4
|
||||
import login_form
|
||||
|
||||
dotenv.load_dotenv()
|
||||
|
||||
|
||||
class DocumentSpecs(BaseModel):
|
||||
format: str
|
||||
style: str
|
||||
linkcolor: str
|
||||
tocdepth: int
|
||||
pdfengine: str
|
||||
content: str
|
||||
fontsize: int
|
||||
paperwidth: int
|
||||
paperheight: int
|
||||
ratio: int
|
||||
margin: int
|
||||
vmargin: int
|
||||
extension: str
|
||||
fps: int
|
||||
stilltime: int
|
||||
|
||||
|
||||
demo_text = """
|
||||
# Ceci est un titre\n
|
||||
## Ceci est un sous-titre\n\n
|
||||
Ceci est un paragraphe\n\n
|
||||
## Ceci est un autre sous-titre\n\n
|
||||
> Ceci est du code\n\n
|
||||
Ceci est un emoji :heart_eyes:\n\n
|
||||
::: {.center}\nCeci est centré\n:::
|
||||
"""
|
||||
|
||||
if 'fabriquedoc_endpoint' not in st.session_state:
|
||||
dotenv.load_dotenv()
|
||||
st.session_state['fabriquedoc_endpoint'] = os.environ.get("FABRIQUEDOC_ENDPOINT",
|
||||
"http://127.0.0.1:8000")
|
||||
if 'options' not in st.session_state:
|
||||
st.session_state['options'] = ""
|
||||
if 'bearer_token' not in st.session_state:
|
||||
st.session_state['bearer_token'] = ""
|
||||
if 'logged_in' not in st.session_state:
|
||||
st.session_state['logged_in'] = False
|
||||
|
||||
st.title("Fabrique à documents")
|
||||
|
||||
fabriquedoc_endpoint = os.environ.get("FABRIQUEDOC_ENDPOINT", "http://127.0.0.1:8000")
|
||||
st.write(f"Endpoint : {st.session_state['fabriquedoc_endpoint']}")
|
||||
|
||||
st.write(f"Endpoint : {fabriquedoc_endpoint}")
|
||||
if not st.session_state['logged_in']:
|
||||
login_form.login_form()
|
||||
|
||||
tab0, tab1, tab2, tab3, tab4 = st.tabs(["Login", "Markdown", "Aperçu", "Paramètres", "Images"])
|
||||
if st.session_state['logged_in']:
|
||||
tab1, tab2, tab3, tab4 = st.tabs(["Markdown", "Aperçu", "Paramètres", "Images"])
|
||||
|
||||
with tab0:
|
||||
with st.form(key='authentication'):
|
||||
username = st.text_input("Username")
|
||||
password = st.text_input("Password", type="password")
|
||||
submit_button = st.form_submit_button(label='Login')
|
||||
if submit_button:
|
||||
# Send a POST request to your authentication endpoint
|
||||
response = requests.post(f'{fabriquedoc_endpoint}/token/', data={"username": username, "password": password})
|
||||
if response.status_code == 200:
|
||||
st.write("Connexion réussie!")
|
||||
bearer_token = response.json()["access_token"]
|
||||
# Store the bearer token in the session state
|
||||
st.session_state['bearer_token'] = bearer_token
|
||||
else:
|
||||
st.error("Connexion échouée!")
|
||||
st.session_state['bearer_token'] = ""
|
||||
with tab1:
|
||||
app_tab1.app_tab1()
|
||||
|
||||
with tab1:
|
||||
def button1_callback():
|
||||
st.session_state['markdown'] = mdformat.text(st.session_state['markdown'],
|
||||
options={"number": True})
|
||||
with tab2:
|
||||
app_tab2.app_tab2()
|
||||
|
||||
with tab3:
|
||||
app_tab3.app_tab3()
|
||||
|
||||
content = st.text_area("Entre ton texte ici. Les images sont dans ./images/", demo_text,
|
||||
height=450,
|
||||
key='markdown')
|
||||
st.button("Formater le texte", on_click=button1_callback)
|
||||
|
||||
with tab2:
|
||||
st.write("Aperçu")
|
||||
st.markdown(content)
|
||||
|
||||
with tab3:
|
||||
st.header("Paramètres")
|
||||
http_headers = {"Authorization": f"Bearer {st.session_state['bearer_token']}"}
|
||||
# Styles
|
||||
response_styles = requests.get(f"{fabriquedoc_endpoint}/styles/", headers=http_headers).json()
|
||||
styles = response_styles.get("styles")
|
||||
selected_style = st.selectbox("Select a style:", styles)
|
||||
# Formats
|
||||
response_formats = requests.get(f"{fabriquedoc_endpoint}/formats/{selected_style}/", headers=http_headers).json()
|
||||
formats = response_formats.get("formats")
|
||||
selected_format = st.selectbox("Select a format:", formats)
|
||||
|
||||
# Autres paramètres
|
||||
response_format_parameters = requests.get(
|
||||
f"{fabriquedoc_endpoint}/format_parameters/{selected_style}/{selected_format}/", headers=http_headers).json()
|
||||
linkcolor = st.text_input("Link color:",
|
||||
value=response_format_parameters.get("linkcolor"))
|
||||
tocdepth = st.number_input("Table of Contents depth:",
|
||||
value=int(response_format_parameters.get("tocdepth")),
|
||||
min_value=1,
|
||||
max_value=5,
|
||||
step=1)
|
||||
pdfengine = st.text_input("PDF engine:",
|
||||
value=response_format_parameters.get("pdfengine"))
|
||||
fontsize = st.number_input("Font size:",
|
||||
value=int(response_format_parameters.get("fontsize")),
|
||||
step=1)
|
||||
paperwidth = st.number_input("Paper width:",
|
||||
value=int(response_format_parameters.get("paperwidth")),
|
||||
step=30)
|
||||
paperheight = st.number_input("Paper height:",
|
||||
value=int(response_format_parameters.get("paperheight")),
|
||||
step=30)
|
||||
ratio = st.number_input("Ratio:",
|
||||
value=int(response_format_parameters.get("ratio")),
|
||||
step=10)
|
||||
margin = st.number_input("Margin:",
|
||||
value=int(response_format_parameters.get("margin")),
|
||||
step=10)
|
||||
vmargin = st.number_input("Vertical margin:",
|
||||
value=int(response_format_parameters.get("vmargin")),
|
||||
step=10)
|
||||
extension = st.selectbox("Extension:", ["jpg", "pdf", "mp4"])
|
||||
if extension == "mp4":
|
||||
fps = st.number_input("FPS:",
|
||||
value=int(response_format_parameters.get("fps")),
|
||||
step=1)
|
||||
stilltime = st.number_input("Still time:",
|
||||
value=int(response_format_parameters.get("stilltime")),
|
||||
step=1)
|
||||
else:
|
||||
fps = 0
|
||||
stilltime = 0
|
||||
|
||||
# Envoi
|
||||
if st.button("Generate post"):
|
||||
document_specs = DocumentSpecs(
|
||||
format=selected_format,
|
||||
style=selected_style,
|
||||
linkcolor=linkcolor,
|
||||
tocdepth=tocdepth,
|
||||
pdfengine=pdfengine,
|
||||
content=content,
|
||||
fontsize=fontsize,
|
||||
paperwidth=paperwidth,
|
||||
paperheight=paperheight,
|
||||
ratio=ratio,
|
||||
margin=margin,
|
||||
vmargin=vmargin,
|
||||
extension=extension,
|
||||
fps=fps,
|
||||
stilltime=stilltime
|
||||
)
|
||||
|
||||
post_headers = http_headers | {"Content-Type": "application/json"}
|
||||
# Send the POST request with the JSON data in the request body
|
||||
response = requests.post(f"{fabriquedoc_endpoint}/generer/",
|
||||
json=document_specs.model_dump(),
|
||||
headers=post_headers)
|
||||
# Check the response status code
|
||||
if 200 <= response.status_code <= 299:
|
||||
# If the request is successful, get the file data from the response
|
||||
file_data = response.content
|
||||
datef = datetime.datetime.now().strftime("%m-%d-%Y")
|
||||
|
||||
if document_specs.extension in ["jpg"]:
|
||||
extn = "zip"
|
||||
else:
|
||||
extn = document_specs.extension
|
||||
|
||||
file_name = f"{document_specs.style}-{document_specs.format}-{datef}-output.{extn}"
|
||||
|
||||
st.download_button('Télécharger', file_data, file_name=file_name)
|
||||
else:
|
||||
# If the request is unsuccessful, display the error status code and message
|
||||
st.error(f"Request failed with status code {response.status_code}: {response.text}")
|
||||
|
||||
with tab4:
|
||||
st.header("Images")
|
||||
|
||||
st.write("Images disponibles")
|
||||
# list uploaded files with a request to the GET /images endpoint
|
||||
response = requests.get(f"{fabriquedoc_endpoint}/images/", headers=http_headers)
|
||||
images = response.json()["images"]
|
||||
selected_image = st.selectbox("Choisis une image:", images)
|
||||
image_response = requests.get(f"{fabriquedoc_endpoint}/images/{selected_image}", headers=http_headers)
|
||||
image_data = image_response.content
|
||||
st.image(image_data)
|
||||
|
||||
st.write("Envoyer une image")
|
||||
uploaded_files = st.file_uploader("Choisis un fichier image",
|
||||
type=["jpg", "jpeg"],
|
||||
accept_multiple_files=True)
|
||||
if uploaded_files is not None:
|
||||
for uploaded_file in uploaded_files:
|
||||
url = f"{fabriquedoc_endpoint}/images/"
|
||||
# Create a FormData object
|
||||
files = {"file": uploaded_file}
|
||||
|
||||
# Submit the file to the endpoint
|
||||
response = requests.post(url, files=files, headers=http_headers)
|
||||
|
||||
# Check the response status
|
||||
if response.status_code < 300:
|
||||
st.write(f"File {uploaded_file.name} sent successfully!")
|
||||
else:
|
||||
st.write(f"File {uploaded_file.name} upload failed.")
|
||||
with tab4:
|
||||
app_tab4.app_tab4()
|
||||
|
|
19
models.py
Normal file
19
models.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class DocumentSpecs(BaseModel):
|
||||
format: str
|
||||
style: str
|
||||
linkcolor: str
|
||||
tocdepth: int
|
||||
pdfengine: str
|
||||
content: str
|
||||
fontsize: int
|
||||
paperwidth: int
|
||||
paperheight: int
|
||||
ratio: int
|
||||
margin: int
|
||||
vmargin: int
|
||||
extension: str
|
||||
fps: int
|
||||
stilltime: int
|
|
@ -1,4 +1,4 @@
|
|||
streamlit~=1.30.0
|
||||
streamlit~=1.37.1
|
||||
requests~=2.31.0
|
||||
pydantic~=2.0.3
|
||||
mdformat~=0.7.17
|
||||
|
|
Loading…
Reference in a new issue