Spaces:
Running
Running
LaurentTRIPIED
commited on
Commit
•
ef58bce
1
Parent(s):
bcfb199
IA avec API Perplexity
Browse files- .gitignore +1 -0
- DATA IA RSE Bordeaux Metropole.png +0 -0
- RECO IA RSE Bordeaux Metropole.png +0 -0
- app.py +37 -5
- collaborons.py +128 -0
- data_manager.py +39 -1
- data_manager_bziiit.py +49 -7
- documentations.py +28 -0
- entreprises_labellisees.py +45 -0
- inspirezvous.py +256 -0
- labelRSE.py +3 -1
- localisation.py +1 -2
- partiesprenantes.py +156 -0
- requirements.txt +1 -0
.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1 |
__pycache__/
|
|
|
|
1 |
__pycache__/
|
2 |
+
.streamlit/secrets.toml
|
DATA IA RSE Bordeaux Metropole.png
ADDED
RECO IA RSE Bordeaux Metropole.png
ADDED
app.py
CHANGED
@@ -7,17 +7,23 @@ from localisation import display_map
|
|
7 |
from statistiques import main as display_statistics
|
8 |
from ActionsRSE import display_actions_rse
|
9 |
from AnalyseActionsRSE import display_analyse_actions_rse
|
|
|
10 |
|
11 |
# Import modifiédes fonctions liées aux scripts
|
12 |
from projetRSE import display_rse_projects
|
13 |
from labelRSE import display_rse_labels
|
14 |
-
from
|
|
|
|
|
|
|
15 |
|
16 |
def main():
|
|
|
|
|
17 |
st.sidebar.title("OPEN DATA & IA au service de la RSE")
|
18 |
section_principale = st.sidebar.radio(
|
19 |
"Choisissez votre section",
|
20 |
-
["Data Bordeaux métropole", "Data bziiit"]
|
21 |
)
|
22 |
|
23 |
if section_principale == "Data Bordeaux métropole":
|
@@ -36,15 +42,41 @@ def main():
|
|
36 |
elif app_mode == "Analyse actions RSE":
|
37 |
display_analyse_actions_rse()
|
38 |
|
|
|
39 |
elif section_principale == "Data bziiit":
|
40 |
ia_mode = st.sidebar.radio(
|
41 |
"Choisissez votre sous-section",
|
42 |
-
["Labels RSE", "
|
43 |
)
|
44 |
if ia_mode == "Labels RSE":
|
45 |
display_rse_labels()
|
46 |
-
elif ia_mode == "
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
# Instructions communes à toutes les sections
|
50 |
st.sidebar.markdown("---")
|
|
|
7 |
from statistiques import main as display_statistics
|
8 |
from ActionsRSE import display_actions_rse
|
9 |
from AnalyseActionsRSE import display_analyse_actions_rse
|
10 |
+
from partiesprenantes import display_materiality_partiesprenantes
|
11 |
|
12 |
# Import modifiédes fonctions liées aux scripts
|
13 |
from projetRSE import display_rse_projects
|
14 |
from labelRSE import display_rse_labels
|
15 |
+
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)
|
22 |
+
|
23 |
st.sidebar.title("OPEN DATA & IA au service de la RSE")
|
24 |
section_principale = st.sidebar.radio(
|
25 |
"Choisissez votre section",
|
26 |
+
["Data Bordeaux métropole", "Data bziiit","IA RSE","Documentation"]
|
27 |
)
|
28 |
|
29 |
if section_principale == "Data Bordeaux métropole":
|
|
|
42 |
elif app_mode == "Analyse actions RSE":
|
43 |
display_analyse_actions_rse()
|
44 |
|
45 |
+
|
46 |
elif section_principale == "Data bziiit":
|
47 |
ia_mode = st.sidebar.radio(
|
48 |
"Choisissez votre sous-section",
|
49 |
+
["Labels RSE", "Entreprises labellisées", "Fiches entreprises"]
|
50 |
)
|
51 |
if ia_mode == "Labels RSE":
|
52 |
display_rse_labels()
|
53 |
+
elif ia_mode == "Entreprises labellisées":
|
54 |
+
display_labelled_companies()
|
55 |
+
elif ia_mode == "Fiches entreprises":
|
56 |
+
data, bziiit_data = fetch_data()
|
57 |
+
selected_company = display_company_selection(data)
|
58 |
+
display_company_info(data, bziiit_data, selected_company)
|
59 |
+
|
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()
|
67 |
+
selected_company = display_company_selection_for_materiality(data)
|
68 |
+
if selected_company:
|
69 |
+
display_materiality_partiesprenantes(selected_company, data, bziiit_data)
|
70 |
+
elif ia_mode == "Matrice de matérialité":
|
71 |
+
data, bziiit_data = fetch_data()
|
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("---")
|
collaborons.py
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from openai import OpenAI
|
3 |
+
from folium import Map, Marker, Icon, Popup
|
4 |
+
from streamlit_folium import folium_static
|
5 |
+
from data_manager import get_data
|
6 |
+
from data_manager_bziiit import *
|
7 |
+
from ISO26000 import classify_actions_rse_ISO26000
|
8 |
+
from urllib.parse import urlparse
|
9 |
+
|
10 |
+
###############################################################################################
|
11 |
+
# PARTIE 0 : Récupération des données API bziiit et Bordeaux Métropole
|
12 |
+
###############################################################################################
|
13 |
+
|
14 |
+
def fetch_data():
|
15 |
+
data, _ = get_data() # Récupération des données de Bordeaux Métropole
|
16 |
+
bziiit_data = get_bziiit_data() # Récupération des données de Bziiit
|
17 |
+
|
18 |
+
return data, bziiit_data
|
19 |
+
|
20 |
+
###############################################################################################
|
21 |
+
# PARTIE 1 : Le sélecteur d'entreprise
|
22 |
+
###############################################################################################
|
23 |
+
def display_company_selection_for_materiality(data):
|
24 |
+
# Get a list of all company names
|
25 |
+
companies = sorted(list(set(record['nom_courant_denomination'] for record in data)), key=str.lower)
|
26 |
+
|
27 |
+
# Add default selection prompt to the beginning of the list
|
28 |
+
companies.insert(0, "Sélectionner l'entreprise engagée à découvrir")
|
29 |
+
|
30 |
+
selected_company = st.selectbox('Sélectionnez une entreprise', companies, index=0)
|
31 |
+
|
32 |
+
# If the default selection is still selected, return None
|
33 |
+
if selected_company == "Sélectionner l'entreprise engagée à découvrir":
|
34 |
+
return None
|
35 |
+
|
36 |
+
return selected_company # Return the selected company name
|
37 |
+
|
38 |
+
# Uniformiser les noms de champs
|
39 |
+
def normalize_company_name(record):
|
40 |
+
# Gère les différences de noms de champs entre les APIs
|
41 |
+
if 'nom_courant_denomination' in record:
|
42 |
+
return record['nom_courant_denomination'].strip().lower()
|
43 |
+
elif 'name' in record:
|
44 |
+
return record['name'].strip().lower()
|
45 |
+
return 'Unknown'
|
46 |
+
|
47 |
+
###############################################################################################
|
48 |
+
# PARTIE 3 : CONNEXION API MISTRAL 8x7b + AFFICHAGE DE LA CONVERSATION
|
49 |
+
###############################################################################################
|
50 |
+
|
51 |
+
def perform_chat(messages):
|
52 |
+
YOUR_API_KEY = st.secrets["API_TOKEN_PERPLEXITYAI"]
|
53 |
+
client = OpenAI(api_key=YOUR_API_KEY, base_url="https://api.perplexity.ai")
|
54 |
+
|
55 |
+
response_stream = client.chat.completions.create(
|
56 |
+
model="mixtral-8x7b-instruct",
|
57 |
+
messages=messages,
|
58 |
+
stream=True
|
59 |
+
)
|
60 |
+
|
61 |
+
assistant_response = ""
|
62 |
+
for chunk in response_stream:
|
63 |
+
assistant_response += chunk.choices[0].delta.content
|
64 |
+
|
65 |
+
st.write(assistant_response)
|
66 |
+
|
67 |
+
###############################################################################################
|
68 |
+
# PARTIE 4 : MATRICE DE MATERIALITE
|
69 |
+
###############################################################################################
|
70 |
+
def display_materiality_matrix(selected_company, data, bziiit_data):
|
71 |
+
st.markdown("### La matrice de matérialité vue par l'IA bziiit / Mistral AI (8x7b)")
|
72 |
+
option = st.radio(
|
73 |
+
"Choisissez une option",
|
74 |
+
('Définition', 'Matrice simplifiée', 'Matrice détaillée'),
|
75 |
+
index=0
|
76 |
+
)
|
77 |
+
|
78 |
+
if option == 'Définition':
|
79 |
+
st.write("""
|
80 |
+
**La matrice de matérialité est un outil stratégique qui permet aux entreprises de classer et de prioriser les enjeux liés à la responsabilité sociale des entreprises (RSE) selon leur importance pour les parties prenantes et leur impact sur la performance de l'entreprise. Les trois points clés de la matrice de matérialité sont :**
|
81 |
+
|
82 |
+
1. **Évaluation et priorisation des enjeux** : La matrice de matérialité aide à identifier et à classer les enjeux RSE en fonction de leur importance pour les parties prenantes et de leur impact sur la performance de l'entreprise. Cela permet aux entreprises de se concentrer sur les enjeux qui sont les plus importants pour leurs parties prenantes et pour leur propre succès.
|
83 |
+
|
84 |
+
2. **Transparence et communication** : La matrice de matérialité encourage la transparence en matière de RSE en offrant un cadre pour la communication des résultats aux parties prenantes. Cela permet aux entreprises de renforcer leur image de marque et de répondre aux attentes croissantes en matière de durabilité.
|
85 |
+
|
86 |
+
3. **Flexibilité et adaptabilité** : La matrice de matérialité est adaptable à différents contextes et tailles d'entreprises, offrant une flexibilité essentielle pour répondre aux besoins variés. Elle est un élément intégral de la planification stratégique d'une entreprise et facilite un reporting ESG transparent et informatif.
|
87 |
+
""")
|
88 |
+
|
89 |
+
|
90 |
+
elif option == 'Matrice simplifiée':
|
91 |
+
company_data = next((item for item in data if item['nom_courant_denomination'].strip().lower() == selected_company.strip().lower()), None)
|
92 |
+
bziiit_brand_data = next((brand for brand in bziiit_data if brand['type'] == 'brand' and brand['name'].strip().lower() == selected_company.strip().lower()), None)
|
93 |
+
if company_data and bziiit_brand_data:
|
94 |
+
run_perplexity_chat_simplified(company_data['nom_courant_denomination'], bziiit_brand_data['description'], company_data['action_rse'])
|
95 |
+
|
96 |
+
|
97 |
+
elif option == 'Matrice détaillée':
|
98 |
+
company_data = next((item for item in data if item['nom_courant_denomination'].strip().lower() == selected_company.strip().lower()), None)
|
99 |
+
bziiit_brand_data = next((brand for brand in bziiit_data if brand['type'] == 'brand' and brand['name'].strip().lower() == selected_company.strip().lower()), None)
|
100 |
+
if company_data and bziiit_brand_data:
|
101 |
+
run_perplexity_chat_detailed(company_data['nom_courant_denomination'], bziiit_brand_data['description'], company_data['action_rse'])
|
102 |
+
|
103 |
+
###############################################################################################
|
104 |
+
# PARTIE 5 : FONCTIONS MATRICE DE MATERIALITE
|
105 |
+
###############################################################################################
|
106 |
+
|
107 |
+
def run_perplexity_chat_simplified(company_name, company_description, company_rse_action):
|
108 |
+
question = f"L'entreprise {company_name}, dont l'activité est {company_description}, a pour action RSE principale {company_rse_action}. Quels peuvent être les principaux éléments de sa matrice de matérialité ? REPONDS TOUJOURS EN FRANCAIS"
|
109 |
+
messages = [
|
110 |
+
{"role": "system", "content": "You are an artificial intelligence assistant and you need to engage in a helpful, detailed, polite conversation with a user."},
|
111 |
+
{"role": "user", "content": question}
|
112 |
+
]
|
113 |
+
st.markdown("**Question posée :**")
|
114 |
+
st.write(question)
|
115 |
+
st.markdown("**Réponse IA :**")
|
116 |
+
perform_chat(messages)
|
117 |
+
|
118 |
+
def run_perplexity_chat_detailed(company_name, company_description, company_rse_action):
|
119 |
+
question = f"L'entreprise {company_name}, dont l'activité est {company_description}, a pour action RSE principale {company_rse_action}. Fais moi une présentation détaillée TOUJOURS EN FRANCAISE de ce que pourraient être sa matrice de matérialité ?"
|
120 |
+
messages = [
|
121 |
+
{"role": "system", "content": "You are an artificial intelligence assistant and you need to engage in a helpful, detailed, polite conversation with a user."},
|
122 |
+
{"role": "user", "content": question}
|
123 |
+
]
|
124 |
+
st.markdown("**Question posée :**")
|
125 |
+
st.write(question)
|
126 |
+
st.markdown("**Réponse IA :**")
|
127 |
+
perform_chat(messages)
|
128 |
+
|
data_manager.py
CHANGED
@@ -1,12 +1,50 @@
|
|
1 |
-
|
2 |
import requests
|
3 |
|
|
|
4 |
def get_data():
|
5 |
url = "https://opendata.bordeaux-metropole.fr/api/records/1.0/search/?dataset=met_etablissement_rse&q=&rows=100"
|
6 |
response = requests.get(url)
|
7 |
if response.status_code == 200:
|
8 |
data = response.json()
|
9 |
records = data.get("records", [])
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
return [record["fields"] for record in records], data.get("nhits", 0)
|
11 |
else:
|
12 |
return [], 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import requests
|
2 |
|
3 |
+
# URL de base de l'API bziiit
|
4 |
def get_data():
|
5 |
url = "https://opendata.bordeaux-metropole.fr/api/records/1.0/search/?dataset=met_etablissement_rse&q=&rows=100"
|
6 |
response = requests.get(url)
|
7 |
if response.status_code == 200:
|
8 |
data = response.json()
|
9 |
records = data.get("records", [])
|
10 |
+
if records:
|
11 |
+
print(records[0]) # Print an example record
|
12 |
+
# Ensure every record includes the 'nom_courant_denomination' key
|
13 |
+
for record in records:
|
14 |
+
if 'nom_courant_denomination' not in record["fields"]:
|
15 |
+
record["fields"]['nom_courant_denomination'] = 'Unknown'
|
16 |
return [record["fields"] for record in records], data.get("nhits", 0)
|
17 |
else:
|
18 |
return [], 0
|
19 |
+
|
20 |
+
"""
|
21 |
+
Exemple de données récupérées via l'API de Bordeaux Métropole:
|
22 |
+
|
23 |
+
st.write("Normalized Company Data:", company_data)
|
24 |
+
|
25 |
+
Normalized Company Data:
|
26 |
+
|
27 |
+
{
|
28 |
+
"point_geo":[
|
29 |
+
0:44.88136729281935
|
30 |
+
1:-0.5145680443292318
|
31 |
+
]
|
32 |
+
"tranche_effectif_etab":"Non déclaré"
|
33 |
+
"siret":"8,1383E+13"
|
34 |
+
"naf_section":"J"
|
35 |
+
"code_naf":"6510Z"
|
36 |
+
"ban_x_lambert_93":422559.4
|
37 |
+
"code_postal":"33310"
|
38 |
+
"naf_groupe":"620"
|
39 |
+
"libelle_section_naf":"Information et communication"
|
40 |
+
"libelle_groupe_naf":"Programmation, conseil et autres activités informatiques"
|
41 |
+
"nom_courant_denomination":"bziiit"
|
42 |
+
"tranche_effectif_entreprise":"6 à 9 Salariés"
|
43 |
+
"commune":"LORMONT"
|
44 |
+
"action_rse":"Face à l'urgence de réduire l'empreinte carbone du numérique, nous avons mis en place le tryptique MESURER - FORMER - REDUIRE sur l'ensemble de nos usages (cloud, intelligence artificielle)"
|
45 |
+
"hierarchie_naf":"Information et communication/Programmation, conseil et autres activités informatiques/libelle_naf"
|
46 |
+
"adresse_numero_et_voie":"6 Rue du Courant"
|
47 |
+
"ban_y_lambert_93":6426418.2
|
48 |
+
}
|
49 |
+
|
50 |
+
"""
|
data_manager_bziiit.py
CHANGED
@@ -1,29 +1,71 @@
|
|
1 |
-
|
2 |
import requests
|
|
|
3 |
|
4 |
# URL de base de l'API bziiit
|
5 |
BASE_URL = "https://bziiitapi-api.azurewebsites.net"
|
6 |
|
|
|
7 |
def get_labels():
|
8 |
-
|
9 |
-
response = requests.get(
|
10 |
if response.status_code == 200:
|
11 |
return response.json()["response"]
|
12 |
else:
|
|
|
13 |
return []
|
14 |
|
|
|
15 |
def get_rse_projects():
|
16 |
-
|
17 |
-
response = requests.get(
|
18 |
if response.status_code == 200:
|
19 |
return response.json()["response"]
|
20 |
else:
|
|
|
21 |
return []
|
22 |
|
|
|
23 |
def get_engaged_brands():
|
24 |
-
|
25 |
-
response = requests.get(
|
26 |
if response.status_code == 200:
|
27 |
return response.json()["response"]
|
28 |
else:
|
|
|
29 |
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import requests
|
2 |
+
import streamlit as st
|
3 |
|
4 |
# URL de base de l'API bziiit
|
5 |
BASE_URL = "https://bziiitapi-api.azurewebsites.net"
|
6 |
|
7 |
+
# Fonction de récupération des labels
|
8 |
def get_labels():
|
9 |
+
url = f"{BASE_URL}/opendata/labels"
|
10 |
+
response = requests.get(url)
|
11 |
if response.status_code == 200:
|
12 |
return response.json()["response"]
|
13 |
else:
|
14 |
+
st.error(f"Échec de récupération des labels: {response.text}")
|
15 |
return []
|
16 |
|
17 |
+
# Fonction de récupération des projets RSE
|
18 |
def get_rse_projects():
|
19 |
+
url = f"{BASE_URL}/opendata/bordeaux-rse/projects"
|
20 |
+
response = requests.get(url)
|
21 |
if response.status_code == 200:
|
22 |
return response.json()["response"]
|
23 |
else:
|
24 |
+
st.error(f"Échec de récupération des projets RSE: {response.text}")
|
25 |
return []
|
26 |
|
27 |
+
# Fonction de récupération des entreprises
|
28 |
def get_engaged_brands():
|
29 |
+
url = f"{BASE_URL}/opendata/bordeaux-rse/brands"
|
30 |
+
response = requests.get(url)
|
31 |
if response.status_code == 200:
|
32 |
return response.json()["response"]
|
33 |
else:
|
34 |
+
st.error(f"Échec de récupération des marques engagées: {response.text}")
|
35 |
return []
|
36 |
+
|
37 |
+
# Fonction consolidant les données labels + projets RSE + marques
|
38 |
+
def get_bziiit_data():
|
39 |
+
labels = get_labels()
|
40 |
+
rse_projects = get_rse_projects()
|
41 |
+
engaged_brands = get_engaged_brands()
|
42 |
+
|
43 |
+
bziiit_data = []
|
44 |
+
|
45 |
+
# Assurez-vous d'utiliser 'name' pour bziiit data et ajoutez une distinction de type
|
46 |
+
for label in labels:
|
47 |
+
bziiit_data.append({
|
48 |
+
'type': 'label', # Ajout du type
|
49 |
+
'name': label.get('name', 'Unknown'),
|
50 |
+
'description': label.get('description', 'Unknown'),
|
51 |
+
'logo_url': label.get('logo_url', 'Unknown'),
|
52 |
+
'labels': [label] # Stocke l'objet label entier si nécessaire
|
53 |
+
})
|
54 |
+
|
55 |
+
for project in rse_projects:
|
56 |
+
bziiit_data.append({
|
57 |
+
'type': 'project', # Ajout du type
|
58 |
+
'name': project.get('name', 'Unknown'),
|
59 |
+
'labels': project.get('labels', []) # Assurez-vous que 'labels' est une liste dans le JSON de réponse
|
60 |
+
})
|
61 |
+
|
62 |
+
for brand in engaged_brands:
|
63 |
+
bziiit_data.append({
|
64 |
+
'type': 'brand', # Ajout du type
|
65 |
+
'name': brand.get('name', 'Unknown'),
|
66 |
+
'logo_url': brand.get('logo_url', 'Unknown'), # Assurez-vous que 'logo_url' est une URL valide
|
67 |
+
'description': brand.get('description', 'Unknown'),
|
68 |
+
'labels': brand.get('labels', [])
|
69 |
+
})
|
70 |
+
|
71 |
+
return bziiit_data
|
documentations.py
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
def display_documentation():
|
4 |
+
|
5 |
+
st.markdown("<hr style='border-color: darkgrey;'>", unsafe_allow_html=True) # Add this line
|
6 |
+
|
7 |
+
st.title("OPEN DATA IA RSE Bordeaux Métropole")
|
8 |
+
st.markdown("## La Data et l'IA au service des démarches RSE (Economie, Social, Environnemental)")
|
9 |
+
|
10 |
+
st.image("DATA IA RSE Bordeaux Metropole.png", caption="Data IA RSE Bordeaux Metropole")
|
11 |
+
st.image("RECO IA RSE Bordeaux Metropole.png", caption="RECO IA RSE Bordeaux Metropole")
|
12 |
+
|
13 |
+
# Credits
|
14 |
+
|
15 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
16 |
+
|
17 |
+
|
18 |
+
st.markdown("""
|
19 |
+
<div class="credits">
|
20 |
+
<p>Data Bordeaux Métropole : Licence MIT 2024 </p>
|
21 |
+
<p>Data bziiit : Licence MIT 2024</p>
|
22 |
+
<p>API IA : Perplexity</p>
|
23 |
+
<p>Avril 2004</p>
|
24 |
+
</div>
|
25 |
+
""", unsafe_allow_html=True)
|
26 |
+
|
27 |
+
if __name__ == "__main__":
|
28 |
+
main()
|
entreprises_labellisees.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from data_manager_bziiit import get_bziiit_data
|
3 |
+
|
4 |
+
def display_labelled_companies():
|
5 |
+
st.markdown("## Entreprises Labellisées (source OPEN DATA bziiit)")
|
6 |
+
st.markdown("### Découvrez les entreprises engagées avec au moins un label RSE")
|
7 |
+
|
8 |
+
# Récupération des données bziiit
|
9 |
+
bziiit_data = get_bziiit_data()
|
10 |
+
|
11 |
+
# Filtrage des entreprises ayant au moins un label
|
12 |
+
labelled_companies = [brand for brand in bziiit_data if brand['type'] == 'brand' and len(brand.get('labels', [])) > 0]
|
13 |
+
|
14 |
+
# Calcul du nombre de labels par entreprise
|
15 |
+
for brand in labelled_companies:
|
16 |
+
brand['label_count'] = len(brand['labels'])
|
17 |
+
|
18 |
+
# Calcul et affichage du nombre et du pourcentage d'entreprises labellisées
|
19 |
+
total_companies = len([brand for brand in bziiit_data if brand['type'] == 'brand'])
|
20 |
+
labelled_companies_count = len(labelled_companies)
|
21 |
+
percentage_labelled = round((labelled_companies_count / total_companies) * 100)
|
22 |
+
st.markdown(f"**Nb entreprises labellisées :** {labelled_companies_count} ({percentage_labelled}%)")
|
23 |
+
|
24 |
+
# Tri des entreprises par le nombre de labels, ordre décroissant
|
25 |
+
labelled_companies.sort(key=lambda x: x['label_count'], reverse=True)
|
26 |
+
|
27 |
+
# Affichage des entreprises
|
28 |
+
for i in range(0, len(labelled_companies), 5):
|
29 |
+
cols = st.columns(5)
|
30 |
+
image_placeholders = [col.empty() for col in cols]
|
31 |
+
padding_placeholders = [col.empty() for col in cols]
|
32 |
+
text_placeholders = [col.empty() for col in cols]
|
33 |
+
for j in range(5):
|
34 |
+
if i + j < len(labelled_companies):
|
35 |
+
company = labelled_companies[i + j]
|
36 |
+
with cols[j]:
|
37 |
+
if company['logo_url'] != 'Unknown':
|
38 |
+
image_placeholders[j].image(company['logo_url'], width=100)
|
39 |
+
padding_placeholders[j].write("") # This will act as padding
|
40 |
+
text_placeholders[j].write(company['name'])
|
41 |
+
text_placeholders[j].write(f"Nb labels : {company['label_count']}")
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
|
inspirezvous.py
ADDED
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import re
|
3 |
+
from folium import Map, Marker, Icon, Popup
|
4 |
+
from streamlit_folium import folium_static
|
5 |
+
from data_manager import get_data
|
6 |
+
from data_manager_bziiit import *
|
7 |
+
from ISO26000 import classify_actions_rse_ISO26000
|
8 |
+
from bs4 import BeautifulSoup
|
9 |
+
from urllib.parse import urlparse
|
10 |
+
|
11 |
+
###############################################################################################
|
12 |
+
# PARTIE 0 : Récupération des données API bziiit et Bordeaux Métropole
|
13 |
+
###############################################################################################
|
14 |
+
|
15 |
+
def fetch_data():
|
16 |
+
data, _ = get_data() # Récupération des données de Bordeaux Métropole
|
17 |
+
bziiit_data = get_bziiit_data() # Récupération des données de Bziiit
|
18 |
+
|
19 |
+
return data, bziiit_data
|
20 |
+
|
21 |
+
###############################################################################################
|
22 |
+
# PARTIE 1 : Le sélecteur d'entreprise
|
23 |
+
###############################################################################################
|
24 |
+
|
25 |
+
def display_company_selection(data):
|
26 |
+
# Get a list of all company names
|
27 |
+
companies = sorted(list(set(record['nom_courant_denomination'] for record in data)), key=str.lower)
|
28 |
+
|
29 |
+
selected_company = st.selectbox('Sélectionnez une entreprise', companies)
|
30 |
+
return selected_company # Return the selected company name
|
31 |
+
|
32 |
+
# Uniformiser les noms de champs
|
33 |
+
def normalize_company_name(record):
|
34 |
+
# Gère les différences de noms de champs entre les APIs
|
35 |
+
if 'nom_courant_denomination' in record:
|
36 |
+
return record['nom_courant_denomination'].strip().lower()
|
37 |
+
elif 'name' in record:
|
38 |
+
return record['name'].strip().lower()
|
39 |
+
return 'Unknown'
|
40 |
+
|
41 |
+
###############################################################################################
|
42 |
+
# PARTIE 2 : AFFICHAGE OPEN DATA BORDEAUX METROPOLE
|
43 |
+
###############################################################################################
|
44 |
+
|
45 |
+
def display_company_info(data, bziiit_data, selected_company):
|
46 |
+
normalized_selected = normalize_company_name({'name': selected_company}) # Assurez-vous que cette fonction normalise correctement comme expliqué dans l'étape 1.
|
47 |
+
company_data = next((record for record in data if normalize_company_name(record) == normalized_selected), None)
|
48 |
+
bziiit_company_data = next((record for record in bziiit_data if normalize_company_name(record) == normalized_selected), None)
|
49 |
+
|
50 |
+
classified_data = classify_actions_rse_ISO26000(data)
|
51 |
+
# Normalize the company name for comparison
|
52 |
+
normalized_selected = normalize_company_name({'name': selected_company})
|
53 |
+
|
54 |
+
# Find the company in the classified data
|
55 |
+
company_category = None
|
56 |
+
for category, companies in classified_data.items():
|
57 |
+
if any(normalize_company_name(company) == normalized_selected for company in companies):
|
58 |
+
company_category = category
|
59 |
+
break
|
60 |
+
|
61 |
+
if bziiit_company_data is None:
|
62 |
+
bziiit_company_data = {}
|
63 |
+
|
64 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
65 |
+
|
66 |
+
if company_data:
|
67 |
+
st.markdown("### Source OPEN DATA Bordeaux Métropole")
|
68 |
+
st.write(f"**Nom de l'entreprise:** {company_data.get('nom_courant_denomination', 'Non disponible')}")
|
69 |
+
|
70 |
+
col10, col20 = st.columns(2)
|
71 |
+
|
72 |
+
with col10:
|
73 |
+
if 'point_geo' in company_data and len(company_data['point_geo']) == 2:
|
74 |
+
lat, lon = company_data['point_geo']
|
75 |
+
m = Map(location=[lat, lon], zoom_start=10)
|
76 |
+
popup_html = f"""
|
77 |
+
<div style="width:300px;">
|
78 |
+
<b>{company_data.get('nom_courant_denomination', 'Sans nom')}</b><br><br>
|
79 |
+
<b>Action RSE:</b><br>
|
80 |
+
{company_data.get('action_rse', 'Non spécifiée')}<br><br>
|
81 |
+
<hr style="margin: 1px 0; border: none; border-top: 1px solid #ccc;">
|
82 |
+
<b>Secteur d'activité:</b> {company_data.get('libelle_section_naf', 'Non spécifié')}
|
83 |
+
</div>
|
84 |
+
"""
|
85 |
+
icon = Icon(icon="leaf", prefix='fa', color='green')
|
86 |
+
Marker([lat, lon], icon=icon, popup=Popup(popup_html, max_width=500)).add_to(m)
|
87 |
+
folium_static(m, width=330, height=500)
|
88 |
+
else:
|
89 |
+
st.write("**Position GPS non disponible pour cette entreprise.**")
|
90 |
+
|
91 |
+
with col20:
|
92 |
+
st.write(f"**Nom de l'entreprise :** {company_data.get('nom_courant_denomination', 'Non disponible')}")
|
93 |
+
st.write(f"**Commune :** {company_data.get('commune', 'Non disponible')}")
|
94 |
+
st.write(f"**Section NAF :** {company_data.get('libelle_section_naf', 'Non disponible')}")
|
95 |
+
st.write(f"**Effectif :** {company_data.get('tranche_effectif_entreprise', 'Non spécifié')}")
|
96 |
+
action_rse = company_data.get('action_rse', 'Non spécifié')
|
97 |
+
st.write(f"**Action RSE :** {action_rse}")
|
98 |
+
|
99 |
+
if action_rse != 'Non spécifié':
|
100 |
+
if company_category:
|
101 |
+
st.write(f"**Classification ISO 26000 (via IA) :** {company_category}")
|
102 |
+
else:
|
103 |
+
st.write("**Classification ISO 26000:** Catégorie non déterminée")
|
104 |
+
|
105 |
+
else:
|
106 |
+
st.error("Aucune donnée disponible pour cette entreprise depuis l'API Bordeaux Métropole.")
|
107 |
+
|
108 |
+
###############################################################################################
|
109 |
+
# PARTIE 3 : AFFICHAGE OPEN DATA bziiit
|
110 |
+
###############################################################################################
|
111 |
+
|
112 |
+
def get_labels():
|
113 |
+
url = f"{BASE_URL}/opendata/labels"
|
114 |
+
response = requests.get(url)
|
115 |
+
if response.status_code == 200:
|
116 |
+
return response.json()["response"]
|
117 |
+
else:
|
118 |
+
st.error(f"Échec de récupération des labels: {response.text}")
|
119 |
+
return []
|
120 |
+
|
121 |
+
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
122 |
+
|
123 |
+
|
124 |
+
if bziiit_company_data:
|
125 |
+
st.markdown("### Source OPEN DATA bziiit")
|
126 |
+
|
127 |
+
# Assurez-vous d'avoir les informations nécessaires
|
128 |
+
logo_url = bziiit_company_data.get('logo_url', '')
|
129 |
+
website_url = bziiit_company_data.get('website_url', '')
|
130 |
+
|
131 |
+
# Affichez le logo
|
132 |
+
if logo_url:
|
133 |
+
st.markdown(f'<div style="text-align: center;"><img src="{logo_url}" style="width:120px;" /></div>', unsafe_allow_html=True)
|
134 |
+
else:
|
135 |
+
st.markdown('<div style="text-align: center;"><em style="font-size: small;">Logo non disponible</em></div>', unsafe_allow_html=True)
|
136 |
+
|
137 |
+
# Récupérez la description
|
138 |
+
description = bziiit_company_data.get('description', '')
|
139 |
+
|
140 |
+
# Utilisez une regex pour trouver les URL dans la description
|
141 |
+
website_url = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', description)
|
142 |
+
|
143 |
+
# Vérifiez si une URL a été trouvée
|
144 |
+
if website_url:
|
145 |
+
# Prenez la première URL trouvée
|
146 |
+
website_url = website_url[0]
|
147 |
+
st.markdown(f'<div style="text-align: center;">[Site web de l\'entreprise]({website_url})</div>', unsafe_allow_html=True)
|
148 |
+
else:
|
149 |
+
st.markdown('<div style="text-align: center;"><em style="font-size: small;">URL du site web non disponible</em></div>', unsafe_allow_html=True)
|
150 |
+
|
151 |
+
description_html = bziiit_company_data.get('description', 'Description non disponible')
|
152 |
+
description_text = BeautifulSoup(description_html, "html.parser").get_text()
|
153 |
+
st.write("📝 **Description de l'entreprise:**")
|
154 |
+
st.write(description_text)
|
155 |
+
|
156 |
+
st.markdown("🏷️ **Labels / Certifications RSE - Qualité :**")
|
157 |
+
labels = get_labels() # Get the labels using the get_labels function
|
158 |
+
label_data = bziiit_company_data.get('labels', [])
|
159 |
+
|
160 |
+
if not label_data:
|
161 |
+
st.write("Pas de Labels / Certifications RSE - Qualité actuellement.")
|
162 |
+
|
163 |
+
else:
|
164 |
+
# ...
|
165 |
+
for i in range(0, len(label_data), 2): # Loop through labels two at a time
|
166 |
+
cols = st.columns(2) # Create two columns
|
167 |
+
for j in range(2): # Loop through the two labels
|
168 |
+
if i + j < len(label_data): # Check if there is a label to process
|
169 |
+
label = label_data[i + j]
|
170 |
+
label_name = label.get("name", "Label non spécifié")
|
171 |
+
# Find the corresponding label in the labels data
|
172 |
+
label_info = next((l for l in labels if l.get("name") == label_name), None)
|
173 |
+
if label_info: # Only process labels with info
|
174 |
+
label_description = label_info.get("description", "Description non disponible") # Get the label description from the label info
|
175 |
+
logo_url = label_info.get("logo_url") # Get the logo URL from the label info
|
176 |
+
try:
|
177 |
+
# Display the image in the corresponding column with a tooltip
|
178 |
+
cols[j].markdown(f'<div style="text-align: center;"><a href="#" title="{label_description}"><img src="{logo_url}" alt="{label_name}" style="width:120px;"></a><p>{label_name}</p></div>', unsafe_allow_html=True)
|
179 |
+
except Exception as e:
|
180 |
+
st.error(f"Erreur lors de l'affichage de l'image : {e}")
|
181 |
+
# ...
|
182 |
+
if st.button('Ici pour visualiser le mail à envoyer pour référencer un nouveau label / certification RSE - Qualité'):
|
183 |
+
st.markdown("""
|
184 |
+
**Objet email :**
|
185 |
+
Demande de référencement Certification / Label RSE - Qualité
|
186 |
+
|
187 |
+
**Corps email :**
|
188 |
+
Bonjour,
|
189 |
+
|
190 |
+
Ci-dessous le lien publique vers la certification / label RSE - Qualité de notre entreprise pour référencement dans votre plateforme OPEN DATA IA RSE Bordeaux Métropole
|
191 |
+
|
192 |
+
URL à renseigner - 01 :
|
193 |
+
URL à renseigner - 02 :
|
194 |
+
URL à renseigner - 03 :
|
195 |
+
...
|
196 |
+
|
197 |
+
Nom du demandeur :
|
198 |
+
Qualité ou statut :
|
199 |
+
|
200 |
+
Destinataire : [email protected]
|
201 |
+
|
202 |
+
Merci par avance de votre aide pour développer la visibilité de vos Labels / Certifications
|
203 |
+
|
204 |
+
L'équipe OPEN DATA IA RSE Bordeaux Métropole
|
205 |
+
""", unsafe_allow_html=True)
|
206 |
+
|
207 |
+
else:
|
208 |
+
st.write("**Aucune donnée bziiit disponible pour cette entreprise.**")
|
209 |
+
|
210 |
+
|
211 |
+
def is_valid_url(url):
|
212 |
+
try:
|
213 |
+
response = requests.head(url)
|
214 |
+
return response.status_code == 200
|
215 |
+
except requests.RequestException:
|
216 |
+
return False
|
217 |
+
|
218 |
+
|
219 |
+
"""
|
220 |
+
###############################################################################################
|
221 |
+
# PARTIE 5 : AFFICHAGE INSPIREZ VOUS
|
222 |
+
###############################################################################################
|
223 |
+
def display_similar_companies(data, selected_company):
|
224 |
+
classified_data = classify_actions_rse_ISO26000(data)
|
225 |
+
company_data = next((record for record in data if record['nom_courant_denomination'] == selected_company), None)
|
226 |
+
if company_data:
|
227 |
+
action_rse = company_data.get('action_rse', 'Unknown').lower()
|
228 |
+
for category, companies in classified_data.items():
|
229 |
+
if any(company.get('action_rse', 'Unknown').lower() == action_rse for company in companies):
|
230 |
+
"""
|
231 |
+
# st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
232 |
+
"""
|
233 |
+
st.write("Ces organisations pourraient également vous inspirer")
|
234 |
+
max_pages = (len(companies) - 1) // 5 + 1
|
235 |
+
cols = st.columns([1,1,1,1,1])
|
236 |
+
if cols[1].button('Précédent'):
|
237 |
+
page = max(page - 1, 1)
|
238 |
+
page = cols[2].number_input('Page', min_value=1, max_value=max_pages, value=1, step=1)
|
239 |
+
if cols[3].button('Suivant'):
|
240 |
+
page = min(page + 1, max_pages)
|
241 |
+
|
242 |
+
companies_to_display = companies[(page - 1) * 5:page * 5]
|
243 |
+
|
244 |
+
st.write(f"Page: {page}") # Debugging line
|
245 |
+
st.write(f"Companies to display: {companies_to_display}") # Debugging line
|
246 |
+
|
247 |
+
for i, company in enumerate(companies_to_display):
|
248 |
+
st.write(f"Company: {company}") # Debugging line
|
249 |
+
logo_url = company.get('logo', 'https://opendata.bordeaux-metropole.fr/assets/theme_image/Open%20data%20-%20Pictos%2050px%20x%2050px-03.jpg')
|
250 |
+
if is_valid_url(logo_url):
|
251 |
+
cols[i].image(logo_url, width=50)
|
252 |
+
else:
|
253 |
+
cols[i].image('https://opendata.bordeaux-metropole.fr/assets/theme_image/Open%20data%20-%20Pictos%2050px%20x%2050px-03.jpg', width=50)
|
254 |
+
cols[i].write(f"**{company.get('name', 'Unknown')}**")
|
255 |
+
cols[i].write(f"{company.get('action_rse', 'Unknown')[:30]}")
|
256 |
+
"""
|
labelRSE.py
CHANGED
@@ -10,12 +10,14 @@ def display_rse_labels():
|
|
10 |
|
11 |
labels_option = st.radio(
|
12 |
"Choisissez les labels à afficher :",
|
13 |
-
("
|
14 |
)
|
15 |
|
|
|
16 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
17 |
|
18 |
labels = get_labels()
|
|
|
19 |
if labels_option == "Tous les labels / Certifications DATA bziiit":
|
20 |
labels.sort(key=lambda x: x['name'])
|
21 |
else:
|
|
|
10 |
|
11 |
labels_option = st.radio(
|
12 |
"Choisissez les labels à afficher :",
|
13 |
+
("Labels / Certifications des organisations engagées Bdx Métropole", "Tous les labels / Certifications DATA bziiit")
|
14 |
)
|
15 |
|
16 |
+
|
17 |
st.markdown("""<hr style='border-color: darkgrey;'>""", unsafe_allow_html=True)
|
18 |
|
19 |
labels = get_labels()
|
20 |
+
|
21 |
if labels_option == "Tous les labels / Certifications DATA bziiit":
|
22 |
labels.sort(key=lambda x: x['name'])
|
23 |
else:
|
localisation.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
|
2 |
from folium import Map, Marker, Icon, Popup
|
3 |
from streamlit_folium import folium_static
|
4 |
import streamlit as st
|
@@ -43,4 +42,4 @@ def display_map():
|
|
43 |
folium_static(m)
|
44 |
|
45 |
if __name__ == "__main__":
|
46 |
-
display_map()
|
|
|
|
|
1 |
from folium import Map, Marker, Icon, Popup
|
2 |
from streamlit_folium import folium_static
|
3 |
import streamlit as st
|
|
|
42 |
folium_static(m)
|
43 |
|
44 |
if __name__ == "__main__":
|
45 |
+
display_map()
|
partiesprenantes.py
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from openai import OpenAI
|
3 |
+
from folium import Map, Marker, Icon, Popup
|
4 |
+
from streamlit_folium import folium_static
|
5 |
+
from data_manager import get_data
|
6 |
+
from data_manager_bziiit import *
|
7 |
+
|
8 |
+
|
9 |
+
###############################################################################################
|
10 |
+
# PARTIE 0 : Récupération des données API bziiit et Bordeaux Métropole
|
11 |
+
###############################################################################################
|
12 |
+
|
13 |
+
def fetch_data():
|
14 |
+
data, _ = get_data() # Récupération des données de Bordeaux Métropole
|
15 |
+
bziiit_data = get_bziiit_data() # Récupération des données de Bziiit
|
16 |
+
|
17 |
+
return data, bziiit_data
|
18 |
+
|
19 |
+
###############################################################################################
|
20 |
+
# PARTIE 1 : Le sélecteur d'entreprise
|
21 |
+
###############################################################################################
|
22 |
+
def display_company_selection_for_materiality(data):
|
23 |
+
# Get a list of all company names
|
24 |
+
companies = sorted(list(set(record['nom_courant_denomination'] for record in data)), key=str.lower)
|
25 |
+
|
26 |
+
# Add default selection prompt to the beginning of the list
|
27 |
+
companies.insert(0, "Sélectionner l'entreprise engagée à découvrir")
|
28 |
+
|
29 |
+
selected_company = st.selectbox('Sélectionnez une entreprise', companies, index=0)
|
30 |
+
|
31 |
+
# If the default selection is still selected, return None
|
32 |
+
if selected_company == "Sélectionner l'entreprise engagée à découvrir":
|
33 |
+
return None
|
34 |
+
|
35 |
+
return selected_company # Return the selected company name
|
36 |
+
|
37 |
+
# Uniformiser les noms de champs
|
38 |
+
def normalize_company_name(record):
|
39 |
+
# Gère les différences de noms de champs entre les APIs
|
40 |
+
if 'nom_courant_denomination' in record:
|
41 |
+
return record['nom_courant_denomination'].strip().lower()
|
42 |
+
elif 'name' in record:
|
43 |
+
return record['name'].strip().lower()
|
44 |
+
return 'Unknown'
|
45 |
+
|
46 |
+
###############################################################################################
|
47 |
+
# PARTIE 3 : CONNEXION API sonar-medium-online + AFFICHAGE DE LA CONVERSATION
|
48 |
+
###############################################################################################
|
49 |
+
|
50 |
+
def perform_chat(messages):
|
51 |
+
YOUR_API_KEY = st.secrets["API_TOKEN_PERPLEXITYAI"]
|
52 |
+
client = OpenAI(api_key=YOUR_API_KEY, base_url="https://api.perplexity.ai")
|
53 |
+
|
54 |
+
response_stream = client.chat.completions.create(
|
55 |
+
model="sonar-medium-online",
|
56 |
+
messages=messages,
|
57 |
+
stream=True
|
58 |
+
)
|
59 |
+
|
60 |
+
assistant_response = ""
|
61 |
+
for chunk in response_stream:
|
62 |
+
assistant_response += chunk.choices[0].delta.content
|
63 |
+
|
64 |
+
st.write(assistant_response)
|
65 |
+
|
66 |
+
###############################################################################################
|
67 |
+
# PARTIE 4 : PARTIES PRENANTES
|
68 |
+
###############################################################################################
|
69 |
+
def display_materiality_partiesprenantes(selected_company, data, bziiit_data):
|
70 |
+
st.markdown("### Les parties prenantes identifiées par l'IA bziiit / Perplexity - sonar-medium-online")
|
71 |
+
option = st.radio(
|
72 |
+
"Choisissez une option",
|
73 |
+
('Définition', 'Parties prenantes prioritaires', 'Parties prenantes détaillées'),
|
74 |
+
index=0
|
75 |
+
)
|
76 |
+
|
77 |
+
if option == 'Définition':
|
78 |
+
st.write("""
|
79 |
+
**L'identification et l'implication des parties prenantes dans une démarche de Responsabilité Sociale des Entreprises (RSE) sont cruciales pour le succès et la légitimité des actions entreprises. Voici une synthèse en trois points clés de leur importance :
|
80 |
+
|
81 |
+
1. **Identification des parties prenantes pour une stratégie RSE inclusive**:
|
82 |
+
- L'identification des parties prenantes est la première étape essentielle pour comprendre qui sont les acteurs impactés par les activités de l'entreprise et qui peuvent influencer ses décisions[4].
|
83 |
+
- Cela inclut un large éventail d'acteurs tels que les employés, clients, fournisseurs, actionnaires, communautés locales, ONG et l'État[4][5].
|
84 |
+
- La norme ISO 26000 recommande d'intégrer les parties prenantes à tous les niveaux de la démarche RSE, ce qui permet de reconnaître et de répondre à leurs intérêts et attentes[3][5].
|
85 |
+
|
86 |
+
2. **Hiérarchisation et cartographie pour prioriser les actions**:
|
87 |
+
- Après l'identification, il est important de qualifier et de hiérarchiser les parties prenantes pour déterminer leur influence et leurs attentes, ainsi que les impacts de l'entreprise sur eux[4].
|
88 |
+
- La cartographie des parties prenantes permet de visualiser et de prioriser les relations en fonction de leur importance stratégique pour l'entreprise[2].
|
89 |
+
- Cette étape aide à concentrer les ressources et les efforts sur les parties prenantes clés et à élaborer des stratégies d'engagement adaptées[2][4].
|
90 |
+
|
91 |
+
3. **Engagement des parties prenantes pour une RSE efficace et crédible**:
|
92 |
+
- L'engagement des parties prenantes est fondamental pour construire une démarche RSE crédible et pour obtenir leur soutien[4][5].
|
93 |
+
- Il s'agit d'établir un dialogue constructif, de définir des objectifs SMART et de mettre en place des actions concrètes pour répondre aux attentes des parties prenantes[4].
|
94 |
+
- L'implication active des parties prenantes internes et externes favorise la transparence, renforce la confiance et améliore l'acceptabilité sociale des activités de l'entreprise[6].
|
95 |
+
|
96 |
+
En somme, l'identification et l'implication des parties prenantes sont des processus interdépendants qui permettent aux entreprises de développer une stratégie RSE cohérente, de gérer les risques et d'optimiser leur impact social et environnemental.
|
97 |
+
|
98 |
+
Citations:
|
99 |
+
[1] https://www.greenflex.com/actualites/articles/rse-parties-prenantes/
|
100 |
+
[2] https://datavalue-consulting.com/cartographie-partie-prenante-rse/
|
101 |
+
[3] https://www.novethic.fr/entreprises-responsables/qui-sont-les-parties-prenantes-de-lentreprise.html
|
102 |
+
[4] https://www.cabinetdesaintfront.fr/publications/comment-engager-ses-parties-prenantes/
|
103 |
+
[5] https://www.labellucie.com/parties-prenantes-rse
|
104 |
+
[6] https://blog.hubspot.fr/marketing/parties-prenantes-rse
|
105 |
+
[7] https://www.erudit.org/fr/revues/mi/2013-v17-n2-mi0560/1015400ar/
|
106 |
+
[8] https://www.civitime.com/rse/parties-prenantes
|
107 |
+
[9] https://speaknact.fr/fr/blog/article/561--impliquer-ses-parties-prenantes-pour-une-rse-efficace
|
108 |
+
[10] https://www.abeautifulgreen.com/le-role-des-parties-prenantes-et-la-rse/
|
109 |
+
[11] https://www.cairn.info/revue-management-et-avenir-2014-2-page-73.htm
|
110 |
+
[12] https://www.squadeasy.com/blog/qui-sont-les-parties-prenantes-dune-entreprise
|
111 |
+
[13] https://www.associatheque.fr/fr/fichiers/bao/fiche-memo-RSE-DD-les-etapes-de-la-demarche.pdf
|
112 |
+
[14] https://greenly.earth/fr-fr/blog/guide-entreprise/rse-partie-prenantes
|
113 |
+
[15] https://www.veolia.com/fr/veolia-group/engagement-rse/engagement-parties-prenantes
|
114 |
+
|
115 |
+
""")
|
116 |
+
|
117 |
+
|
118 |
+
elif option == 'Parties prenantes prioritaires':
|
119 |
+
company_data = next((item for item in data if item['nom_courant_denomination'].strip().lower() == selected_company.strip().lower()), None)
|
120 |
+
bziiit_brand_data = next((brand for brand in bziiit_data if brand['type'] == 'brand' and brand['name'].strip().lower() == selected_company.strip().lower()), None)
|
121 |
+
if company_data and bziiit_brand_data:
|
122 |
+
run_perplexity_chat_parties_prenantes_prioritaires(company_data['nom_courant_denomination'], bziiit_brand_data['description'], company_data['action_rse'])
|
123 |
+
|
124 |
+
|
125 |
+
elif option == 'Parties prenantes détaillées':
|
126 |
+
company_data = next((item for item in data if item['nom_courant_denomination'].strip().lower() == selected_company.strip().lower()), None)
|
127 |
+
bziiit_brand_data = next((brand for brand in bziiit_data if brand['type'] == 'brand' and brand['name'].strip().lower() == selected_company.strip().lower()), None)
|
128 |
+
if company_data and bziiit_brand_data:
|
129 |
+
run_perplexity_chat_parties_prenantes_detailed(company_data['nom_courant_denomination'], bziiit_brand_data['description'], company_data['action_rse'])
|
130 |
+
|
131 |
+
###############################################################################################
|
132 |
+
# PARTIE 5 : FONCTIONS PARTIES PRENANTES
|
133 |
+
###############################################################################################
|
134 |
+
|
135 |
+
def run_perplexity_chat_parties_prenantes_prioritaires(company_name, company_description, company_rse_action):
|
136 |
+
question = f"En tant que spécialiste RSE et notamment de l'identification des parties prenantes d'une entreprise, tu es chargé d'identifier les parties prenantes prioritaires de l'entreprise dont : le nom est {company_name}, l'activité est {company_description}, ses principales actions RSE sont {company_rse_action}. Affiche les résultats TOUJOURS EN FRANCAIS classés par catégories de parties prenantes et cite les sources en bas de ta réponse."
|
137 |
+
messages = [
|
138 |
+
{"role": "system", "content": "You are an artificial intelligence assistant and you need to engage in a helpful, detailed, polite conversation with a user."},
|
139 |
+
{"role": "user", "content": question}
|
140 |
+
]
|
141 |
+
st.markdown("**Question posée :**")
|
142 |
+
st.write(question)
|
143 |
+
st.markdown("**Réponse IA :**")
|
144 |
+
perform_chat(messages)
|
145 |
+
|
146 |
+
def run_perplexity_chat_parties_prenantes_detailed(company_name, company_description, company_rse_action):
|
147 |
+
question = f"En tant que spécialiste RSE et notamment de l'identification des parties prenantes d'une entreprise, tu es chargé d'identifier l'ensemble des parties prenantes de l'entreprise dont : le nom est {company_name}, l'activité est {company_description}, ses principales actions RSE sont {company_rse_action},. Affiche les résultats détaillés TOUJOURS EN FRANCAIS classés par catégories de parties prenantes et cite les sources en bas de ta réponse."
|
148 |
+
messages = [
|
149 |
+
{"role": "system", "content": "You are an artificial intelligence assistant and you need to engage in a helpful, detailed, polite conversation with a user."},
|
150 |
+
{"role": "user", "content": question}
|
151 |
+
]
|
152 |
+
st.markdown("**Question posée :**")
|
153 |
+
st.write(question)
|
154 |
+
st.markdown("**Réponse IA :**")
|
155 |
+
perform_chat(messages)
|
156 |
+
|
requirements.txt
CHANGED
@@ -10,3 +10,4 @@ torchaudio
|
|
10 |
wordcloud
|
11 |
plotly
|
12 |
matplotlib
|
|
|
|
10 |
wordcloud
|
11 |
plotly
|
12 |
matplotlib
|
13 |
+
|