chatgraph 0.2.6__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of chatgraph might be problematic. Click here for more details.
- {chatgraph-0.2.6 → chatgraph-0.3.1}/PKG-INFO +4 -1
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/__init__.py +5 -4
- chatgraph-0.3.1/chatgraph/auth/__pycache__/credentials.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/bot/__pycache__/chatbot_app.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/bot/__pycache__/chatbot_model.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/bot/__pycache__/chatbot_router.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/bot/__pycache__/user_state.cpython-312.pyc +0 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/bot/chatbot_model.py +70 -50
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/bot/chatbot_router.py +4 -0
- chatgraph-0.3.1/chatgraph/error/__pycache__/chatbot_error.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/error/__pycache__/error_handler.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/error/__pycache__/route_error.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/gRPC/__pycache__/gRPCCall.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/gRPC/gRPCCall.py +125 -0
- chatgraph-0.3.1/chatgraph/messages/__pycache__/__init__.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/messages/__pycache__/base_message_consumer.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/messages/__pycache__/message_consumer.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/messages/__pycache__/rabbitMQ_message_consumer.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/messages/__pycache__/test_message_consumer.cpython-312-pytest-8.3.2.pyc +0 -0
- chatgraph-0.2.6/chatgraph/messages/rabbitMQ_message_consumer.py → chatgraph-0.3.1/chatgraph/messages/message_consumer.py +14 -8
- chatgraph-0.3.1/chatgraph/pb/__pycache__/userstate_pb2.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/pb/__pycache__/userstate_pb2_grpc.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/pb/__pycache__/voll_pb2.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/pb/__pycache__/voll_pb2_grpc.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/pb/userstate.proto +29 -0
- chatgraph-0.3.1/chatgraph/pb/userstate_pb2.py +43 -0
- chatgraph-0.3.1/chatgraph/pb/userstate_pb2_grpc.py +226 -0
- chatgraph-0.3.1/chatgraph/pb/voll.proto +32 -0
- chatgraph-0.3.1/chatgraph/pb/voll_pb2.py +43 -0
- chatgraph-0.3.1/chatgraph/pb/voll_pb2_grpc.py +183 -0
- chatgraph-0.3.1/chatgraph/types/__pycache__/message_types.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/types/__pycache__/output_state.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/types/__pycache__/route.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/types/__pycache__/user_state.cpython-312.pyc +0 -0
- chatgraph-0.3.1/chatgraph/types/message_types.py +214 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/types/output_state.py +40 -1
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/types/route.py +7 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/pyproject.toml +4 -1
- chatgraph-0.2.6/chatgraph/messages/base_message_consumer.py +0 -40
- chatgraph-0.2.6/chatgraph/messages/base_message_sender.py +0 -23
- chatgraph-0.2.6/chatgraph/messages/rabbitMQ_message_sender.py +0 -79
- chatgraph-0.2.6/chatgraph/messages/test_message_consumer.py +0 -17
- chatgraph-0.2.6/chatgraph/types/message_types.py +0 -41
- chatgraph-0.2.6/chatgraph/types/user_state.py +0 -98
- {chatgraph-0.2.6 → chatgraph-0.3.1}/LICENSE +0 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/README.md +0 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/auth/credentials.py +0 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/error/chatbot_error.py +0 -0
- {chatgraph-0.2.6 → chatgraph-0.3.1}/chatgraph/error/route_error.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: chatgraph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: A user-friendly chatbot library
|
|
5
5
|
Home-page: https://github.com/irissonnlima/chatgraph
|
|
6
6
|
License: MIT
|
|
@@ -11,7 +11,10 @@ Requires-Python: >=3.12,<4.0
|
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Dist: grpcio (>=1.66.2,<2.0.0)
|
|
15
|
+
Requires-Dist: grpcio-tools (>=1.66.2,<2.0.0)
|
|
14
16
|
Requires-Dist: pika (>=1.3.2,<2.0.0)
|
|
17
|
+
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
|
15
18
|
Requires-Dist: rich (>=13.8.1,<14.0.0)
|
|
16
19
|
Project-URL: Repository, https://github.com/irissonnlima/chatgraph
|
|
17
20
|
Description-Content-Type: text/markdown
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
from .auth.credentials import Credential
|
|
2
2
|
from .bot.chatbot_model import ChatbotApp
|
|
3
3
|
from .bot.chatbot_router import ChatbotRouter
|
|
4
|
-
from .messages.
|
|
5
|
-
from .types.message_types import
|
|
4
|
+
from .messages.message_consumer import MessageConsumer
|
|
5
|
+
from .types.message_types import UserCall, UserState, Element
|
|
6
6
|
from .types.output_state import ChatbotResponse, RedirectResponse, EndChatResponse, TransferToHuman
|
|
7
7
|
from .types.route import Route
|
|
8
8
|
|
|
9
9
|
__all__ = [
|
|
10
10
|
'ChatbotApp',
|
|
11
11
|
'Credential',
|
|
12
|
-
'
|
|
12
|
+
'UserCall',
|
|
13
13
|
'ChatbotRouter',
|
|
14
14
|
'ChatbotResponse',
|
|
15
15
|
'RedirectResponse',
|
|
16
|
-
'
|
|
16
|
+
'MessageConsumer',
|
|
17
17
|
'Route',
|
|
18
18
|
'EndChatResponse',
|
|
19
19
|
'TransferToHuman',
|
|
20
20
|
'UserState',
|
|
21
|
+
'Element',
|
|
21
22
|
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
from abc import ABC
|
|
3
2
|
from functools import wraps
|
|
4
3
|
from logging import debug
|
|
5
4
|
import json
|
|
5
|
+
from logging import error
|
|
6
6
|
|
|
7
7
|
from ..error.chatbot_error import ChatbotError, ChatbotMessageError
|
|
8
|
-
from ..messages.
|
|
9
|
-
from ..types.message_types import
|
|
8
|
+
from ..messages.message_consumer import MessageConsumer
|
|
9
|
+
from ..types.message_types import UserCall
|
|
10
10
|
from ..types.output_state import ChatbotResponse, RedirectResponse, EndChatResponse, TransferToHuman
|
|
11
11
|
from ..types.route import Route
|
|
12
12
|
from .chatbot_router import ChatbotRouter
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
class ChatbotApp
|
|
15
|
+
class ChatbotApp:
|
|
16
16
|
"""
|
|
17
17
|
Classe principal para a aplicação do chatbot, gerencia as rotas e a lógica de processamento de mensagens.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
def __init__(self, message_consumer: MessageConsumer):
|
|
20
|
+
def __init__(self, message_consumer: MessageConsumer = None):
|
|
21
21
|
"""
|
|
22
22
|
Inicializa a classe ChatbotApp com um estado de usuário e um consumidor de mensagens.
|
|
23
23
|
|
|
24
24
|
Args:
|
|
25
25
|
message_consumer (MessageConsumer): O consumidor de mensagens que lida com a entrada de mensagens no sistema.
|
|
26
26
|
"""
|
|
27
|
+
if not message_consumer:
|
|
28
|
+
message_consumer = MessageConsumer.load_dotenv()
|
|
29
|
+
|
|
27
30
|
self.__message_consumer = message_consumer
|
|
28
31
|
self.__routes = {}
|
|
29
32
|
|
|
@@ -101,12 +104,12 @@ class ChatbotApp(ABC):
|
|
|
101
104
|
self.__message_consumer.reprer()
|
|
102
105
|
self.__message_consumer.start_consume(self.process_message)
|
|
103
106
|
|
|
104
|
-
def process_message(self,
|
|
107
|
+
def process_message(self, userCall: UserCall):
|
|
105
108
|
"""
|
|
106
109
|
Processa uma mensagem recebida, identificando a rota correspondente e executando a função associada.
|
|
107
110
|
|
|
108
111
|
Args:
|
|
109
|
-
|
|
112
|
+
userCall (Message): A mensagem a ser processada.
|
|
110
113
|
|
|
111
114
|
Raises:
|
|
112
115
|
ChatbotMessageError: Se nenhuma rota for encontrada para o menu atual do usuário.
|
|
@@ -115,60 +118,51 @@ class ChatbotApp(ABC):
|
|
|
115
118
|
Returns:
|
|
116
119
|
str: A resposta gerada pela função da rota, que pode ser uma mensagem ou o resultado de uma redireção.
|
|
117
120
|
"""
|
|
118
|
-
customer_id =
|
|
119
|
-
|
|
120
|
-
menu =
|
|
121
|
-
|
|
122
|
-
handler = self.__routes.get(
|
|
121
|
+
customer_id = userCall.customer_id
|
|
122
|
+
route = userCall.route.lower()
|
|
123
|
+
menu = userCall.menu.lower()
|
|
124
|
+
obs = userCall.obs
|
|
125
|
+
handler = self.__routes.get(route, None)
|
|
123
126
|
|
|
124
127
|
if not handler:
|
|
125
128
|
raise ChatbotMessageError(
|
|
126
|
-
customer_id, f'Rota não encontrada para {
|
|
129
|
+
customer_id, f'Rota não encontrada para {route}!'
|
|
127
130
|
)
|
|
131
|
+
|
|
128
132
|
func = handler['function']
|
|
129
|
-
|
|
133
|
+
userCall_name = handler['params'].get(UserCall, None)
|
|
130
134
|
route_state_name = handler['params'].get(Route, None)
|
|
131
135
|
|
|
132
136
|
kwargs = dict()
|
|
133
|
-
if
|
|
134
|
-
kwargs[
|
|
137
|
+
if userCall_name:
|
|
138
|
+
kwargs[userCall_name] = userCall
|
|
135
139
|
if route_state_name:
|
|
136
|
-
kwargs[route_state_name] = Route(
|
|
140
|
+
kwargs[route_state_name] = Route(route, list(self.__routes.keys()))
|
|
137
141
|
|
|
138
|
-
|
|
142
|
+
userCall_response = func(**kwargs)
|
|
143
|
+
|
|
144
|
+
if isinstance(userCall_response, (str, float, int)):
|
|
145
|
+
return self.__create_response(userCall_response, customer_id, route, menu, obs)
|
|
146
|
+
|
|
147
|
+
elif isinstance(userCall_response, ChatbotResponse):
|
|
148
|
+
adjusted_route = self.__adjust_route(userCall_response.route, route)
|
|
149
|
+
return self.__create_response(userCall_response.json(), customer_id, adjusted_route, menu, obs)
|
|
150
|
+
|
|
151
|
+
elif isinstance(userCall_response, (EndChatResponse, TransferToHuman)):
|
|
152
|
+
return self.__end_chat_response(userCall_response, customer_id)
|
|
153
|
+
|
|
154
|
+
elif isinstance(userCall_response, RedirectResponse):
|
|
155
|
+
route = self.__adjust_route(userCall_response.route, route)
|
|
156
|
+
userCall.route = route
|
|
157
|
+
return self.process_message(userCall)
|
|
158
|
+
|
|
159
|
+
elif not userCall_response:
|
|
160
|
+
return self.__create_response('', customer_id, None, None, None)
|
|
139
161
|
|
|
140
|
-
if type(message_response) in (str, float, int):
|
|
141
|
-
response = ChatbotResponse(message_response)
|
|
142
|
-
response = message_response.json()
|
|
143
|
-
response['user_state'] = {
|
|
144
|
-
'customer_id': customer_id,
|
|
145
|
-
'menu': menu,
|
|
146
|
-
'obs': user_state.obs,
|
|
147
|
-
}
|
|
148
|
-
return json.dumps(response)
|
|
149
|
-
elif type(message_response) == ChatbotResponse:
|
|
150
|
-
route = self.__adjust_route(message_response.route, menu)
|
|
151
|
-
response = message_response.json()
|
|
152
|
-
response['user_state'] = {
|
|
153
|
-
'customer_id': customer_id,
|
|
154
|
-
'menu': route,
|
|
155
|
-
'obs': user_state.obs,
|
|
156
|
-
}
|
|
157
|
-
return json.dumps(response)
|
|
158
|
-
elif type(message_response) in (EndChatResponse, TransferToHuman):
|
|
159
|
-
response = message_response.json()
|
|
160
|
-
response['user_state'] = {
|
|
161
|
-
'customer_id': customer_id,
|
|
162
|
-
'menu': None,
|
|
163
|
-
'obs': None,
|
|
164
|
-
}
|
|
165
|
-
return json.dumps(response)
|
|
166
|
-
elif type(message_response) == RedirectResponse:
|
|
167
|
-
route = self.__adjust_route(message_response.route, menu)
|
|
168
|
-
message.user_state.menu = route
|
|
169
|
-
return self.process_message(message)
|
|
170
162
|
else:
|
|
171
|
-
|
|
163
|
+
error('Tipo de retorno inválido!')
|
|
164
|
+
return None
|
|
165
|
+
|
|
172
166
|
|
|
173
167
|
def __adjust_route(self, route: str, absolute_route: str) -> str:
|
|
174
168
|
"""
|
|
@@ -187,4 +181,30 @@ class ChatbotApp(ABC):
|
|
|
187
181
|
if 'start' not in route:
|
|
188
182
|
route = absolute_route + route
|
|
189
183
|
|
|
190
|
-
return route
|
|
184
|
+
return route
|
|
185
|
+
|
|
186
|
+
def __create_response(self, response, customer_id, route, menu, obs):
|
|
187
|
+
"""
|
|
188
|
+
Cria uma resposta padronizada em formato JSON com o estado do usuário.
|
|
189
|
+
"""
|
|
190
|
+
response = ChatbotResponse(response).json() if not isinstance(response, dict) else response
|
|
191
|
+
response['user_state'] = {
|
|
192
|
+
'customer_id': customer_id,
|
|
193
|
+
'route': route,
|
|
194
|
+
'menu': menu,
|
|
195
|
+
'obs': obs,
|
|
196
|
+
}
|
|
197
|
+
return json.dumps(response)
|
|
198
|
+
|
|
199
|
+
def __end_chat_response(self, response, customer_id):
|
|
200
|
+
"""
|
|
201
|
+
Gera a resposta de finalização ou transferência de chat.
|
|
202
|
+
"""
|
|
203
|
+
response = response.json()
|
|
204
|
+
response['user_state'] = {
|
|
205
|
+
'customer_id': customer_id,
|
|
206
|
+
'menu': None,
|
|
207
|
+
'route': None,
|
|
208
|
+
'obs': None,
|
|
209
|
+
}
|
|
210
|
+
return json.dumps(response)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import inspect
|
|
2
3
|
from functools import wraps
|
|
3
4
|
from logging import debug
|
|
@@ -37,6 +38,7 @@ class ChatbotRouter:
|
|
|
37
38
|
signature = inspect.signature(func)
|
|
38
39
|
output_param = signature.return_annotation
|
|
39
40
|
|
|
41
|
+
# Itera sobre os parâmetros da função e extrai seus tipos
|
|
40
42
|
for name, param in signature.parameters.items():
|
|
41
43
|
param_type = (
|
|
42
44
|
param.annotation
|
|
@@ -46,6 +48,7 @@ class ChatbotRouter:
|
|
|
46
48
|
params[param_type] = name
|
|
47
49
|
debug(f'Parameter: {name}, Type: {param_type}')
|
|
48
50
|
|
|
51
|
+
# Adiciona a função e seus parâmetros à rota especificada
|
|
49
52
|
self.routes[route_name.strip().lower()] = {
|
|
50
53
|
'function': func,
|
|
51
54
|
'params': params,
|
|
@@ -74,6 +77,7 @@ class ChatbotRouter:
|
|
|
74
77
|
if 'start' not in router.routes.keys():
|
|
75
78
|
raise ChatbotError('Erro ao incluir rota, start não encontrado!')
|
|
76
79
|
|
|
80
|
+
# Adiciona prefixo às rotas do roteador incluído
|
|
77
81
|
prefixed_routes = {
|
|
78
82
|
(
|
|
79
83
|
f'{prefix.lower()}'
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import grpc
|
|
3
|
+
import chatgraph.pb.userstate_pb2 as userstate_pb2
|
|
4
|
+
import chatgraph.pb.userstate_pb2_grpc as userstate_pb2_grpc
|
|
5
|
+
|
|
6
|
+
import chatgraph.pb.voll_pb2 as whatsapp_pb2
|
|
7
|
+
import chatgraph.pb.voll_pb2_grpc as whatsapp_pb2_grpc
|
|
8
|
+
|
|
9
|
+
class WhatsappServiceClient:
|
|
10
|
+
def __init__(self, grpc_uri=None):
|
|
11
|
+
|
|
12
|
+
self.grpc_uri = grpc_uri
|
|
13
|
+
|
|
14
|
+
if not grpc_uri:
|
|
15
|
+
self.grpc_uri = os.getenv('GRPC_URI')
|
|
16
|
+
|
|
17
|
+
if not self.grpc_uri:
|
|
18
|
+
raise ValueError("A variável de ambiente 'GRPC_URI' não está definida.")
|
|
19
|
+
|
|
20
|
+
# Cria o canal gRPC
|
|
21
|
+
self.channel = grpc.insecure_channel(self.grpc_uri)
|
|
22
|
+
|
|
23
|
+
# Cria o stub (client) para o serviço gRPC
|
|
24
|
+
self.stub = whatsapp_pb2_grpc.MessageServiceStub(self.channel)
|
|
25
|
+
|
|
26
|
+
def send_button(self, message_data):
|
|
27
|
+
# Cria o request para o método SendButton
|
|
28
|
+
request = whatsapp_pb2.MessageRequest(**message_data)
|
|
29
|
+
|
|
30
|
+
# Faz a chamada ao serviço gRPC
|
|
31
|
+
try:
|
|
32
|
+
response = self.stub.SendButton(request)
|
|
33
|
+
return response
|
|
34
|
+
except grpc.RpcError as e:
|
|
35
|
+
print(f"Erro ao fazer a requisição gRPC SendButton: {e}")
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
def send_list(self, message_data):
|
|
39
|
+
# Cria o request para o método SendList
|
|
40
|
+
request = whatsapp_pb2.MessageRequest(**message_data)
|
|
41
|
+
|
|
42
|
+
# Faz a chamada ao serviço gRPC
|
|
43
|
+
try:
|
|
44
|
+
response = self.stub.SendList(request)
|
|
45
|
+
return response
|
|
46
|
+
except grpc.RpcError as e:
|
|
47
|
+
print(f"Erro ao fazer a requisição gRPC SendList: {e}")
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
def send_text(self, message_data):
|
|
51
|
+
# Cria o request para o método SendText
|
|
52
|
+
request = whatsapp_pb2.MessageRequest(**message_data)
|
|
53
|
+
|
|
54
|
+
# Faz a chamada ao serviço gRPC
|
|
55
|
+
try:
|
|
56
|
+
response = self.stub.SendText(request)
|
|
57
|
+
return response
|
|
58
|
+
except grpc.RpcError as e:
|
|
59
|
+
print(f"Erro ao fazer a requisição gRPC SendText: {e}")
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
class UserStateServiceClient:
|
|
63
|
+
def __init__(self, grpc_uri=None):
|
|
64
|
+
|
|
65
|
+
self.grpc_uri = grpc_uri
|
|
66
|
+
|
|
67
|
+
if not grpc_uri:
|
|
68
|
+
self.grpc_uri = os.getenv('GRPC_URI')
|
|
69
|
+
|
|
70
|
+
if not self.grpc_uri:
|
|
71
|
+
raise ValueError("A variável de ambiente 'GRPC_URI' não está definida.")
|
|
72
|
+
|
|
73
|
+
# Cria o canal gRPC
|
|
74
|
+
self.channel = grpc.insecure_channel(self.grpc_uri)
|
|
75
|
+
|
|
76
|
+
# Cria o stub (client) para o serviço gRPC
|
|
77
|
+
self.stub = userstate_pb2_grpc.UserStateServiceStub(self.channel)
|
|
78
|
+
|
|
79
|
+
def select_user_state(self, user_id):
|
|
80
|
+
# Cria o request para o método SelectUserState
|
|
81
|
+
request = userstate_pb2.UserStateId(user_id=user_id)
|
|
82
|
+
|
|
83
|
+
# Faz a chamada ao serviço gRPC
|
|
84
|
+
try:
|
|
85
|
+
response = self.stub.SelectUserState(request)
|
|
86
|
+
return response
|
|
87
|
+
except grpc.RpcError as e:
|
|
88
|
+
print(f"Erro ao fazer a requisição gRPC SelectUserState: {e}")
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
def insert_user_state(self, user_state_data):
|
|
92
|
+
# Cria o request para o método InsertUserState
|
|
93
|
+
request = userstate_pb2.UserState(**user_state_data)
|
|
94
|
+
|
|
95
|
+
# Faz a chamada ao serviço gRPC
|
|
96
|
+
try:
|
|
97
|
+
response = self.stub.InsertUserState(request)
|
|
98
|
+
return response
|
|
99
|
+
except grpc.RpcError as e:
|
|
100
|
+
print(f"Erro ao fazer a requisição gRPC InsertUserState: {e}")
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
def update_user_state(self, user_state_data):
|
|
104
|
+
# Cria o request para o método UpdateUserState
|
|
105
|
+
request = userstate_pb2.UserState(**user_state_data)
|
|
106
|
+
|
|
107
|
+
# Faz a chamada ao serviço gRPC
|
|
108
|
+
try:
|
|
109
|
+
response = self.stub.UpdateUserState(request)
|
|
110
|
+
return response
|
|
111
|
+
except grpc.RpcError as e:
|
|
112
|
+
print(f"Erro ao fazer a requisição gRPC UpdateUserState: {e}")
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
def delete_user_state(self, user_id):
|
|
116
|
+
# Cria o request para o método DeleteUserState
|
|
117
|
+
request = userstate_pb2.UserStateId(user_id=user_id)
|
|
118
|
+
|
|
119
|
+
# Faz a chamada ao serviço gRPC
|
|
120
|
+
try:
|
|
121
|
+
response = self.stub.DeleteUserState(request)
|
|
122
|
+
return response
|
|
123
|
+
except grpc.RpcError as e:
|
|
124
|
+
print(f"Erro ao fazer a requisição gRPC DeleteUserState: {e}")
|
|
125
|
+
return None
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
chatgraph-0.3.1/chatgraph/messages/__pycache__/test_message_consumer.cpython-312-pytest-8.3.2.pyc
ADDED
|
Binary file
|
|
@@ -4,14 +4,13 @@ import os
|
|
|
4
4
|
import pika
|
|
5
5
|
from typing import Callable
|
|
6
6
|
from ..auth.credentials import Credential
|
|
7
|
-
from ..types.message_types import
|
|
8
|
-
from .base_message_consumer import MessageConsumer
|
|
7
|
+
from ..types.message_types import UserCall, UserState
|
|
9
8
|
from rich.console import Console
|
|
10
9
|
from rich.table import Table
|
|
11
10
|
from rich.text import Text
|
|
12
11
|
from rich.panel import Panel
|
|
13
12
|
|
|
14
|
-
class
|
|
13
|
+
class MessageConsumer:
|
|
15
14
|
"""
|
|
16
15
|
Implementação de MessageConsumer para consumir mensagens de uma fila RabbitMQ.
|
|
17
16
|
|
|
@@ -27,6 +26,7 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
27
26
|
self,
|
|
28
27
|
credential: Credential,
|
|
29
28
|
amqp_url: str,
|
|
29
|
+
grpc_uri: str,
|
|
30
30
|
queue_consume: str,
|
|
31
31
|
prefetch_count: int = 1,
|
|
32
32
|
virtual_host: str = '/',
|
|
@@ -45,6 +45,7 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
45
45
|
self.__prefetch_count = prefetch_count
|
|
46
46
|
self.__queue_consume = queue_consume
|
|
47
47
|
self.__amqp_url = amqp_url
|
|
48
|
+
self.__grpc_uri = grpc_uri
|
|
48
49
|
self.__credentials = pika.PlainCredentials(
|
|
49
50
|
credential.username, credential.password
|
|
50
51
|
)
|
|
@@ -58,7 +59,8 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
58
59
|
queue_env: str = 'RABBIT_QUEUE',
|
|
59
60
|
prefetch_env: str = 'RABBIT_PREFETCH',
|
|
60
61
|
vhost_env: str = 'RABBIT_VHOST',
|
|
61
|
-
|
|
62
|
+
grpc_uri: str = 'GRPC_URI',
|
|
63
|
+
) -> 'MessageConsumer':
|
|
62
64
|
"""
|
|
63
65
|
Carrega as configurações do RabbitMQ a partir de variáveis de ambiente e retorna uma instância de RabbitMessageConsumer.
|
|
64
66
|
|
|
@@ -82,8 +84,9 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
82
84
|
queue = os.getenv(queue_env)
|
|
83
85
|
prefetch = os.getenv(prefetch_env, 1)
|
|
84
86
|
vhost = os.getenv(vhost_env, '/')
|
|
87
|
+
grpc = os.getenv(grpc_uri)
|
|
85
88
|
|
|
86
|
-
if not username or not password or not url or not queue:
|
|
89
|
+
if not username or not password or not url or not queue or not grpc:
|
|
87
90
|
raise ValueError('Corrija as variáveis de ambiente!')
|
|
88
91
|
|
|
89
92
|
return cls(
|
|
@@ -92,6 +95,7 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
92
95
|
queue_consume=queue,
|
|
93
96
|
prefetch_count=int(prefetch),
|
|
94
97
|
virtual_host=vhost,
|
|
98
|
+
grpc_uri=grpc,
|
|
95
99
|
)
|
|
96
100
|
|
|
97
101
|
def start_consume(self, process_message: Callable) -> None:
|
|
@@ -122,7 +126,7 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
122
126
|
),
|
|
123
127
|
)
|
|
124
128
|
|
|
125
|
-
info('[x] Aguardando solicitações RPC')
|
|
129
|
+
info('[x] Server inicializado! Aguardando solicitações RPC')
|
|
126
130
|
channel.start_consuming()
|
|
127
131
|
except pika.exceptions.StreamLostError as e:
|
|
128
132
|
debug(e)
|
|
@@ -154,7 +158,7 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
154
158
|
)
|
|
155
159
|
ch.basic_ack(delivery_tag=method.delivery_tag)
|
|
156
160
|
|
|
157
|
-
def __transform_message(self, message: dict) ->
|
|
161
|
+
def __transform_message(self, message: dict) -> UserCall:
|
|
158
162
|
"""
|
|
159
163
|
Transforma o dicionário JSON recebido em uma instância de Message.
|
|
160
164
|
|
|
@@ -166,12 +170,13 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
166
170
|
"""
|
|
167
171
|
|
|
168
172
|
user_state = message.get('user_state', {})
|
|
169
|
-
return
|
|
173
|
+
return UserCall(
|
|
170
174
|
type=message.get('type', ''),
|
|
171
175
|
text=message.get('text', ''),
|
|
172
176
|
user_state=UserState(
|
|
173
177
|
customer_id=user_state.get('customer_id', ''),
|
|
174
178
|
menu=user_state.get('menu', ''),
|
|
179
|
+
route=user_state.get('route', ''),
|
|
175
180
|
lst_update=user_state.get('lst_update', ''),
|
|
176
181
|
obs=user_state.get('obs', {}),
|
|
177
182
|
),
|
|
@@ -179,6 +184,7 @@ class RabbitMessageConsumer(MessageConsumer):
|
|
|
179
184
|
customer_phone=message.get('customer_phone', ''),
|
|
180
185
|
company_phone=message.get('company_phone', ''),
|
|
181
186
|
status=message.get('status'),
|
|
187
|
+
grpc_uri=self.__grpc_uri,
|
|
182
188
|
)
|
|
183
189
|
|
|
184
190
|
def reprer(self):
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package userstate;
|
|
4
|
+
|
|
5
|
+
option go_package = "./pb/userstate";
|
|
6
|
+
|
|
7
|
+
service UserStateService {
|
|
8
|
+
rpc SelectUserState(UserStateId) returns (UserState);
|
|
9
|
+
rpc InsertUserState(UserState) returns (RequestStatus);
|
|
10
|
+
rpc UpdateUserState(UserState) returns (RequestStatus);
|
|
11
|
+
rpc DeleteUserState(UserStateId) returns (RequestStatus);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
message UserState {
|
|
15
|
+
string user_id = 1;
|
|
16
|
+
string menu_id = 2;
|
|
17
|
+
string route = 3;
|
|
18
|
+
string obs = 4;
|
|
19
|
+
string date = 5;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
message UserStateId {
|
|
23
|
+
string user_id = 1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
message RequestStatus {
|
|
27
|
+
bool status = 1;
|
|
28
|
+
string message = 2;
|
|
29
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: userstate.proto
|
|
5
|
+
# Protobuf Python Version: 5.27.2
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
5,
|
|
15
|
+
27,
|
|
16
|
+
2,
|
|
17
|
+
'',
|
|
18
|
+
'userstate.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fuserstate.proto\x12\tuserstate\"W\n\tUserState\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x0f\n\x07menu_id\x18\x02 \x01(\t\x12\r\n\x05route\x18\x03 \x01(\t\x12\x0b\n\x03obs\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61te\x18\x05 \x01(\t\"\x1e\n\x0bUserStateId\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"0\n\rRequestStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\t2\x9e\x02\n\x10UserStateService\x12?\n\x0fSelectUserState\x12\x16.userstate.UserStateId\x1a\x14.userstate.UserState\x12\x41\n\x0fInsertUserState\x12\x14.userstate.UserState\x1a\x18.userstate.RequestStatus\x12\x41\n\x0fUpdateUserState\x12\x14.userstate.UserState\x1a\x18.userstate.RequestStatus\x12\x43\n\x0f\x44\x65leteUserState\x12\x16.userstate.UserStateId\x1a\x18.userstate.RequestStatusB\x10Z\x0e./pb/userstateb\x06proto3')
|
|
28
|
+
|
|
29
|
+
_globals = globals()
|
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'userstate_pb2', _globals)
|
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\016./pb/userstate'
|
|
35
|
+
_globals['_USERSTATE']._serialized_start=30
|
|
36
|
+
_globals['_USERSTATE']._serialized_end=117
|
|
37
|
+
_globals['_USERSTATEID']._serialized_start=119
|
|
38
|
+
_globals['_USERSTATEID']._serialized_end=149
|
|
39
|
+
_globals['_REQUESTSTATUS']._serialized_start=151
|
|
40
|
+
_globals['_REQUESTSTATUS']._serialized_end=199
|
|
41
|
+
_globals['_USERSTATESERVICE']._serialized_start=202
|
|
42
|
+
_globals['_USERSTATESERVICE']._serialized_end=488
|
|
43
|
+
# @@protoc_insertion_point(module_scope)
|