DanielDJ1987 commited on
Commit
225f551
·
verified ·
1 Parent(s): 0356da3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +193 -0
app.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from pathlib import Path
3
+ import pickle
4
+
5
+ import streamlit as st
6
+ import openai
7
+ from unidecode import unidecode
8
+
9
+ PASTA_CONFIGURACOES = Path(__file__).parent / 'configuracoes'
10
+ PASTA_CONFIGURACOES.mkdir(exist_ok=True)
11
+ PASTA_MENSAGENS = Path(__file__).parent / 'mensagens'
12
+ PASTA_MENSAGENS.mkdir(exist_ok=True)
13
+ CACHE_DESCONVERTE = {}
14
+
15
+ # API OPENAI ================================================
16
+ def retorna_resposta_modelo(mensagens,
17
+ openai_key,
18
+ modelo='gpt-4o-mini',
19
+ temperatura=0,
20
+ stream=False):
21
+ openai.api_key = openai_key
22
+ response = openai.ChatCompletion.create(
23
+ model=modelo,
24
+ messages=mensagens,
25
+ temperature=temperatura,
26
+ stream=stream
27
+ )
28
+ return response
29
+
30
+ # SALVAMENTO E LEITURA DE CONVERSAS ========================
31
+
32
+ def converte_nome_mensagem(nome_mensagem):
33
+ nome_arquivo = unidecode(nome_mensagem)
34
+ nome_arquivo = re.sub('\\W+', '', nome_arquivo).lower()
35
+ return nome_arquivo
36
+
37
+ def desconverte_nome_mensagem(nome_arquivo):
38
+ if not nome_arquivo in CACHE_DESCONVERTE:
39
+ nome_mensagem = ler_mensagem_por_nome_arquivo(nome_arquivo, key='nome_mensagem')
40
+ CACHE_DESCONVERTE[nome_arquivo] = nome_mensagem
41
+ return CACHE_DESCONVERTE[nome_arquivo]
42
+
43
+ def retorna_nome_da_mensagem(mensagens):
44
+ nome_mensagem = ''
45
+ for mensagem in mensagens:
46
+ if mensagem['role'] == 'user':
47
+ nome_mensagem = mensagem['content'][:30]
48
+ break
49
+ return nome_mensagem
50
+
51
+ def salvar_mensagens(mensagens):
52
+ if len(mensagens) == 0:
53
+ return False
54
+ nome_mensagem = retorna_nome_da_mensagem(mensagens)
55
+ nome_arquivo = converte_nome_mensagem(nome_mensagem)
56
+ arquivo_salvar = {'nome_mensagem': nome_mensagem,
57
+ 'nome_arquivo': nome_arquivo,
58
+ 'mensagem': mensagens}
59
+ with open(PASTA_MENSAGENS / nome_arquivo, 'wb') as f:
60
+ pickle.dump(arquivo_salvar, f)
61
+
62
+ def ler_mensagem_por_nome_arquivo(nome_arquivo, key='mensagem'):
63
+ with open(PASTA_MENSAGENS / nome_arquivo, 'rb') as f:
64
+ mensagens = pickle.load(f)
65
+ return mensagens[key]
66
+
67
+ def ler_mensagens(mensagens, key='mensagem'):
68
+ if len(mensagens) == 0:
69
+ return []
70
+ nome_mensagem = retorna_nome_da_mensagem(mensagens)
71
+ nome_arquivo = converte_nome_mensagem(nome_mensagem)
72
+ with open(PASTA_MENSAGENS / nome_arquivo, 'rb') as f:
73
+ mensagens = pickle.load(f)
74
+ return mensagens[key]
75
+
76
+ def listar_conversas():
77
+ conversas = list(PASTA_MENSAGENS.glob('*'))
78
+ conversas = sorted(conversas, key=lambda item: item.stat().st_mtime_ns, reverse=True)
79
+ return [c.stem for c in conversas]
80
+
81
+ # SALVAMENTO E LEITURA DA APIKEY ========================
82
+
83
+ def salva_chave(chave):
84
+ with open(PASTA_CONFIGURACOES / 'chave', 'wb') as f:
85
+ pickle.dump(chave, f)
86
+
87
+ def le_chave():
88
+ if (PASTA_CONFIGURACOES / 'chave').exists():
89
+ with open(PASTA_CONFIGURACOES / 'chave', 'rb') as f:
90
+ return pickle.load(f)
91
+ else:
92
+ return ''
93
+
94
+ # PÁGINAS ==================================================
95
+
96
+ def inicializacao():
97
+ if not 'mensagens' in st.session_state:
98
+ st.session_state.mensagens = []
99
+ if not 'conversa_atual' in st.session_state:
100
+ st.session_state.conversa_atual = ''
101
+ if not 'modelo' in st.session_state:
102
+ st.session_state.modelo = 'gpt-4o-mini'
103
+ if not 'api_key' in st.session_state:
104
+ st.session_state.api_key = le_chave()
105
+
106
+ def pagina_principal():
107
+
108
+ mensagens = ler_mensagens(st.session_state['mensagens'])
109
+
110
+ st.header('🤖 Chatbot', divider=True)
111
+
112
+ for mensagem in mensagens:
113
+ chat = st.chat_message(mensagem['role'])
114
+ chat.markdown(mensagem['content'])
115
+
116
+ prompt = st.chat_input('Fale com o chat')
117
+ if prompt:
118
+ if st.session_state['api_key'] == '':
119
+ st.error('Adicone uma chave de api na aba de configurações')
120
+ else:
121
+ nova_mensagem = {'role': 'user',
122
+ 'content': prompt}
123
+ chat = st.chat_message(nova_mensagem['role'])
124
+ chat.markdown(nova_mensagem['content'])
125
+ mensagens.append(nova_mensagem)
126
+
127
+ chat = st.chat_message('assistant')
128
+ placeholder = chat.empty()
129
+ placeholder.markdown("▌")
130
+ resposta_completa = ''
131
+ respostas = retorna_resposta_modelo(mensagens,
132
+ st.session_state['api_key'],
133
+ modelo=st.session_state['modelo'],
134
+ stream=True)
135
+ for resposta in respostas:
136
+ resposta_completa += resposta.choices[0].delta.get('content', '')
137
+ placeholder.markdown(resposta_completa + "▌")
138
+ placeholder.markdown(resposta_completa)
139
+ nova_mensagem = {'role': 'assistant',
140
+ 'content': resposta_completa}
141
+ mensagens.append(nova_mensagem)
142
+
143
+ st.session_state['mensagens'] = mensagens
144
+ salvar_mensagens(mensagens)
145
+
146
+ def tab_conversas(tab):
147
+
148
+ tab.button('➕ Nova conversa',
149
+ on_click=seleciona_conversa,
150
+ args=('', ),
151
+ use_container_width=True)
152
+ tab.markdown('')
153
+ conversas = listar_conversas()
154
+ for nome_arquivo in conversas:
155
+ nome_mensagem = desconverte_nome_mensagem(nome_arquivo).capitalize()
156
+ if len(nome_mensagem) == 30:
157
+ nome_mensagem += '...'
158
+ tab.button(nome_mensagem,
159
+ on_click=seleciona_conversa,
160
+ args=(nome_arquivo, ),
161
+ disabled=nome_arquivo==st.session_state['conversa_atual'],
162
+ use_container_width=True)
163
+
164
+ def seleciona_conversa(nome_arquivo):
165
+ if nome_arquivo == '':
166
+ st.session_state['mensagens'] = []
167
+ else:
168
+ mensagem = ler_mensagem_por_nome_arquivo(nome_arquivo)
169
+ st.session_state['mensagens'] = mensagem
170
+ st.session_state['conversa_atual'] = nome_arquivo
171
+
172
+ def tab_configuracoes(tab):
173
+ modelo_escolhido = tab.selectbox('Selecione o modelo',
174
+ ['gpt-4o-mini','gpt-3.5-turbo', 'gpt-4'])
175
+ st.session_state['modelo'] = modelo_escolhido
176
+
177
+ chave = tab.text_input('Adicione sua api key', value=st.session_state['api_key'])
178
+ if chave != st.session_state['api_key']:
179
+ st.session_state['api_key'] = chave
180
+ salva_chave(chave)
181
+ tab.success('Chave salva com sucesso')
182
+
183
+ def main():
184
+ inicializacao()
185
+ pagina_principal()
186
+ tab1, tab2 = st.sidebar.tabs(['Conversas', 'Configurações'])
187
+ tab_conversas(tab1)
188
+ tab_configuracoes(tab2)
189
+
190
+
191
+
192
+ if __name__ == '__main__':
193
+ main()