datacipen commited on
Commit
0c4f473
·
verified ·
1 Parent(s): 58f8480

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +32 -189
main.py CHANGED
@@ -1,14 +1,11 @@
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
 
13
  os.environ["GITHUB_TOKEN"] = os.environ["GITHUB_TOKEN"]
14
 
@@ -53,92 +50,40 @@ def Chargement_des_datas_web(profile):
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):
110
- return client.chat.stream(
111
- model="Mistral-Nemo",
112
  messages=[
113
  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"),
114
  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 :\"."),
115
  ],
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="")
137
 
138
  for update in response:
139
- if update.data.choices:
140
  time.sleep(0.125)
141
- await msg.stream_token(update.data.choices[0].delta.content.replace('Ã','é').replace('©','').replace('Ã','è').replace('¨','').replace('â','\'').replace('€','').replace('™','').replace('Å','oe').replace('“','').replace('®','î').replace('´','ô').replace('<','').replace('>','').replace('/',''))
142
 
143
  await msg.send()
144
  return msg
@@ -188,33 +133,16 @@ async def on_action(action):
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,60 +302,6 @@ async def chat_profile():
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,48 +311,17 @@ async def 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!")
 
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
 
10
  os.environ["GITHUB_TOKEN"] = os.environ["GITHUB_TOKEN"]
11
 
 
50
  fileOpen.close()
51
  return txt
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  @cl.step(type="llm", show_input=True)
54
  def Connexion_Mistral():
55
+ return ChatCompletionsClient(
56
+ endpoint="https://models.inference.ai.azure.com",
57
+ credential=AzureKeyCredential(os.environ["GITHUB_TOKEN"]),
58
+ )
59
 
60
  @cl.step(type="tool", show_input=True)
61
  def Generation_reponse(client, data, question):
62
+ return client.complete(
63
+ stream=True,
64
  messages=[
65
  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"),
66
  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 :\"."),
67
  ],
68
+ model="Phi-3.5-MoE-instruct",
69
+ presence_penalty=0.1,
70
+ frequency_penalty=0.8,
71
  max_tokens=1024,
72
+ stop=["<|endoftext|>"],
73
+ temperature=0,
74
+ top_p=1,
75
+ model_extras={
76
+ "logprobs": True
77
+ }
78
+ )
 
 
 
 
 
 
 
 
 
79
  @cl.step(type="tool", show_input=True)
80
  async def Affichage_reponse(response):
81
  msg = cl.Message(author="COPILOT",content="")
82
 
83
  for update in response:
84
+ if update.choices:
85
  time.sleep(0.125)
86
+ await msg.stream_token(update.choices[0].delta.content.replace('Ã','é').replace('©','').replace('Ã','è').replace('¨','').replace('â','\'').replace('€','').replace('™','').replace('Å','oe').replace('“','').replace('®','î').replace('´','ô').replace('<','').replace('>','').replace('/',''))
87
 
88
  await msg.send()
89
  return msg
 
133
  async def on_action(action):
134
  client = cl.user_session.get("client")
135
  data = Chargement_des_datas_web(cl.user_session.get("chat_profile"))
136
+ data = data[0:6975]
 
 
 
137
  question = action.value
138
 
139
+ response = Generation_reponse(client, data, question)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  msg = await Affichage_reponse(response)
142
 
143
+ answer = msg.content
144
 
145
+ await Affichage_question_contexte(answer, question)
146
 
147
 
148
  @cl.set_chat_profiles
 
302
  )
303
  ]
304
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  ]
306
 
307
  @cl.on_chat_start
 
311
 
312
  @cl.on_message
313
  async def main(message: cl.Message):
314
+ data = Chargement_des_datas(cl.user_session.get("chat_profile"))
315
+ cl.user_session.set("data", data)
316
+ client = cl.user_session.get("client")
 
317
 
318
+ response = Generation_reponse(client, data, message.content)
319
 
320
+ msg = await Affichage_reponse(response)
321
 
322
+ answer = msg.content
323
+ await Affichage_question_contexte(answer, message.content)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
 
 
 
 
 
 
 
 
325
  @cl.on_stop
326
  def on_stop():
327
  print("L'utilisateur veut arrêter la completion en cours!")