datacipen commited on
Commit
2ca46bb
·
verified ·
1 Parent(s): dff657f

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +180 -37
main.py CHANGED
@@ -1,14 +1,15 @@
1
  import json
2
  import os
3
  import time
 
 
4
  from pathlib import Path
5
  import chainlit as cl
6
- #from azure.ai.inference import ChatCompletionsClient
7
- #from azure.ai.inference.models import SystemMessage, UserMessage
8
- #from azure.core.credentials import AzureKeyCredential
9
  from mistralai.client import MistralClient
10
  from mistralai import Mistral, UserMessage, SystemMessage
11
-
 
 
12
  os.environ["GITHUB_TOKEN"] = os.environ["GITHUB_TOKEN"]
13
 
14
  @cl.step(type="tool", show_input=True)
@@ -52,15 +53,57 @@ def Chargement_des_datas_web(profile):
52
  fileOpen.close()
53
  return txt
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  @cl.step(type="llm", show_input=True)
56
  def Connexion_Mistral():
57
- #token = os.environ["GITHUB_TOKEN"]
58
  endpoint = "https://models.inference.ai.azure.com"
59
  return Mistral(api_key=os.environ["GITHUB_TOKEN"], server_url=endpoint)
60
- #return ChatCompletionsClient(
61
- # endpoint="https://models.inference.ai.azure.com",
62
- # credential=AzureKeyCredential(os.environ["GITHUB_TOKEN"]),
63
- #)
64
 
65
  @cl.step(type="tool", show_input=True)
66
  def Generation_reponse(client, data, question):
@@ -73,23 +116,21 @@ def Generation_reponse(client, data, question):
73
  temperature=0.1,
74
  max_tokens=1024,
75
  )
76
- #return client.complete(
77
- # stream=True,
78
- # messages=[
79
- # SystemMessage(content="Tu es un spécialiste de l'enseignement supérieur, des formations et de la pédagogie. Tu es en capacité d'analyser en profondeur les séances pédagogiques et de les mettre en adéquation avec les théories de la recherche en éducation. Répondez à la question seulement et exclusivement à partir du contexte et des définitions ci-contre, de la manière la plus pertinente, seulement en fonction des informations fournies. Contexte : " + str(data) + ". Définition : les formations MIPI (Management de l'Innovation et du Patrimoine Immobilier) concernent le secteur de l'immobilier : facility management, property management, asset management. Les formations MITIC (Management de l'Innovation des Technologies de l'Information et de la Communication) concernent le secteur du numérique : management de projet, innovation et conseil, support numérique aux métiers"),
80
- # UserMessage(content=question + "Donne le résultat au format texte markdown, jusqu'à 3000 caractères convertis en UTF-8. Continue la réponse en citant, dans un paragraphe supplémentaire de 3 lignes, introduit un saut de ligne et par \"\n📚 Sources : \", les 3 verbatim, jusqu'à 100 caractères pour chaque verbatim, avec leur numéro de ligne respectif, qui ont permis de générer la réponse, à partir du contexte. Termine la réponse en créant, dans un dernier paragraphe d'une seule et unique ligne, introduite par un saut de ligne et par \"\n📣 Question en relation avec le sujet : \", 1 seule et unique question en relation avec la question posée, en commençant la ligne par \"Question relative au contexte :\"."),
81
- # ],
82
- #model="Phi-3.5-MoE-instruct",
83
- # presence_penalty=0.1,
84
- # frequency_penalty=0.8,
85
- # max_tokens=1024,
86
- # stop=["<|endoftext|>"],
87
- # temperature=0,
88
- # top_p=1,
89
- # model_extras={
90
- # "logprobs": True
91
- # }
92
- #)
93
  @cl.step(type="tool", show_input=True)
94
  async def Affichage_reponse(response):
95
  msg = cl.Message(author="COPILOT",content="")
@@ -147,16 +188,33 @@ async def on_action(action):
147
  async def on_action(action):
148
  client = cl.user_session.get("client")
149
  data = Chargement_des_datas_web(cl.user_session.get("chat_profile"))
150
- data = data[0:6975]
 
 
 
151
  question = action.value
152
 
153
- response = Generation_reponse(client, data, question)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  msg = await Affichage_reponse(response)
156
 
157
- answer = msg.content
158
 
159
- await Affichage_question_contexte(answer, question)
160
 
161
 
162
  @cl.set_chat_profiles
@@ -316,6 +374,60 @@ async def chat_profile():
316
  )
317
  ]
318
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  ]
320
 
321
  @cl.on_chat_start
@@ -325,17 +437,48 @@ async def on_chat_start():
325
 
