chatgraph 1.2.4__tar.gz → 1.2.5__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.
Files changed (65) hide show
  1. {chatgraph-1.2.4 → chatgraph-1.2.5}/PKG-INFO +1 -1
  2. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/__init__.py +4 -1
  3. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/logger/__init__.py +11 -11
  4. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/logger/user_logger.py +88 -88
  5. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/messages/message_consumer.py +14 -4
  6. chatgraph-1.2.5/chatgraph/models/platform_state.py +35 -0
  7. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/services/router_http_client.py +8 -3
  8. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/types/usercall.py +22 -8
  9. {chatgraph-1.2.4 → chatgraph-1.2.5}/docs/gaps-go-to-python.md +150 -150
  10. {chatgraph-1.2.4 → chatgraph-1.2.5}/docs/gaps-python-to-go.md +65 -65
  11. {chatgraph-1.2.4 → chatgraph-1.2.5}/example2.py +59 -59
  12. {chatgraph-1.2.4 → chatgraph-1.2.5}/pyproject.toml +1 -1
  13. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_default_guard.py +93 -92
  14. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_message_consumer.py +403 -403
  15. chatgraph-1.2.5/tests/unit/test_models_platform_state.py +52 -0
  16. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_router_http_client.py +105 -14
  17. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_user_logger.py +146 -146
  18. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_usercall.py +436 -400
  19. {chatgraph-1.2.4 → chatgraph-1.2.5}/.env.example +0 -0
  20. {chatgraph-1.2.4 → chatgraph-1.2.5}/.github/agents/SkillManager.agent.md +0 -0
  21. {chatgraph-1.2.4 → chatgraph-1.2.5}/.github/agents/architect.agent.md +0 -0
  22. {chatgraph-1.2.4 → chatgraph-1.2.5}/.github/agents/code-reviewer.agent.md +0 -0
  23. {chatgraph-1.2.4 → chatgraph-1.2.5}/.github/agents/developer.agent.md +0 -0
  24. {chatgraph-1.2.4 → chatgraph-1.2.5}/.github/copilot-instructions.md +0 -0
  25. {chatgraph-1.2.4 → chatgraph-1.2.5}/.github/skills/chatgraph-framework/SKILL.md +0 -0
  26. {chatgraph-1.2.4 → chatgraph-1.2.5}/.gitignore +0 -0
  27. {chatgraph-1.2.4 → chatgraph-1.2.5}/.python-version +0 -0
  28. {chatgraph-1.2.4 → chatgraph-1.2.5}/LICENSE +0 -0
  29. {chatgraph-1.2.4 → chatgraph-1.2.5}/README.md +0 -0
  30. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/auth/credentials.py +0 -0
  31. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/bot/chatbot_model.py +0 -0
  32. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/bot/chatbot_router.py +0 -0
  33. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/bot/default_functions.py +0 -0
  34. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/bot/default_guard.py +0 -0
  35. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/cli/__init__.py +0 -0
  36. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/container/container.py +0 -0
  37. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/error/chatbot_error.py +0 -0
  38. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/error/route_error.py +0 -0
  39. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/gRPC/gRPCCall.py +0 -0
  40. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/logger/logger.py +0 -0
  41. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/models/actions.py +0 -0
  42. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/models/http_responses.py +0 -0
  43. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/models/message.py +0 -0
  44. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/models/userstate.py +0 -0
  45. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/pb/router.proto +0 -0
  46. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/pb/router_pb2.py +0 -0
  47. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/pb/router_pb2_grpc.py +0 -0
  48. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/services/__init__.py +0 -0
  49. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/types/background_task.py +0 -0
  50. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/types/end_types.py +0 -0
  51. {chatgraph-1.2.4 → chatgraph-1.2.5}/chatgraph/types/route.py +0 -0
  52. {chatgraph-1.2.4 → chatgraph-1.2.5}/example.py +0 -0
  53. {chatgraph-1.2.4 → chatgraph-1.2.5}/jsons/voll_return.json +0 -0
  54. {chatgraph-1.2.4 → chatgraph-1.2.5}/poetry.lock +0 -0
  55. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/__init__.py +0 -0
  56. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/integration/__init__.py +0 -0
  57. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/integration/conftest.py +0 -0
  58. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/integration/test_router_client_integration.py +0 -0
  59. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/__init__.py +0 -0
  60. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/conftest.py +0 -0
  61. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_guard.py +0 -0
  62. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_models_actions.py +0 -0
  63. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_models_message.py +0 -0
  64. {chatgraph-1.2.4 → chatgraph-1.2.5}/tests/unit/test_models_userstate.py +0 -0
  65. {chatgraph-1.2.4 → chatgraph-1.2.5}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatgraph
