Spaces:
Running
Running
Ilyas KHIAT
commited on
Commit
•
f484ffe
1
Parent(s):
6a371ef
correction
Browse files- RAG_PDF_WEB.py +138 -123
- chat_with_pps.py +6 -3
- download_chart.py +3 -1
- high_chart.py +7 -2
- partie_prenante_carte.py +85 -48
RAG_PDF_WEB.py
CHANGED
@@ -13,6 +13,7 @@ from langchain_community.document_loaders import WebBaseLoader
|
|
13 |
import os
|
14 |
|
15 |
from session import set_rag
|
|
|
16 |
|
17 |
def get_docs_from_website(urls):
|
18 |
loader = WebBaseLoader(urls, header_template={
|
@@ -71,7 +72,13 @@ def get_conversation_chain(vectorstore):
|
|
71 |
)
|
72 |
return rag_chain
|
73 |
|
|
|
|
|
|
|
|
|
|
|
74 |
def rag_pdf_web():
|
|
|
75 |
load_dotenv()
|
76 |
st.header("INDIQUEZ VOS PAGES WEB ET/OU DOCUMENTS D’ENTREPRISE POUR AUDITER LE CONTENU RSE")
|
77 |
|
@@ -86,134 +93,142 @@ def rag_pdf_web():
|
|
86 |
url3 = st.text_input("URL 3")
|
87 |
# Process the URLs
|
88 |
sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
if option == "A partir de vos documents entreprise":
|
167 |
pdf_docs = st.file_uploader("Upload les documents concernant la marque (maximum 3 fichiers de taille max de 5 Mo)", type="pdf", accept_multiple_files=True)
|
168 |
# Process the PDF documents
|
169 |
sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
217 |
|
218 |
if vectorstore and chain:
|
219 |
set_rag(vectorstore, chain)
|
|
|
13 |
import os
|
14 |
|
15 |
from session import set_rag
|
16 |
+
from partie_prenante_carte import complete_and_verify_url
|
17 |
|
18 |
def get_docs_from_website(urls):
|
19 |
loader = WebBaseLoader(urls, header_template={
|
|
|
72 |
)
|
73 |
return rag_chain
|
74 |
|
75 |
+
def verify_and_complete_urls(urls):
|
76 |
+
for i in range(len(urls)):
|
77 |
+
is_valid, urls[i] = complete_and_verify_url(urls[i])
|
78 |
+
return urls
|
79 |
+
|
80 |
def rag_pdf_web():
|
81 |
+
|
82 |
load_dotenv()
|
83 |
st.header("INDIQUEZ VOS PAGES WEB ET/OU DOCUMENTS D’ENTREPRISE POUR AUDITER LE CONTENU RSE")
|
84 |
|
|
|
93 |
url3 = st.text_input("URL 3")
|
94 |
# Process the URLs
|
95 |
sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
|
96 |
+
try:
|
97 |
+
if st.button("Process"):
|
98 |
+
with st.spinner("Processing..."):
|
99 |
+
#get text from the website
|
100 |
+
urls = [url1, url2, url3]
|
101 |
+
filtered_urls = [url for url in urls if url]
|
102 |
+
|
103 |
+
#verify and complete urls
|
104 |
+
filtered_urls = verify_and_complete_urls(filtered_urls)
|
105 |
+
|
106 |
+
#get text from the website
|
107 |
+
docs = get_docs_from_website(filtered_urls)
|
108 |
+
|
109 |
+
#get text chunks
|
110 |
+
text_chunks = get_doc_chunks(docs)
|
111 |
+
|
112 |
+
#create vectorstore
|
113 |
+
vectorstore = get_vectorstore_from_docs(text_chunks)
|
114 |
+
|
115 |
+
chain = get_conversation_chain(vectorstore)
|
116 |
+
|
117 |
+
if sous_options == "Ambition, Vision, Missions, Valeurs":
|
118 |
+
# question = '''voici les 4 points à génerer absolument, pas de reponse comme je ne sais pas; et n'oublie aucun des points , chaque paragraphe doit être de minimum 150 caractères:
|
119 |
+
# \n
|
120 |
+
# ### Ambition : \n
|
121 |
+
# Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)
|
122 |
+
# \n
|
123 |
+
# ### Vision : \n
|
124 |
+
# Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)
|
125 |
+
# \n
|
126 |
+
# ### Missions : \n
|
127 |
+
# Quelles sont les missions de l'entreprise ? (répondre avec maximum 250 caractères)
|
128 |
+
# \n
|
129 |
+
# renvoie ta réponse en markdown et bien formatée'''
|
130 |
+
# response = chain.invoke(question)
|
131 |
+
# st.markdown(response.content)
|
132 |
+
|
133 |
+
#ambition
|
134 |
+
ambition = chain.invoke("Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)")
|
135 |
+
st.markdown("### Ambition :")
|
136 |
+
st.markdown(ambition.content)
|
137 |
+
|
138 |
+
#vision
|
139 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
140 |
+
st.markdown("### Vision :")
|
141 |
+
st.markdown(ambition.content)
|
142 |
+
|
143 |
+
#Mission
|
144 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
145 |
+
st.markdown("### Mission :")
|
146 |
+
st.markdown(ambition.content)
|
147 |
+
|
148 |
+
#values
|
149 |
+
values = chain.invoke("Quels sont les valeurs de l'entreprise ? (répondre avec 10 mots maximum en bullet points)")
|
150 |
+
st.markdown("### Valeurs :")
|
151 |
+
st.markdown(values.content)
|
152 |
+
|
153 |
+
elif sous_options == "3 piliers de la démarche RSE":
|
154 |
+
question = ''' suggère nous les 3 piliers principaux de la démarche RSE pour cette entreprise. N'oublie aucun pilier RSE , ca doit avoir ce format :
|
155 |
+
\n
|
156 |
+
### le titre du pilier numero 1 \n
|
157 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
158 |
+
\n
|
159 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
160 |
+
\n
|
161 |
+
### le titre du pilier numero 2 \n
|
162 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
163 |
+
\n
|
164 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
165 |
+
\n
|
166 |
+
### le titre du pilier numero 3 \n
|
167 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
168 |
+
\n
|
169 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
170 |
+
\n
|
171 |
+
renvoie ta réponse en markdown et bien formatée
|
172 |
+
'''
|
173 |
+
response = chain.invoke(question)
|
174 |
+
st.markdown(response.content)
|
175 |
+
except Exception as e:
|
176 |
+
st.error(f"Une erreur s'est produite : Url non valide ou problème de connexion à internet. Veuillez réessayer. erreur:{e}")
|
177 |
|
178 |
if option == "A partir de vos documents entreprise":
|
179 |
pdf_docs = st.file_uploader("Upload les documents concernant la marque (maximum 3 fichiers de taille max de 5 Mo)", type="pdf", accept_multiple_files=True)
|
180 |
# Process the PDF documents
|
181 |
sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
|
182 |
+
try:
|
183 |
+
if st.button("Process"):
|
184 |
+
with st.spinner("Processing..."):
|
185 |
+
#get pdf text in raw format
|
186 |
+
raw_text = get_pdf_text(pdf_docs)
|
187 |
+
|
188 |
+
#get text chunks
|
189 |
+
text_chunks = get_text_chunks(raw_text)
|
190 |
+
|
191 |
+
#create vectorstore
|
192 |
+
vectorstore = get_vectorstore(text_chunks)
|
193 |
+
|
194 |
+
chain = get_conversation_chain(vectorstore)
|
195 |
+
|
196 |
+
if sous_options == "Ambition, Vision, Missions, Valeurs":
|
197 |
+
|
198 |
+
#ambition
|
199 |
+
ambition = chain.invoke("Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)")
|
200 |
+
st.markdown("### Ambition :")
|
201 |
+
st.markdown(ambition.content)
|
202 |
+
|
203 |
+
#vision
|
204 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
205 |
+
st.markdown("### Vision :")
|
206 |
+
st.markdown(ambition.content)
|
207 |
+
|
208 |
+
#Mission
|
209 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
210 |
+
st.markdown("### Mission :")
|
211 |
+
st.markdown(ambition.content)
|
212 |
+
|
213 |
+
#values
|
214 |
+
values = chain.invoke("Quels sont les valeurs de l'entreprise ? (répondre avec 10 mots maximum en bullet points)")
|
215 |
+
st.markdown("### Valeurs :")
|
216 |
+
st.markdown(values.content)
|
217 |
+
|
218 |
+
elif sous_options == "3 piliers de la démarche RSE":
|
219 |
+
question = ''' suggère nous les 3 piliers principaux de la démarche RSE pour cette entreprise. Pour chaque pilier RSE doit avoir ce format :
|
220 |
+
\n
|
221 |
+
### le titre du ieme pilier \n
|
222 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
223 |
+
\n
|
224 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
225 |
+
\n
|
226 |
+
renvoie ta réponse en markdown et bien formatée
|
227 |
+
'''
|
228 |
+
response = chain.invoke(question)
|
229 |
+
st.markdown(response.content)
|
230 |
+
except Exception as e:
|
231 |
+
st.error(f"Une erreur s'est produite : Url non valide ou problème de connexion à internet. Veuillez réessayer. erreur:{e}")
|
232 |
|
233 |
if vectorstore and chain:
|
234 |
set_rag(vectorstore, chain)
|
chat_with_pps.py
CHANGED
@@ -10,9 +10,10 @@ from download_chart import construct_plot
|
|
10 |
load_dotenv()
|
11 |
|
12 |
def format_context(partie_prenante_grouped,marque):
|
13 |
-
context = ""
|
14 |
-
|
15 |
-
|
|
|
16 |
|
17 |
segmentation = '''
|
18 |
Les parties prenantes sont segmentées en 4 catégories:
|
@@ -69,6 +70,7 @@ def display_chat():
|
|
69 |
AIMessage(content="Salut, voici votre cartographie des parties prenantes. Que puis-je faire pour vous?"),
|
70 |
]
|
71 |
|
|
|
72 |
|
73 |
# conversation
|
74 |
for message in st.session_state.chat_history:
|
@@ -90,6 +92,7 @@ def display_chat():
|
|
90 |
st.markdown(user_query)
|
91 |
|
92 |
with st.chat_message("AI"):
|
|
|
93 |
response = st.write_stream(get_response(user_query, st.session_state.chat_history,format_context(st.session_state['pp_grouped'],st.session_state['Nom de la marque'])))
|
94 |
if "cartographie des parties prenantes" in message.content:
|
95 |
display_chart()
|
|
|
10 |
load_dotenv()
|
11 |
|
12 |
def format_context(partie_prenante_grouped,marque):
|
13 |
+
context = "la marque est " + marque + ".\n"
|
14 |
+
context += f"Le nombre de parties prenantes est {len(partie_prenante_grouped)} et ils sont les suivantes:\n"
|
15 |
+
for i,partie_prenante in enumerate(partie_prenante_grouped):
|
16 |
+
context += f"{i}.{partie_prenante['name']} est une partie prenante de {marque} et a un pouvoir de {partie_prenante['y']}% et une influence de {partie_prenante['x']}%.\n"
|
17 |
|
18 |
segmentation = '''
|
19 |
Les parties prenantes sont segmentées en 4 catégories:
|
|
|
70 |
AIMessage(content="Salut, voici votre cartographie des parties prenantes. Que puis-je faire pour vous?"),
|
71 |
]
|
72 |
|
73 |
+
st.markdown(format_context(st.session_state['pp_grouped'],st.session_state['Nom de la marque']))
|
74 |
|
75 |
# conversation
|
76 |
for message in st.session_state.chat_history:
|
|
|
92 |
st.markdown(user_query)
|
93 |
|
94 |
with st.chat_message("AI"):
|
95 |
+
|
96 |
response = st.write_stream(get_response(user_query, st.session_state.chat_history,format_context(st.session_state['pp_grouped'],st.session_state['Nom de la marque'])))
|
97 |
if "cartographie des parties prenantes" in message.content:
|
98 |
display_chart()
|
download_chart.py
CHANGED
@@ -49,7 +49,9 @@ def construct_plot():
|
|
49 |
|
50 |
# Update layout
|
51 |
fig.update_layout(
|
52 |
-
title="
|
|
|
|
|
53 |
xaxis=dict(title="Influence", range=[0, 100]),
|
54 |
yaxis=dict(title="Pouvoir", range=[0, 100]),
|
55 |
showlegend=True
|
|
|
49 |
|
50 |
# Update layout
|
51 |
fig.update_layout(
|
52 |
+
legend=dict( orientation="h", yanchor="bottom",y=1.02,title="Parties prenantes"),
|
53 |
+
height=600,
|
54 |
+
title=dict(text="Cartographie des parties prenantes", x=0.5, y=1, xanchor="center", yanchor="top"),
|
55 |
xaxis=dict(title="Influence", range=[0, 100]),
|
56 |
yaxis=dict(title="Pouvoir", range=[0, 100]),
|
57 |
showlegend=True
|
high_chart.py
CHANGED
@@ -189,9 +189,16 @@ def test_chart():
|
|
189 |
chart = hct.streamlit_highcharts(cd2,640) #640 is the chart height
|
190 |
# if chart:
|
191 |
# st.session_state['pp_grouped'] = chart
|
|
|
|
|
192 |
|
|
|
|
|
|
|
193 |
emp = st.empty()
|
194 |
|
|
|
|
|
195 |
col0, col1, col2, col3 = st.columns([1,1,1,1])
|
196 |
|
197 |
if col1.button("Sauvegarder"):
|
@@ -206,5 +213,3 @@ def test_chart():
|
|
206 |
st.session_state['pp_grouped'] = chart.copy()
|
207 |
fig = dc.construct_plot()
|
208 |
st.plotly_chart(fig)
|
209 |
-
|
210 |
-
return chart
|
|
|
189 |
chart = hct.streamlit_highcharts(cd2,640) #640 is the chart height
|
190 |
# if chart:
|
191 |
# st.session_state['pp_grouped'] = chart
|
192 |
+
|
193 |
+
|
194 |
|
195 |
+
if st.session_state['save']:
|
196 |
+
st.session_state['save'] = False
|
197 |
+
st.session_state['pp_grouped'] = chart.copy()
|
198 |
emp = st.empty()
|
199 |
|
200 |
+
|
201 |
+
|
202 |
col0, col1, col2, col3 = st.columns([1,1,1,1])
|
203 |
|
204 |
if col1.button("Sauvegarder"):
|
|
|
213 |
st.session_state['pp_grouped'] = chart.copy()
|
214 |
fig = dc.construct_plot()
|
215 |
st.plotly_chart(fig)
|
|
|
|
partie_prenante_carte.py
CHANGED
@@ -30,8 +30,12 @@ def get_docs_from_website(urls):
|
|
30 |
loader = WebBaseLoader(urls, header_template={
|
31 |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
32 |
})
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
35 |
|
36 |
def get_doc_chunks(docs):
|
37 |
# Split the loaded data
|
@@ -93,6 +97,8 @@ def display_list_urls():
|
|
93 |
|
94 |
# Button to delete the entry, placed in the second column
|
95 |
if col2.button("❌", key=f"but{index}"):
|
|
|
|
|
96 |
temp = st.session_state['parties_prenantes'][index]
|
97 |
delete_pp(temp)
|
98 |
del st.session_state.urls[index]
|
@@ -107,6 +113,24 @@ def display_list_urls():
|
|
107 |
else:
|
108 |
emp.empty() # Clear the placeholder if the index exceeds the list
|
109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
def extract_pp(urls,input_variables):
|
111 |
template_extraction_PP = '''
|
112 |
Objectif : identifiez tout les noms de marques qui sont des parties prenantes de la marque suivante pour développer un marketing de coopération (co-op marketing)
|
@@ -114,7 +138,7 @@ def extract_pp(urls,input_variables):
|
|
114 |
Le nom de la marque de référence est le suivant : {BRAND_NAME}
|
115 |
Son activité est la suivante : {BRAND_DESCRIPTION}
|
116 |
|
117 |
-
TA REPONSE DOIT ETRE SOUS FORME DE LISTE DE NOMS DE MARQUES
|
118 |
|
119 |
SI TU NE TROUVES PAS DE NOM DE MARQUE, REPONDS "444"
|
120 |
'''
|
@@ -122,6 +146,9 @@ def extract_pp(urls,input_variables):
|
|
122 |
|
123 |
docs = get_docs_from_website(urls)
|
124 |
|
|
|
|
|
|
|
125 |
#get text chunks
|
126 |
text_chunks = get_doc_chunks(docs)
|
127 |
|
@@ -143,35 +170,19 @@ def extract_pp(urls,input_variables):
|
|
143 |
|
144 |
return partie_prenante
|
145 |
|
146 |
-
def disp_vertical_slider(partie_prenante):
|
147 |
-
number_of_sliders = len(partie_prenante)
|
148 |
-
st.set_page_config(layout="wide")
|
149 |
-
st.subheader("Vertical Slider")
|
150 |
-
st.title("Vertical Slider")
|
151 |
-
st.write("This is a vertical slider example")
|
152 |
-
bar = st.columns(number_of_sliders)
|
153 |
-
for i in range(number_of_sliders):
|
154 |
-
with bar[i]:
|
155 |
-
tst = vertical_slider(
|
156 |
-
label=partie_prenante[i],
|
157 |
-
height=100,
|
158 |
-
key=partie_prenante[i],
|
159 |
-
default_value=50,
|
160 |
-
thumb_color= "orange", #Optional - Defaults to Streamlit Red
|
161 |
-
step=1,
|
162 |
-
min_value=0,
|
163 |
-
max_value=100,
|
164 |
-
value_always_visible=False,
|
165 |
-
)
|
166 |
-
st.write(tst)
|
167 |
-
|
168 |
def format_pp_add_viz(pp):
|
169 |
-
|
|
|
170 |
for i in range(len(st.session_state['pp_grouped'])):
|
|
|
|
|
|
|
|
|
|
|
171 |
if st.session_state['pp_grouped'][i]['name'] == pp:
|
172 |
return None
|
173 |
else:
|
174 |
-
st.session_state['pp_grouped'].append({'name':pp, 'x':
|
175 |
|
176 |
def add_pp(new_pp, default_value=50):
|
177 |
new_pp = sorted(new_pp)
|
@@ -180,6 +191,13 @@ def add_pp(new_pp, default_value=50):
|
|
180 |
for pp in new_pp:
|
181 |
format_pp_add_viz(pp)
|
182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
|
184 |
def complete_and_verify_url(partial_url):
|
185 |
# Regex pattern for validating a URL
|
@@ -192,8 +210,15 @@ def complete_and_verify_url(partial_url):
|
|
192 |
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
|
193 |
|
194 |
# Complete the URL if it doesn't have http:// or https://
|
195 |
-
if not partial_url.startswith(('http://', 'https://')):
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
complete_url = 'https://' + partial_url
|
|
|
197 |
else:
|
198 |
complete_url = partial_url
|
199 |
|
@@ -203,6 +228,7 @@ def complete_and_verify_url(partial_url):
|
|
203 |
else:
|
204 |
return (False, complete_url)
|
205 |
|
|
|
206 |
def display_pp():
|
207 |
|
208 |
load_dotenv()
|
@@ -218,6 +244,9 @@ def display_pp():
|
|
218 |
st.session_state['parties_prenantes'] = []
|
219 |
if "pp_grouped" not in st.session_state: #servira pour le plot et la cartographie des parties prenantes, regroupe sans doublons
|
220 |
st.session_state['pp_grouped'] = []
|
|
|
|
|
|
|
221 |
|
222 |
st.header("Parties prenantes de la marque")
|
223 |
#set brand name and description
|
@@ -233,35 +262,40 @@ def display_pp():
|
|
233 |
|
234 |
#if the user clicks on the button
|
235 |
if st.button("ajouter"):
|
236 |
-
|
237 |
#complete and verify the url
|
238 |
is_valid,url = complete_and_verify_url(url)
|
239 |
-
st.write(url)
|
240 |
if not is_valid:
|
241 |
st.error("URL invalide")
|
242 |
elif url in st.session_state["urls"] :
|
243 |
st.error("URL déjà ajoutée")
|
244 |
|
245 |
else:
|
|
|
|
|
|
|
|
|
246 |
# Création de l'expander
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
|
|
|
|
265 |
|
266 |
# alphabet = [ pp[0] for pp in partie_prenante]
|
267 |
# pouvoir = [ 50 for _ in range(len(partie_prenante))]
|
@@ -280,6 +314,9 @@ def display_pp():
|
|
280 |
# disp_vertical_slider(partie_prenante)
|
281 |
# st.altair_chart(c, use_container_width=True)
|
282 |
display_list_urls()
|
|
|
|
|
|
|
283 |
test_chart()
|
284 |
|
285 |
|
|
|
30 |
loader = WebBaseLoader(urls, header_template={
|
31 |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
32 |
})
|
33 |
+
try:
|
34 |
+
docs = loader.load()
|
35 |
+
return docs
|
36 |
+
except Exception as e:
|
37 |
+
return None
|
38 |
+
|
39 |
|
40 |
def get_doc_chunks(docs):
|
41 |
# Split the loaded data
|
|
|
97 |
|
98 |
# Button to delete the entry, placed in the second column
|
99 |
if col2.button("❌", key=f"but{index}"):
|
100 |
+
|
101 |
+
st.session_state["save"] = True
|
102 |
temp = st.session_state['parties_prenantes'][index]
|
103 |
delete_pp(temp)
|
104 |
del st.session_state.urls[index]
|
|
|
113 |
else:
|
114 |
emp.empty() # Clear the placeholder if the index exceeds the list
|
115 |
|
116 |
+
def display_list_pps():
|
117 |
+
for index, item in enumerate(st.session_state["pp_grouped"]):
|
118 |
+
emp = st.empty()
|
119 |
+
col1, col2 = emp.columns([7, 3])
|
120 |
+
|
121 |
+
if col2.button("❌", key=f"butp{index}"):
|
122 |
+
|
123 |
+
del st.session_state["pp_grouped"][index]
|
124 |
+
st.experimental_rerun()
|
125 |
+
|
126 |
+
if len(st.session_state["pp_grouped"]) > index:
|
127 |
+
name = st.session_state["pp_grouped"][index]["name"]
|
128 |
+
col1.markdown(f"{name}")
|
129 |
+
else:
|
130 |
+
emp.empty()
|
131 |
+
|
132 |
+
|
133 |
+
|
134 |
def extract_pp(urls,input_variables):
|
135 |
template_extraction_PP = '''
|
136 |
Objectif : identifiez tout les noms de marques qui sont des parties prenantes de la marque suivante pour développer un marketing de coopération (co-op marketing)
|
|
|
138 |
Le nom de la marque de référence est le suivant : {BRAND_NAME}
|
139 |
Son activité est la suivante : {BRAND_DESCRIPTION}
|
140 |
|
141 |
+
TA REPONSE DOIT ETRE SOUS FORME DE LISTE DE NOMS DE MARQUES SANS NUMEROTATION ET SEPARES PAR DES SAUTS DE LIGNE
|
142 |
|
143 |
SI TU NE TROUVES PAS DE NOM DE MARQUE, REPONDS "444"
|
144 |
'''
|
|
|
146 |
|
147 |
docs = get_docs_from_website(urls)
|
148 |
|
149 |
+
if docs == None:
|
150 |
+
return "445"
|
151 |
+
|
152 |
#get text chunks
|
153 |
text_chunks = get_doc_chunks(docs)
|
154 |
|
|
|
170 |
|
171 |
return partie_prenante
|
172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
def format_pp_add_viz(pp):
|
174 |
+
y = 50
|
175 |
+
x = 50
|
176 |
for i in range(len(st.session_state['pp_grouped'])):
|
177 |
+
if st.session_state['pp_grouped'][i]['y'] == y and st.session_state['pp_grouped'][i]['x'] == x:
|
178 |
+
y += 5
|
179 |
+
if y > 95:
|
180 |
+
y = 50
|
181 |
+
x += 5
|
182 |
if st.session_state['pp_grouped'][i]['name'] == pp:
|
183 |
return None
|
184 |
else:
|
185 |
+
st.session_state['pp_grouped'].append({'name':pp, 'x':x,'y':y})
|
186 |
|
187 |
def add_pp(new_pp, default_value=50):
|
188 |
new_pp = sorted(new_pp)
|
|
|
191 |
for pp in new_pp:
|
192 |
format_pp_add_viz(pp)
|
193 |
|
194 |
+
def add_pp_input_text():
|
195 |
+
new_pp = st.text_input("Ajouter une partie prenante")
|
196 |
+
if st.button("Ajouter"):
|
197 |
+
st.session_state["save"] = True
|
198 |
+
add_pp([new_pp])
|
199 |
+
|
200 |
+
import re
|
201 |
|
202 |
def complete_and_verify_url(partial_url):
|
203 |
# Regex pattern for validating a URL
|
|
|
210 |
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
|
211 |
|
212 |
# Complete the URL if it doesn't have http:// or https://
|
213 |
+
if not partial_url.startswith(('http://', 'https://', 'www.')):
|
214 |
+
if not partial_url.startswith('www.'):
|
215 |
+
complete_url = 'https://www.' + partial_url
|
216 |
+
else:
|
217 |
+
complete_url = 'https://' + partial_url
|
218 |
+
|
219 |
+
elif partial_url.startswith('www.'):
|
220 |
complete_url = 'https://' + partial_url
|
221 |
+
|
222 |
else:
|
223 |
complete_url = partial_url
|
224 |
|
|
|
228 |
else:
|
229 |
return (False, complete_url)
|
230 |
|
231 |
+
|
232 |
def display_pp():
|
233 |
|
234 |
load_dotenv()
|
|
|
244 |
st.session_state['parties_prenantes'] = []
|
245 |
if "pp_grouped" not in st.session_state: #servira pour le plot et la cartographie des parties prenantes, regroupe sans doublons
|
246 |
st.session_state['pp_grouped'] = []
|
247 |
+
|
248 |
+
if "save" not in st.session_state:
|
249 |
+
st.session_state["save"] = False
|
250 |
|
251 |
st.header("Parties prenantes de la marque")
|
252 |
#set brand name and description
|
|
|
262 |
|
263 |
#if the user clicks on the button
|
264 |
if st.button("ajouter"):
|
265 |
+
st.session_state["save"] = True
|
266 |
#complete and verify the url
|
267 |
is_valid,url = complete_and_verify_url(url)
|
|
|
268 |
if not is_valid:
|
269 |
st.error("URL invalide")
|
270 |
elif url in st.session_state["urls"] :
|
271 |
st.error("URL déjà ajoutée")
|
272 |
|
273 |
else:
|
274 |
+
docs = get_docs_from_website(url)
|
275 |
+
if docs is None:
|
276 |
+
st.error("Aucune url trouvée ou erreur lors de la récupération du contenu")
|
277 |
+
else:
|
278 |
# Création de l'expander
|
279 |
+
with st.expander("Cliquez ici pour éditer et voir le document"):
|
280 |
+
cleaned_text = re.sub(r'\n\n+', '\n\n', docs[0].page_content.strip())
|
281 |
+
text_value = st.text_area("Modifier le texte ci-dessous:", value=cleaned_text, height=300)
|
282 |
+
if st.button('Sauvegarder'):
|
283 |
+
st.success("Texte sauvegardé avec succès!")
|
284 |
+
|
285 |
+
with st.spinner("Processing..."):
|
286 |
+
|
287 |
+
#handle the extraction
|
288 |
+
input_variables = {"BRAND_NAME": brand_name, "BRAND_DESCRIPTION": "no information"}
|
289 |
+
partie_prenante = extract_pp([url], input_variables)
|
290 |
+
|
291 |
+
if "444" in partie_prenante: #444 is the code for no brand found , chosen
|
292 |
+
st.error("Aucune partie prenante trouvée")
|
293 |
+
elif "445" in partie_prenante: #445 is the code for no website found with the given url
|
294 |
+
st.error("Aucun site web trouvé avec l'url donnée")
|
295 |
+
else:
|
296 |
+
partie_prenante = sorted(partie_prenante)
|
297 |
+
st.session_state["urls"].append(url)
|
298 |
+
add_pp(partie_prenante)
|
299 |
|
300 |
# alphabet = [ pp[0] for pp in partie_prenante]
|
301 |
# pouvoir = [ 50 for _ in range(len(partie_prenante))]
|
|
|
314 |
# disp_vertical_slider(partie_prenante)
|
315 |
# st.altair_chart(c, use_container_width=True)
|
316 |
display_list_urls()
|
317 |
+
with st.expander("Liste des parties prenantes"):
|
318 |
+
add_pp_input_text()
|
319 |
+
display_list_pps()
|
320 |
test_chart()
|
321 |
|
322 |
|