326
  @cl.on_message
327
  async def main(message: cl.Message):
328
- data = Chargement_des_datas(cl.user_session.get("chat_profile"))
329
- cl.user_session.set("data", data)
330
- client = cl.user_session.get("client")
 
331
 
332
- response = Generation_reponse(client, data, message.content)
333
 
334
- msg = await Affichage_reponse(response)
335
 
336
- answer = msg.content
337
- await Affichage_question_contexte(answer, message.content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
 
 
 
 
 
 
 
339
  @cl.on_stop
340
  def on_stop():
341
  print("L'utilisateur veut arrêter la completion en cours!")
 
1
  import json
2
  import os
3
  import time
4
+ import datetime
5
+ import pandas as pd
6
  from pathlib import Path
7
  import chainlit as cl
 
 
 
8
  from mistralai.client import MistralClient
9
  from mistralai import Mistral, UserMessage, SystemMessage
10
+ from offres_emploi import Api
11
+ from offres_emploi.utils import dt_to_str_iso
12
+ from IPython.display import display
13
  os.environ["GITHUB_TOKEN"] = os.environ["GITHUB_TOKEN"]
14
 
15
  @cl.step(type="tool", show_input=True)
 
53
  fileOpen.close()
54
  return txt
55
 
56
+ def connexion_France_Travail():
57
+ client = Api(client_id=os.getenv('POLE_EMPLOI_CLIENT_ID'),
58
+ client_secret=os.getenv('POLE_EMPLOI_CLIENT_SECRET'))
59
+ return client
60
+
61
+ def API_France_Travail_ROME(romeListArray):
62
+ client = connexion_France_Travail()
63
+ todayDate = datetime.datetime.today()
64
+ month, year = (todayDate.month-1, todayDate.year) if todayDate.month != 1 else (12, todayDate.year-1)
65
+ start_dt = todayDate.replace(day=1, month=month, year=year)
66
+ end_dt = datetime.datetime.today()
67
+ results = []
68
+ romeList = []
69
+ if romeListArray.find('-') != -1:
70
+ romeList = romeListArray.split('-')
71
+ else:
72
+ romeList.append(romeListArray)
73
+ for k in romeList:
74
+ k = k.lstrip()
75
+ k = k.rstrip()
76
+ params = {"motsCles": k.replace('/', '').replace('-', '').replace(',', '').replace(' ', ','),'minCreationDate': dt_to_str_iso(start_dt),'maxCreationDate': dt_to_str_iso(end_dt),'range':'0-149'}
77
+ try:
78
+ search_on_big_data = client.search(params=params)
79
+ results += search_on_big_data["resultats"]
80
+ except:
81
+ print("Il n'y a pas d'offres d'emploi.")
82
+
83
+ results_df = pd.DataFrame(results)
84
+ return results_df
85
+
86
+ def API_France_Travail_Metier(metier):
87
+ client = connexion_France_Travail()
88
+ todayDate = datetime.datetime.today()
89
+ month, year = (todayDate.month-1, todayDate.year) if todayDate.month != 1 else (12, todayDate.year-1)
90
+ start_dt = todayDate.replace(day=1, month=month, year=year)
91
+ end_dt = datetime.datetime.today()
92
+ results = []
93
+ params = {"motsCles": metier,'minCreationDate': dt_to_str_iso(start_dt),'maxCreationDate': dt_to_str_iso(end_dt),'range':'0-149'}
94
+ try:
95
+ search_on_big_data = client.search(params=params)
96
+ results += search_on_big_data["resultats"]
97
+ except:
98
+ print("Il n'y a pas d'offres d'emploi.")
99
+
100
+ results_df = pd.DataFrame(results)
101
+ return results_df
102
+
103
  @cl.step(type="llm", show_input=True)
104
  def Connexion_Mistral():
 
105
  endpoint = "https://models.inference.ai.azure.com"
106
  return Mistral(api_key=os.environ["GITHUB_TOKEN"], server_url=endpoint)
 
 
 
 
107
 
108
  @cl.step(type="tool", show_input=True)
109
  def Generation_reponse(client, data, question):
 
116
  temperature=0.1,
117
  max_tokens=1024,
118
  )