3
- Version: 1.2.4
3
+ Version: 1.2.5
4
4
  Summary: A user-friendly chatbot library
5
5
  Project-URL: Homepage, https://github.com/irissonnlima/chatgraph
6
6
  Project-URL: Repository, https://github.com/irissonnlima/chatgraph
@@ -6,15 +6,16 @@ from .container.container import Container
6
6
  from .logger import logger, set_level
7
7
  from .messages.message_consumer import MessageConsumer
8
8
  from .models.message import Button, File, Message, SendType, TextMessage
9
+ from .models.platform_state import PlatformState, VollStateData
9
10
  from .models.userstate import (
10
11
  AuthLevel,
11
12
  ChatID,
12
13
  Menu,
14
+ User,
13
15
  UserData,
14
16
  UserIdentity,
15
17
  UserInternal,
16
18
  UserState,
17
- User,
18
19
  )
19
20
  from .types.background_task import BackgroundTask
20
21
  from .types.end_types import (
@@ -54,4 +55,6 @@ __all__ = [
54
55
  "BackgroundTask",
55
56
  "Container", "logger",
56
57
  "default_guard",
58
+ "PlatformState",
59
+ "VollStateData",
57
60
  ]
@@ -1,11 +1,11 @@
1
- import logging
2
-
3
- from .user_logger import UserLoggerManager
4
-
5
- logger_httpx = logging.getLogger('httpx')
6
- logger_httpx.setLevel(logging.ERROR)
7
-
8
- get_system_logger = UserLoggerManager.get_system_logger
9
- get_user_logger = UserLoggerManager.get_user_logger
10
- set_level = UserLoggerManager.set_level
11
- remove_user_logger = UserLoggerManager.remove_user_logger
1
+ import logging
2
+
3
+ from .user_logger import UserLoggerManager
4
+
5
+ logger_httpx = logging.getLogger('httpx')
6
+ logger_httpx.setLevel(logging.ERROR)
7
+
8
+ get_system_logger = UserLoggerManager.get_system_logger
9
+ get_user_logger = UserLoggerManager.get_user_logger
10
+ set_level = UserLoggerManager.set_level
11
+ remove_user_logger = UserLoggerManager.remove_user_logger
@@ -1,88 +1,88 @@
1
- import logging
2
- import os
3
- import sys
4
-
5
- LOG_DIR = "chatgraph_logs"
6
- LOG_FORMAT = "%(asctime)s | %(levelname)s | %(message)s | %(funcName)s | %(name)s"
7
-
8
- _ENV_LEVEL = os.getenv("CHATGRAPH_LOG_LEVEL", "").upper()
9
- _DEFAULT_LEVEL: int = getattr(logging, _ENV_LEVEL, logging.INFO)
10
-
11
-
12
- class UserLoggerManager:
13
- _loggers: dict[str, logging.Logger] = {}
14
- _level: int = _DEFAULT_LEVEL
15
-
16
- @classmethod
17
- def set_level(cls, level: int | str) -> None:
18
- if isinstance(level, str):
19
- numeric = getattr(logging, level.upper(), None)
20
- if numeric is None:
21
- raise ValueError(f"Nível de log inválido: '{level}'")
22
- level = numeric
23
- cls._level = level
24
- for logger in cls._loggers.values():
25
- logger.setLevel(level)
26
- for handler in logger.handlers:
27
- handler.setLevel(level)
28
-
29
- @classmethod
30
- def get_user_logger(cls, user_id: str, company_id: str) -> logging.Logger:
31
- key = f"{user_id}_{company_id}"
32
- if key in cls._loggers:
33
- return cls._loggers[key]
34
-
35
- os.makedirs(LOG_DIR, exist_ok=True)
36
-
37
- logger = logging.getLogger(key)
38
- logger.setLevel(cls._level)
39
-
40
- if not logger.handlers:
41
- handler = logging.FileHandler(
42
- os.path.join(LOG_DIR, f"{key}.log"), encoding="utf-8"
43
- )
44
- handler.setLevel(cls._level)
45
- handler.setFormatter(logging.Formatter(LOG_FORMAT))
46
- logger.addHandler(handler)
47
- stream_handler = logging.StreamHandler(sys.stdout)
48
- stream_handler.setLevel(cls._level)
49
- stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
50
- logger.addHandler(stream_handler)
51
-
52
- cls._loggers[key] = logger
53
- return logger
54
-
55
- @classmethod
56
- def remove_user_logger(cls, user_id: str, company_id: str) -> None:
57
- key = f"{user_id}_{company_id}"
58
- logger = cls._loggers.pop(key, None)
59
- if logger:
60
- for handler in logger.handlers[:]:
61
- handler.close()
62
- logger.removeHandler(handler)
63
-
64
- @classmethod
65
- def get_system_logger(cls) -> logging.Logger:
66
- key = "chatgraph.system"
67
- if key in cls._loggers:
68
- return cls._loggers[key]
69
-
70
- os.makedirs(LOG_DIR, exist_ok=True)
71
-
72
- logger = logging.getLogger(key)
73
- logger.setLevel(cls._level)
74
-
75
- if not logger.handlers:
76
- handler = logging.FileHandler(
77
- os.path.join(LOG_DIR, "system.log"), encoding="utf-8"
78
- )
79
- handler.setLevel(cls._level)
80
- handler.setFormatter(logging.Formatter(LOG_FORMAT))
81
- logger.addHandler(handler)
82
- stream_handler = logging.StreamHandler(sys.stdout)
83
- stream_handler.setLevel(cls._level)
84
- stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
85
- logger.addHandler(stream_handler)
86
-
87
- cls._loggers[key] = logger
88
- return logger
1
+ import logging
2
+ import os
3
+ import sys
4
+
5
+ LOG_DIR = "chatgraph_logs"
6
+ LOG_FORMAT = "%(asctime)s | %(levelname)s | %(message)s | %(funcName)s | %(name)s"
7
+
8
+ _ENV_LEVEL = os.getenv("CHATGRAPH_LOG_LEVEL", "").upper()
9
+ _DEFAULT_LEVEL: int = getattr(logging, _ENV_LEVEL, logging.INFO)
10
+
11
+
12
+ class UserLoggerManager:
13
+ _loggers: dict[str, logging.Logger] = {}
14
+ _level: int = _DEFAULT_LEVEL
15
+
16
+ @classmethod
17
+ def set_level(cls, level: int | str) -> None:
18
+ if isinstance(level, str):
19
+ numeric = getattr(logging, level.upper(), None)
20
+ if numeric is None:
21
+ raise ValueError(f"Nível de log inválido: '{level}'")
22
+ level = numeric
23
+ cls._level = level
24
+ for logger in cls._loggers.values():
25
+ logger.setLevel(level)
26
+ for handler in logger.handlers:
27
+ handler.setLevel(level)
28
+
29
+ @classmethod
30
+ def get_user_logger(cls, user_id: str, company_id: str) -> logging.Logger:
31
+ key = f"{user_id}_{company_id}"
32
+ if key in cls._loggers:
33
+ return cls._loggers[key]
34
+
35
+ os.makedirs(LOG_DIR, exist_ok=True)
36
+
37
+ logger = logging.getLogger(key)
38
+ logger.setLevel(cls._level)
39
+
40
+ if not logger.handlers:
41
+ handler = logging.FileHandler(
42
+ os.path.join(LOG_DIR, f"{key}.log"), encoding="utf-8"
43
+ )
44
+ handler.setLevel(cls._level)
45
+ handler.setFormatter(logging.Formatter(LOG_FORMAT))
46
+ logger.addHandler(handler)
47
+ stream_handler = logging.StreamHandler(sys.stdout)
48
+ stream_handler.setLevel(cls._level)
49
+ stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
50
+ logger.addHandler(stream_handler)
51
+
52
+ cls._loggers[key] = logger
53
+ return logger
54
+
55
+ @classmethod
56
+ def remove_user_logger(cls, user_id: str, company_id: str) -> None:
57
+ key = f"{user_id}_{company_id}"
58
+ logger = cls._loggers.pop(key, None)
59
+ if logger:
60
+ for handler in logger.handlers[:]:
61
+ handler.close()
62
+ logger.removeHandler(handler)
63
+
64
+ @classmethod
65
+ def get_system_logger(cls) -> logging.Logger:
66
+ key = "chatgraph.system"
67
+ if key in cls._loggers:
68
+ return cls._loggers[key]
69
+
70
+ os.makedirs(LOG_DIR, exist_ok=True)
71
+
72
+ logger = logging.getLogger(key)
73
+ logger.setLevel(cls._level)
74
+
75
+ if not logger.handlers:
76
+ handler = logging.FileHandler(
77
+ os.path.join(LOG_DIR, "system.log"), encoding="utf-8"
78
+ )
79
+ handler.setLevel(cls._level)
80
+ handler.setFormatter(logging.Formatter(LOG_FORMAT))
81
+ logger.addHandler(handler)
82
+ stream_handler = logging.StreamHandler(sys.stdout)
83
+ stream_handler.setLevel(cls._level)
84
+ stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
85
+ logger.addHandler(stream_handler)
86
+
87
+ cls._loggers[key] = logger
88
+ return logger
@@ -13,6 +13,7 @@ from rich.text import Text
13
13
  from ..auth.credentials import Credential
14
14
  from ..logger.user_logger import UserLoggerManager
15
15
  from ..models.message import Message
16
+ from ..models.platform_state import PlatformState
16
17
  from ..models.userstate import UserState
17
18
  from ..services.router_http_client import RouterHTTPClient
18
19
  from ..types.usercall import UserCall
@@ -154,7 +155,9 @@ class MessageConsumer:
154
155
  channel = await connection.channel()
155
156
  await channel.set_qos(prefetch_count=self.__prefetch_count)
156
157
  queue = await self.__declare_queue(channel)
157
- _logger.info('[x] Server inicializado! Aguardando solicitações RPC')
158
+ _logger.info(
159
+ '[x] Server inicializado! Aguardando solicitações RPC'
160
+ )
158
161
  async for message in queue:
159
162
  async with message.process():
160
163
  await self.on_request(message.body, process_message)
@@ -188,12 +191,14 @@ class MessageConsumer:
188
191
  _logger.error(f'Erro ao processar mensagem: {e}')
189
192
  finally:
190
193
  if pure_message is not None:
191
- UserLoggerManager.remove_user_logger(pure_message.user_id, pure_message.company_id)
194
+ UserLoggerManager.remove_user_logger(
195
+ pure_message.user_id, pure_message.company_id
196
+ )
192
197
 
193
198
  async def __transform_message(self, message: dict) -> UserCall:
194
199
  user_state = message.get('user_state', {})
195
200
  message_data = message.get('message', {})
196
- observation = user_state.get('observation', "{}")
201
+ observation = user_state.get('observation', '{}')
197
202
 
198
203
  if isinstance(observation, str):
199
204
  observation = json.loads(observation)
@@ -201,13 +206,18 @@ class MessageConsumer:
201
206
  user_state_models = UserState.from_dict(user_state)
202
207
  message_models = Message.from_dict(message_data)
203
208
 
204
- # Reutilizar o mesmo cliente para todas as mensagens
209
+ platform_state_data = message.get('platform_state', {})
210
+ if not isinstance(platform_state_data, dict):
211
+ platform_state_data = None
212
+ platform_state = PlatformState.from_dict(platform_state_data)
213
+
205
214
  router_client = await self.__initialize_router()
206
215
 
207
216
  usercall = UserCall(
208
217
  user_state=user_state_models,
209
218
  message=message_models,
210
219
  router_client=router_client,
220
+ platform_state=platform_state,
211
221
  )
212
222
 
213
223
  return usercall
@@ -0,0 +1,35 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class PlatformState:
7
+ data: dict = field(default_factory=dict)
8
+
9
+ def to_dict(self) -> dict:
10
+ return self.data
11
+
12
+ @classmethod
13
+ def from_dict(cls, data: Optional[dict]) -> 'PlatformState':
14
+ if data is None:
15
+ return cls(data={})
16
+ return cls(data=data)
17
+
18
+ @property
19
+ def as_voll(self) -> Optional['VollStateData']:
20
+ try:
21
+ return VollStateData(**self.data)
22
+ except (TypeError, ValueError):
23
+ return None
24
+
25
+ def __bool__(self) -> bool:
26
+ return bool(self.data)
27
+
28
+
29
+ @dataclass
30
+ class VollStateData:
31
+ session_id: int
32
+ customer_id: str
33
+ platform: str
34
+ protocol: str
35
+ campaign: str
@@ -3,10 +3,11 @@ from typing import Any, Dict, Optional
3
3
  import httpx
4
4
 
5
5
  from ..logger.user_logger import UserLoggerManager
6
- from ..models.http_responses import RouterResponses
7
- from ..models.userstate import UserState, ChatID, Menu, User, UserIdentity
8
- from ..models.message import Message, File
9
6
  from ..models.actions import EndAction
7
+ from ..models.http_responses import RouterResponses
8
+ from ..models.message import File, Message
9
+ from ..models.platform_state import PlatformState
10
+ from ..models.userstate import ChatID, Menu, User, UserIdentity, UserState
10
11
 
11
12
  _logger = UserLoggerManager.get_system_logger()
12
13
 
@@ -258,6 +259,7 @@ class RouterHTTPClient:
258
259
  self,
259
260
  message_data: Message,
260
261
  user_state: UserState,
262
+ platform_state: PlatformState = PlatformState(),
261
263
  ) -> Any:
