evolution-client-python/evolutionapi/client.py
Davidson Gomes b0131a1141 feat: Add full support for WebSocket configuration and management in the Evolution API Client library
- Implement WebSocketConfig and WebSocketInfo models for event configuration
- Add create_websocket() method in the client for simplified creation of WebSocket handlers
- Expand WebSocket service with set_websocket() and find_websocket() methods
- Update README with detailed documentation on WebSocket configuration and usage
- Add new event handlers in the test example (on_qrcode, on_connection)
2025-03-06 09:44:59 -03:00

139 lines
5.2 KiB
Python

import requests
from requests_toolbelt import MultipartEncoder
from .exceptions import EvolutionAuthenticationError, EvolutionNotFoundError, EvolutionAPIError
from .services.instance import InstanceService
from .services.instance_operations import InstanceOperationsService
from .services.message import MessageService
from .services.call import CallService
from .services.chat import ChatService
from .services.label import LabelService
from .services.profile import ProfileService
from .services.group import GroupService
from .services.websocket import WebSocketService, WebSocketManager
class EvolutionClient:
"""
Cliente para interagir com a API Evolution.
Args:
base_url (str): A URL base do servidor da API Evolution.
api_token (str): O token de autenticação para acessar a API.
"""
def __init__(self, base_url: str, api_token: str):
self.base_url = base_url.rstrip('/')
self.api_token = api_token
self.instances = InstanceService(self)
self.instance_operations = InstanceOperationsService(self)
self.messages = MessageService(self)
self.calls = CallService(self)
self.chat = ChatService(self)
self.label = LabelService(self)
self.profile = ProfileService(self)
self.group = GroupService(self)
self.websocket = WebSocketService(self)
def _get_headers(self, instance_token: str = None):
return {
'apikey': instance_token or self.api_token,
'Content-Type': 'application/json'
}
def _get_full_url(self, endpoint):
return f'{self.base_url}/{endpoint}'
def _handle_response(self, response):
if response.status_code == 401:
raise EvolutionAuthenticationError('Falha na autenticação.')
elif response.status_code == 404:
raise EvolutionNotFoundError('Recurso não encontrado.')
elif response.ok:
try:
return response.json()
except ValueError:
return response.content
else:
error_detail = ''
try:
error_detail = f' - {response.json()}'
except:
error_detail = f' - {response.text}'
raise EvolutionAPIError(f'Erro na requisição: {response.status_code}{error_detail}')
def get(self, endpoint: str, instance_token: str = None):
"""Faz uma requisição GET."""
url = self._get_full_url(endpoint)
response = requests.get(url, headers=self._get_headers(instance_token))
return self._handle_response(response)
def post(self, endpoint: str, data: dict = None, instance_token: str = None, files: dict = None):
url = f'{self.base_url}/{endpoint}'
headers = self._get_headers(instance_token)
if files:
# Remove o Content-Type do header quando enviando arquivos
if 'Content-Type' in headers:
del headers['Content-Type']
# Prepara os campos do multipart
fields = {}
# Adiciona os campos do data
for key, value in data.items():
fields[key] = str(value) if not isinstance(value, (int, float)) else (None, str(value), 'text/plain')
# Adiciona o arquivo
file_tuple = files['file']
fields['file'] = (file_tuple[0], file_tuple[1], file_tuple[2])
# Cria o multipart encoder
multipart = MultipartEncoder(fields=fields)
headers['Content-Type'] = multipart.content_type
response = requests.post(
url,
headers=headers,
data=multipart
)
else:
response = requests.post(
url,
headers=headers,
json=data
)
return response.json()
def put(self, endpoint, data=None):
"""Faz uma requisição PUT."""
url = self._get_full_url(endpoint)
response = requests.put(url, headers=self.headers, json=data)
return self._handle_response(response)
def delete(self, endpoint: str, instance_token: str = None):
"""Faz uma requisição DELETE."""
url = self._get_full_url(endpoint)
response = requests.delete(url, headers=self._get_headers(instance_token))
return self._handle_response(response)
def create_websocket(self, instance_id: str, api_token: str, max_retries: int = 5, retry_delay: float = 1.0) -> WebSocketManager:
"""
Create a WebSocket manager for the specified instance.
Args:
instance_id (str): The instance ID
api_token (str): The API token
max_retries (int): Maximum number of reconnection attempts
retry_delay (float): Initial delay between attempts in seconds
Returns:
WebSocketManager: The WebSocket manager instance
"""
return WebSocketManager(
base_url=self.base_url,
instance_id=instance_id,
api_token=api_token,
max_retries=max_retries,
retry_delay=retry_delay
)