119
+
120
+ def Generation_completion(client, data, question):
121
+ response = client.chat.complete(
122
+ model="Mistral-Nemo",
123
+ messages=[
124
+ SystemMessage(content="Tu es un spécialiste de l'enseignement supérieur, des formations et de la pédagogie. Tu es en capacité d'analyser en profondeur les séances pédagogiques et de les mettre en adéquation avec les théories de la recherche en éducation. Répondez à la question seulement et exclusivement à partir du contexte et des définitions ci-contre, de la manière la plus pertinente, seulement en fonction des informations fournies. Contexte : " + str(data) + ". Définition : les formations MIPI (Management de l'Innovation et du Patrimoine Immobilier) concernent le secteur de l'immobilier : facility management, property management, asset management. Les formations MITIC (Management de l'Innovation des Technologies de l'Information et de la Communication) concernent le secteur du numérique : management de projet, innovation et conseil, support numérique aux métiers"),
125
+ UserMessage(content=question + "Donne le résultat au format texte markdown, jusqu'à 3000 caractères convertis en UTF-8. Continue la réponse en citant, dans un paragraphe supplémentaire de 3 lignes, introduit un saut de ligne et par \"\n📚 Sources : \", les 3 verbatim, jusqu'à 100 caractères pour chaque verbatim, avec leur numéro de ligne respectif, qui ont permis de générer la réponse, à partir du contexte. Termine la réponse en créant, dans un dernier paragraphe d'une seule et unique ligne, introduite par un saut de ligne et par \"\n📣 Question en relation avec le sujet : \", 1 seule et unique question en relation avec la question posée, en commençant la ligne par \"Question relative au contexte :\"."),
126
+ ],
127
+ temperature=0.1,
128
+ max_tokens=1024,
129
+ top_p=0.1
130
+ )
131
+ msg = response.choices[0].message.content
132
+ return msg
133
+
 
 
134
  @cl.step(type="tool", show_input=True)
135
  async def Affichage_reponse(response):
136
  msg = cl.Message(author="COPILOT",content="")
 
188
  async def on_action(action):
189
  client = cl.user_session.get("client")
190
  data = Chargement_des_datas_web(cl.user_session.get("chat_profile"))
191
+
192
+ diviseur = str(len(data) // 23500)
193
+ reste = str(len(data) % 23500)
194
+
195
  question = action.value
196
 
197
+ answer = ''
198
+ if diviseur != 0:
199
+ for i in range(0, 3):
200
+ operator = i + 1
201
+ deb = i * 23500
202
+ end = operator * 23500
203
+ webData = data[deb:end]
204
+ answer += Generation_completion(client, webData, question)
205
+ else:
206
+ answer += Generation_reponse(client, data, question)
207
+
208
+ if diviseur != 0 and reste !=0 and len(reste) <= 23500:
209
+ answer += Generation_completion(client, reste, question)
210
+
211
+ response = Generation_reponse(client, answer, question)
212
 
213
  msg = await Affichage_reponse(response)
214
 
215
+ result = msg.content
216
 
217
+ await Affichage_question_contexte(result, question)
218
 
219
 
220
  @cl.set_chat_profiles
 
374
  )
375
  ]
376
  ),
377
+ cl.ChatProfile(
378
+ name="Offres d'emploi par code ROME",
379
+ markdown_description="Posez vos questions sur les offres d'emploi en direct avec France Travail grâce aux codes ROME rattachés aux formations.",
380
+ icon="/public/public_request-theme.svg",
381
+ starters = [
382
+ cl.Starter(
383
+ label="Offres d'emploi de la licence MIPI",
384
+ message="M1403-M1604-M1204-M1605-M1203",
385
+ icon="/public/public_learn.svg",
386
+ ),
387
+ cl.Starter(
388
+ label="Offres d'emploi de la licence MITIC",
389
+ message="M1403-M1604-M1204-M1605-M1203",
390
+ icon="/public/public_learn.svg",
391
+ ),
392
+ cl.Starter(
393
+ label="Offres d'emploi du master MIPI",
394
+ message="M1702-M1402-M1403-H1206-M1703",
395
+ icon="/public/public_learn.svg",
396
+ ),
397
+ cl.Starter(
398
+ label="Offres d'emploi du master MITIC",
399
+ message="M1702-M1402-M1403-H1206-M1703",
400
+ icon="/public/public_learn.svg",
401
+ )
402
+ ]
403
+ ),
404
+ cl.ChatProfile(
405
+ name="Offres d'emploi par métier type",
406
+ markdown_description="Posez vos questions sur les offres d'emploi en direct avec France Travail par métier type.",
407
+ icon="/public/public_request-theme.svg",
408
+ starters = [
409
+ cl.Starter(
410
+ label="Responsable de site industriel ou tertiaire",
411
+ message="Responsable de site industriel ou tertiaire",
412
+ icon="/public/public_learn.svg",
413
+ ),
414
+ cl.Starter(
415
+ label="Conseiller en investissement immobilier",
416
+ message="Conseiller en investissement immobilier",
417
+ icon="/public/public_learn.svg",
418
+ ),
419
+ cl.Starter(
420
+ label="Chef de projet digital",
421
+ message="Chef de projet digital",
422
+ icon="/public/public_learn.svg",
423
+ ),
424
+ cl.Starter(
425
+ label="Manager de l'innovation numérique",
426
+ message="Manager de l'innovation numérique",
427
+ icon="/public/public_learn.svg",
428
+ )
429
+ ]
430
+ ),
431
  ]
