Thanks to visit codestin.com
Credit goes to github.com

Skip to content

"dictionary doesn't specify a version" error with GoogleAdsClient.load_from_storage on Windows" #1011

@JCZOPOLATO

Description

@JCZOPOLATO

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageNew issue; requires attention

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions