Upload 10 files
Browse files- Dockerfile +8 -0
- app.py +208 -0
- data_process.py +50 -0
- document_scrapped.py +202 -0
- intents_v2.txt +70 -0
- key_extract.py +24 -0
- qa_txt.py +86 -0
- requirements.txt +19 -0
- sumarize.py +25 -0
- trans.py +14 -0
Dockerfile
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.10.9
|
2 |
+
COPY . .
|
3 |
+
|
4 |
+
WORKDIR /
|
5 |
+
|
6 |
+
RUN pip install --no-cache-dir --upgrade -r /requirements.txt
|
7 |
+
|
8 |
+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
app.py
ADDED
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain.prompts import StringPromptTemplate
|
2 |
+
import re
|
3 |
+
from document_scrapped import get_data
|
4 |
+
import langchain
|
5 |
+
from qa_txt import conversation_chain
|
6 |
+
# from key_extract import chain
|
7 |
+
from langchain_core.prompts import PromptTemplate
|
8 |
+
from bs4 import BeautifulSoup
|
9 |
+
import requests
|
10 |
+
from data_process import *
|
11 |
+
from langchain.tools.base import StructuredTool
|
12 |
+
from langchain.agents import initialize_agent
|
13 |
+
from qa_txt import llm
|
14 |
+
from trans import trans
|
15 |
+
import pathlib
|
16 |
+
import gradio as gr
|
17 |
+
from pydantic import BaseModel
|
18 |
+
from fastapi import FastAPI
|
19 |
+
from fastapi.middleware.cors import CORSMiddleware
|
20 |
+
|
21 |
+
# import threading, time
|
22 |
+
from langchain.agents import (
|
23 |
+
create_react_agent,
|
24 |
+
AgentExecutor,
|
25 |
+
tool,
|
26 |
+
)
|
27 |
+
from langchain import hub
|
28 |
+
import os
|
29 |
+
|
30 |
+
app = FastAPI(title="Data Gov MA API", description="API for Data Gov MA", version="1.0.0")
|
31 |
+
|
32 |
+
|
33 |
+
class Generate(BaseModel):
|
34 |
+
text:str
|
35 |
+
|
36 |
+
|
37 |
+
file_text = pathlib.Path('intents_v2.txt').read_text()
|
38 |
+
|
39 |
+
prompt = hub.pull("hwchase17/react")
|
40 |
+
|
41 |
+
def faq(query: str) -> str:
|
42 |
+
reponse = conversation_chain.invoke({"input": query, 'document': file_text})
|
43 |
+
return reponse
|
44 |
+
|
45 |
+
qa_faq = StructuredTool.from_function(
|
46 |
+
func = faq ,
|
47 |
+
description="""
|
48 |
+
Respond to general questions about the website like the documentation, contact, utility, support... Don't use it when the user request data about a subject (economie, justice, water, or any type of public dataset) only for contact or useful links data.
|
49 |
+
|
50 |
+
Parameters :
|
51 |
+
- query (string) : the same input as the user input no more no less and dont translate it even if it is in another language.
|
52 |
+
|
53 |
+
Returns :
|
54 |
+
- string : the output as returned from the function in french.
|
55 |
+
""",
|
56 |
+
|
57 |
+
)
|
58 |
+
|
59 |
+
analyze_data = StructuredTool.from_function(
|
60 |
+
func=get_data,
|
61 |
+
description = """
|
62 |
+
Analyze and summarize data from a given url asked by the user to summarize or analyze dont use it with the tool request_data and the user must write analyze before this function get executed.
|
63 |
+
Parameters :
|
64 |
+
- url (string) : the url given by the user.
|
65 |
+
Returns :
|
66 |
+
- string : Once the data is outputed from the function it get summarized and returned to the user and it must be in french.
|
67 |
+
Example:
|
68 |
+
>>> analyse this data of this link : https://data.gov.ma/data/fr/dataset/evolution-des-affaires-au-cours-du-quinquennat-2018-2022
|
69 |
+
>>> input : https://data.gov.ma/data/fr/dataset/evolution-des-affaires-au-cours-du-quinquennat-2018-2022
|
70 |
+
""",
|
71 |
+
return_direct = True,
|
72 |
+
)
|
73 |
+
|
74 |
+
def request_data(query: str) -> str:
|
75 |
+
mot_cle = nettoyer_string(query)
|
76 |
+
mots = mot_cle.split()
|
77 |
+
ui = mots[0]
|
78 |
+
rg = chercher_data(ui)
|
79 |
+
if len(rg[0]):
|
80 |
+
reponse_final = format_reponse(rg)
|
81 |
+
return reponse_final
|
82 |
+
else:
|
83 |
+
return query
|
84 |
+
|
85 |
+
fetch_data = StructuredTool.from_function(
|
86 |
+
func=request_data,
|
87 |
+
description="""
|
88 |
+
Request and fetch data using a search keyword.
|
89 |
+
Parameters :
|
90 |
+
- query (string) : A keyword in french about the subject of what to user is looking for, it must be always be in french and a noun if not convert it.For example if the user inputed "I want data about water" you need to input water in french which is "eau" same for other languages and the words translatted must be nouns not adjectives or verbs also the user may request data about an organization where you need to take just the main subject for example "Je veux les données de l'agence de développement digitale" you take just "développement".
|
91 |
+
Returns :
|
92 |
+
- string : the output as returned from the function in french , includes the link to all the data about the keyword along with an example.
|
93 |
+
""",
|
94 |
+
return_direct = True,
|
95 |
+
)
|
96 |
+
# def request_data(query: str) -> str:
|
97 |
+
# request = chain.invoke({"input": query})
|
98 |
+
# mot_cle = nettoyer_string(request)
|
99 |
+
# mots = mot_cle.split()
|
100 |
+
# ui = mots[0]
|
101 |
+
# rg = chercher_data(ui)
|
102 |
+
# if len(rg[0]):
|
103 |
+
# reponse_final = format_reponse(rg)
|
104 |
+
# return reponse_final
|
105 |
+
# else:
|
106 |
+
# return "Désolé, il semble que nous n'ayons pas de données correspondant à votre demande pour le moment. Avez-vous une autre question ou avez-vous besoin d'aide sur quelque chose d'autre?"
|
107 |
+
|
108 |
+
# fetch_data = StructuredTool.from_function(
|
109 |
+
# func=request_data,
|
110 |
+
# description="""
|
111 |
+
# Request and fetch data using a search keyword.
|
112 |
+
|
113 |
+
# Parameters :
|
114 |
+
# - query (string) : the same input as the user input no more no less and always it must be in french if it isn't already. For example : "give me data about health" the input is health in french which is santé, same for other languages and the words translatted must be nouns not adjectives or verbs also the user may request data about an organization where you need to take just the main subject for example "Je veux les données de l'agence de développement digitale" you take just "développement".
|
115 |
+
# Returns :
|
116 |
+
# - string : the output as returned from the function in french , includes the link to all the data about the keyword along with an example.
|
117 |
+
# """,
|
118 |
+
# )
|
119 |
+
|
120 |
+
def translate(query: str) -> str:
|
121 |
+
translated = trans.invoke({"input": query})
|
122 |
+
return translated
|
123 |
+
|
124 |
+
translate_text = StructuredTool.from_function(
|
125 |
+
func=translate,
|
126 |
+
description= """
|
127 |
+
Translate from any language to french. Don't use it if the text is already in french. Use it only with the function request_data don't use it with the other tools
|
128 |
+
|
129 |
+
Parameters :
|
130 |
+
- query (string) : the same input as the user input no more no less only if it isnt in french already.
|
131 |
+
Returns :
|
132 |
+
- string : isolate just the translated text in french with no other useless words.
|
133 |
+
""",
|
134 |
+
)
|
135 |
+
|
136 |
+
|
137 |
+
|
138 |
+
# template = '''Answer the following questions as best you can. You have access to the following tools:
|
139 |
+
|
140 |
+
# {tools}
|
141 |
+
|
142 |
+
# Use the following format:
|
143 |
+
|
144 |
+
# Question: the input question you must answer and must be in french if not translate it in french
|
145 |
+
# Thought: you should always think about what to do
|
146 |
+
# Action: the action to take, should be one of [{tool_names}]
|
147 |
+
# Action Input: the input to the action
|
148 |
+
# Observation: the result of the action, don't include /nObservation in the end of each observation just what you observed
|
149 |
+
# ... (this Thought/Action/Action Input/Observation can repeat N times)
|
150 |
+
# Thought: I now know the final answer
|
151 |
+
# Final Answer: the final answer to the original input question and must always be in french no matter what.
|
152 |
+
|
153 |
+
# Begin!
|
154 |
+
|
155 |
+
# Question: {input}
|
156 |
+
# Thought:{agent_scratchpad}'''
|
157 |
+
|
158 |
+
# prompt_2 = PromptTemplate.from_template(template)
|
159 |
+
|
160 |
+
tools_add = [
|
161 |
+
qa_faq,
|
162 |
+
fetch_data,
|
163 |
+
analyze_data,
|
164 |
+
translate_text,
|
165 |
+
]
|
166 |
+
|
167 |
+
agent = create_react_agent(llm=llm, tools=tools_add, prompt=prompt)
|
168 |
+
|
169 |
+
agent_executor = AgentExecutor(
|
170 |
+
agent=agent,
|
171 |
+
tools=tools_add,
|
172 |
+
verbose=True,
|
173 |
+
max_iterations = 10,
|
174 |
+
handle_parsing_errors=True,
|
175 |
+
#max_execution_time = 45, optionel mais useful dans le deployement
|
176 |
+
|
177 |
+
)
|
178 |
+
|
179 |
+
def data_gov_ma(message, history = []):
|
180 |
+
try:
|
181 |
+
response = agent_executor.invoke({"input": message})
|
182 |
+
final_response = response['output']
|
183 |
+
timeout_iteration_error = 'Agent stopped due to iteration limit or time limit.'
|
184 |
+
if final_response == timeout_iteration_error:
|
185 |
+
return Generate(text="Je suis désolé, je n'ai pas compris votre question.Pourriez-vous la reformuler s'il vous plaît ?")
|
186 |
+
else:
|
187 |
+
return Generate(text=final_response)
|
188 |
+
except ValueError as e:
|
189 |
+
return Generate(text="Je suis désolé, je n'ai pas compris votre question.Pourriez-vous la reformuler s'il vous plaît ?")
|
190 |
+
|
191 |
+
app.add_middleware(
|
192 |
+
CORSMiddleware,
|
193 |
+
allow_origins=["*"],
|
194 |
+
allow_credentials=True,
|
195 |
+
allow_methods=["*"],
|
196 |
+
allow_headers=["*"],
|
197 |
+
)
|
198 |
+
|
199 |
+
@app.get("/", tags=["Home"])
|
200 |
+
def api_home():
|
201 |
+
return {'detail': 'Welcome to FastAPI TextGen Tutorial!'}
|
202 |
+
|
203 |
+
@app.post("/api/generate", summary="Generate text from prompt", tags=["Generate"], response_model=Generate)
|
204 |
+
def inference(input_prompt: str):
|
205 |
+
return data_gov_ma(message=input_prompt)
|
206 |
+
|
207 |
+
|
208 |
+
|
data_process.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
from bs4 import BeautifulSoup
|
3 |
+
import requests
|
4 |
+
|
5 |
+
def nettoyer_string(mot):
|
6 |
+
mot_non_special = re.sub(r'[^\w\sÀ-ÿ]' , '', mot)
|
7 |
+
mot_ns_ne = re.sub(r'\s+', ' ', mot_non_special)
|
8 |
+
mot_final = mot_ns_ne.strip()
|
9 |
+
|
10 |
+
|
11 |
+
return mot_final
|
12 |
+
|
13 |
+
|
14 |
+
def chercher_data(mot,titles = [], links = [] ):
|
15 |
+
response = requests.get("https://data.gov.ma/data/fr/dataset", params={'q': mot})
|
16 |
+
if response.status_code != 200:
|
17 |
+
return titles, links, response.url, 0
|
18 |
+
soup = BeautifulSoup(response.text, features="lxml")
|
19 |
+
nb_text = soup.find('h1').text
|
20 |
+
nombre_don = re.findall(r'\d+', nb_text)
|
21 |
+
media = soup.find('ul', class_='dataset-list list-unstyled')
|
22 |
+
if media:
|
23 |
+
thm = media.find_all('li', class_ = 'dataset-item')
|
24 |
+
for m in thm:
|
25 |
+
link = m.find('a')['href']
|
26 |
+
links.append('https://data.gov.ma' + link)
|
27 |
+
title = m.find('h2').text.strip()
|
28 |
+
titles.append(title)
|
29 |
+
else:
|
30 |
+
return titles, links, response.url, 0
|
31 |
+
|
32 |
+
if not titles:
|
33 |
+
return titles, links, response.url, 0
|
34 |
+
|
35 |
+
return titles, links ,response.url, nombre_don[0]
|
36 |
+
|
37 |
+
|
38 |
+
def format_reponse(data):
|
39 |
+
if len(data[0]) == 1:
|
40 |
+
response = f"Ici le lien vers la donnée correspondant au mot recherché : {data[-2]}\n"
|
41 |
+
response += f"Voici le seul résultat trouvé :\n"
|
42 |
+
response += f"Titre : {data[0][0]}\n"
|
43 |
+
response += f"Lien : {data[1][0]}\n"
|
44 |
+
return response
|
45 |
+
else:
|
46 |
+
response = f"Ici le lien vers toutes les {data[-1]} données correspondant au mot recherché : {data[-2]}\n"
|
47 |
+
response += f"Voici un exemple parmi les résultats trouvés :\n"
|
48 |
+
response += f"Titre : {data[0][-1]}\n"
|
49 |
+
response += f"Lien : {data[1][-1]}\n"
|
50 |
+
return response
|
document_scrapped.py
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
from bs4 import BeautifulSoup
|
3 |
+
import requests
|
4 |
+
import json
|
5 |
+
import io
|
6 |
+
import fitz
|
7 |
+
from pptx import Presentation
|
8 |
+
from io import BytesIO
|
9 |
+
import chardet
|
10 |
+
from docx import Document
|
11 |
+
import pandas as pd
|
12 |
+
from sumarize import summarize
|
13 |
+
from io import BytesIO
|
14 |
+
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
|
15 |
+
from pdfminer.converter import TextConverter
|
16 |
+
from io import StringIO
|
17 |
+
from pdfminer.layout import LAParams
|
18 |
+
from pdfminer.pdfpage import PDFPage
|
19 |
+
|
20 |
+
def trim_input_words(input_str, max_new_tokens = 512, max_total_tokens=32768):
|
21 |
+
words = input_str.split()
|
22 |
+
max_input_tokens = max_total_tokens - max_new_tokens
|
23 |
+
|
24 |
+
if len(words) > max_input_tokens - 100:
|
25 |
+
words = words[:max_input_tokens]
|
26 |
+
trimmed_input_str = ' '.join(words)
|
27 |
+
|
28 |
+
return trimmed_input_str
|
29 |
+
|
30 |
+
def select_words_until_char_limit(s, char_limit):
|
31 |
+
s_no_punct = re.sub(r'[^\w\s]', '', s) # remove punctuation, but leave spaces
|
32 |
+
words = s_no_punct.split()
|
33 |
+
selected_words = []
|
34 |
+
total_chars = 0
|
35 |
+
for word in words:
|
36 |
+
if total_chars + len(word) + 1 <= char_limit:
|
37 |
+
selected_words.append(word)
|
38 |
+
total_chars += len(word) + 1 # add 1 for the space
|
39 |
+
else:
|
40 |
+
break
|
41 |
+
f = trim_input_words(' '.join(selected_words))
|
42 |
+
return f
|
43 |
+
|
44 |
+
|
45 |
+
|
46 |
+
def downl(url):
|
47 |
+
try:
|
48 |
+
rq = requests.get(url)
|
49 |
+
if rq.status_code != 200:
|
50 |
+
return ""
|
51 |
+
bs = BeautifulSoup(rq.text, features='lxml')
|
52 |
+
lis = bs.find_all('ul', class_='dropdown-menu')[-1].find_all('li')
|
53 |
+
link = lis[-1].find('a').get('href')
|
54 |
+
print(link)
|
55 |
+
return link
|
56 |
+
except Exception as e:
|
57 |
+
return ""
|
58 |
+
|
59 |
+
|
60 |
+
def pdf(url):
|
61 |
+
# Download the PDF content
|
62 |
+
response = requests.get(url)
|
63 |
+
pdf_content = response.content
|
64 |
+
|
65 |
+
# Convert the bytes object to a file-like object
|
66 |
+
pdf_file = BytesIO(pdf_content)
|
67 |
+
|
68 |
+
# Extract text from the downloaded PDF content
|
69 |
+
resource_manager = PDFResourceManager()
|
70 |
+
fake_file_handle = StringIO()
|
71 |
+
converter = TextConverter(resource_manager, fake_file_handle, laparams=LAParams())
|
72 |
+
page_interpreter = PDFPageInterpreter(resource_manager, converter)
|
73 |
+
|
74 |
+
for page in PDFPage.get_pages(pdf_file):
|
75 |
+
page_interpreter.process_page(page)
|
76 |
+
|
77 |
+
text = fake_file_handle.getvalue()
|
78 |
+
f = select_words_until_char_limit(text, 30000)
|
79 |
+
converter.close()
|
80 |
+
fake_file_handle.close()
|
81 |
+
return f
|
82 |
+
|
83 |
+
|
84 |
+
def excel(link : str) -> str:
|
85 |
+
try:
|
86 |
+
response = requests.get(link)
|
87 |
+
if response.status_code == 200:
|
88 |
+
file_content = response.content
|
89 |
+
df = pd.read_excel(BytesIO(file_content))
|
90 |
+
if df.shape[0] > 50:
|
91 |
+
sample_size = 50
|
92 |
+
sample_df = df.sample(n=sample_size, random_state=42)
|
93 |
+
else:
|
94 |
+
sample_df = df
|
95 |
+
json_data = sample_df.to_json(orient='records')
|
96 |
+
js = json.loads(json_data)
|
97 |
+
rs = select_words_until_char_limit(f"{js}", 32000)
|
98 |
+
return rs
|
99 |
+
else:
|
100 |
+
print("Failed to download file")
|
101 |
+
return "No dat avaible error"
|
102 |
+
except Exception as e:
|
103 |
+
print(e)
|
104 |
+
return "No data avaible"
|
105 |
+
|
106 |
+
|
107 |
+
def csv(link : str) -> str:
|
108 |
+
try:
|
109 |
+
response = requests.get(link)
|
110 |
+
|
111 |
+
if response.status_code == 200:
|
112 |
+
file_content = response.content
|
113 |
+
detected_encoding = chardet.detect(file_content)['encoding']
|
114 |
+
df = pd.read_csv(io.BytesIO(file_content), encoding=detected_encoding, sep=';')
|
115 |
+
if df.empty:
|
116 |
+
print("The DataFrame is empty.")
|
117 |
+
return 'The data frame is empty'
|
118 |
+
|
119 |
+
if df.shape[0] > 50:
|
120 |
+
sample_size = 50
|
121 |
+
sample_df = df.sample(n=sample_size, random_state=42)
|
122 |
+
else:
|
123 |
+
sample_df = df
|
124 |
+
|
125 |
+
json_data = sample_df.to_json(orient='records')
|
126 |
+
js = json.loads(json_data)
|
127 |
+
rs = select_words_until_char_limit(f"{js}", 32000)
|
128 |
+
return rs
|
129 |
+
|
130 |
+
except Exception as e:
|
131 |
+
return 'No data avaible'
|
132 |
+
|
133 |
+
|
134 |
+
def docx(url : str) -> str:
|
135 |
+
try:
|
136 |
+
response = requests.get(url)
|
137 |
+
response.raise_for_status() # Ensure we notice bad responses
|
138 |
+
|
139 |
+
# Read the .docx file
|
140 |
+
file_stream = io.BytesIO(response.content)
|
141 |
+
doc = Document(file_stream)
|
142 |
+
|
143 |
+
# Extract text
|
144 |
+
full_text = []
|
145 |
+
for para in doc.paragraphs:
|
146 |
+
full_text.append(para.text)
|
147 |
+
|
148 |
+
f = "\n".join(full_text)
|
149 |
+
n = select_words_until_char_limit(f, 32000)
|
150 |
+
return n
|
151 |
+
except Exception as e:
|
152 |
+
print(f"An error occurred: {e}")
|
153 |
+
return 'No data avaible'
|
154 |
+
|
155 |
+
|
156 |
+
|
157 |
+
|
158 |
+
def pptx(url : str) -> str:
|
159 |
+
try:
|
160 |
+
response = requests.get(url)
|
161 |
+
response.raise_for_status()
|
162 |
+
|
163 |
+
# Read the .pptx file
|
164 |
+
file_stream = io.BytesIO(response.content)
|
165 |
+
presentation = Presentation(file_stream)
|
166 |
+
|
167 |
+
# Extract text
|
168 |
+
full_text = []
|
169 |
+
for slide in presentation.slides:
|
170 |
+
for shape in slide.shapes:
|
171 |
+
if hasattr(shape, "text"):
|
172 |
+
full_text.append(shape.text)
|
173 |
+
|
174 |
+
g = "\n".join(full_text)
|
175 |
+
c = select_words_until_char_limit(g, 32000)
|
176 |
+
return c
|
177 |
+
except Exception as e:
|
178 |
+
print(f"An error occurred: {e}")
|
179 |
+
return 'No data avaible'
|
180 |
+
|
181 |
+
def get_data(url):
|
182 |
+
ki = url.replace('\nObservation', '').replace('"\nObservation', '')
|
183 |
+
jo = downl(ki)
|
184 |
+
ext = jo.split(".")[-1]
|
185 |
+
if ext == 'xlsx' or ext == 'xls' or ext == 'xlsm':
|
186 |
+
rs = excel(jo)
|
187 |
+
return summarize.invoke({"input":rs})
|
188 |
+
elif ext == 'pdf':
|
189 |
+
rs = pdf(jo)
|
190 |
+
return summarize.invoke({"input":rs})
|
191 |
+
elif ext == 'docx':
|
192 |
+
rs = docx(jo)
|
193 |
+
return summarize.invoke({"input":rs})
|
194 |
+
elif ext == 'csv':
|
195 |
+
rs = csv(jo)
|
196 |
+
return summarize.invoke({"input":rs})
|
197 |
+
elif ext == 'pptx' or ext == 'ppt':
|
198 |
+
rs = pptx(jo)
|
199 |
+
return summarize.invoke({"input":rs})
|
200 |
+
elif ext == 'doc':
|
201 |
+
return "L'extension .doc non supportée."
|
202 |
+
return "No data returned"
|
intents_v2.txt
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
"Bonjour! Comment puis-je vous aider aujourd'hui?",
|
3 |
+
|
4 |
+
"Au revoir! N'hesitez pas a revenir si vous avez d'autres questions.",
|
5 |
+
|
6 |
+
"Le portail www.data.gov.ma, qui a été initialement lancé en 2011 par le Ministère de l’Industrie, du Commerce et de l’Economie Numérique, est actuellement géré par l’Agence de Développement du Digital.",
|
7 |
+
|
8 |
+
"Vous etes le bienvenu! Avez-vous besoin d'aide avec autre chose?",
|
9 |
+
|
10 |
+
"Bien sûr, voici le lien vers la page contenant les liens utiles : https://data.gov.ma/fr/liens-utiles . Vous y trouverez une sélection de ressources pertinentes pour répondre à vos besoins. Si vous avez d'autres questions, n'hésitez pas à demander !",
|
11 |
+
|
12 |
+
"Vous pouvez nous trouver sur LinkedIn : https://www.linkedin.com/company/agence-de-developpement-du-digital/. Suivez notre page pour rester informé de nos dernières actualités et opportunités professionnelles.",
|
13 |
+
|
14 |
+
"Notre agence est située à l'adresse suivante : Espace les Lauriers aile B, angle des Avenues Ennakhil et Mehdi Ben Barka, Hay Ryad - Rabat. Si vous souhaitez nous rendre visite ou avoir des indications pour venir, n'hésitez pas à nous contacter.",
|
15 |
+
|
16 |
+
"Vous pouvez nous contacter par téléphone au : +212 (0) 5 37 56 93 00. Notre équipe est disponible pour répondre à vos questions et vous fournir toute l'aide nécessaire. N'hésitez pas à nous appeler si vous avez besoin d'assistance supplémentaire.",
|
17 |
+
|
18 |
+
"Bien entendu ! Vous pouvez nous contacter par e-mail à l'adresse suivante : [email protected] . Si vous avez des questions, des suggestions ou besoin d'assistance, n'hésitez pas à nous écrire. Nous serons heureux de vous aider !",
|
19 |
+
|
20 |
+
"Absolument ! Pour rester au courant des actualités et des nouveaux événements, vous pouvez consulter la rubrique "Actualités" sur notre site web. Vous y trouverez toutes les informations récentes sur nos activités, événements à venir, et autres nouvelles importantes. Cliquez sur ce lien pour y accéder : https://data.gov.ma/fr/actualites. Si vous avez d'autres questions, n'hésitez pas à demander !",
|
21 |
+
|
22 |
+
"Bien sûr ! Pour obtenir des statistiques telles que le nombre de données disponibles, les tendances récentes, ou d'autres informations statistiques, vous pouvez consulter la rubrique "Statistiques" sur notre site web. Vous y trouverez des données actualisées et des analyses pertinentes. Cliquez sur ce lien pour y accéder : https://data.gov.ma/index.php/fr/node/7. Si vous avez besoin de plus de détails ou avez d'autres questions, n'hésitez pas à demander !",
|
23 |
+
|
24 |
+
"Ce document a pour but la gestion d’un inventaire de données ouvertes au sein de leurs structures respectives. Vous pouvez le consulter ici : https://www.data.gov.ma/sites/default/files/2023-03/guide_inventaire_1.3_Fev.%202023.pdf",
|
25 |
+
|
26 |
+
"Ce manuel est divisé en trois parties. La première partie présente les concepts clés de l’Open Data, la deuxième partie présente le cycle de vie de la donnée, et enfin la troisième partie présente les fonctions et activités du Responsable Open Data. Vous pouvez le telecharger ici : https://data.gov.ma/sites/default/files/docs/Open_data_manuel_ROD_Avril%202021.pdf",
|
27 |
+
|
28 |
+
"Ce document est un manuel à destination des Gestionnaires de Données (GdD) au sein des structures publiques. Vous pouvez le telecharger ici : https://data.gov.ma/sites/default/files/docs/Open_data_manuel_GgD%20_vf_Avril%202021.pdf",
|
29 |
+
|
30 |
+
"Bien sûr ! Nous avons organisé plusieurs ateliers et nous disposons de présentations que vous pouvez consulter. Vous pouvez trouver ces présentations dans ce lien dans la rubrique Supports de sensibilisation et formation : https://data.gov.ma/index.php/fr/documentations. Si vous avez des questions ou besoin de plus d'informations, n'hésitez pas à demander !",
|
31 |
+
|
32 |
+
"Les donnees gouvernementales ouvertes, egalement connues sous le nom d'Open Government Data, sont des donnees accessibles a tous, librement utilisables, modifiables et partageables sans restrictions techniques ou legales. Elles sont publiees dans un format techniquement ouvert, tel que CSV ou TXT, permettant une utilisation facile par les programmes informatiques. De plus, elles sont accompagnees d'une licence ouverte qui autorise leur reutilisation a des fins commerciales et non commerciales, tout en preservant la provenance et l'accessibilite des informations."
|
33 |
+
|
34 |
+
"Bienvenue sur data.gov.ma! Le site est organise en categories de donnees, une barre de recherche et des sections pour les dernieres mises a jour. Commencez par explorer les categories.",
|
35 |
+
|
36 |
+
"Les informations à caractère personnel qui sont demandées à l’utilisateur via ce portail, sont nécessaires au traitement de sa demande. Les informations à caractère personnelles fournies, sont protégées conformément à la loi n°09-08 relative à la protection des personnes physiques à l'égard du traitement des données à caractère personnel."
|
37 |
+
|
38 |
+
"Votre avis est precieux pour nous! Vous pouvez soumettre vos commentaires ou suggestions via le formulaire de contact sur notre site."
|
39 |
+
|
40 |
+
"Vous pouvez acceder et telecharger des jeux de donnees publiques directement depuis notre site. Utilisez la barre de recherche ou parcourez les categories pour trouver ce dont vous avez besoin."
|
41 |
+
|
42 |
+
"Nous sommes desoles d'apprendre que vous rencontrez des problemes. Veuillez utiliser notre formulaire de contact pour signaler tout probleme ou erreur sur le site.",
|
43 |
+
|
44 |
+
"Vous êtes libres de partager, de créer et d'adapter la base de données selon les conditions de la licence spécifiée. Cela signifie que vous pouvez copier, distribuer et utiliser la base de données, produire des créations à partir de celle-ci, et modifier, transformer et construire à partir de la base de données. Pour plus d'informations, veuillez consulter ce lein : https://data.gov.ma/fr/node/14"
|
45 |
+
|
46 |
+
"Votre enthousiasme a contribuer est tres apprecie! Vous pouvez participer en soumettant vos propres jeux de donnees via notre formulaire de soumission : https://data.gov.ma/node/add/feedback. N'oubliez pas de consulter les criteres de contribution.",
|
47 |
+
|
48 |
+
"Nous nous engageons a maintenir nos donnees a jour. Les frequences de mise a jour peuvent varier selon les datasets. Verifiez la section 'derniere mise a jour' pour chaque jeu de donnees."
|
49 |
+
|
50 |
+
"Si vous rencontrez des problemes techniques, n'hesitez pas a contacter notre support technique à travers les adresses de contact ici : https://data.gov.ma/fr/contact. Nous sommes la pour vous aider."
|
51 |
+
|
52 |
+
"Vous pouvez consulter nos conditions d'utilisation et mentions légales sur cette page : https://data.gov.ma/fr/node/13. Ces documents fournissent des informations importantes sur l'utilisation de nos services et les dispositions légales. Si vous avez des questions supplémentaires, n'hésitez pas à nous contacter."
|
53 |
+
|
54 |
+
"L'Open Data vise a promouvoir la reutilisation des donnees publiques pour divers usages tels que repondre a des questions, prendre des decisions importantes, beneficier de services quotidiens, ou encourager la transparence des institutions. Le portail data.gov.ma est destine aux producteurs de donnees desireux de les publier de maniere ouverte, aux reutilisateurs souhaitant partager leurs travaux bases sur ces donnees, et a toute personne, association ou entreprise interessee par l'exploration et l'utilisation des donnees disponibles."
|
55 |
+
"Les producteurs disponibles sont : ADD, Agence du Bassin Hydraulique de Souss Massa,
|
56 |
+
Agence Urbaine Safi - Youssoufia, ANRT, Archives du Maroc, Autorité de
|
57 |
+
Contrôle des Assurances et de la Prévoyance Sociale, Bank Al-Maghrib,
|
58 |
+
Centre Régional d'Investissement Drâa Tafilalet, Centre Régional
|
59 |
+
d'Investissement Souss Massa, Chambre de Commerce, d’Industrie et de
|
60 |
+
Services de la Région Marrakech – Safi (CCISRMS), CMR, CNOPS, CNSS,
|
61 |
+
Département de l'Agriculture, Département de la Pêche Maritime, Fondation
|
62 |
+
Nationale des Musées, HCP, IMANOR, INPPLC, MAECAMRE, MATNUHPV, MEF,
|
63 |
+
MENPS, MESRSI, MIC, MIEPEEC, Ministère de l'Equipement et de l'Eau, MJ,
|
64 |
+
MJCC, MSPS, MTAESS, MTNRA, Parlement, Poste Maroc, Région Béni MellalKhénifra, Région Souss Massa, Région Tanger-Tétouan-Al Hoceima, SOREAD
|
65 |
+
2M"
|
66 |
+
|
67 |
+
"Les thèmes possibles sont: agriculture, assurance, cartographie, culture,
|
68 |
+
economie et finance, education, emploi, equipement, habitat et urbanisme,
|
69 |
+
it & télécoms, justice, média, normalisation, pêche maritime, recherche
|
70 |
+
et développement, santé, société, tourisme, transparence."
|
key_extract.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain.prompts.prompt import PromptTemplate
|
2 |
+
from langchain_community.llms import HuggingFaceEndpoint
|
3 |
+
#from langchain.chains import LLMChain
|
4 |
+
from langchain_core.output_parsers import StrOutputParser
|
5 |
+
from qa_txt import llm
|
6 |
+
# llm = HuggingFaceEndpoint(
|
7 |
+
# repo_id='mistralai/Mixtral-8x7B-Instruct-v0.1',
|
8 |
+
# temperature = 0.2,
|
9 |
+
# max_new_tokens = 10,
|
10 |
+
# top_k = 30,
|
11 |
+
# load_in_8bit = True,
|
12 |
+
# )
|
13 |
+
|
14 |
+
template = """
|
15 |
+
|
16 |
+
Vous êtes un Système d'Extraction de Mots-Clés personnalisé pour une utilisation dans un environnement WhatsApp Business. Son rôle consiste à reconnaître et isoler les mots-clés cruciaux contenus dans les demandes des utilisateurs. Il est impératif de garantir que la sortie comporte exactement un mot français, sans aucun contexte supplémentaire ni texte explicatif. Cette conformité aux directives permettra une compatibilité avec les fonctions subséquentes, telles que la recherche de sites Web contenant des sources de données publiques à l'aide du mot-clé fourni. De plus, veuillez extraire les mots-clés sous forme d'abréviations, tels que CNSS, MIC, ADD...
|
17 |
+
Current conversation:
|
18 |
+
Human: {input}
|
19 |
+
AI Assistant:"""
|
20 |
+
|
21 |
+
prompt = PromptTemplate(input_variables=['input'], template = template)
|
22 |
+
chain = prompt | llm | StrOutputParser()
|
23 |
+
|
24 |
+
|
qa_txt.py
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# from langchain_community.document_loaders import TextLoader
|
2 |
+
# from langchain.text_splitter import RecursiveCharacterTextSplitter, CharacterTextSplitter
|
3 |
+
# from langchain.chains import ConversationalRetrievalChain
|
4 |
+
|
5 |
+
from langchain_community.embeddings import HuggingFaceEmbeddings
|
6 |
+
# from langchain_community.llms import HuggingFaceEndpoint
|
7 |
+
from langchain.prompts.prompt import PromptTemplate
|
8 |
+
# from pathlib import Path
|
9 |
+
from langchain_core.output_parsers import StrOutputParser
|
10 |
+
from unidecode import unidecode
|
11 |
+
# # import tqdm
|
12 |
+
# from langchain_community.vectorstores import FAISS
|
13 |
+
from langchain_huggingface import HuggingFaceEndpoint
|
14 |
+
import os
|
15 |
+
# import accelerate
|
16 |
+
|
17 |
+
# c_splitter = CharacterTextSplitter(
|
18 |
+
|
19 |
+
# chunk_size = 350,
|
20 |
+
# chunk_overlap = 4,
|
21 |
+
# separator = """,
|
22 |
+
# ]""",
|
23 |
+
|
24 |
+
# )
|
25 |
+
|
26 |
+
# def load_doc(file_path):
|
27 |
+
# loader = TextLoader(file_path)
|
28 |
+
# pages = loader.load()
|
29 |
+
# text_splitter = c_splitter
|
30 |
+
# doc_splits = text_splitter.split_documents(pages)
|
31 |
+
# return doc_splits
|
32 |
+
|
33 |
+
huggingfacehub_api_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
|
34 |
+
|
35 |
+
llm = HuggingFaceEndpoint(
|
36 |
+
repo_id='mistralai/Mixtral-8x7B-Instruct-v0.1',
|
37 |
+
temperature = 0.17,
|
38 |
+
max_new_tokens = 512,
|
39 |
+
top_k = 30,
|
40 |
+
huggingfacehub_api_token = huggingfacehub_api_token,
|
41 |
+
add_to_git_credential=True,
|
42 |
+
)
|
43 |
+
|
44 |
+
# def process_data():
|
45 |
+
# splt = load_doc('intents_v2.txt')
|
46 |
+
# embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
|
47 |
+
# db = FAISS.from_documents(splt, embeddings)
|
48 |
+
# return db
|
49 |
+
|
50 |
+
# db = process_data()
|
51 |
+
|
52 |
+
|
53 |
+
prompt = """You are an Assistant with expertise in providing answers based on provided information about a specific website. The user will present a general question related to the site, and using the available data, you should formulate an accurate and helpful answer. Your role includes web data comprehension, question interpretation, and clear communication. Remember to tailor your responses according to the context presented by the user and the details extracted from the pertinent website."
|
54 |
+
|
55 |
+
For a more detailed breakdown, consider these elements:
|
56 |
+
|
57 |
+
Role: Website Information Assistant
|
58 |
+
|
59 |
+
Skills: Web Data Comprehension, Question Interpretation, Clear Communication
|
60 |
+
|
61 |
+
Context: User presents a general question related to a particular website; you provide an accurate and helpful answer utilizing available data.
|
62 |
+
|
63 |
+
Task: Analyze user questions, understand associated web data, and construct appropriate answers.
|
64 |
+
|
65 |
+
Steps:
|
66 |
+
|
67 |
+
Acknowledge the user's question and express understanding.
|
68 |
+
Identify keywords or concepts within the question that relate to the website data.
|
69 |
+
Search through the available data to locate relevant facts or explanations.
|
70 |
+
Formulate a concise and engaging response addressing the user's query.
|
71 |
+
Validate the accuracy and relevancy of the generated answer before delivering it.
|
72 |
+
Answer Characteristics: Accurate, well-structured, easy to comprehend, directly addresses the user's question.
|
73 |
+
Here is the website informations : {document}
|
74 |
+
Human: {input}
|
75 |
+
AI Assistant:
|
76 |
+
"""
|
77 |
+
|
78 |
+
prompt_2 = PromptTemplate(input_variables=['input', 'document'], template = prompt)
|
79 |
+
conversation_chain = prompt_2 | llm | StrOutputParser()
|
80 |
+
# Set up a conversational chain to retrieve and generate responses.
|
81 |
+
# conversation_chain = ConversationalRetrievalChain.from_llm(
|
82 |
+
# llm=llm,
|
83 |
+
# retriever=db.as_retriever(),
|
84 |
+
# condense_question_prompt=PromptTemplate(input_variables=['input'], template=prompt),
|
85 |
+
# )
|
86 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
langchain
|
2 |
+
unidecode
|
3 |
+
requests
|
4 |
+
bs4
|
5 |
+
pandas
|
6 |
+
lxml
|
7 |
+
langchainhub
|
8 |
+
langchain_community
|
9 |
+
langchain-huggingface
|
10 |
+
python-pptx
|
11 |
+
PyMuPDF
|
12 |
+
python-docx
|
13 |
+
docx
|
14 |
+
pdfminer.six
|
15 |
+
chardet
|
16 |
+
openpyxl
|
17 |
+
fastapi==0.99.1
|
18 |
+
uvicorn
|
19 |
+
pydantic==1.10.12
|
sumarize.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain_core.output_parsers import StrOutputParser
|
2 |
+
from qa_txt import llm
|
3 |
+
from langchain_core.prompts import PromptTemplate
|
4 |
+
|
5 |
+
temp = """
|
6 |
+
Je te fournirai des données pertinentes. Ton objectif sera de générer un bref résumé de ces données et de proposer une légère analyse qui mettra en évidence certains points clés.
|
7 |
+
|
8 |
+
Suis ces étapes pour accomplir ta tâche:
|
9 |
+
|
10 |
+
Examine le fichier et identifie la nature des données.
|
11 |
+
Rédige un court paragraphe présentant les principales tendances et idées découlant des données.
|
12 |
+
Identifie quelques faits marquants ou statistiques importantes susceptibles d'intéresser l'audience.
|
13 |
+
Propose des pistes d'analyse complémentaire pouvant être développées ultérieurement.
|
14 |
+
Les caractéristiques de l'output souhaité sont les suivantes:
|
15 |
+
|
16 |
+
Un texte concis et clair, présentant les grandes lignes des données du fichier.
|
17 |
+
Une sélection des aspects les plus intrigants ou significatifs de ces données.
|
18 |
+
Des suggestions pour creuser davantage certaines observations et interprétations.
|
19 |
+
Si tout semble correct selon toi, tu peux maintenant démarrer!
|
20 |
+
|
21 |
+
Human : {input}
|
22 |
+
AI : """
|
23 |
+
|
24 |
+
pro= PromptTemplate(input_variables=['input'], template = temp)
|
25 |
+
summarize = pro | llm | StrOutputParser()
|
trans.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain.prompts.prompt import PromptTemplate
|
2 |
+
from langchain_community.llms import HuggingFaceEndpoint
|
3 |
+
from langchain_core.output_parsers import StrOutputParser
|
4 |
+
from qa_txt import llm
|
5 |
+
|
6 |
+
template_v2 = """
|
7 |
+
Vous êtes un traducteur automatique doté de capacités de reconnaissance linguistique avancées. Mon contexte est que je veux faire traduire des phrases dans diverses langues en français, en utilisant uniquement les mêmes mots que dans l'entrée initiale et en affichant une traduction simple. Veuillez effectuer la traduction comme suit : écouter la phrase entrée > identifier la langue source > traduire le texte en français > présenter exclusivement le texte traduit en sortie. Les caractéristiques du résultat attendu sont une sortie stricte aux seuls termes traduits, sans modification ni addition de mots.
|
8 |
+
Current conversation:
|
9 |
+
Human: {input}
|
10 |
+
AI Assistant: Here is the transltion in french
|
11 |
+
"""
|
12 |
+
|
13 |
+
prompt = PromptTemplate(input_variables=['input'], template = template_v2)
|
14 |
+
trans = prompt | llm | StrOutputParser()
|