-
Notifications
You must be signed in to change notification settings - Fork 509
Description
Estou encontrando um erro persistente ao tentar inicializar o GoogleAdsClient usando GoogleAdsClient.load_from_storage em um ambiente Windows, mesmo após múltiplas tentativas de depuração, atualizações de Python e reinstalações da biblioteca.
Comportamento Esperado:
Espero que o GoogleAdsClient.load_from_storage inicialize o cliente com sucesso, utilizando as configurações do arquivo google_ads.yaml e as credenciais OAuth válidas, permitindo que eu realize chamadas à API Google Ads (ex: listar campanhas).
Comportamento Observado:
A chamada GoogleAdsClient.load_from_storage falha consistentemente com o erro:
Ocorreu um erro inesperado: dictionary doesn't specify a version
Detalhes do Ambiente:
Sistema Operacional: Windows 10/11 (64-bit)
Versão do Python: 3.12.10
Versão da Biblioteca google-ads: 27.0.0
Versão PyYAML: 6.0.2
Ferramenta: Visual Studio Code com PowerShell integrado.
Passos para Reproduzir:
Tenha um arquivo google_ads.yaml configurado (veja o conteúdo abaixo).
Tenha um refresh_token válido gerado e inserido no google_ads.yaml. A fase de autenticação OAuth com accounts.google.com/o/oauth2/token retorna HTTP 200 OK (conforme logs abaixo), indicando que o refresh_token e as credenciais OAuth são válidos e a troca de token é bem-sucedida.
Utilize o seguinte script Python (test_api.py):
Python
import yaml
from google.ads.googleads.client import GoogleAdsClient
import io
import sys
import logging
import http.client as httplib # Importa httplib para depuração HTTP
Configura o logging para HTTP client, que mostrará as requisições e respostas
e configura o logging básico para DEBUG. O log da biblioteca Google Ads também será ativado.
httplib.HTTPConnection.debuglevel = 1
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
Caminho para o seu arquivo google_ads.yaml
YAML_FILE_PATH = "google_ads.yaml"
OUTPUT_FILE_PATH = "api_output.txt" # Novo arquivo para a saída da API
ERROR_LOG_FILE_PATH = "api_error_log.txt" # Arquivo para logar erros capturados
def main():
# Redirecionar stdout e stderr para buffers para capturar tudo
original_stdout = sys.stdout
original_stderr = sys.stderr
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
try:
# O ID da conta Google Ads que você quer acessar (a conta cliente)
customer_id_to_access = "7168775798" # Exemplo de ID de conta cliente
sys.stdout.write(f"Tentando conectar à Google Ads API v17 para a conta: {customer_id_to_access}\n")
# Inicializar o cliente Google Ads, carregando diretamente do arquivo YAML
client = GoogleAdsClient.load_from_storage(path=YAML_FILE_PATH, version="v17")
# Obter o serviço de Campanha (este código não é alcançado devido ao erro de inicialização)
# campaign_service = client.get_service("CampaignService")
# ... Resto do código para listar campanhas (não relevante, pois a falha ocorre antes)
sys.stdout.write("Campanhas listadas com sucesso!\n")
with open(OUTPUT_FILE_PATH, "w", encoding="utf-8") as f:
f.write(sys.stdout.getvalue())
sys.__stdout__.write(f"\nSaída da API salva em: {OUTPUT_FILE_PATH}\n")
except Exception as e:
error_message = f"Ocorreu um erro inesperado: {e}"
sys.__stdout__.write(f"\n{error_message}\n")
with open(ERROR_LOG_FILE_PATH, "w", encoding="utf-8") as f_err:
f_err.write(error_message + "\n")
f_err.write("\nstdout capturado:\n")
f_err.write(sys.stdout.getvalue())
f_err.write("\nstderr capturado:\n")
f_err.write(sys.stderr.getvalue())
sys.__stdout__.write(f"Detalhes do erro logados em: {ERROR_LOG_FILE_PATH}\n")
finally:
sys.stdout = original_stdout
sys.stderr = original_stderr
if name == 'main':
main()
Crie e ative um ambiente virtual limpo (venv_googleads_new) com Python 3.12.10.
Instale pip install google-ads (ou pip install google-ads==27.0.0 para fixar a versão).
Execute python test_api.py.
Conteúdo do google_ads.yaml:
YAML
developer_token: SEU_DEVELOPER_TOKEN_AQUI
client_id: SEU_CLIENT_ID_AQUI
client_secret: SEU_CLIENT_SECRET_AQUI
refresh_token: SEU_REFRESH_TOKEN_AQUI
login_customer_id: 9420048858 # Seu login_customer_id (MCC)
(Nota: Os tokens e IDs são placeholders e foram verificados como corretos e funcionais na fase de autenticação.)
Log de Erro Completo (api_error_log.txt da última execução):
Ocorreu um erro inesperado: dictionary doesn't specify a version
stdout capturado:
Tentando conectar à Google Ads API v17 para a conta: 7168775798
send: b'POST /o/oauth2/token HTTP/1.1\r\nHost: accounts.google.com\r\nUser-Agent: python-requests/2.32.4\r\nAccept-Encoding: gzip, deflate\r\nAccept: /\r\nConnection: keep-alive\r\nContent-Type: application/x-www-form-urlencoded\r\nx-goog-api-client: gl-python/3.9.13 auth/2.40.3 cred-type/u\r\nContent-Length: 280\r\n\r\n'
send: b'grant_type=refresh_token&client_id=REDACTED&client_secret=REDACTED&refresh_token=REDACTED
reply: 'HTTP/1.1 200 OK\r\n'
header: Pragma: no-cache
header: Date: Tue, 01 Jul 2025 13:05:57 GMT
header: Cache-Control: no-cache, no-store, max-age=0, must-revalidate
header: Expires: Mon, 01 Jan 1990 00:00:00 GMT
header: Content-Type: application/json; charset=utf-8
header: Vary: Origin
header: Vary: X-Origin
header: Vary: Referer
header: Content-Encoding: gzip
header: Server: scaffolding on HTTPServer2
header: X-XSS-Protection: 0
header: X-Frame-Options: SAMEORIGIN
header: X-Content-Type-Options: nosniff
header: Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
header: Transfer-Encoding: chunked
stderr capturado:
(Nota: O log acima foi extraído do terminal e api_error_log.txt e mostra que o refresh_token funciona, mas o erro de inicialização persiste.)
O que já tentei (e não resolveu):
Atualização do Python de 3.9.x para 3.12.10.
Criação de novos ambientes virtuais limpos.
Múltiplas reinstalações da biblioteca google-ads e suas dependências (incluindo PyYAML, protobuf, grpcio), tanto a versão mais recente quanto versões fixas.
Verificação rigorosa do formato e conteúdo do google_ads.yaml.
Confirmação de que o refresh_token está ativo e funcionando via requisição OAuth 2.0 (retorno 200 OK).
Agradeço qualquer assistência na identificação da causa raiz deste problema.<!-- PLEASE READ