Compare commits
11 commits
woodpecker
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
7a9ef6d974 | ||
|
a0e2067f2b | ||
|
62cd159d0f | ||
|
2b11731561 | ||
|
a50bf9e598 | ||
|
e8b82a1f3d | ||
|
c7e193b912 | ||
|
19953b8429 | ||
|
9857d6fb21 | ||
|
2478d41729 | ||
4765b1dc9a |
15 changed files with 282 additions and 183 deletions
1
.env.template
Normal file
1
.env.template
Normal file
|
@ -0,0 +1 @@
|
|||
FABRIQUEDOC_ENDPOINT=
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/.idea/
|
||||
/.env
|
||||
|
|
2
CHANGE
2
CHANGE
|
@ -1 +1 @@
|
|||
3
|
||||
2
|
|
@ -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'])
|
96
app_tab3.py
Normal file
96
app_tab3.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
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 = "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)
|
||||
|
||||
# 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,
|
||||
timeout=(30, 3000)) # 30 seconds connect timeout, 5 minutes read timeout
|
||||
# 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")
|
||||
|
||||
file_name = f"{document_specs.style}-{document_specs.format}-{datef}-output.zip"
|
||||
|
||||
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}")
|
34
app_tab4.py
Normal file
34
app_tab4.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
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",
|
||||
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.")
|
49
demo_text.py
Normal file
49
demo_text.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
demo_text = """
|
||||
## Guide rapide Markdown
|
||||
|
||||
- Texte simple
|
||||
- **Gras**
|
||||
- *Italique*
|
||||
- ~~Barré~~
|
||||
- `Code en ligne`
|
||||
|
||||
::: {.center}\nCeci est centré\n:::
|
||||
|
||||
- Titres
|
||||
- # Titre 1
|
||||
- ## Titre 2
|
||||
- ### Titre 3
|
||||
- #### Titre 4
|
||||
- ##### Titre 5
|
||||
- ###### Titre 6
|
||||
|
||||
- Listes
|
||||
- Liste non ordonnée
|
||||
- Sous-élément
|
||||
- Autre sous-élément
|
||||
- Liste ordonnée
|
||||
1. Premier élément
|
||||
2. Deuxième élément
|
||||
3. Troisième élément
|
||||
|
||||
- Liens
|
||||
- [Lien texte](https://www.example.com)
|
||||
- [Lien avec titre](https://www.example.com "Titre du lien")
|
||||
- URL directe : <https://www.example.com>
|
||||
|
||||
- Images
|
||||
- ![Texte alternatif](url-de-l-image.jpg)
|
||||
- [![Image avec lien](url-de-l-image-miniature.jpg)](url-de-l-image-complete.jpg)
|
||||
|
||||
- Citations
|
||||
> Ceci est une citation
|
||||
>
|
||||
> Elle peut s'étendre sur plusieurs lignes
|
||||
|
||||
- Code
|
||||
```python
|
||||
def hello_world():
|
||||
print("Hello, World!")
|
||||
```
|
||||
|
||||
"""
|
|
@ -1,4 +1,5 @@
|
|||
docker network create fabriquedoc
|
||||
docker stop fabriquedoc-frontend
|
||||
docker rm fabriquedoc-frontend
|
||||
# Ce programme sert à lancer le job_dispatcher dans un docker localement pour tester
|
||||
docker run -p 8051:8051 --name fabriquedoc-frontend --network fabriquedoc --env FABRIQUEDOC_ENDPOINT=http://fabriquedoc:8000 local/fabriquedoc-frontend
|
||||
docker run -p 8051:8051 --env-file=.env --name fabriquedoc-frontend --network fabriquedoc --env FABRIQUEDOC_ENDPOINT=http://fabriquedoc:8000 local/fabriquedoc-frontend
|
|
@ -1,4 +1,4 @@
|
|||
docker stop fabriquedoc-frontend
|
||||
docker rm fabriquedoc-frontend
|
||||
# Ce programme sert à lancer le job_dispatcher dans un docker localement pour tester
|
||||
docker run -p 8051:8051 --name fabriquedoc-frontend --network host local/fabriquedoc-frontend
|
||||
docker run -p 8051:8051 --env-file=.env --name fabriquedoc-frontend --network host local/fabriquedoc-frontend
|
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
|
202
main.py
202
main.py
|
@ -16,192 +16,44 @@
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
|
||||
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
|
||||
|
||||
|
||||
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://0.0.0.0:8000")
|
||||
st.write(f"Endpoint : {st.session_state['fabriquedoc_endpoint']}")
|
||||
|
||||
tab1, tab2, tab3, tab4 = st.tabs(["Markdown", "Aperçu", "Paramètres", "Images"])
|
||||
if not st.session_state['logged_in']:
|
||||
login_form.login_form()
|
||||
|
||||
with tab1:
|
||||
def button1_callback():
|
||||
st.session_state['markdown'] = mdformat.text(st.session_state['markdown'],
|
||||
options={"number": True})
|
||||
if st.session_state['logged_in']:
|
||||
tab1, tab2, tab3, tab4 = st.tabs(["Markdown", "Aperçu", "Paramètres", "Images"])
|
||||
|
||||
with tab1:
|
||||
app_tab1.app_tab1()
|
||||
|
||||
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:
|
||||
app_tab2.app_tab2()
|
||||
|
||||
with tab2:
|
||||
st.write("Aperçu")
|
||||
st.markdown(content)
|
||||
with tab3:
|
||||
app_tab3.app_tab3()
|
||||
|
||||
with tab3:
|
||||
st.header("Paramètres")
|
||||
# Styles
|
||||
response_styles = requests.get(f"{fabriquedoc_endpoint}/styles")
|
||||
styles = response_styles.json()["styles"]
|
||||
selected_style = st.selectbox("Select a style:", styles)
|
||||
# Formats
|
||||
response_formats = requests.get(f"{fabriquedoc_endpoint}/formats/{selected_style}/")
|
||||
formats = response_formats.json()["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}")
|
||||
format_parameters = response_format_parameters.json()
|
||||
st.write(format_parameters)
|
||||
linkcolor = st.text_input("Link color:",
|
||||
value=format_parameters.get("linkcolor"))
|
||||
tocdepth = st.number_input("Table of Contents depth:",
|
||||
value=int(format_parameters.get("tocdepth")),
|
||||
min_value=1,
|
||||
max_value=5,
|
||||
step=1)
|
||||
pdfengine = st.text_input("PDF engine:",
|
||||
value=format_parameters.get("pdfengine"))
|
||||
fontsize = st.number_input("Font size:",
|
||||
value=int(format_parameters.get("fontsize")),
|
||||
step=1)
|
||||
paperwidth = st.number_input("Paper width:",
|
||||
value=int(format_parameters.get("paperwidth")),
|
||||
step=30)
|
||||
paperheight = st.number_input("Paper height:",
|
||||
value=int(format_parameters.get("paperheight")),
|
||||
step=30)
|
||||
ratio = st.number_input("Ratio:",
|
||||
value=int(format_parameters.get("ratio")),
|
||||
step=10)
|
||||
margin = st.number_input("Margin:",
|
||||
value=int(format_parameters.get("margin")),
|
||||
step=10)
|
||||
vmargin = st.number_input("Vertical margin:",
|
||||
value=int(format_parameters.get("vmargin")),
|
||||
step=10)
|
||||
extension = st.selectbox("Extension:", ["png", "jpg", "pdf", "mp4"])
|
||||
if extension == "mp4":
|
||||
fps = st.number_input("FPS:",
|
||||
value=int(format_parameters.get("fps")),
|
||||
step=1)
|
||||
stilltime = st.number_input("Still time:",
|
||||
value=int(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
|
||||
)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
# Send the POST request with the JSON data in the request body
|
||||
response = requests.get(f"{fabriquedoc_endpoint}/generer/",
|
||||
json=document_specs.model_dump(),
|
||||
headers=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", 'png']:
|
||||
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/")
|
||||
images = response.json()["images"]
|
||||
selected_image = st.selectbox("Choisis une image:", images)
|
||||
image_response = requests.get(f"{fabriquedoc_endpoint}/images/{selected_image}")
|
||||
image_data = image_response.content
|
||||
st.image(image_data)
|
||||
|
||||
st.write("Envoyer une image")
|
||||
uploaded_files = st.file_uploader("Choisis un fichier image",
|
||||
type=["png", "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)
|
||||
|
||||
# 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,5 @@
|
|||
streamlit~=1.24.0
|
||||
requests~=2.28.2
|
||||
pydantic~=2.0.1
|
||||
mdformat~=0.7.16
|
||||
streamlit~=1.37.1
|
||||
requests~=2.31.0
|
||||
pydantic~=2.0.3
|
||||
mdformat~=0.7.17
|
||||
python-dotenv~=1.0.1
|
Reference in a new issue