import os import time import datetime import requests import textwrap import dash from offres_emploi import Api from offres_emploi.utils import dt_to_str_iso from dash import Dash, html, dcc, callback, Output, Input, dash_table, State, _dash_renderer, clientside_callback import dash_bootstrap_components as dbc import plotly.express as px import plotly.graph_objects as go import dash_mantine_components as dmc from dash_iconify import DashIconify import pandas as pd from dotenv import load_dotenv _dash_renderer._set_react_version("18.2.0") import plotly.io as pio from langchain_community.llms import HuggingFaceEndpoint from langchain_core.prompts import ChatPromptTemplate, PromptTemplate from langchain.schema.output_parser import StrOutputParser from pinecone import Pinecone from bs4 import BeautifulSoup from flask import Flask server = Flask(__name__) # external JavaScript files external_scripts = [ 'https://datacipen-eventia.hf.space/copilot/index.js' ] # Create a customized version of the plotly_dark theme with a modified background color custom_plotly_dark_theme = { "layout": { "paper_bgcolor": "#1E1E1E", # Update the paper background color "plot_bgcolor": "#1E1E1E", # Update the plot background color "font": { "color": "#FFFFFF" # Update the font color }, "xaxis": { "gridcolor": "#333333", # Update the x-axis grid color "zerolinecolor": "#666666" # Update the x-axis zero line color }, "yaxis": { "gridcolor": "#333333", # Update the y-axis grid color "zerolinecolor": "#666666" # Update the y-axis zero line color } } } # Apply the customized theme to your Plotly figures pio.templates["custom_plotly_dark"] = custom_plotly_dark_theme pio.templates.default = "custom_plotly_dark" load_dotenv() def removeTags(all): for data in all(['style', 'script']): data.decompose() return ''.join(all.stripped_strings) def htmlToDataframe(htmlTable): data = [] list_header = [] soup = BeautifulSoup(htmlTable,'html.parser') header = soup.find_all("table")[0].find("tr") for items in header: try: list_header.append(items.get_text()) except: continue HTML_data = soup.find_all("table")[0].find_all("tr")[1:] for element in HTML_data: sub_data = [] for sub_element in element: try: sub_data.append(sub_element.get_text()) except: continue data.append(sub_data) dataFrame = pd.DataFrame(data = data, columns = list_header) return dataFrame def getSavoirFaireFromHTMLMetier(url): response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") allSavoirFaire = soup.select('ul[data-cy="liste-savoir-faire-metier"] > li') if len(allSavoirFaire) != 0: allSF = "" for i in range(0,len(allSavoirFaire)): blockSavoirFaire = allSavoirFaire[i] try: soupSavoirFaire = BeautifulSoup(str(blockSavoirFaire), "html.parser") titleSavoirFaire = soupSavoirFaire.select('h4.fm-block-form-title') descriptSavoirFaire = soupSavoirFaire.select('div.fm-block-form-collapse-content') if removeTags(titleSavoirFaire[0]) != None: for j in range(0,len(descriptSavoirFaire)): ssblockSavoirFaire = descriptSavoirFaire[j] soupssSavoirFaire = BeautifulSoup(str(ssblockSavoirFaire), "html.parser") sstitleSavoirFaire = soupssSavoirFaire.select('h5.fm-block-form-subtitle') listSavoirFaire = soupssSavoirFaire.select('ul.list-unstyled > li') if len(listSavoirFaire) != 0: for k in range(0,len(listSavoirFaire)): blockListSavoirFaire = removeTags(listSavoirFaire[k]) allSF += "" except: print("Pas de Savoir-Faire!") allSF += "
Savoir-faireLibelleTypeCategorie
" + removeTags(titleSavoirFaire[0]) + "" + blockListSavoirFaire + "" + removeTags(sstitleSavoirFaire[0]) + "1
" return allSF def getSavoirFromHTMLMetier(url): response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") allSavoirFaire = soup.select('ul[data-cy="liste-savoir-metier"] > li') if len(allSavoirFaire) != 0: allSF = "" for i in range(0,len(allSavoirFaire)): blockSavoirFaire = allSavoirFaire[i] try: soupSavoirFaire = BeautifulSoup(str(blockSavoirFaire), "html.parser") titleSavoirFaire = soupSavoirFaire.select('h4.fm-block-form-title') descriptSavoirFaire = soupSavoirFaire.select('div.fm-block-form-collapse-content') if removeTags(titleSavoirFaire[0]) != None: for j in range(0,len(descriptSavoirFaire)): ssblockSavoirFaire = descriptSavoirFaire[j] soupssSavoirFaire = BeautifulSoup(str(ssblockSavoirFaire), "html.parser") listSavoirFaire = soupssSavoirFaire.select('ul.list-unstyled > li') if len(listSavoirFaire) != 0: for k in range(0,len(listSavoirFaire)): blockListSavoirFaire = removeTags(listSavoirFaire[k]) allSF += "" except: print("Pas de Savoir-Faire!") allSF += "
Savoir-faireLibelleCategorie
" + removeTags(titleSavoirFaire[0]) + "" + blockListSavoirFaire + "1
" return allSF def getContextFromHTMLMetier(url): response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") allContext = soup.select('div[data-cy="liste-contextes"] > div.fm-context') count = 0 if len(allContext) != 0: allSF = "" for i in range(0,len(allContext)): count = count + 1 blockContext = allContext[i] try: soupContext = BeautifulSoup(str(blockContext), "html.parser") titleSavoirFaire = soupContext.select('h3.fm-context-title') descriptSavoirFaire = soupContext.select('ul > li') if removeTags(titleSavoirFaire[0]) != None: for j in range(0,len(descriptSavoirFaire)): ssblockSavoirFaire = descriptSavoirFaire[j] if len(ssblockSavoirFaire) != 0: allSF += "" except: print("Pas de Savoir-Faire!") allSF += "
Savoir-faireLibelleCategorie
" + removeTags(titleSavoirFaire[0]) + "" + removeTags(ssblockSavoirFaire) + "1
" return allSF def datavisualisation_skills_context(df, template, paper_bgcolor, plot_bgcolor, title_template, codeRome): train = df array_df = list(df.columns) if any(x == "Type" for x in array_df): df1 = train.groupby(['Savoir-faire', 'Type'])['Categorie'].count().reset_index() df1.columns = ['source', 'target', 'value'] df2 = train.groupby(['Type', 'Libelle'])['Categorie'].count().reset_index() df2.columns = ['source', 'target', 'value'] all_links = pd.concat([df1, df2], axis=0) else: df1 = train.groupby(['Savoir-faire', 'Libelle'])['Categorie'].count().reset_index() df1.columns = ['source', 'target', 'value'] all_links = df1 unique_source_target = list(pd.unique(all_links[['source', 'target']].values.ravel('K'))) mapping_dict = {k: v for v, k in enumerate(unique_source_target)} all_links['source'] = all_links['source'].map(mapping_dict) all_links['target'] = all_links['target'].map(mapping_dict) links_dict = all_links.to_dict(orient='list') #Sankey Diagram Code colors = [ "blue","blueviolet","brown","burlywood","cadetblue", "chartreuse","chocolate","coral","cornflowerblue", "cornsilk","crimson","cyan","darkblue","darkcyan", "darkgoldenrod","darkgray","darkgrey","darkgreen", "darkkhaki","darkmagenta","darkolivegreen","darkorange", "darkorchid","darkred","darksalmon","darkseagreen", "darkslateblue","darkslategray","darkslategrey", "darkturquoise","darkviolet","deeppink","deepskyblue", "dimgray","dimgrey","dodgerblue","firebrick", "floralwhite","forestgreen","fuchsia","gainsboro", "ghostwhite","gold","goldenrod","gray","grey","green", "greenyellow","honeydew","hotpink","indianred","indigo", "ivory","khaki","lavender","lavenderblush","lawngreen", "lemonchiffon","lightblue","lightcoral","lightcyan", "lightgoldenrodyellow","lightgray","lightgrey", "lightgreen","lightpink","lightsalmon","lightseagreen", "lightskyblue","lightslategray","lightslategrey", "lightsteelblue","lightyellow", "lime","limegreen", "linen","magenta","maroon","mediumaquamarine", "mediumblue","mediumorchid","mediumpurple", "mediumseagreen","mediumslateblue","mediumspringgreen", "mediumturquoise","mediumvioletred","midnightblue", "mintcream","mistyrose","moccasin","navajowhite","navy", "oldlace","olive","olivedrab","orange","orangered", "orchid","palegoldenrod","palegreen","paleturquoise", "palevioletred","papayawhip","peachpuff","peru","pink", "plum","powderblue","purple","red","rosybrown", "royalblue","rebeccapurple","saddlebrown","salmon", "sandybrown","seagreen","seashell","sienna","silver", "skyblue","slateblue","slategray","slategrey","snow", "aliceblue","antiquewhite","aqua","aquamarine","azure", "beige","bisque","black","blanchedalmond" ] array_label_rome = searchByRome(codeRome) fig = go.Figure(data=[go.Sankey( node = dict( pad = 15, thickness = 20, line = dict(color = "black", width = 0.5), label = unique_source_target, color = colors ), link = dict( source = links_dict["source"], target = links_dict["target"], value = links_dict["value"], color="lightgrey" ))]).update_layout(template=template, paper_bgcolor=paper_bgcolor, plot_bgcolor=plot_bgcolor, title_text=title_template + " du code ROME : " + array_label_rome[0]['label'], font_size=10,width=1000, height=800) return fig def datavisualisation_chiffres_cles_emplois(url): response = requests.get(url) soup = BeautifulSoup(response.text, "lxml") alldemandeurs = '' allsalaires = '' alldifficultes = '' allrepartitions = '' allentreprises = '' allembauches = soup.select('p.population_category') allnumembauchesfirst = soup.select('p.population_main-num.data') allnumembauches = removeTags(allnumembauchesfirst[0]).split('\xa0') allnumembauches = ''.join(allnumembauches) allnumoffres = removeTags(allnumembauchesfirst[1]).split('\xa0') allnumoffres = ''.join(allnumoffres) alldetailembauches = soup.select('p.hiring_text.ng-star-inserted') allnumevolutionembauches = soup.select('p.main.ng-star-inserted') alldetailevolutionembauches = soup.select('p.population_bubble-title') alldemandeurs = "" else: alldemandeurs += "" alldemandeurs += "" alldemandeurs += "" else: alldemandeurs += "" alldemandeurs += "" alldemandeurs += "
IndicateurValeur
" + removeTags(allembauches[0]) + " (" + removeTags(alldetailembauches[0]) + ");" if len(alldetailevolutionembauches) >= 1 and len(allnumevolutionembauches) >= 1: alldemandeurs += "\nÉvolution demandeurs d'emploi (" + removeTags(alldetailevolutionembauches[0]) + ": " + removeTags(allnumevolutionembauches[0]) + ")" + allnumembauches + "
" + removeTags(allembauches[1]) + " (" + removeTags(alldetailembauches[1]) + ");" if len(alldetailevolutionembauches) >= 2 and len(allnumevolutionembauches) >= 2: alldemandeurs += "\nÉvolution offres d'emploi (" + removeTags(alldetailevolutionembauches[1]) + ": " + removeTags(allnumevolutionembauches[1]) + ")" + allnumoffres + "
" allFAP = soup.select('tr.sectorTable__line.ng-star-inserted') allcategorie = soup.select('td.sectorTable__cell') alltypesalaires = soup.select('th.sectorTable__cell') allFAPsalaires = soup.select('p.sectorTable__cellValue') if len(allFAPsalaires) >= 3: allsalaires = "" allsalaires += "" allsalaires += "" allsalaires += "" if len(allFAP) >= 2 and len(allFAPsalaires) == 6: allsalaires += "" allsalaires += "" allsalaires += "" allsalaires += "
categorieemploisalaire
" + removeTags(alltypesalaires[1]) + "" + removeTags(allcategorie[0]) + "" + removeTags(allFAPsalaires[0]).replace('\xa0','').replace(' ','').replace('€','') + "
" + removeTags(alltypesalaires[2]) + "" + removeTags(allcategorie[0]) + "" + removeTags(allFAPsalaires[1]).replace('\xa0','').replace(' ','').replace('€','') + "
" + removeTags(alltypesalaires[3]) + "" + removeTags(allcategorie[0]) + "" + removeTags(allFAPsalaires[2]).replace('\xa0','').replace(' ','').replace('€','') + "
" + removeTags(alltypesalaires[1]) + "" + removeTags(allcategorie[4]) + "" + removeTags(allFAPsalaires[3]).replace('\xa0','').replace(' ','').replace('€','') + "
" + removeTags(alltypesalaires[2]) + "" + removeTags(allcategorie[4]) + "" + removeTags(allFAPsalaires[4]).replace('\xa0','').replace(' ','').replace('€','') + "
" + removeTags(alltypesalaires[3]) + "" + removeTags(allcategorie[4]) + "" + removeTags(allFAPsalaires[5]).replace('\xa0','').replace(' ','').replace('€','') + "
" alltypedifficultes = soup.select('.tabs-main-content_persp-col2-bar.ng-star-inserted') alldifficulte = soup.select('p.horizontal-graph_title') allpcdifficulte = soup.select('div.horizontal-graph_data') alldifficultes = "" for i in range(0,len(alltypedifficultes)): alldifficultes += "" alldifficultes += "
IndicateurValeur
" + removeTags(alldifficulte[i]) + "" + removeTags(allpcdifficulte[i]).replace('Pour le territoire principal FRANCE pour les ' + removeTags(alldifficulte[i]),'').replace('%','') + "
" alltyperepartitions = soup.select('div.hiring-contract_legende_item.ng-star-inserted') allrepartition = soup.select('p.hiring-contract_legende_item_label') allpcrepartition = soup.select('span.hiring-contract_legende_item-first') allrepartitions = "" for i in range(0,len(alltyperepartitions)): allrepartitions += "" allrepartitions += "
IndicateurValeur
" + removeTags(allrepartition[i]).replace('(' + removeTags(allpcrepartition[i]) + ')','') + "" + removeTags(allpcrepartition[i]).replace('%','').replace(',','.') + "
" allentrepriserepartitions = soup.select('div.horizontal-graph_pattern.sm-bubble_wrapper > span') allentreprise = soup.select('span.sr-only') allpcentreprise = soup.select('span.data.ng-star-inserted') allentreprises = "" for i in range(0,len(allentrepriserepartitions)): allentreprises += "" allentreprises += "
IndicateurValeur
" + removeTags(allentrepriserepartitions[i])[0:-4] + "" + removeTags(allentrepriserepartitions[i])[-4:].replace('%','').replace(',','.') + "
" return [alldemandeurs, allsalaires, alldifficultes, allrepartitions, allentreprises] def localisation(): ListCentroids = [ { "ID": "01", "Longitude": 5.3245259, "Latitude":46.0666003 }, { "ID": "02", "Longitude": 3.5960246, "Latitude": 49.5519632 }, { "ID": "03", "Longitude": 3.065278, "Latitude": 46.4002783 }, { "ID": "04", "Longitude": 6.2237688, "Latitude": 44.1105837 }, { "ID": "05", "Longitude": 6.2018836, "Latitude": 44.6630487 }, { "ID": "06", "Longitude": 7.0755745, "Latitude":43.9463082 }, { "ID": "07", "Longitude": 4.3497308, "Latitude": 44.7626044 }, { "ID": "08", "Longitude": 4.6234893, "Latitude": 49.6473884 }, { "ID": "09", "Longitude": 1.6037147, "Latitude": 42.9696091 }, { "ID": "10", "Longitude": 4.1394954, "Latitude": 48.2963286 }, { "ID": "11", "Longitude": 2.3140163, "Latitude": 43.1111427 }, { "ID": "12", "Longitude": 2.7365234, "Latitude": 44.2786323 }, { "ID": "13", "Longitude": 5.0515492, "Latitude": 43.5539098 }, { "ID": "14", "Longitude": -0.3930779, "Latitude": 49.1024215 }, { "ID": "15", "Longitude": 2.6367657, "Latitude": 44.9643217 }, { "ID": "16", "Longitude": 0.180475, "Latitude": 45.706264 }, { "ID": "17", "Longitude": -0.7082589, "Latitude": 45.7629699 }, { "ID": "18", "Longitude": 2.5292424, "Latitude": 47.0926687 }, { "ID": "19", "Longitude": 1.8841811, "Latitude": 45.3622055 }, { "ID": "2A", "Longitude": 8.9906834, "Latitude": 41.8619761 }, { "ID": "2B", "Longitude": 9.275489, "Latitude": 42.372014 }, { "ID": "21", "Longitude": 4.7870471, "Latitude": 47.4736746 }, { "ID": "22", "Longitude": -2.9227591, "Latitude": 48.408402 }, { "ID": "23", "Longitude": 2.0265508, "Latitude": 46.0837382 }, { "ID": "24", "Longitude": 0.7140145, "Latitude": 45.1489678 }, { "ID": "25", "Longitude": 6.3991355, "Latitude": 47.1879451 }, { "ID": "26", "Longitude": 5.1717552, "Latitude": 44.8055408 }, { "ID": "27", "Longitude": 0.9488116, "Latitude": 49.1460288 }, { "ID": "28", "Longitude": 1.2793491, "Latitude": 48.3330017 }, { "ID": "29", "Longitude": -4.1577074, "Latitude": 48.2869945 }, { "ID": "30", "Longitude": 4.2650329, "Latitude": 43.9636468 }, { "ID": "31", "Longitude": 1.2728958, "Latitude": 43.3671081 }, { "ID": "32", "Longitude": 0.4220039, "Latitude": 43.657141 }, { "ID": "33", "Longitude": -0.5760716, "Latitude": 44.8406068 }, { "ID": "34", "Longitude": 3.4197556, "Latitude": 43.62585 }, { "ID": "35", "Longitude": -1.6443812, "Latitude": 48.1801254 }, { "ID": "36", "Longitude": 1.6509938, "Latitude": 46.7964222 }, { "ID": "37", "Longitude": 0.7085619, "Latitude": 47.2802601 }, { "ID": "38", "Longitude": 5.6230772, "Latitude": 45.259805 }, { "ID": "39", "Longitude": 5.612871, "Latitude": 46.7398138 }, { "ID": "40", "Longitude": -0.8771738, "Latitude": 44.0161251 }, { "ID": "41", "Longitude": 1.3989178, "Latitude": 47.5866519 }, { "ID": "42", "Longitude": 4.2262355, "Latitude": 45.7451186 }, { "ID": "43", "Longitude": 3.8118151, "Latitude": 45.1473029 }, { "ID": "44", "Longitude": -1.7642949, "Latitude": 47.4616509 }, { "ID": "45", "Longitude": 2.2372695, "Latitude": 47.8631395 }, { "ID": "46", "Longitude": 1.5732157, "Latitude": 44.6529284 }, { "ID": "47", "Longitude": 0.4788052, "Latitude": 44.4027215 }, { "ID": "48", "Longitude": 3.4991239, "Latitude": 44.5191573 }, { "ID": "49", "Longitude": -0.5136056, "Latitude": 47.3945201 }, { "ID": "50", "Longitude": -1.3203134, "Latitude": 49.0162072 }, { "ID": "51", "Longitude": 4.2966555, "Latitude": 48.9479636 }, { "ID": "52", "Longitude": 5.1325796, "Latitude": 48.1077196 }, { "ID": "53", "Longitude": -0.7073921, "Latitude": 48.1225795 }, { "ID": "54", "Longitude": 6.144792, "Latitude": 48.7995163 }, { "ID": "55", "Longitude": 5.2888292, "Latitude": 49.0074545 }, { "ID": "56", "Longitude": -2.8746938, "Latitude": 47.9239486 }, { "ID": "57", "Longitude": 6.5610683, "Latitude": 49.0399233 }, { "ID": "58", "Longitude": 3.5544332, "Latitude": 47.1122301 }, { "ID": "59", "Longitude": 3.2466616, "Latitude": 50.4765414 }, { "ID": "60", "Longitude": 2.4161734, "Latitude": 49.3852913 }, { "ID": "61", "Longitude": 0.2248368, "Latitude": 48.5558919 }, { "ID": "62", "Longitude": 2.2555152, "Latitude": 50.4646795 }, { "ID": "63", "Longitude": 3.1322144, "Latitude": 45.7471805 }, { "ID": "64", "Longitude": -0.793633, "Latitude": 43.3390984 }, { "ID": "65", "Longitude": 0.1478724, "Latitude": 43.0526238 }, { "ID": "66", "Longitude": 2.5239855, "Latitude": 42.5825094 }, { "ID": "67", "Longitude": 7.5962225, "Latitude": 48.662515 }, { "ID": "68", "Longitude": 7.2656284, "Latitude": 47.8586205 }, { "ID": "69", "Longitude": 4.6859896, "Latitude": 45.8714754 }, { "ID": "70", "Longitude": 6.1388571, "Latitude": 47.5904191 }, { "ID": "71", "Longitude": 4.6394021, "Latitude": 46.5951234 }, { "ID": "72", "Longitude": 0.1947322, "Latitude": 48.0041421 }, { "ID": "73", "Longitude": 6.4662232, "Latitude": 45.4956055 }, { "ID": "74", "Longitude": 6.3609606, "Latitude": 46.1045902 }, { "ID": "75", "Longitude": 2.3416082, "Latitude": 48.8626759 }, { "ID": "76", "Longitude": 1.025579, "Latitude": 49.6862911 }, { "ID": "77", "Longitude": 2.8977309, "Latitude": 48.5957831 }, { "ID": "78", "Longitude": 1.8080138, "Latitude": 48.7831982 }, { "ID": "79", "Longitude": -0.3159014, "Latitude": 46.5490257 }, { "ID": "80", "Longitude": 2.3380595, "Latitude": 49.9783317 }, { "ID": "81", "Longitude": 2.2072751, "Latitude": 43.8524305 }, { "ID": "82", "Longitude": 1.2649374, "Latitude": 44.1254902 }, { "ID": "83", "Longitude": 6.1486127, "Latitude": 43.5007903 }, { "ID": "84", "Longitude": 5.065418, "Latitude": 44.0001599 }, { "ID": "85", "Longitude": -1.3956692, "Latitude": 46.5929102 }, { "ID": "86", "Longitude": 0.4953679, "Latitude": 46.5719095 }, { "ID": "87", "Longitude": 1.2500647, "Latitude": 45.9018644 }, { "ID": "88", "Longitude": 6.349702, "Latitude": 48.1770451 }, { "ID": "89", "Longitude": 3.5634078, "Latitude": 47.8474664 }, { "ID": "90", "Longitude": 6.9498114, "Latitude": 47.6184394 }, { "ID": "91", "Longitude": 2.2714555, "Latitude": 48.5203114 }, { "ID": "92", "Longitude": 2.2407148, "Latitude": 48.835321 }, { "ID": "93", "Longitude": 2.4811577, "Latitude": 48.9008719 }, { "ID": "94", "Longitude": 2.4549766, "Latitude": 48.7832368 }, { "ID": "95", "Longitude": 2.1802056, "Latitude": 49.076488 }, { "ID": "974", "Longitude": 55.536384, "Latitude": -21.115141 }, { "ID": "973", "Longitude": -53.125782, "Latitude": 3.933889 }, { "ID": "972", "Longitude": -61.024174, "Latitude": 14.641528 }, { "ID": "971", "Longitude": -61.551, "Latitude": 16.265 } ] return ListCentroids def vectorDatabase_connexion(): pc = Pinecone(api_key=os.environ['PINECONE_API_KEY']) index_name = "all-skills" index = pc.Index(index_name) return index def searchByRome(codeRome): index = vectorDatabase_connexion() allRome = [] if codeRome: all_docs = index.query( top_k=1500, vector= [0] * 768, # embedding dimension namespace='', filter={"categorie": {"$eq": "rome"},"rome": {"$eq": codeRome}}, include_metadata=True ) else: all_docs = index.query( top_k=1500, vector= [0] * 768, # embedding dimension namespace='', filter={"categorie": {"$eq": "rome"}}, include_metadata=True ) for refRome in all_docs['matches']: allRome.append({"value": refRome['metadata']['rome'], "label": refRome['metadata']['rome'] + " - " + refRome['metadata']['libelle_rome']}) return sorted(allRome, key=lambda element:element["value"]) theme_toggle = dmc.Tooltip( dmc.ActionIcon( [ dmc.Paper(DashIconify(icon="radix-icons:sun", width=25), darkHidden=True), dmc.Paper(DashIconify(icon="radix-icons:moon", width=25), lightHidden=True), ], variant="transparent", color="yellow", id="color-scheme-toggle", size="lg", ms="auto", ), label="Changez de thème", position="left", withArrow=True, arrowSize=6, ) styleRefresh = { "color": "lightgrey", "textDecoration" : "none" } styleTitle = { "textAlign": "center" } styleUSERIA = { "textAlign": "right", "marginBottom" : "5px" } styleSUBMITIA = { "marginLeft":"auto", "marginRight":"auto", "marginTop": "5px", "marginBottom" : "5px" } styleSYSIA = { "marginTop":"10px", "marginBottom":"120px", } styleTopvar = { "display": "none" } styleToggle = { "marginTop":"25px", "textAlign": "right", } styleIcon = { "marginTop":"10px", } styleSubmitBox = { "position":"fixed", "width": "100%", "top": "calc(100vh - 100px)", "right": "0" } #datadefault = [ # {"value": "K2105", "label": "K2105"}, # {"value": "L1101", "label": "L1101"}, # {"value": "L1202", "label": "L1202"}, # {"value": "L1507", "label": "L1507"}, # {"value": "L1508", "label": "L1508"}, # {"value": "L1509", "label": "L1509"}, #] def custom_error_handler(err): # This function defines what we want to happen when an exception occurs # For now, we just print the exception to the terminal with additional text print(f"The app raised the following exception: {err}") def textbox(text, box="AI", name="Philippe"): text = text.replace(f"{name}:", "").replace("You:", "") #text = textile.textile(text) style = { "max-width": "60%", "width": "max-content", "padding": "5px 10px", "border-radius": 25, "margin-bottom": 20, } if box == "user": style["margin-left"] = "auto" style["margin-right"] = 0 #return dbc.Card(text, style=style, body=True, color="primary", inverse=True) return html.Div(dmc.Badge(text, size="xl", variant="gradient", gradient={"from": "grape", "to": "pink"},), style=styleUSERIA) elif box == "AI": style["margin-left"] = 0 style["margin-right"] = "auto" thumbnail = html.Img( src=app.get_asset_url("sparkles.gif"), style={ "border-radius": 50, "height": 36, "margin-right": 5, "float": "left", }, ) text = f"""{text}""" text = text.replace(" ","") textbox = dmc.Card(children=[dcc.Markdown(text, style={"font-size":"0.8em"})],withBorder=False,w="100%", style=styleSYSIA) return html.Div([thumbnail, textbox]) else: raise ValueError("Incorrect option for `box`.") #description = """ #Philippe is the principal architect at a condo-development firm in Paris. He lives with his girlfriend of five years in a 2-bedroom condo, with a small dog named Coco. Since the pandemic, his firm has seen a significant drop in condo requests. As such, he’s been spending less time designing and more time on cooking, his favorite hobby. He loves to cook international foods, venturing beyond French cuisine. But, he is eager to get back to architecture and combine his hobby with his occupation. That’s why he’s looking to create a new design for the kitchens in the company’s current inventory. Can you give him advice on how to do that? #""" # Authentication #openai.api_key = os.getenv("OPENAI_KEY") # Define Layout conversation = html.Div( html.Div(id="display-conversation"), style={ "overflow-y": "auto", "display": "flex", "height": "calc(100vh - 100px)", "flex-direction": "column-reverse", }, ) controls = dbc.InputGroup( children=[ dmc.TextInput(id="user-input", placeholder="Ecrire votre requête...", w="400", style=styleSUBMITIA), dbc.InputGroupAddon(dmc.Button(leftSection=DashIconify("Envoyer", icon="tabler:send", width=20), id="submit"), addon_type="append", style=styleTitle), #dbc.Input(id="user-input", placeholder="Ecrire votre requête...", type="text"), #dbc.InputGroupAddon(dbc.Button("Submit", id="submit"), addon_type="append"), ],style=styleSubmitBox ) class CustomDash(Dash): def interpolate_index(self, **kwargs): # Inspect the arguments by printing them return ''' Dashboard des compétences
{app_entry} {config} {scripts} {renderer} '''.format( app_entry=kwargs['app_entry'], config=kwargs['config'], scripts=kwargs['scripts'], renderer=kwargs['renderer']) #app = Dash(__name__, external_scripts=external_scripts, external_stylesheets=dmc.styles.ALL, on_error=custom_error_handler) app = CustomDash(__name__, server=server, use_pages=True, pages_folder='', external_scripts=external_scripts, external_stylesheets=dmc.styles.ALL, on_error=custom_error_handler) def connexion_France_Travail(): client = Api(client_id=os.getenv('POLE_EMPLOI_CLIENT_ID'), client_secret=os.getenv('POLE_EMPLOI_CLIENT_SECRET')) return client def API_France_Travail(romeListArray): client = connexion_France_Travail() todayDate = datetime.datetime.today() month, year = (todayDate.month-1, todayDate.year) if todayDate.month != 1 else (12, todayDate.year-1) start_dt = todayDate.replace(day=1, month=month, year=year) end_dt = datetime.datetime.today() results = [] for k in romeListArray: if k[0:1] == ' ': k = k[1:] params = {"motsCles": k.replace('/', '').replace('-', '').replace(',', '').replace(' ', ','),'minCreationDate': dt_to_str_iso(start_dt),'maxCreationDate': dt_to_str_iso(end_dt),'range':'0-149'} try: search_on_big_data = client.search(params=params) results += search_on_big_data["resultats"] except: print("Il n'y a pas d'offres d'emploi.") results_df = pd.DataFrame(results) return results_df def layout(**kwargs): listRome = [] try: selectArgRome = kwargs['selectRome'].replace(' ','').replace('%20','') if selectArgRome.find(',') != -1 and len(selectArgRome) > 5: listArgRome = selectArgRome.split(',') listRome = listArgRome elif selectArgRome.find(',') == -1 and len(selectArgRome) > 5: listRome.append(selectArgRome[0:4]) else: listRome.append(selectArgRome) except: listRome.append('M1705') return dmc.MantineProvider( [ html.Div( children=[ dmc.Container( children=[ dmc.Grid( children=[ dmc.GridCol(html.Div( children=[ dmc.MultiSelect( placeholder="Selectionnez vos Codes ROME", id="framework-multi-select", value=listRome, data=searchByRome(''), w=600, mt=10, styles={ "input": {"borderColor": "grey"}, "label": {"color": dmc.DEFAULT_THEME["colors"]["orange"][4]}, }, ), dmc.Drawer( title="Mistral répond à vos questions sur les datas de l'emploi et des compétences.", children=[dbc.Container( fluid=False, children=[ dcc.Store(id="store-conversation", data=""), html.Div(dmc.Button("Bonjour, Mistral est à votre écoute!", variant="gradient", gradient={"from": "grape", "to": "pink", "deg": 35}), style=styleUSERIA), conversation, dcc.Loading(html.Div(id="loading-component"),type="default"), controls, #dbc.Spinner(html.Div(id="loading-component")), ], ) ], id="drawer-simple", padding="md", size="50%", position="right" ),] ), span=5), dmc.GridCol(html.Div(dmc.Title(f"Le marché et les statistiques de l'emploi", order=1, size="30", my="20", id="chainlit-call-fn", style=styleTitle)), span=5), dmc.GridCol(html.Div(theme_toggle, style=styleToggle), span=1), dmc.GridCol(html.Div(dmc.Tooltip(dmc.Button(leftSection=DashIconify(icon="tabler:sparkles", width=30), id="drawer-demo-button"), label="IA générative sur les données",position="left",withArrow=True,arrowSize=6,), style=styleToggle), span=1), dmc.GridCol(html.A(DashIconify(icon="tabler:restore", width=20), href='/', style=styleRefresh), p=0,style=styleUSERIA, span=12), dmc.GridCol(dmc.Tabs( [ dmc.TabsList(mx="auto",grow=True, children=[ dmc.TabsTab("Marché de l'emploi", leftSection=DashIconify(icon="tabler:graph"), value="1"), dmc.TabsTab("Statistiques de l'emploi", leftSection=DashIconify(icon="tabler:chart-pie"), value="2"), dmc.TabsTab("Savoir-faire, Savoirs et Contexte des métiers", leftSection=DashIconify(icon="tabler:ikosaedr"), value="3"), ] ), dmc.TabsPanel( dmc.Grid( children=[ dmc.GridCol(html.Div( dcc.Loading( id="loadingRepartition", children=(dcc.Graph(id="figRepartition",selectedData={'points': [{'hovertext': ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','971','972','973','974']}]})), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingEmplois", children=(dcc.Graph(id="figEmplois")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingContrats", children=(dcc.Graph(id="figContrats")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingExperiences", children=(dcc.Graph(id="figExperiences")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingCompetences", children=(dcc.Graph(id="figCompetences")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingTransversales", children=(dcc.Graph(id="figTransversales")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingNiveau", children=(dcc.Graph(id="figNiveau")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingSecteur", children=(dcc.Graph(id="figSecteur")), type="default", ) ), span=6), dmc.GridCol(html.Div( dcc.Loading( id="loadingTableau", children=(dbc.Container(id="tableauEmplois")), type="default", ) ), span=12), ] ) , value="1"), dmc.TabsPanel( children=[ dmc.Button("Afficher les statistiques des métiers", mt=10, ml="auto", id="loading-button", leftSection=DashIconify(icon="tabler:chart-pie")), html.Div(id="clicked-output"), html.Div(id="clicked-output-tabs"), ], value="2"), dmc.TabsPanel( children=[ dmc.Button("Afficher les savoirs des métiers", mt=10, ml="auto", id="loading-skills", leftSection=DashIconify(icon="tabler:ikosaedr")), html.Div(id="clicked-output-skills"), html.Div(id="clicked-output-skills-tabs"), ], value="3"), ], value="1", ), span=12), ], gutter="xs", ) ],size="xxl",fluid=True ), ] ) ], id="mantine-provider", forceColorScheme="dark", theme={ "primaryColor": "indigo", "fontFamily": "'Inter', sans-serif", "components": { "Button": {"defaultProps": {"fw": 400}}, "Alert": {"styles": {"title": {"fontWeight": 500}}}, "AvatarGroup": {"styles": {"truncated": {"fontWeight": 500}}}, "Badge": {"styles": {"root": {"fontWeight": 500}}}, "Progress": {"styles": {"label": {"fontWeight": 500}}}, "RingProgress": {"styles": {"label": {"fontWeight": 500}}}, "CodeHighlightTabs": {"styles": {"file": {"padding": 12}}}, "Table": { "defaultProps": { "highlightOnHover": True, "withTableBorder": True, "verticalSpacing": "sm", "horizontalSpacing": "md", } }, }, # add your colors "colors": { "deepBlue": ["#E9EDFC", "#C1CCF6", "#99ABF0"], # 10 color elements }, "shadows": { # other shadows (xs, sm, lg) will be merged from default theme "md": "1px 1px 3px rgba(0,0,0,.25)", "xl": "5px 5px 3px rgba(0,0,0,.25)", }, "headings": { "fontFamily": "Roboto, sans-serif", "sizes": { "h1": {"fontSize": 30}, }, }, }, ) dash.register_page("home", layout=layout, path="/") app.layout = html.Div(dash.page_container) @callback( Output("mantine-provider", "forceColorScheme"), Input("color-scheme-toggle", "n_clicks"), State("mantine-provider", "forceColorScheme"), prevent_initial_call=True, ) def switch_theme(_, theme): return "dark" if theme == "light" else "light" @callback( Output("drawer-simple", "opened"), Input("drawer-demo-button", "n_clicks"), prevent_initial_call=True, ) def drawer_demo(n_clicks): return True @callback( Output(component_id='figRepartition', component_property='figure'), Output(component_id='figCompetences', component_property='figure'), Output(component_id='figTransversales', component_property='figure'), Output(component_id='figNiveau', component_property='figure'), Output(component_id='figSecteur', component_property='figure'), Input(component_id='framework-multi-select', component_property='value'), Input('figEmplois', 'selectedData'), Input("mantine-provider", "forceColorScheme"), ) def create_repartition(array_value, selectedData, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' plot_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' plot_bgcolor = 'rgba(255, 255, 255, 1)' df_FT = API_France_Travail(array_value) ######## localisation ######## df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail','secteurActiviteLibelle']].copy() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) ######## Filtre Emplois ######## options = [] options_FT = [] df_FT.dropna(subset=['intitule', 'qualitesProfessionnelles','formations','competences'], inplace=True) if selectedData != None: customEmplois = selectedData['points'][0]['y'][:-3] if type(selectedData['points'][0]['y']) == str: options.append(selectedData['points'][0]['y'][:-3]) options_FT.append(selectedData['points'][0]['y'][:-3]) else: options = selectedData['points'][0]['y'][:-3] options_FT = selectedData['points'][0]['y'][:-3] else: customEmplois = " " options = df['intitule'].values.tolist() options_FT = df_FT['intitule'].values.tolist() df = df[df['intitule'].isin(options)] df_FT = df_FT[df_FT['intitule'].isin(options_FT)] ######## localisation ######## ListCentroids = localisation() df_localisation = df.groupby('lieuTravail').size().reset_index(name='obs') df_localisation = df_localisation.sort_values(by=['lieuTravail']) df_localisation['longitude'] = df_localisation['lieuTravail'] df_localisation['latitude'] = df_localisation['lieuTravail'] df_localisation["longitude"] = df_localisation['longitude'].apply(lambda x:[loc['Longitude'] for loc in ListCentroids if loc['ID'] == x]).apply(lambda x:''.join(map(str, x))) df_localisation["longitude"] = pd.to_numeric(df_localisation["longitude"], downcast="float") df_localisation["latitude"] = df_localisation['latitude'].apply(lambda x:[loc['Latitude'] for loc in ListCentroids if loc['ID'] == x]).apply(lambda x:''.join(map(str, x))) df_localisation["latitude"] = pd.to_numeric(df_localisation["latitude"], downcast="float") res = requests.get( "https://raw.githubusercontent.com/codeforgermany/click_that_hood/main/public/data/france-regions.geojson" ) fig_localisation = px.scatter_mapbox(df_localisation, lat="latitude", lon="longitude", height=600, template=template, hover_name="lieuTravail", size="obs").update_layout( mapbox={ "style": "carto-positron", "center": {"lon": 2, "lat" : 47}, "zoom": 4.5, "layers": [ { "source": res.json(), "type": "line", "color": "green", "line": {"width": 0}, } ], },font=dict(size=10),paper_bgcolor=paper_bgcolor,autosize=True,clickmode='event+select' ).add_annotation(x=0, y=0.90, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='La répartition géographique des emplois
{}'.format(customEmplois),font=dict(color="black",size=14)) ######## Compétences professionnelles ######## #df_FT.dropna(subset=['intitule', 'qualitesProfessionnelles','formations','competences'], inplace=True) df_FT["competences"] = df_FT["competences"].apply(lambda x:[str(e['libelle']) for e in x]).apply(lambda x:'; '.join(map(str, x))) df_FT["qualitesProfessionnelles"] = df_FT["qualitesProfessionnelles"].apply(lambda x:[str(e['libelle']) + ": " + str(e['description']) for e in x]).apply(lambda x:'; '.join(map(str, x))) df_comp = df_FT df_comp['competences'] = df_FT['competences'].str.split(';') df_comp = df_comp.explode('competences') df_comp = df_comp.groupby('competences').size().reset_index(name='obs') df_comp = df_comp.sort_values(by=['obs']) df_comp = df_comp.iloc[-25:] fig_competences = px.bar(df_comp, x='obs', y='competences', orientation='h', color='obs', height=600, template=template, labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,clickmode='event+select',autosize=True).update_traces(hovertemplate=df_comp["competences"] + '
Nombre : %{x}', y=[y[:100] + "..." for y in df_comp['competences']], showlegend=False).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les principales compétences professionnelles
{}'.format(customEmplois),font=dict(size=14)) ######## Compétences transversales ######## df_transversales = df_FT df_transversales['qualitesProfessionnelles'] = df_FT['qualitesProfessionnelles'].str.split(';') df_comptransversales = df_transversales.explode('qualitesProfessionnelles') df_comptransversales = df_comptransversales.groupby('qualitesProfessionnelles').size().reset_index(name='obs') df_comptransversales = df_comptransversales.sort_values(by=['obs']) df_comptransversales = df_comptransversales.iloc[-25:] fig_transversales = px.bar(df_comptransversales, x='obs', y='qualitesProfessionnelles', orientation='h', color='obs', height=600, template=template, labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True).update_traces(hovertemplate=df_comptransversales["qualitesProfessionnelles"] + '
Nombre : %{x}', y=[y[:80] + "..." for y in df_comptransversales["qualitesProfessionnelles"]], showlegend=False).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les principales compétences transversales
{}'.format(customEmplois),font=dict(size=14)) ######## Niveaux de qualification ######## df_niveau = df_FT df_niveau["formations"] = df_niveau["formations"].apply(lambda x:[str(e['niveauLibelle']) for e in x]).apply(lambda x:'; '.join(map(str, x))) df_niveau = df_niveau.groupby('formations').size().reset_index(name='obs') fig_niveau = px.pie(df_niveau, names='formations', height=600, values='obs', color='obs', template=template, labels={'obs':'nombre'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les niveaux de qualification
{}'.format(customEmplois),font=dict(size=14)) ######## Secteurs ######## df_secteur = df.groupby('secteurActiviteLibelle').size().reset_index(name='obs') df_secteur = df_secteur.sort_values(by=['obs']) df_secteur = df_secteur.iloc[-25:] fig_secteur = px.bar(df_secteur, x='obs', y='secteurActiviteLibelle', height=600, orientation='h', color='obs', template=template, labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True).update_traces(hovertemplate=df_secteur["secteurActiviteLibelle"] + '
Nombre : %{x}', y=[y[:80] + "..." for y in df_secteur["secteurActiviteLibelle"]], showlegend=False).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les principaux secteurs d\'activités
{}'.format(customEmplois),font=dict(size=14)) return fig_localisation, fig_competences, fig_transversales, fig_niveau, fig_secteur def create_emploi(df, theme, customRepartition): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' plot_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' plot_bgcolor = 'rgba(255, 255, 255, 1)' ######## Emplois ######## df_intitule = df.groupby('intitule').size().reset_index(name='obs') df_intitule = df_intitule.sort_values(by=['obs']) df_intitule = df_intitule.iloc[-25:] fig_intitule = px.bar(df_intitule, x='obs', y='intitule', height=600, orientation='h', color='obs', template=template, labels={'obs':'nombre'}, color_continuous_scale="Teal", text_auto=True).update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,clickmode='event+select',autosize=True).update_traces(hovertemplate=df_intitule["intitule"] + '
Nombre : %{x}', y=[y[:100] + "..." for y in df_intitule["intitule"]], showlegend=False).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les principaux emplois
{}'.format(customRepartition),font=dict(size=14)) return fig_intitule def create_contrat(df, customEmplois, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' ######## Types de contrat ######## df_contrat = df.groupby('typeContratLibelle').size().reset_index(name='obs') fig_contrat = px.pie(df_contrat, names='typeContratLibelle', values='obs', color='obs', height=600, template=template, labels={'obs':'nombre'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les types de contrat
{}'.format(customEmplois),font=dict(size=14)) return fig_contrat def create_experience(df, customEmplois, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' ######## Expériences professionnelles ######## df_experience = df.groupby('experienceLibelle').size().reset_index(name='obs') fig_experience = px.pie(df_experience, names='experienceLibelle', values='obs', color='obs', height=600, template=template, labels={'obs':'nombre'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor).add_annotation(x=0, y=1.0, xanchor='left', yanchor='bottom', xref='paper', yref='paper', showarrow=False, align='left', text='Les expériences professionnelles
{}'.format(customEmplois),font=dict(size=14)) return fig_experience def create_tableau(df, theme): if theme == "dark": style_header = { 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'rgb(30, 30, 30)', 'color': 'white' } style_data={ 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'rgb(50, 50, 50)', 'color': 'white' } style_tooltip='background-color: lightgrey; font-family: "Inter", sans-serif; font-size:10px; color: white' else: style_header = { 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'transparent', 'color': 'black' } style_data={ 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'transparent', 'color': 'black' } style_tooltip='background-color: lightgrey; font-family: "Inter", sans-serif; font-size:10px; color: black' ######## Tableau des emplois ######## #df = df.fillna('N/A').replace('', 'N/A') df_tableau = df[['origineOffre','intitule','typeContratLibelle','experienceLibelle','description','lieuTravail']].copy() dictHeader = {'origineOffre': 'Lien','intitule': 'Offre','typeContratLibelle': 'Type de contrat','experienceLibelle':'Expérience','description':'Détail','lieuTravail':'Département'} df_tableau.rename(columns=dictHeader,inplace=True) tableau_Emplois = dash_table.DataTable( data=df_tableau.to_dict('records'), sort_action='native', columns=[{'id': c, 'name': c, 'presentation': 'markdown'} if c == 'Lien' else {'id': c, 'name': c} for c in df_tableau.columns], filter_action="native", filter_options={"placeholder_text": "Filtrer les valeurs de la colonne..."}, page_action='native', page_current= 0, page_size= 10, style_header=style_header, style_data=style_data, style_table={'overflowX': 'auto'}, style_cell={ 'overflow': 'hidden', 'textOverflow': 'ellipsis', 'maxWidth': 0, }, tooltip_data=[ { column: {'value': str(value), 'type': 'markdown'} for column, value in row.items() } for row in df_tableau.to_dict('records') ], css=[{ 'selector': '.dash-table-tooltip', 'rule': style_tooltip },{ 'selector': '.dash-table-tooltip > p', 'rule': style_tooltip }], tooltip_delay=0, tooltip_duration=None ) return tableau_Emplois @callback( Output(component_id='figEmplois', component_property='figure'), Input('figRepartition', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_emploi(selectedData, array_value, theme): options = [] if selectedData != None: customRepartition = selectedData['points'][0]['hovertext'] if isinstance(customRepartition, list): customRepartition = " " else: customRepartition = "Département : " + customRepartition if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: customRepartition = " " options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','971','972','973','974'] df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) df = df[df['lieuTravail'].isin(options)] return create_emploi(df, theme, customRepartition) @callback( Output(component_id='figContrats', component_property='figure'), Input('figRepartition', 'selectedData'), Input('figEmplois', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_contrat(selectedData, selectedDataEmplois, array_value, theme): df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() options = [] options_FT = [] if selectedData != None: if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','971','972','973','974'] if selectedDataEmplois != None: customEmplois = selectedDataEmplois['points'][0]['y'][:-3] if type(selectedDataEmplois['points'][0]['y']) == str: options_FT.append(selectedDataEmplois['points'][0]['y'][:-3]) else: options_FT = selectedDataEmplois['points'][0]['y'][:-3] else: customEmplois = " " options_FT = df['intitule'].values.tolist() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) df = df[df['lieuTravail'].isin(options)] df = df[df['intitule'].isin(options_FT)] return create_contrat(df, customEmplois, theme) @callback( Output(component_id='figExperiences', component_property='figure'), Input('figRepartition', 'selectedData'), Input('figEmplois', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_experience(selectedData, selectedDataEmplois, array_value, theme): df_FT = API_France_Travail(array_value) df = df_FT[['intitule','typeContratLibelle','experienceLibelle','lieuTravail']].copy() options = [] options_FT = [] if selectedData != None: if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','971','972','973','974'] if selectedDataEmplois != None: customEmplois = selectedDataEmplois['points'][0]['y'][:-3] if type(selectedDataEmplois['points'][0]['y']) == str: options_FT.append(selectedDataEmplois['points'][0]['y'][:-3]) else: options_FT = selectedDataEmplois['points'][0]['y'][:-3] else: customEmplois = " " options_FT = df['intitule'].values.tolist() df["lieuTravail"] = df["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df.drop(df[df['lieuTravail'] == 'Fra'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'FRA'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Ile'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Mar'].index, inplace = True) df.drop(df[df['lieuTravail'] == 'Bou'].index, inplace = True) df.drop(df[df['lieuTravail'] == '976'].index, inplace = True) df = df[df['lieuTravail'].isin(options)] df = df[df['intitule'].isin(options_FT)] return create_experience(df, customEmplois, theme) @callback( Output(component_id='tableauEmplois', component_property='children'), Input('figRepartition', 'selectedData'), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), ) def update_tableau(selectedData, array_value, theme): options = [] if selectedData != None: if type(selectedData['points'][0]['hovertext']) == str: options.append(selectedData['points'][0]['hovertext']) else: options = selectedData['points'][0]['hovertext'] else: options = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','2A','2B','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','971','972','973','974'] df_FT = API_France_Travail(array_value) df_FT["origineOffre"] = df_FT["origineOffre"].apply(lambda x: "[Voir l'offre sur le site web de France Travail](" + x['urlOrigine'] + ")") df_FT["lieuTravail"] = df_FT["lieuTravail"].apply(lambda x: x['libelle']).apply(lambda x: x[0:3]).apply(lambda x: x.strip()) df_FT.drop(df_FT[df_FT['lieuTravail'] == 'Fra'].index, inplace = True) df_FT.drop(df_FT[df_FT['lieuTravail'] == 'FRA'].index, inplace = True) df_FT.drop(df_FT[df_FT['lieuTravail'] == 'Ile'].index, inplace = True) df_FT.drop(df_FT[df_FT['lieuTravail'] == 'Mar'].index, inplace = True) df_FT.drop(df_FT[df_FT['lieuTravail'] == 'Bou'].index, inplace = True) df_FT.drop(df_FT[df_FT['lieuTravail'] == '976'].index, inplace = True) df_FT = df_FT[df_FT['lieuTravail'].isin(options)] return create_tableau(df_FT, theme) clientside_callback( """ function updateLoadingState(n_clicks) { return true } """, Output("loading-button", "loading", allow_duplicate=True), Input("loading-button", "n_clicks"), prevent_initial_call=True, ) @callback( Output("clicked-output", "children"), Output("clicked-output-tabs", "children"), Output("loading-button", "loading"), Input("loading-button", "n_clicks"), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), prevent_initial_call=True, ) def load_from_stats(n_clicks, array_value, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' plot_bgcolor = 'rgba(36, 36, 36, 1)' style_header = { 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'rgb(30, 30, 30)', 'color': 'white' } style_data={ 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'rgb(50, 50, 50)', 'color': 'white' } else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' plot_bgcolor = 'rgba(255, 255, 255, 1)' style_header = { 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'transparent', 'color': 'black' } style_data={ 'fontFamily': "'Inter', sans-serif", 'fontSize': '10px', 'backgroundColor': 'transparent', 'color': 'black' } children = [] children_tabs = [] for j in range(0, len(array_value)): table = datavisualisation_chiffres_cles_emplois("https://dataemploi.pole-emploi.fr/metier/chiffres-cles/NAT/FR/" + array_value[j]) array_label_rome = searchByRome(array_value[j]) df_demandeur = htmlToDataframe(table[0]) df_demandeur = df_demandeur.sort_values(by=['Indicateur']) fig_demandeur = px.histogram(df_demandeur, x='Indicateur', y='Valeur', height=800, template=template, title="Demandeurs d'emploi et offres d'emploi du code ROME : " + array_label_rome[0]['label'], color='Indicateur', labels={'Valeur':'Nombre'}, text_auto=True).update_layout(font=dict(size=9),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_demandeur)),type="default")), span=6),) children_tabs.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=[dbc.Label("Demandeurs d'emploi et offres d'emploi du code ROME : " + array_label_rome[0]['label']),dash_table.DataTable(data=df_demandeur.to_dict('records'),sort_action='native', columns=[{'id': c, 'name': c} for c in df_demandeur.columns],page_action='native', page_current= 0,page_size= 10,style_header=style_header,style_data=style_data,style_table={'overflowX': 'auto'},style_cell={'overflow': 'hidden','textOverflow': 'ellipsis','maxWidth': 0,})],type="default")), span=12),) if len(table[1]) > 0: df_salaire = htmlToDataframe(table[1]) df_salaire = df_salaire.sort_values(by=['salaire']) fig_salaire = px.histogram(df_salaire, x='emploi', y='salaire', height=600, template=template, barmode='group', title="Salaires médians du code ROME : " + array_label_rome[0]['label'], color='categorie', text_auto=True).update_layout(font=dict(size=9),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_salaire)),type="default")), span=6),) children_tabs.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=[dbc.Label("Salaires médians du code ROME : " + array_label_rome[0]['label']),dash_table.DataTable(data=df_salaire.to_dict('records'),sort_action='native', columns=[{'id': c, 'name': c} for c in df_salaire.columns],page_action='native', page_current= 0,page_size= 10,style_header=style_header,style_data=style_data,style_table={'overflowX': 'auto'},style_cell={'overflow': 'hidden','textOverflow': 'ellipsis','maxWidth': 0,})],type="default")), span=12),) df_difficulte = htmlToDataframe(table[2]) if len(df_difficulte) == 0: title = "Aucune donnée difficulté de recrutement renseignée!" else: title = "Difficulté de recrutement du code ROME : " + array_label_rome[0]['label'] df_difficulte = df_difficulte.sort_values(by=['Valeur']) fig_difficulte = px.histogram(df_difficulte, x='Indicateur', y='Valeur', height=600, template=template, title=title, color='Indicateur', labels={'Valeur':'Pourcentage'}, text_auto=True).update_layout(font=dict(size=9),paper_bgcolor=paper_bgcolor,plot_bgcolor=plot_bgcolor,autosize=True) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_difficulte)),type="default")), span=6)) children_tabs.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=[dbc.Label(title),dash_table.DataTable(data=df_difficulte.to_dict('records'),sort_action='native', columns=[{'id': c, 'name': c} for c in df_difficulte.columns],page_action='native', page_current= 0,page_size= 10,style_header=style_header,style_data=style_data,style_table={'overflowX': 'auto'},style_cell={'overflow': 'hidden','textOverflow': 'ellipsis','maxWidth': 0,})],type="default")), span=12),) df_repartitionContrat = htmlToDataframe(table[3]) df_repartitionContrat = df_repartitionContrat.sort_values(by=['Valeur']) fig_repartitionContrat = px.pie(df_repartitionContrat, names='Indicateur', values='Valeur', color='Indicateur', template=template, title="Répartition des embauches du métier : type de contrat du code ROME : " + array_label_rome[0]['label'], labels={'Valeur':'pourcentage'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_repartitionContrat)),type="default")), span=6)) children_tabs.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=[dbc.Label("Répartition des embauches du métier : type de contrat du code ROME : " + array_label_rome[0]['label']),dash_table.DataTable(data=df_repartitionContrat.to_dict('records'),sort_action='native', columns=[{'id': c, 'name': c} for c in df_repartitionContrat.columns],page_action='native', page_current= 0,page_size= 10,style_header=style_header,style_data=style_data,style_table={'overflowX': 'auto'},style_cell={'overflow': 'hidden','textOverflow': 'ellipsis','maxWidth': 0,})],type="default")), span=12),) df_repartitionEntreprise = htmlToDataframe(table[4]) df_repartitionEntreprise = df_repartitionEntreprise.sort_values(by=['Valeur']) fig_repartitionEntreprise = px.pie(df_repartitionEntreprise, names='Indicateur', values='Valeur', color='Indicateur', template=template, title="Répartition des embauches du métier : type entreprise du code ROME : " + array_label_rome[0]['label'], labels={'Valeur':'pourcentage'}, color_discrete_sequence=px.colors.qualitative.Safe).update_traces(textposition='inside', textinfo='percent+label').update_layout(font=dict(size=10),paper_bgcolor=paper_bgcolor) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_repartitionEntreprise)),type="default")), span=6)) children_tabs.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=[dbc.Label("Répartition des embauches du métier : type entreprise du code ROME : " + array_label_rome[0]['label']),dash_table.DataTable(data=df_repartitionEntreprise.to_dict('records'),sort_action='native', columns=[{'id': c, 'name': c} for c in df_repartitionEntreprise.columns],page_action='native', page_current= 0,page_size= 10,style_header=style_header,style_data=style_data,style_table={'overflowX': 'auto'},style_cell={'overflow': 'hidden','textOverflow': 'ellipsis','maxWidth': 0,})],type="default")), span=12),) return dmc.Grid(children=children), dmc.Grid(children=children_tabs), False clientside_callback( """ function updateLoadingState(n_clicks) { return true } """, Output("loading-skills", "loading", allow_duplicate=True), Input("loading-skills", "n_clicks"), prevent_initial_call=True, ) @callback( Output("clicked-output-skills", "children"), Output("loading-skills", "loading"), Input("loading-skills", "n_clicks"), Input(component_id='framework-multi-select', component_property='value'), Input("mantine-provider", "forceColorScheme"), prevent_initial_call=True, ) def load_from_skills(n_clicks, array_value, theme): if theme == "dark": template = "plotly_dark" paper_bgcolor = 'rgba(36, 36, 36, 1)' plot_bgcolor = 'rgba(36, 36, 36, 1)' else: template = "ggplot2" paper_bgcolor = 'rgba(255, 255, 255, 1)' plot_bgcolor = 'rgba(255, 255, 255, 1)' children = [] for j in range(0, len(array_value)): ficheSF = getSavoirFaireFromHTMLMetier("https://candidat.francetravail.fr/metierscope/fiche-metier/" + array_value[j]) fig_SF = datavisualisation_skills_context(htmlToDataframe(ficheSF), template, paper_bgcolor, plot_bgcolor, "Savoir-faire", array_value[j]) ficheSavoir = getSavoirFromHTMLMetier("https://candidat.francetravail.fr/metierscope/fiche-metier/" + array_value[j]) fig_Savoir = datavisualisation_skills_context(htmlToDataframe(ficheSavoir), template, paper_bgcolor, plot_bgcolor, "Savoirs", array_value[j]) ficheContext = getContextFromHTMLMetier("https://candidat.francetravail.fr/metierscope/fiche-metier/" + array_value[j]) fig_Context = datavisualisation_skills_context(htmlToDataframe(ficheContext), template, paper_bgcolor, plot_bgcolor, "Contexte", array_value[j]) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_SF)), type="default"), style=styleTitle), span=12),) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_Savoir)), type="default"), style=styleTitle), span=12),) children.append(dmc.GridCol(html.Div(dcc.Loading(id="loadingPlot",children=(dcc.Graph(figure=fig_Context)), type="default"), style=styleTitle), span=12),) return dmc.Grid(children=children), False ########### IA Chatbot ########### @app.callback( Output("display-conversation", "children"), [Input("store-conversation", "data")] ) def update_display(chat_history): return [ textbox(x, box="user") if i % 2 == 0 else textbox(x, box="AI") for i, x in enumerate(chat_history.split("")[:-1]) ] @app.callback( Output("user-input", "value"), [Input("submit", "n_clicks"), Input("user-input", "n_submit")], ) def clear_input(n_clicks, n_submit): return "" @app.callback( [Output("store-conversation", "data"), Output("loading-component", "children")], [Input("submit", "n_clicks"), Input("user-input", "n_submit")], [State("user-input", "value"), State("store-conversation", "data")], Input(component_id='framework-multi-select', component_property='value'), ) def run_chatbot(n_clicks, n_submit, user_input, chat_history, array_value): if n_clicks == 0 and n_submit is None: return "", None if user_input is None or user_input == "": return chat_history, None df_FT = API_France_Travail(array_value) df_FT_Select = df_FT[['intitule','typeContratLibelle','experienceLibelle','competences','description','qualitesProfessionnelles','salaire','lieuTravail','formations']].copy() list_FT = df_FT_Select.values.tolist() context = '' for i in range(0,len(list_FT)): 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 : département n°" + 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\n" #context = df_FT.to_string(index=False) template = """[INST] Vous êtes un ingénieur pédagogique de l'enseignement supérieur et vous êtes doué pour faire des analyses des formations de l'enseignement supérieur et de faire le rapprochement entre les compétences académiques et les compétences professionnelles attendues par le marché de l'emploi et les les recruteurs, en fonction des critères définis ci-avant. En fonction des informations suivantes et du contexte suivant seulement et strictement, répondez en langue française strictement à la question ci-dessous, en 5000 mots au moins. Lorsque cela est possible, cite les sources du contexte. Si vous ne pouvez pas répondre à la question sur la base des informations, dites que vous ne trouvez pas de réponse ou que vous ne parvenez pas à trouver de réponse. Essayez donc de comprendre en profondeur le contexte et répondez uniquement en vous basant sur les informations fournies. Ne générez pas de réponses non pertinentes. Répondez à la question ci-dessous à partir du contexte ci-dessous : {context} {question} [/INST] """ context_p = context[:28500] name = "Mistral" chat_history += f"Vous: {user_input}{name}:" model_input = template + chat_history.replace("", "\n") #model_input = template prompt = PromptTemplate(template=model_input, input_variables=["question","context"]) #prompt = dedent( # f""" #{description} #Vous: Bonjour {name}! #{name}: Bonjour! Ravi de parler avec vous aujourd'hui. #""" #) # First add the user input to the chat history os.environ['HUGGINGFACEHUB_API_TOKEN'] = os.environ['HUGGINGFACEHUB_API_TOKEN'] #repo_id = "mistralai/Mistral-7B-Instruct-v0.3" repo_id = "mistralai/Mistral-7B-Instruct-v0.2" #repo_id = "microsoft/Phi-3.5-mini-instruct" #mistral_url = "https://api-inference.huggingface.co/models/mistralai/Mixtral-8x22B-Instruct-v0.1" llm = HuggingFaceEndpoint( repo_id=repo_id, task="text2text-generation", max_new_tokens=8000, temperature=0.7, streaming=True ) model_output = "" chain = prompt | llm | StrOutputParser() for s in chain.stream({"question":"D'après le contexte, " + user_input,"context":context_p}): model_output = model_output + s print(s, end="", flush=True) #response = openai.Completion.create( # engine="davinci", # prompt=model_input, # max_tokens=250, # stop=["You:"], # temperature=0.9, #) #model_output = response.choices[0].text.strip() chat_history += f"{model_output}" return chat_history, None if __name__ == '__main__': app.run_server(debug=True)