432
 
433
  @cl.on_chat_start
 
437
 
438
  @cl.on_message
439
  async def main(message: cl.Message):
440
+ if cl.user_session.get("chat_profile") != "Offres d'emploi par code ROME" and cl.user_session.get("chat_profile") != "Offres d'emploi par métier type":
441
+ data = Chargement_des_datas(cl.user_session.get("chat_profile"))
442
+ cl.user_session.set("data", data)
443
+ client = cl.user_session.get("client")
444
 
445
+ response = Generation_reponse(client, data, message.content)
446
 
447
+ msg = await Affichage_reponse(response)
448
 
449
+ answer = msg.content
450
+ await Affichage_question_contexte(answer, message.content)
451
+ else:
452
+ codeRomeStr = message.content
453
+ if codeRomeStr.find('-') != -1 or isinstance(codeRomeStr[-4], int) or isinstance(codeRomeStr[1:5], int):
454
+ await cl.Message(author="COPILOT", content="📊 Connexion à l'API France Travail").send()
455
+ df_FT = API_France_Travail_ROME(codeRomeStr)
456
+ elif isinstance(codeRomeStr[-4], int):
457
+ await cl.Message(author="COPILOT", content="📊 Connexion à l'API France Travail").send()
458
+ df_FT = API_France_Travail_ROME(codeRomeStr)
459
+ else:
460
+ df_FT = API_France_Travail_Metier(codeRomeStr)
461
+
462
+ await cl.Message(author="COPILOT", content="📈 Tableau des emplois les plus représentatifs").send()
463
+ df_intitule = df_FT.groupby('intitule').size().reset_index(name='obs')
464
+ df_intitule = df_intitule.sort_values(by=['obs'], ascending=True)
465
+ df_intitule = df_intitule.iloc[-25:]
466
+ displayTable = df_intitule.sort_values(by=['obs'], ascending=True).to_markdown
467
+ await cl.Message(author="COPILOT", content=displayTable).send()
468
+
469
+ df_FT_Select = df_FT[['intitule','typeContratLibelle','experienceLibelle','competences','description','qualitesProfessionnelles','salaire','lieuTravail','formations']].copy()
470
+ list_FT = df_FT_Select.values.tolist()
471
+ context = ''
472
+ for i in range(0,len(list_FT)):
473
+ context += "\n✔️ Emploi : " + str(list_FT[i][0]) + ";\n◉ Contrat : " + str(list_FT[i][1]) + ";\n◉ Compétences professionnelles : " + str(list_FT[i][3]).replace("{","").replace("}","").replace("[","").replace("]","").replace("code","").replace("libelle","") + ";\n" + "◉ Salaire : " + str(list_FT[i][6]).replace("{","").replace("}","").replace("[","").replace("]","") + ";\n◉ Qualification : " + str(list_FT[i][5]).replace("'libelle'","\n• 'libelle").replace("{","").replace("}","").replace("[","").replace("]","").replace("code","") + ";\n◉ Localisation : " + str(list_FT[i][7]).replace("{","").replace("}","").replace("[","").replace("]","") + ";\n◉ Expérience : " + str(list_FT[i][2]) + ";\n◉ Niveau de qualification : " + str(list_FT[i][8]).replace("{","").replace("}","").replace("[","").replace("]","") + ";\n◉ Description de l'emploi : " + str(list_FT[i][4]) + "\n"
474
 
475
+ listEmplois_name = f"Liste des emplois"
476
+ text_elements = []
477
+ text_elements.append(
478
+ cl.Text(content="Question : " + codeRomeStr + "\n\nRéponse :\n" + context.replace('[','').replace(']','').replace('{','').replace('}','').replace("'code'","\n• 'code'"), name=listEmplois_name, display="side")
479
+ )
480
+ await cl.Message(author="COPILOT", content="👨‍💼 Source France Travail : " + listEmplois_name, elements=text_elements).send()
481
+
482
  @cl.on_stop
483
  def on_stop():
484
  print("L'utilisateur veut arrêter la completion en cours!")