262
264
  """
263
265
  Envia uma mensagem de texto ao usuário.
@@ -267,6 +269,7 @@ class RouterHTTPClient:
267
269
  - chat_id: ID do chat (user_id, company_id)
268
270
  - type: Tipo da mensagem
269
271
  - detail: Conteúdo da mensagem
272
+ platform_state: Estado específico da plataforma (opcional).
270
273
 
271
274
  Returns:
272
275
  Objeto de resposta com atributo 'status' indicando sucesso/falha.
@@ -280,6 +283,8 @@ class RouterHTTPClient:
280
283
  'message': message_data.to_dict(),
281
284
  'user_state': user_state.to_dict(),
282
285
  }
286
+ if platform_state:
287
+ payload['platform_state'] = platform_state.to_dict()
283
288
  _logger.debug(f"[send_message] POST {endpoint}")
284
289
  response = await self._actions_client.post(
285
290
  endpoint,
@@ -1,5 +1,4 @@
1
1
  import asyncio
2
- import concurrent.futures
3
2
  import json
4
3
  import logging
5
4
  from typing import Optional
@@ -10,6 +9,7 @@ from chatgraph.models.message import (
10
9
  Message,
11
10
  MessageTypes,
12
11
  )
12
+ from chatgraph.models.platform_state import PlatformState
13
13
  from chatgraph.models.userstate import Menu, User, UserIdentity, UserState
14
14
  from chatgraph.services.router_http_client import RouterHTTPClient
15
15
 
@@ -33,11 +33,13 @@ class UserCall: # noqa: PLR0904
33
33
  user_state: UserState,
34
34
  message: Message,
35
35
  router_client: RouterHTTPClient,
36
+ platform_state: PlatformState = PlatformState(),
36
37
  ) -> None:
37
38
  self.type = type
38
39
  self.__message = message
39
40
  self.__user_state = user_state
40
41
  self.__router_client = router_client
42
+ self.__platform_state = platform_state
41
43
  self.__content_message = self.__message.text_message.detail
42
44
 
43
45
  @property
@@ -115,21 +117,23 @@ class UserCall: # noqa: PLR0904
115
117
 
116
118
  async def __send(self, message: Message) -> None:
117
119
  try:
118
- self.logger.debug(
120
+ self.logger.info(
119
121
  f'Enviando mensagem | user={self.user_id} | company={self.company_id} | tipo={message.type if hasattr(message, "type") else "N/A"}'
120
122
  )
121
123
  response = await self.__router_client.send_message(
122
- message, self.__user_state
124
+ message, self.__user_state, self.__platform_state
123
125
  )
124
126
 
125
127
  if response:
126
- self.logger.debug(
128
+ self.logger.info(
127
129
  f'Mensagem enviada com sucesso | user={self.user_id}'
128
130
  )
129
131
 
130
132
  await asyncio.sleep(0.1)
131
133
  except Exception as e:
132
- raise Exception(f'Erro ao enviar mensagem: {e}')
134
+ raise Exception(
135
+ f'[ChatID: {self.__user_state.chat_id}] - Erro ao enviar mensagem: {e}'
136
+ )
133
137
 
134
138
  async def send(
135
139
  self,
@@ -321,7 +325,9 @@ class UserCall: # noqa: PLR0904
321
325
  async def load_identity(self, cpf: Optional[str] = None) -> UserIdentity:
322
326
  try:
323
327
  self.logger.debug(f'Consultando identidade | user={self.user_id}')
324
- identity = await self.__router_client.get_identity(self.user_id, cpf=cpf)
328
+ identity = await self.__router_client.get_identity(
329
+ self.user_id, cpf=cpf
330
+ )
325
331
  if self.__user_state.user is None:
326
332
  self.__user_state.user = User()
327
333
  self.__user_state.user.identity = identity
@@ -336,9 +342,13 @@ class UserCall: # noqa: PLR0904
336
342
  async def load_userstate(self) -> UserState:
337
343
  try:
338
344
  self.logger.debug(f'Carregando userstate | user={self.user_id}')
339
- resultado = await self.__router_client.get_session_by_chat_id(self.__user_state.chat_id)
345
+ resultado = await self.__router_client.get_session_by_chat_id(
346
+ self.__user_state.chat_id
347
+ )
340
348
  if resultado is None:
341
- raise ValueError('Sessão não encontrada para o chat_id informado.')
349
+ raise ValueError(
350
+ 'Sessão não encontrada para o chat_id informado.'
351
+ )
342
352
  self.__user_state = resultado
343
353
  self.logger.info(
344
354
  f'Userstate carregado | user={self.user_id} | route={self.__user_state.route}'
@@ -400,6 +410,10 @@ class UserCall: # noqa: PLR0904
400
410
  def observation(self):
401
411
  return self.__user_state.observation_dict
402
412
 
413
+ @property
414
+ def platform_state(self) -> PlatformState:
415
+ return self.__platform_state
416
+
403
417
  @property
404
418
  def content_message(self):
405
419
  return self.__content_message