Spaces:
Sleeping
Sleeping
Ilyas KHIAT
commited on
Commit
•
fb86b93
1
Parent(s):
34c79da
implementation rag v0.0
Browse files- .streamlit/.env +1 -1
- .streamlit/config.toml +2 -0
- AnalyseActionsRSE.py +102 -33
- ODD.py +90 -0
- RAG_PDF.py +77 -0
- RAG_PDF_WEB.py +212 -0
- README.md +5 -6
- app.py +5 -2
- collaborons.py +1 -0
- htmlTemplates.py +44 -0
- requirements.txt +11 -0
.streamlit/.env
CHANGED
@@ -1 +1 @@
|
|
1 |
-
|
|
|
1 |
+
|
.streamlit/config.toml
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
[server]
|
2 |
+
maxUploadSize = 5
|
AnalyseActionsRSE.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
import streamlit as st
|
2 |
from ISO26000 import classify_actions_rse_ISO26000 as classify_iso26000
|
|
|
|
|
3 |
from impactscore import classify_actions_rse_IMPACTSCORE as classify_impactscore
|
4 |
from data_manager import get_data
|
5 |
|
@@ -79,39 +81,8 @@ def display_analyse_actions_rse():
|
|
79 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
80 |
st.markdown(f"**Total des actions RSE :** {total_actions}")
|
81 |
|
82 |
-
elif approach == "Impact Score (en cours de développement)":
|
83 |
-
# Récupérer les données depuis data_manager.py
|
84 |
-
data, total_hits = get_data()
|
85 |
-
|
86 |
-
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
87 |
-
|
88 |
-
st.markdown("""
|
89 |
-
🌳 **QU'EST-CE QUE L'IMPACT SCORE ?**
|
90 |
-
|
91 |
-
Ce référentiel commun et unique a été co-construit par 30 réseaux d’entreprises afin de publier en transparence leurs données d’impact, exigence européenne depuis 2024.
|
92 |
-
|
93 |
-
**COMMENT EST-IL STRUCTURÉE ?**
|
94 |
-
|
95 |
-
IMPACT SCORE repose sur 3 piliers essentiels :
|
96 |
-
|
97 |
-
- 🚫 LIMITATION DES EXTERNALITÉS NÉGATIVES
|
98 |
-
- 💡 PARTAGE DU POUVOIR ET DE LA VALEUR
|
99 |
-
- 🎯 STRATÉGIE À IMPACT
|
100 |
-
""")
|
101 |
-
|
102 |
-
|
103 |
-
st.markdown("""<small>Source MOUVEMENT IMPACT FRANCE : <a href="https://impactscore.fr/comprendre-limpact-score/" target="_blank">https://impactscore.fr/comprendre-limpact-score/</a></small>""", unsafe_allow_html=True)
|
104 |
-
|
105 |
-
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
106 |
-
|
107 |
-
criteria_counts = classify_impactscore(data)
|
108 |
-
|
109 |
-
total_actions = sum([len(actions) for actions in criteria_counts.values()])
|
110 |
-
st.markdown(f"**Total des actions RSE :** {total_actions}")
|
111 |
-
|
112 |
-
### OBJECTIF DE DEVELOPPEMENT DURABLE ###
|
113 |
elif approach == "ODD Objectifs de Développement Durable (en cours de développement)":
|
114 |
-
|
115 |
data, total_hits = get_data()
|
116 |
|
117 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
@@ -146,11 +117,95 @@ def display_analyse_actions_rse():
|
|
146 |
|
147 |
st.markdown("""<small>Source AGENDA 2030 EN FRANCE : <a href="https://www.agenda-2030.fr/17-objectifs-de-developpement-durable/?" target="_blank">https://impactscore.fr/comprendre-limpact-score/</a></small>""", unsafe_allow_html=True)
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
criteria_counts = classify_impactscore(data)
|
152 |
|
153 |
-
total_actions =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
st.markdown(f"**Total des actions RSE :** {total_actions}")
|
155 |
|
156 |
if approach == "Norme ISO 26000":
|
@@ -160,5 +215,19 @@ def display_analyse_actions_rse():
|
|
160 |
for category, count in synthesis_sorted.items():
|
161 |
st.write(f"{category}: {count} action(s) RSE")
|
162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
if __name__ == "__main__":
|
164 |
display_analyse_actions_rse()
|
|
|
1 |
import streamlit as st
|
2 |
from ISO26000 import classify_actions_rse_ISO26000 as classify_iso26000
|
3 |
+
from ODD import classify_actions_rse_ODD as classify_odd
|
4 |
+
from impactscore import classify_actions_rse_IMPACTSCORE as classify_impactscore
|
5 |
from impactscore import classify_actions_rse_IMPACTSCORE as classify_impactscore
|
6 |
from data_manager import get_data
|
7 |
|
|
|
81 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
82 |
st.markdown(f"**Total des actions RSE :** {total_actions}")
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
elif approach == "ODD Objectifs de Développement Durable (en cours de développement)":
|
85 |
+
# Récupérer les données depuis data_manager.py
|
86 |
data, total_hits = get_data()
|
87 |
|
88 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
|
|
117 |
|
118 |
st.markdown("""<small>Source AGENDA 2030 EN FRANCE : <a href="https://www.agenda-2030.fr/17-objectifs-de-developpement-durable/?" target="_blank">https://impactscore.fr/comprendre-limpact-score/</a></small>""", unsafe_allow_html=True)
|
119 |
|
120 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
121 |
+
|
122 |
+
pictograms = {
|
123 |
+
"Pas de pauvreté": "🏚️",
|
124 |
+
"Faim « Zéro »": "🌾",
|
125 |
+
"Bonne santé et bien-être": "🏥",
|
126 |
+
"Éducation de qualité": "🎓",
|
127 |
+
"Égalité entre les sexes": "⚧️",
|
128 |
+
"Eau propre et assainissement": "💧",
|
129 |
+
"Énergie propre et d'un coût abordable": "⚡",
|
130 |
+
"Travail décent et croissance économique": "👷",
|
131 |
+
"Industrie, innovation et infrastructure": "🏭",
|
132 |
+
"Inégalités réduites": "⚖️",
|
133 |
+
"Villes et communautés durables": "🏙️",
|
134 |
+
"Consommation et production responsables": "♻️",
|
135 |
+
"Lutte contre les changements climatiques": "🌍",
|
136 |
+
"Vie aquatique": "🐟",
|
137 |
+
"Vie terrestre": "🌳",
|
138 |
+
"Paix, justice et institutions efficaces": "⚖️",
|
139 |
+
"Partenariats pour la réalisation des objectifs": "🤝",
|
140 |
+
"Autres": "❓"
|
141 |
+
}
|
142 |
+
|
143 |
+
|
144 |
+
criteria_counts = classify_odd(data)
|
145 |
+
|
146 |
+
total_actions = 0
|
147 |
+
|
148 |
+
for category, actions in criteria_counts.items():
|
149 |
+
if category in pictograms:
|
150 |
+
st.subheader(f"{pictograms[category]} {category}")
|
151 |
+
else:
|
152 |
+
st.subheader(f"{pictograms['Autres']} Autres")
|
153 |
+
total_actions += len(actions)
|
154 |
+
for action in actions:
|
155 |
+
nom_entreprise = action.get('nom_courant_denomination', 'Information non disponible')
|
156 |
+
st.write(f"Entreprise : {action.get('name','N/A')}, Action RSE : {action.get('action_rse', 'N/A')}, Activité : {action.get('activity', 'N/A')}, Ville : {action.get('city', 'N/A')}")
|
157 |
+
|
158 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
159 |
+
st.markdown(f"**Total des actions RSE :** {total_actions}")
|
160 |
+
|
161 |
+
### OBJECTIF DE DEVELOPPEMENT DURABLE ###
|
162 |
+
elif approach == "Impact Score (en cours de développement)":
|
163 |
+
# Récupérer les données depuis data_manager.py
|
164 |
+
data, total_hits = get_data()
|
165 |
+
|
166 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
167 |
|
168 |
+
st.markdown("""
|
169 |
+
🌳 **QU'EST-CE QUE L'IMPACT SCORE ?**
|
170 |
+
|
171 |
+
Ce référentiel commun et unique a été co-construit par 30 réseaux d’entreprises afin de publier en transparence leurs données d’impact, exigence européenne depuis 2024.
|
172 |
+
|
173 |
+
**COMMENT EST-IL STRUCTURÉE ?**
|
174 |
+
|
175 |
+
IMPACT SCORE repose sur 3 piliers essentiels :
|
176 |
+
|
177 |
+
- 🚫 LIMITATION DES EXTERNALITÉS NÉGATIVES
|
178 |
+
- 💡 PARTAGE DU POUVOIR ET DE LA VALEUR
|
179 |
+
- 🎯 STRATÉGIE À IMPACT
|
180 |
+
""")
|
181 |
+
|
182 |
+
|
183 |
+
st.markdown("""<small>Source MOUVEMENT IMPACT FRANCE : <a href="https://impactscore.fr/comprendre-limpact-score/" target="_blank">https://impactscore.fr/comprendre-limpact-score/</a></small>""", unsafe_allow_html=True)
|
184 |
+
|
185 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
186 |
+
|
187 |
+
pictograms = {
|
188 |
+
"Initiatives pour réduire l'empreinte carbone": "🌍",
|
189 |
+
"Amélioration des conditions de travail": "👷",
|
190 |
+
"Promotion du recyclage": "♻️",
|
191 |
+
"Autres": "❓"
|
192 |
+
}
|
193 |
+
|
194 |
criteria_counts = classify_impactscore(data)
|
195 |
|
196 |
+
total_actions = 0
|
197 |
+
|
198 |
+
for category, actions in criteria_counts.items():
|
199 |
+
if category in pictograms:
|
200 |
+
st.subheader(f"{pictograms[category]} {category}")
|
201 |
+
else:
|
202 |
+
st.subheader(f"{pictograms['Autres']} Autres")
|
203 |
+
total_actions += len(actions)
|
204 |
+
for action in actions:
|
205 |
+
nom_entreprise = action.get('nom_courant_denomination', 'Information non disponible')
|
206 |
+
st.write(f"Entreprise : {action.get('name','N/A')}, Action RSE : {action.get('action_rse', 'N/A')}, Activité : {action.get('activity', 'N/A')}, Ville : {action.get('city', 'N/A')}")
|
207 |
+
|
208 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
209 |
st.markdown(f"**Total des actions RSE :** {total_actions}")
|
210 |
|
211 |
if approach == "Norme ISO 26000":
|
|
|
215 |
for category, count in synthesis_sorted.items():
|
216 |
st.write(f"{category}: {count} action(s) RSE")
|
217 |
|
218 |
+
if approach == "ODD Objectifs de Développement Durable (en cours de développement)":
|
219 |
+
st.subheader("Synthèse par catégorie ODD")
|
220 |
+
synthesis = {category: len(actions) for category, actions in criteria_counts.items()}
|
221 |
+
synthesis_sorted = dict(sorted(synthesis.items(), key=lambda item: item[1], reverse=True))
|
222 |
+
for category, count in synthesis_sorted.items():
|
223 |
+
st.write(f"{category}: {count} action(s) RSE")
|
224 |
+
|
225 |
+
if approach == "Impact Score (en cours de développement)":
|
226 |
+
st.subheader("Synthèse par catégorie ODD")
|
227 |
+
synthesis = {category: len(actions) for category, actions in criteria_counts.items()}
|
228 |
+
synthesis_sorted = dict(sorted(synthesis.items(), key=lambda item: item[1], reverse=True))
|
229 |
+
for category, count in synthesis_sorted.items():
|
230 |
+
st.write(f"{category}: {count} action(s) RSE")
|
231 |
+
|
232 |
if __name__ == "__main__":
|
233 |
display_analyse_actions_rse()
|
ODD.py
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from data_manager import get_data
|
2 |
+
|
3 |
+
def classify_actions_rse_ODD(data):
|
4 |
+
data, _ = get_data() # Récupérer les données depuis data_manager.py
|
5 |
+
|
6 |
+
criteria = {
|
7 |
+
"Pas de pauvreté": [],
|
8 |
+
"Faim « Zéro »": [],
|
9 |
+
"Bonne santé et bien-être": [],
|
10 |
+
"Éducation de qualité": [],
|
11 |
+
"Égalité entre les sexes": [],
|
12 |
+
"Eau propre et assainissement": [],
|
13 |
+
"Énergie propre et d'un coût abordable": [],
|
14 |
+
"Travail décent et croissance économique": [],
|
15 |
+
"Industrie, innovation et infrastructure": [],
|
16 |
+
"Inégalités réduites": [],
|
17 |
+
"Villes et communautés durables": [],
|
18 |
+
"Consommation et production responsables": [],
|
19 |
+
"Lutte contre les changements climatiques": [],
|
20 |
+
"Vie aquatique": [],
|
21 |
+
"Vie terrestre": [],
|
22 |
+
"Paix, justice et institutions efficaces": [],
|
23 |
+
"Partenariats pour la réalisation des objectifs": [],
|
24 |
+
"Autres": []
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
# Keywords for each ISO 26000 category to help in classifying the actions
|
29 |
+
keywords = {
|
30 |
+
"Pas de pauvreté": ["pauvreté", "aide financière", "microcrédit", "inclusion financière", "projets anti-pauvreté", "programmes de soutien", "subventions sociales", "initiatives d'entreprenariat"],
|
31 |
+
"Faim « Zéro »": ["faim", "sécurité alimentaire", "nutrition", "agriculture durable", "programmes de nutrition", "alimentation scolaire", "agroécologie", "technologies agricoles"],
|
32 |
+
"Bonne santé et bien-être": ["santé", "bien-être", "vaccination", "hôpitaux", "soins médicaux", "prévention des maladies", "santé mentale", "accès aux soins"],
|
33 |
+
"Éducation de qualité": ["éducation", "scolarisation", "formation", "alphabétisation", "éducation pour tous", "technologie éducative", "programmes éducatifs", "qualité de l'enseignement"],
|
34 |
+
"Égalité entre les sexes": ["égalité des sexes", "droits des femmes", "empowerment des femmes", "lutte contre les violences de genre", "participation des femmes", "leadership féminin", "éducation des filles", "santé reproductive"],
|
35 |
+
"Eau propre et assainissement": ["eau propre", "assainissement", "accès à l'eau", "traitement de l'eau", "gestion des ressources en eau", "sanitation", "qualité de l'eau", "hygiène"],
|
36 |
+
"Énergie propre et d'un coût abordable": ["énergie renouvelable", "énergie propre", "efficacité énergétique", "technologies énergétiques", "accès à l'énergie", "énergie solaire", "énergie éolienne", "infrastructures énergétiques"],
|
37 |
+
"Travail décent et croissance économique": ["emploi", "droits du travail", "croissance économique", "entreprise responsable", "économie inclusive", "emploi de qualité", "conditions de travail équitables", "sécurité de l'emploi"],
|
38 |
+
"Industrie, innovation et infrastructure": ["industrie", "innovation", "infrastructure", "technologie", "recherche et développement", "industrialisation durable", "innovation technologique", "infrastructures résilientes"],
|
39 |
+
"Inégalités réduites": ["réduction des inégalités", "inclusion sociale", "équité", "justice sociale", "accès équitable", "droits de l'homme", "intégration sociale", "lutte contre la discrimination"],
|
40 |
+
"Villes et communautés durables": ["urbanisme durable", "communautés résilientes", "transports publics", "éco-quartiers", "développement urbain", "mobilité urbaine", "gestion urbaine", "logement abordable"],
|
41 |
+
"Consommation et production responsables": ["consommation durable", "production durable", "économie circulaire", "recyclage", "gestion des déchets", "consommation éthique", "réduction de l'empreinte écologique", "sourcing responsable"],
|
42 |
+
"Lutte contre les changements climatiques": ["changements climatiques", "atténuation", "adaptation au climat", "réduction des émissions", "politiques climatiques", "énergies vertes", "carboneutralité", "initiatives climatiques"],
|
43 |
+
"Vie aquatique": ["océans", "mers", "conservation marine", "pêche durable", "biodiversité marine", "écosystèmes marins", "protection des habitats marins", "lutte contre la pollution marine"],
|
44 |
+
"Vie terrestre": ["biodiversité terrestre", "conservation des forêts", "reforestation", "lutte contre la désertification", "protection de la faune", "aires protégées", "gestion durable des terres", "restauration des habitats"],
|
45 |
+
"Paix, justice et institutions efficaces": ["paix", "justice", "lutte contre la corruption", "institutions solides", "état de droit", "droits humains", "transparence gouvernementale", "accès à la justice"],
|
46 |
+
"Partenariats pour la réalisation des objectifs": ["partenariats mondiaux", "coopération internationale", "mobilisation des ressources", "alignement des politiques", "collaboration multisectorielle", "coopération transfrontalière", "engagement des parties prenantes", "synergies globales"]
|
47 |
+
}
|
48 |
+
|
49 |
+
keywords = {
|
50 |
+
"Pas de pauvreté": ["pauvreté", "aide financière", "microcrédit", "inclusion financière", "soutien économique", "subventions", "réduction de la pauvreté"],
|
51 |
+
"Faim « Zéro »": ["faim", "sécurité alimentaire", "nutrition", "agriculture durable", "aide alimentaire", "cultures résilientes"],
|
52 |
+
"Bonne santé et bien-être": ["santé", "bien-être", "vaccination", "hôpitaux", "soins médicaux", "prévention des maladies", "santé publique", "accès aux soins"],
|
53 |
+
"Éducation de qualité": ["éducation", "scolarisation", "formation", "alphabétisation", "accès à l'éducation", "qualité de l'enseignement"],
|
54 |
+
"Égalité entre les sexes": ["égalité des sexes", "droits des femmes", "empowerment des femmes", "égalité de genre", "lutte contre les discriminations de genre", "participation des femmes", "leadership féminin", "éducation des filles", "santé reproductive", "violences de genre","leadership féminin", "parité", "lutte contre le harcèlement sexuel", "programmes de mentorat pour femmes", "initiatives pour l'équité salariale", "soutien à l'entrepreneuriat féminin", "formation sur la diversité", "sensibilisation au genre", "promotion de la diversité", "inclusion de genre"],
|
55 |
+
"Eau propre et assainissement": ["eau propre", "assainissement", "accès à l'eau", "traitement de l'eau", "gestion durable de l'eau"],
|
56 |
+
"Énergie propre et d'un coût abordable": ["énergie renouvelable", "énergie propre", "efficacité énergétique", "énergie solaire", "énergie éolienne", "réduction de la consommation énergétique"],
|
57 |
+
"Travail décent et croissance économique": ["emploi", "droits du travail", "croissance économique", "entreprise responsable", "travail décent", "conditions de travail", "économie inclusive"],
|
58 |
+
"Industrie, innovation et infrastructure": ["industrie", "innovation", "infrastructure", "technologie", "innovation industrielle", "développement durable industriel"],
|
59 |
+
"Inégalités réduites": ["réduction des inégalités", "inclusion sociale", "équité", "justice sociale", "égalité des chances"],
|
60 |
+
"Villes et communautés durables": ["urbanisme durable", "communautés résilientes", "transports publics", "développement urbain durable", "mobilité urbaine"],
|
61 |
+
"Consommation et production responsables": ["consommation durable", "production durable", "économie circulaire", "recyclage", "gestion des déchets", "réduction de l'empreinte carbone"],
|
62 |
+
"Lutte contre les changements climatiques": ["changements climatiques", "atténuation", "adaptation au climat", "réduction des émissions", "initiatives climatiques", "sobriété carbone"],
|
63 |
+
"Vie aquatique": ["océans", "mers", "conservation marine", "pêche durable", "biodiversité aquatique", "protection des écosystèmes marins"],
|
64 |
+
"Vie terrestre": ["biodiversité terrestre", "conservation des forêts", "reforestation", "protection des écosystèmes terrestres", "lutte contre la désertification"],
|
65 |
+
"Paix, justice et institutions efficaces": ["paix", "justice", "lutte contre la corruption", "institutions solides", "état de droit", "transparence", "accessibilité de la justice"],
|
66 |
+
"Partenariats pour la réalisation des objectifs": ["partenariats mondiaux", "coopération internationale", "engagement multi-acteurs", "collaboration stratégique", "synergie"]
|
67 |
+
}
|
68 |
+
|
69 |
+
#keywords.update(keywords_sdg)
|
70 |
+
|
71 |
+
for record in data:
|
72 |
+
action_rse = record.get("action_rse", "").lower()
|
73 |
+
company_info = {
|
74 |
+
"name": record.get("nom_courant_denomination", "N/A"),
|
75 |
+
"action_rse": action_rse,
|
76 |
+
"activity": record.get("libelle_section_naf", "N/A"),
|
77 |
+
"city": record.get("commune", "N/A")
|
78 |
+
}
|
79 |
+
found_category = False
|
80 |
+
for criterion, key_phrases in keywords.items():
|
81 |
+
if any(key_phrase in action_rse for key_phrase in key_phrases):
|
82 |
+
criteria[criterion].append(company_info)
|
83 |
+
found_category = True
|
84 |
+
break # Assuming each action belongs to one category only
|
85 |
+
|
86 |
+
# Si l'action n'a pas été classifiée dans une catégorie existante, la placer dans "Autres"
|
87 |
+
if not found_category:
|
88 |
+
criteria["Autres"].append(company_info)
|
89 |
+
|
90 |
+
return criteria
|
RAG_PDF.py
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
from PyPDF2 import PdfReader
|
4 |
+
from langchain.text_splitter import CharacterTextSplitter
|
5 |
+
from langchain_community.embeddings import HuggingFaceInstructEmbeddings
|
6 |
+
from langchain_community.vectorstores import FAISS
|
7 |
+
from langchain_community.chat_models import ChatOpenAI
|
8 |
+
from langchain.llms import HuggingFaceHub
|
9 |
+
from langchain import hub
|
10 |
+
from langchain_core.output_parsers import StrOutputParser
|
11 |
+
from langchain_core.runnables import RunnablePassthrough
|
12 |
+
import os
|
13 |
+
|
14 |
+
|
15 |
+
def get_pdf_text(pdf_docs):
|
16 |
+
text = ""
|
17 |
+
for pdf in pdf_docs:
|
18 |
+
pdf_reader = PdfReader(pdf)
|
19 |
+
for page in pdf_reader.pages:
|
20 |
+
text += page.extract_text()
|
21 |
+
return text
|
22 |
+
|
23 |
+
def get_text_chunks(text):
|
24 |
+
text_splitter = CharacterTextSplitter(
|
25 |
+
separator="\n",
|
26 |
+
chunk_size=500, # the character length of the chunck
|
27 |
+
chunk_overlap=100, # the character length of the overlap between chuncks
|
28 |
+
length_function=len # the length function - in this case, character length (aka the python len() fn.)
|
29 |
+
)
|
30 |
+
chunks = text_splitter.split_text(text)
|
31 |
+
return chunks
|
32 |
+
|
33 |
+
def get_vectorstore(text_chunks):
|
34 |
+
model_name = "hkunlp/instructor-xl"
|
35 |
+
hf = HuggingFaceInstructEmbeddings(model_name=model_name)
|
36 |
+
vectorstore = FAISS.from_texts(texts=text_chunks, embedding=hf)
|
37 |
+
return vectorstore
|
38 |
+
|
39 |
+
def get_conversation_chain(vectorstore):
|
40 |
+
llm = HuggingFaceHub(repo_id="mistralai/Mistral-7B-Instruct-v0.2",model_kwargs={"Temperature": 0.5, "MaxTokens": 1024})
|
41 |
+
retriever=vectorstore.as_retriever()
|
42 |
+
prompt = hub.pull("rlm/rag-prompt")
|
43 |
+
# Chain
|
44 |
+
rag_chain = (
|
45 |
+
{"context": retriever, "question": RunnablePassthrough()}
|
46 |
+
| prompt
|
47 |
+
| llm
|
48 |
+
)
|
49 |
+
response = rag_chain.invoke("A partir de documents PDF, concernant la transition écologique en France, proposer un plan de transition en fonction de la marque").split("\nAnswer:")[-1]
|
50 |
+
return response
|
51 |
+
|
52 |
+
def rag_pdf():
|
53 |
+
load_dotenv()
|
54 |
+
st.header("SUGGESTION POUR PLAN DE TRANSITION DE MARQUE RESPECTANT LES NORMES DE LA RSE")
|
55 |
+
|
56 |
+
if "conversation" not in st.session_state:
|
57 |
+
st.session_state.conversation = None
|
58 |
+
|
59 |
+
|
60 |
+
with st.sidebar:
|
61 |
+
st.subheader("INFOS SUR LA MARQUE")
|
62 |
+
pdf_docs = st.file_uploader("Upload les documents concerant la marque et clique sur process", type="pdf",accept_multiple_files=True)
|
63 |
+
if st.button("Process"):
|
64 |
+
with st.spinner("Processing..."):#loading bar to enhance user experience
|
65 |
+
#get pdf text in raw format
|
66 |
+
raw_text = get_pdf_text(pdf_docs)
|
67 |
+
|
68 |
+
#get text chunks
|
69 |
+
text_chunks = get_text_chunks(raw_text)
|
70 |
+
|
71 |
+
#create vectorstore
|
72 |
+
vectorstore = get_vectorstore(text_chunks)
|
73 |
+
|
74 |
+
#create conversation chain
|
75 |
+
st.session_state.conversation = get_conversation_chain(vectorstore)
|
76 |
+
|
77 |
+
st.write(st.session_state.conversation)
|
RAG_PDF_WEB.py
ADDED
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
from PyPDF2 import PdfReader
|
4 |
+
from langchain.text_splitter import CharacterTextSplitter
|
5 |
+
from langchain_community.embeddings import OpenAIEmbeddings
|
6 |
+
from langchain_community.vectorstores import FAISS
|
7 |
+
from langchain_community.chat_models import ChatOpenAI
|
8 |
+
from langchain.llms import HuggingFaceHub
|
9 |
+
from langchain import hub
|
10 |
+
from langchain_core.output_parsers import StrOutputParser
|
11 |
+
from langchain_core.runnables import RunnablePassthrough
|
12 |
+
from langchain_community.document_loaders import WebBaseLoader
|
13 |
+
import os
|
14 |
+
|
15 |
+
def get_docs_from_website(urls):
|
16 |
+
loader = WebBaseLoader(urls)
|
17 |
+
docs = loader.load()
|
18 |
+
return docs
|
19 |
+
|
20 |
+
def get_pdf_text(pdf_docs):
|
21 |
+
text = ""
|
22 |
+
for pdf in pdf_docs:
|
23 |
+
pdf_reader = PdfReader(pdf)
|
24 |
+
for page in pdf_reader.pages:
|
25 |
+
text += page.extract_text()
|
26 |
+
return text
|
27 |
+
|
28 |
+
def get_text_chunks(text):
|
29 |
+
text_splitter = CharacterTextSplitter(
|
30 |
+
separator="\n",
|
31 |
+
chunk_size=1000, # the character length of the chunck
|
32 |
+
chunk_overlap=200, # the character length of the overlap between chuncks
|
33 |
+
length_function=len # the length function - in this case, character length (aka the python len() fn.)
|
34 |
+
)
|
35 |
+
chunks = text_splitter.split_text(text)
|
36 |
+
return chunks
|
37 |
+
|
38 |
+
def get_doc_chunks(docs):
|
39 |
+
# Split the loaded data
|
40 |
+
text_splitter = CharacterTextSplitter(separator='\n',
|
41 |
+
chunk_size=500,
|
42 |
+
chunk_overlap=40)
|
43 |
+
|
44 |
+
docs = text_splitter.split_documents(docs)
|
45 |
+
return docs
|
46 |
+
|
47 |
+
def get_vectorstore_from_docs(doc_chunks):
|
48 |
+
embedding = OpenAIEmbeddings(model="text-embedding-3-small")
|
49 |
+
vectorstore = FAISS.from_documents(documents=doc_chunks, embedding=embedding)
|
50 |
+
return vectorstore
|
51 |
+
|
52 |
+
def get_vectorstore(text_chunks):
|
53 |
+
embedding = OpenAIEmbeddings(model="text-embedding-3-small")
|
54 |
+
vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embedding)
|
55 |
+
return vectorstore
|
56 |
+
|
57 |
+
def get_conversation_chain(vectorstore):
|
58 |
+
llm = ChatOpenAI(model="gpt-3.5-turbo",temperature=0.5, max_tokens=2048)
|
59 |
+
retriever=vectorstore.as_retriever()
|
60 |
+
prompt = hub.pull("rlm/rag-prompt")
|
61 |
+
|
62 |
+
# Chain
|
63 |
+
rag_chain = (
|
64 |
+
{"context": retriever , "question": RunnablePassthrough()}
|
65 |
+
| prompt
|
66 |
+
| llm
|
67 |
+
)
|
68 |
+
return rag_chain
|
69 |
+
|
70 |
+
def rag_pdf_web():
|
71 |
+
load_dotenv()
|
72 |
+
st.header("SUGGESTION POUR PLAN DE TRANSITION DE MARQUE RESPECTANT LES NORMES DE LA RSE")
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
st.subheader("Générer Plan RSE")
|
77 |
+
option = st.radio("Source", ("A partir de votre site web", "A partir de vos documents entreprise"))
|
78 |
+
|
79 |
+
if option == "A partir de votre site web":
|
80 |
+
url1 = st.text_input("URL 1")
|
81 |
+
url2 = st.text_input("URL 2")
|
82 |
+
url3 = st.text_input("URL 3")
|
83 |
+
# Process the URLs
|
84 |
+
sous_options = st.radio("SChoisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
|
85 |
+
if st.button("Process"):
|
86 |
+
with st.spinner("Processing..."):
|
87 |
+
#get text from the website
|
88 |
+
urls = [url1, url2, url3]
|
89 |
+
filtered_urls = [url for url in urls if url]
|
90 |
+
|
91 |
+
#get text from the website
|
92 |
+
docs = get_docs_from_website(filtered_urls)
|
93 |
+
|
94 |
+
#get text chunks
|
95 |
+
text_chunks = get_doc_chunks(docs)
|
96 |
+
|
97 |
+
#create vectorstore
|
98 |
+
vectorstore = get_vectorstore_from_docs(text_chunks)
|
99 |
+
|
100 |
+
chain = get_conversation_chain(vectorstore)
|
101 |
+
|
102 |
+
if sous_options == "Ambition, Vision, Missions, Valeurs":
|
103 |
+
# 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:
|
104 |
+
# \n
|
105 |
+
# ### Ambition : \n
|
106 |
+
# Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)
|
107 |
+
# \n
|
108 |
+
# ### Vision : \n
|
109 |
+
# Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)
|
110 |
+
# \n
|
111 |
+
# ### Missions : \n
|
112 |
+
# Quelles sont les missions de l'entreprise ? (répondre avec maximum 250 caractères)
|
113 |
+
# \n
|
114 |
+
# renvoie ta réponse en markdown et bien formatée'''
|
115 |
+
# response = chain.invoke(question)
|
116 |
+
# st.markdown(response.content)
|
117 |
+
|
118 |
+
#ambition
|
119 |
+
ambition = chain.invoke("Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)")
|
120 |
+
st.markdown("### Ambition :")
|
121 |
+
st.markdown(ambition.content)
|
122 |
+
|
123 |
+
#vision
|
124 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
125 |
+
st.markdown("### Vision :")
|
126 |
+
st.markdown(ambition.content)
|
127 |
+
|
128 |
+
#Mission
|
129 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
130 |
+
st.markdown("### Mission :")
|
131 |
+
st.markdown(ambition.content)
|
132 |
+
|
133 |
+
#values
|
134 |
+
values = chain.invoke("Quels sont les valeurs de l'entreprise ? (répondre avec 10 mots maximum en bullet points)")
|
135 |
+
st.markdown("### Valeurs :")
|
136 |
+
st.markdown(values.content)
|
137 |
+
|
138 |
+
elif sous_options == "3 piliers de la démarche RSE":
|
139 |
+
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 :
|
140 |
+
\n
|
141 |
+
### le titre du pilier numero 1 \n
|
142 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
143 |
+
\n
|
144 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
145 |
+
\n
|
146 |
+
### le titre du pilier numero 2 \n
|
147 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
148 |
+
\n
|
149 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
150 |
+
\n
|
151 |
+
### le titre du pilier numero 3 \n
|
152 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
153 |
+
\n
|
154 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
155 |
+
\n
|
156 |
+
renvoie ta réponse en markdown et bien formatée
|
157 |
+
'''
|
158 |
+
response = chain.invoke(question)
|
159 |
+
st.markdown(response.content)
|
160 |
+
|
161 |
+
|
162 |
+
if option == "A partir de vos documents entreprise":
|
163 |
+
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)
|
164 |
+
# Process the PDF documents
|
165 |
+
sous_options = st.radio("Choisissez votre sous-section", ("Ambition, Vision, Missions, Valeurs", "3 piliers de la démarche RSE"))
|
166 |
+
if st.button("Process"):
|
167 |
+
with st.spinner("Processing..."):
|
168 |
+
#get pdf text in raw format
|
169 |
+
raw_text = get_pdf_text(pdf_docs)
|
170 |
+
|
171 |
+
#get text chunks
|
172 |
+
text_chunks = get_text_chunks(raw_text)
|
173 |
+
|
174 |
+
#create vectorstore
|
175 |
+
vectorstore = get_vectorstore(text_chunks)
|
176 |
+
|
177 |
+
chain = get_conversation_chain(vectorstore)
|
178 |
+
|
179 |
+
if sous_options == "Ambition, Vision, Missions, Valeurs":
|
180 |
+
|
181 |
+
#ambition
|
182 |
+
ambition = chain.invoke("Quelle est l'ambition de l'entreprise ? (répondre avec maximum 250 caractères)")
|
183 |
+
st.markdown("### Ambition :")
|
184 |
+
st.markdown(ambition.content)
|
185 |
+
|
186 |
+
#vision
|
187 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
188 |
+
st.markdown("### Vision :")
|
189 |
+
st.markdown(ambition.content)
|
190 |
+
|
191 |
+
#Mission
|
192 |
+
ambition = chain.invoke(" Quelle est la vision de l'entreprise ? (répondre avec maximum 250 caractères)")
|
193 |
+
st.markdown("### Mission :")
|
194 |
+
st.markdown(ambition.content)
|
195 |
+
|
196 |
+
#values
|
197 |
+
values = chain.invoke("Quels sont les valeurs de l'entreprise ? (répondre avec 10 mots maximum en bullet points)")
|
198 |
+
st.markdown("### Valeurs :")
|
199 |
+
st.markdown(values.content)
|
200 |
+
|
201 |
+
elif sous_options == "3 piliers de la démarche RSE":
|
202 |
+
question = ''' suggère nous les 3 piliers principaux de la démarche RSE pour cette entreprise. Pour chaque pilier RSE doit avoir ce format :
|
203 |
+
\n
|
204 |
+
### le titre du ieme pilier \n
|
205 |
+
-la description du pilier (répondre avec maximum 250 caractères)
|
206 |
+
\n
|
207 |
+
- 2 indicateurs cibles pertinents à atteindre avec suggestion de valeur cible min, max
|
208 |
+
\n
|
209 |
+
renvoie ta réponse en markdown et bien formatée
|
210 |
+
'''
|
211 |
+
response = chain.invoke(question)
|
212 |
+
st.markdown(response.content)
|
README.md
CHANGED
@@ -1,13 +1,12 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: streamlit
|
7 |
-
sdk_version: 1.
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
-
license: mit
|
11 |
---
|
12 |
|
13 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: Opendata Rse
|
3 |
+
emoji: 📊
|
4 |
+
colorFrom: yellow
|
5 |
+
colorTo: gray
|
6 |
sdk: streamlit
|
7 |
+
sdk_version: 1.34.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
|
|
10 |
---
|
11 |
|
12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
CHANGED
@@ -16,6 +16,7 @@ from entreprises_labellisees import display_labelled_companies
|
|
16 |
from inspirezvous import *
|
17 |
from collaborons import display_company_selection_for_materiality,display_materiality_matrix
|
18 |
from documentations import display_documentation
|
|
|
19 |
|
20 |
def main():
|
21 |
st.markdown(":point_left: Cliquez pour vous inspirer", unsafe_allow_html=True)
|
@@ -60,7 +61,7 @@ def main():
|
|
60 |
elif section_principale == "IA RSE":
|
61 |
ia_mode = st.sidebar.radio(
|
62 |
"Choisissez votre sous-section",
|
63 |
-
["Parties prenantes", "Matrice de matérialité"]
|
64 |
)
|
65 |
if ia_mode == "Parties prenantes":
|
66 |
data, bziiit_data = fetch_data()
|
@@ -72,12 +73,14 @@ def main():
|
|
72 |
selected_company = display_company_selection_for_materiality(data)
|
73 |
if selected_company:
|
74 |
display_materiality_matrix(selected_company, data, bziiit_data)
|
|
|
|
|
|
|
75 |
|
76 |
|
77 |
elif section_principale == "Documentation":
|
78 |
display_documentation()
|
79 |
|
80 |
-
|
81 |
# Instructions communes à toutes les sections
|
82 |
st.sidebar.markdown("---")
|
83 |
st.sidebar.markdown("Powered by **bziiit IA RSE**")
|
|
|
16 |
from inspirezvous import *
|
17 |
from collaborons import display_company_selection_for_materiality,display_materiality_matrix
|
18 |
from documentations import display_documentation
|
19 |
+
from RAG_PDF_WEB import rag_pdf_web
|
20 |
|
21 |
def main():
|
22 |
st.markdown(":point_left: Cliquez pour vous inspirer", unsafe_allow_html=True)
|
|
|
61 |
elif section_principale == "IA RSE":
|
62 |
ia_mode = st.sidebar.radio(
|
63 |
"Choisissez votre sous-section",
|
64 |
+
["Parties prenantes", "Matrice de matérialité","Generer un Plan RSE"]
|
65 |
)
|
66 |
if ia_mode == "Parties prenantes":
|
67 |
data, bziiit_data = fetch_data()
|
|
|
73 |
selected_company = display_company_selection_for_materiality(data)
|
74 |
if selected_company:
|
75 |
display_materiality_matrix(selected_company, data, bziiit_data)
|
76 |
+
|
77 |
+
elif ia_mode == "Generer un Plan RSE":
|
78 |
+
rag_pdf_web()
|
79 |
|
80 |
|
81 |
elif section_principale == "Documentation":
|
82 |
display_documentation()
|
83 |
|
|
|
84 |
# Instructions communes à toutes les sections
|
85 |
st.sidebar.markdown("---")
|
86 |
st.sidebar.markdown("Powered by **bziiit IA RSE**")
|
collaborons.py
CHANGED
@@ -59,6 +59,7 @@ def perform_chat(messages):
|
|
59 |
client = openai.OpenAI(api_key=YOUR_API_KEY, base_url="https://api.perplexity.ai")
|
60 |
|
61 |
response_stream = client.chat.completions.create(
|
|
|
62 |
model="sonar-medium-online",
|
63 |
messages=messages,
|
64 |
stream=True
|
|
|
59 |
client = openai.OpenAI(api_key=YOUR_API_KEY, base_url="https://api.perplexity.ai")
|
60 |
|
61 |
response_stream = client.chat.completions.create(
|
62 |
+
|
63 |
model="sonar-medium-online",
|
64 |
messages=messages,
|
65 |
stream=True
|
htmlTemplates.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
css = '''
|
2 |
+
<style>
|
3 |
+
.chat-message {
|
4 |
+
padding: 1.5rem; border-radius: 0.5rem; margin-bottom: 1rem; display: flex
|
5 |
+
}
|
6 |
+
.chat-message.user {
|
7 |
+
background-color: #2b313e
|
8 |
+
}
|
9 |
+
.chat-message.bot {
|
10 |
+
background-color: #475063
|
11 |
+
}
|
12 |
+
.chat-message .avatar {
|
13 |
+
width: 20%;
|
14 |
+
}
|
15 |
+
.chat-message .avatar img {
|
16 |
+
max-width: 78px;
|
17 |
+
max-height: 78px;
|
18 |
+
border-radius: 50%;
|
19 |
+
object-fit: cover;
|
20 |
+
}
|
21 |
+
.chat-message .message {
|
22 |
+
width: 80%;
|
23 |
+
padding: 0 1.5rem;
|
24 |
+
color: #fff;
|
25 |
+
}
|
26 |
+
'''
|
27 |
+
|
28 |
+
bot_template = '''
|
29 |
+
<div class="chat-message bot">
|
30 |
+
<div class="avatar">
|
31 |
+
<img src="data:image/png;base64,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" style="max-height: 78px; max-width: 78px; border-radius: 50%; object-fit: cover;">
|
32 |
+
</div>
|
33 |
+
<div class="message">{{MSG}}</div>
|
34 |
+
</div>
|
35 |
+
'''
|
36 |
+
|
37 |
+
user_template = '''
|
38 |
+
<div class="chat-message user">
|
39 |
+
<div class="avatar">
|
40 |
+
<img src="https://media.licdn.com/dms/image/C4E03AQGvvkYN1sbUbA/profile-displayphoto-shrink_400_400/0/1588147295529?e=1714003200&v=beta&t=pAlX20zTPhqbi7ipYCkj_oUOhOgtvsy5TuJFikbH-f4">
|
41 |
+
</div>
|
42 |
+
<div class="message">{{MSG}}</div>
|
43 |
+
</div>
|
44 |
+
'''
|
requirements.txt
CHANGED
@@ -12,3 +12,14 @@ plotly
|
|
12 |
matplotlib
|
13 |
openai
|
14 |
beautifulsoup4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
matplotlib
|
13 |
openai
|
14 |
beautifulsoup4
|
15 |
+
python-dotenv
|
16 |
+
faiss-cpu
|
17 |
+
langchain
|
18 |
+
huggingface-hub
|
19 |
+
streamlit
|
20 |
+
PyPDF2
|
21 |
+
tiktoken
|
22 |
+
openai
|
23 |
+
InstructorEmbedding
|
24 |
+
sentence-transformers==2.2.2
|
25 |
+
langchainhub
|