Title: Sugestão: Adicionar um padrão de uso recomendado com Singleton para o cliente · Issue #11 · EvolutionAPI/evolution-client-python · GitHub
Open Graph Title: Sugestão: Adicionar um padrão de uso recomendado com Singleton para o cliente · Issue #11 · EvolutionAPI/evolution-client-python
X Title: Sugestão: Adicionar um padrão de uso recomendado com Singleton para o cliente · Issue #11 · EvolutionAPI/evolution-client-python
Description: Olá! Primeiramente, parabéns pela biblioteca, é muito útil. Ao utilizá-la em um projeto web (Django/Flask), percebi que para gerenciar a conexão de forma eficiente e evitar criar múltiplas instâncias do EvolutionClient, a melhor abordage...
Open Graph Description: Olá! Primeiramente, parabéns pela biblioteca, é muito útil. Ao utilizá-la em um projeto web (Django/Flask), percebi que para gerenciar a conexão de forma eficiente e evitar criar múltiplas instânci...
X Description: Olá! Primeiramente, parabéns pela biblioteca, é muito útil. Ao utilizá-la em um projeto web (Django/Flask), percebi que para gerenciar a conexão de forma eficiente e evitar criar múltiplas instânci...
Opengraph URL: https://github.com/EvolutionAPI/evolution-client-python/issues/11
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Sugestão: Adicionar um padrão de uso recomendado com Singleton para o cliente","articleBody":"Olá!\n\nPrimeiramente, parabéns pela biblioteca, é muito útil.\n\nAo utilizá-la em um projeto web (Django/Flask), percebi que para gerenciar a conexão de forma eficiente e evitar criar múltiplas instâncias do `EvolutionClient`, a melhor abordagem é usar um padrão Singleton.\n\nDesenvolvi um wrapper que gerencia a instância do cliente, garante que ele seja único em toda a aplicação e ainda mantém a lógica de retentativas e reconexão. Acredito que adicionar este padrão à documentação como um \"exemplo de uso avançado\" ou \"melhor prática\" ajudaria muito outros desenvolvedores.\n\nSugestão de implementação:\n\nAdicionar uma seção \"Uso Avançado / Melhores Práticas\" no README.md.\nOu criar uma pasta examples/ no repositório com este exemplo.\nSe concordar com a ideia, posso preparar um Pull Request com a alteração na documentação.\nObrigado!\n\nAbaixo está o código sugerido:\n\n\n```python\nimport logging\nimport time\nfrom typing import Optional\nfrom decouple import config\nfrom evolutionapi.client import EvolutionClient\nfrom evolutionapi.exceptions import EvolutionAPIError, EvolutionAuthenticationError\n\n# Configuração de logging\nlogger = logging.getLogger('integrations')\n\n# Carregamento das variáveis de ambiente\nURL_SERVE = config('URL_SERVE', default='')\nAPI_KEY = config('API_KEY', default='')\nMAX_RETRIES = config('MAX_RETRIES', default=3, cast=int)\nRETRY_DELAY = config('RETRY_DELAY', default=2, cast=int)\n\nclass EvolutionClientManager:\n \"\"\"\n Gerencia a conexão com o cliente da Evolution API, incluindo a\n conexão inicial com retentativas e a lógica de reconexão.\n \"\"\"\n def __init__(self, base_url: str, api_token: str, max_retries: int, retry_delay: int):\n if not base_url or not api_token:\n logger.error('ERRO: Variáveis de ambiente URL_SERVE ou API_KEY estão faltando.')\n raise EnvironmentError('Variáveis de ambiente URL_SERVE ou API_KEY estão faltando.')\n\n self.base_url = base_url\n self.api_token = api_token\n self.max_retries = max_retries\n self.retry_delay = retry_delay\n self._client: Optional[EvolutionClient] = None\n \n # Inicia a conexão ao instanciar\n self._connect()\n\n def _connect(self) -\u003e None:\n \"\"\"Inicializa a conexão com o cliente da Evolution API com retentativas.\"\"\"\n logger.info(\"Tentando conectar ao serviço Evolution API...\")\n for attempt in range(1, self.max_retries + 1):\n try:\n self._client = EvolutionClient(\n base_url=self.base_url,\n api_token=self.api_token\n )\n logger.info('Cliente EvolutionClient instanciado com sucesso.')\n return # Conexão bem-sucedida\n except (EvolutionAuthenticationError, EvolutionAPIError) as e:\n if attempt \u003c self.max_retries:\n logger.warning(f\"Tentativa {attempt} falhou: {e}. Nova tentativa em {self.retry_delay} segundos...\")\n time.sleep(self.retry_delay)\n else:\n logger.error(f\"Falha ao conectar ao serviço após {self.max_retries} tentativas: {e}\")\n self._client = None # Garante que o cliente seja None em caso de falha total\n raise\n except Exception as e:\n logger.error(f\"Erro inesperado ao inicializar o cliente: {e}\")\n self._client = None\n raise\n\n def get_client(self) -\u003e Optional[EvolutionClient]:\n \"\"\"\n Retorna a instância do cliente EvolutionClient.\n Se a conexão foi perdida, tenta reconectar.\n \"\"\"\n if not self._client:\n logger.warning(\"Cliente não conectado. Tentando reconectar...\")\n try:\n self._connect()\n except Exception as e:\n logger.error(f\"Não foi possível recuperar o cliente na reconexão: {e}\")\n return None\n return self._client\n\n# --- Instância Única (Singleton) no Nível do Módulo ---\n# Este bloco de código é executado apenas uma vez quando o módulo é importado,\n# garantindo que exista apenas uma instância do gerenciador.\ntry:\n _client_manager = EvolutionClientManager(\n base_url=URL_SERVE,\n api_token=API_KEY,\n max_retries=MAX_RETRIES,\n retry_delay=RETRY_DELAY\n )\nexcept Exception as e:\n logger.critical(f\"Falha crítica ao inicializar o EvolutionClientManager: {e}\")\n _client_manager = None\n\n\ndef get_evolution_client() -\u003e Optional[EvolutionClient]:\n \"\"\"Função utilitária para obter a instância do cliente em qualquer parte do código.\"\"\"\n if _client_manager:\n return _client_manager.get_client()\n \n logger.error(\"Gerenciador do cliente não foi inicializado devido a erros de configuração ou conexão.\")\n return None\n\n# --- Como Usar ---\n\n\nfrom apps.integrations.clients.whatsapp.evolution_client import get_evolution_client\n\ndef minha_view(request):\n try:\n client = get_evolution_client()\n if not client:\n # O log de erro já foi registrado pela função get_evolution_client\n raise ConnectionError(\"Cliente da Evolution API não está disponível.\")\n\n # Usa o client normalmente\n instances = client.instances.fetch_instances()\n context = {'instances': instances}\n\n except Exception as e:\n context = {'error': f'Ocorreu um erro: {str(e)}'}\n\n return render(request, 'dashboard/base.html', context)\n\n\n\n","author":{"url":"https://github.com/Brunohvg","@type":"Person","name":"Brunohvg"},"datePublished":"2025-07-04T12:47:39.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/11/evolution-client-python/issues/11"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:d4122f71-2369-f45a-4435-3d094167476d |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | BEFC:2946F1:334C74E:432AD9F:696DC098 |
| html-safe-nonce | 357c3dcef5b48220744e02d92164fce3997e5568fb52f484a808a747b34de771 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRUZDOjI5NDZGMTozMzRDNzRFOjQzMkFEOUY6Njk2REMwOTgiLCJ2aXNpdG9yX2lkIjoiNTU1MDQxNjIwODY3MTM5MTg5NiIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 7b800fc22104dd5e6eda147f1e79f195a45793649fff2db1e75ba258e91051ca |
| hovercard-subject-tag | issue:3202637655 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/EvolutionAPI/evolution-client-python/11/issue_layout |
| twitter:image | https://opengraph.githubassets.com/b34a1088aed7cf66b9ed12d08149606146753bec535b33ed87d8ee9147d7c715/EvolutionAPI/evolution-client-python/issues/11 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/b34a1088aed7cf66b9ed12d08149606146753bec535b33ed87d8ee9147d7c715/EvolutionAPI/evolution-client-python/issues/11 |
| og:image:alt | Olá! Primeiramente, parabéns pela biblioteca, é muito útil. Ao utilizá-la em um projeto web (Django/Flask), percebi que para gerenciar a conexão de forma eficiente e evitar criar múltiplas instânci... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | Brunohvg |
| hostname | github.com |
| expected-hostname | github.com |
| None | 4922b452d03cd8dbce479d866a11bc25b59ef6ee2da23aa9b0ddefa6bd4d0064 |
| turbo-cache-control | no-preview |
| go-import | github.com/EvolutionAPI/evolution-client-python git https://github.com/EvolutionAPI/evolution-client-python.git |
| octolytics-dimension-user_id | 136080052 |
| octolytics-dimension-user_login | EvolutionAPI |
| octolytics-dimension-repository_id | 880874407 |
| octolytics-dimension-repository_nwo | EvolutionAPI/evolution-client-python |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 880874407 |
| octolytics-dimension-repository_network_root_nwo | EvolutionAPI/evolution-client-python |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7e5ae23c70136152637ceee8d6faceb35596ec46 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width