Gemini network proxy: configurar e diagnosticar a conexão do cliente

12 min de leitura

Como encaminhar o google-genai 2.30.1 por HTTPS_PROXY, manter o TLS com SSL_CERT_FILE e separar ConnectError, 407 e ClientError da API.

Gemini network proxy: configurar e diagnosticar a conexão do cliente

Este guia é para quem, no Brasil, encaminha o cliente Python da Gemini Developer API por um proxy HTTP CONNECT e precisa ler a falha. Não promete conta, região nem desvio de bloqueio. O laboratório usa só 127.0.0.1. Não distribuímos chave grátis nem vendemos IP.

01Qual cliente Gemini este guia usa

A palavra Gemini cobre produtos diferentes. O app e o site de consumidor não leem HTTPS_PROXY do seu processo Python. A Gemini Developer API fala HTTPS com generativelanguage.googleapis.com quando você usa uma chave. O Vertex AI e o Gemini Enterprise Agent Platform pedem projeto, localização e credencial de nuvem. O Gemini CLI é outro binário. Este texto escolhe um único cliente versionado: o SDK síncrono google-genai 2.30.1, transporte HTTPX 0.28.1, endpoint de desenvolvedor. Não é um guia do app, do CLI nem do Vertex.

A página de regiões atualizada em 28 de abril de 2026 lista o Brazil entre os países da Gemini API e do Google AI Studio. Isso descreve disponibilidade do produto, não o IP de saída do seu proxy. Encaminhar o TLS por CONNECT não cria faturamento, cota nem direito de conta. Se a Google recusar a chave, o proxy ter funcionado não muda o recado.

  1. Pin o pacote e confira as versões no mesmo interpretador que vai rodar o cliente. O PyPI do google-genai 2.30.1 pede Python >=3.10. O laboratório usou Python 3.12.12, google-genai 2.30.1 e HTTPX 0.28.1. O extra aiohttp não estava instalado. O README do SDK diz que o padrão síncrono e o assíncrono usam HTTPX, e que google-genai[aiohttp] é opção de desempenho com trust_env=True. Este guia não executou aiohttp nem generate_content em stream.
Comando para pinar google-genai 2.30.1 e HTTPX 0.28.1
Caso versions: google-genai 2.30.1, httpx 0.28.1, LibreSSL 3.3.6

Instale no mesmo interpretador Python 3.10 ou mais novo, salve a receita abaixo como public_sdk_recipe.py e rode no mesmo processo em que as variáveis já existem.

python3.12 -m venv .venv
.venv/bin/pip install google-genai==2.30.1
export GEMINI_API_KEY='sua-chave'
export HTTPS_PROXY='http://USUARIO:SENHA@host:porta'
# SSL_CERT_FILE só se o destino exigir um CA extra
export SSL_CERT_FILE=/caminho/ca.pem
# sem GEMINI_PT_BASE_URL o SDK usa https://generativelanguage.googleapis.com/
export GEMINI_PT_BASE_URL='https://127.0.0.1:PORTA'
.venv/bin/python public_sdk_recipe.py

Sem GEMINI_PT_BASE_URL o cliente fala com o host padrão da Developer API. Com a variável, o mesmo arquivo aponta para um mock seu. A receita abaixo foi executada só contra o loopback já existente, com JSON simulado. Não é chamada paga à Google.

#!/usr/bin/env python3
"""Receita pública: google-genai 2.30.1 via HTTPS_PROXY.

Padrão do SDK: https://generativelanguage.googleapis.com/
Mock próprio: defina GEMINI_PT_BASE_URL.
"""

from __future__ import annotations

import os
import sys

from google import genai
from google.genai import types


def main() -> int:
    api_key = os.environ.get("GEMINI_API_KEY")
    if not api_key:
        print("defina GEMINI_API_KEY no processo", file=sys.stderr)
        return 2
    kwargs: dict = {"api_key": api_key}
    base_url = os.environ.get("GEMINI_PT_BASE_URL")
    if base_url:
        kwargs["http_options"] = types.HttpOptions(base_url=base_url)
    client = genai.Client(**kwargs)
    try:
        response = client.models.generate_content(
            model="gemini-flash-latest",
            contents="ping",
        )
        print(response.text)
        return 0
    finally:
        client.close()


if __name__ == "__main__":
    raise SystemExit(main())

O modelo no laboratório foi gemini-flash-latest, o mesmo identificador de texto curto do README atual. A URL montada pelo SDK no loopback foi /v1beta/models/gemini-flash-latest:generateContent. Fora do laboratório o host padrão do cliente de desenvolvedor, no código instalado, é https://generativelanguage.googleapis.com/. Não misture esse host com o endpoint regional do Vertex.

02Como configurar o HTTPSPROXY que o SDK documenta

O README do python-genai na seção Proxy, linhas 269 a 277 da cópia de 14 de outubro de 2026, manda exportar o proxy e, se precisar, SSL_CERT_FILE antes de criar o Client. O exemplo oficial usa HTTPS_PROXY='http://username:REDACTED@proxy_uri:port'. O primeiro salto é HTTP até o proxy. O destino continua HTTPS. Isso não é erro de digitação: o cliente pede CONNECT e só então faz o handshake TLS com a origem.

O SDK não implementa um parser próprio de proxy. O HTTPX 0.28.1 lê o ambiente com trust_env=True por padrão. A classe SyncHttpxClient do _api_client.py 2.30.1 não desliga isso. O README também cita urllib.request.getproxies. No macOS essa função pode olhar a configuração do sistema se as variáveis estiverem vazias. No laboratório getproxies() começou vazio. Se o seu notebook herda NO_PROXY=127.0.0.1,localhost de outro job, o CONNECT local some sem aviso útil. Limpe NO_PROXY só no processo do teste. Não mude o proxy do sistema operacional.

  1. Monte a URL com usuário e senha e exporte HTTPS_PROXY no mesmo processo. Percent-encode @, : e # na senha se eles existirem. Crie o Client depois. No laboratório a URL redigida foi http://labuser:REDACTED@127.0.0.1:60021. Com Basic correto o proxy contou proxy_auth_ok: 1. Sem userinfo o mesmo proxy devolveu 407 e o HTTPX levantou httpx.ProxyError.
Export de HTTPS_PROXY e SSL_CERT_FILE antes do Client
Caso https_proxy_connect_simulated_200 com CONNECT autenticado

SOCKS5 aparece no README só se você instala httpx[socks] e passa http_options.client_args={'proxy': 'socks5://...'}. Isso não foi instalado nem executado aqui. Não trate SOCKS5 como padrão do google-genai 2.30.1. O protocolo que este guia prova é HTTP CONNECT com Basic no userinfo.

O tipo de IP é outra conversa. HTTP descreve o salto. Residencial, móvel ou datacenter descrevem a origem do endereço. Para filtrar origem, use o catálogo de proxies residenciais ou a página de proxies móveis. Depois de colar o endpoint no processo, o verificador de proxy testa no servidor o endpoint que você informa. A página meu IP mostra o endereço de entrada do navegador. Nenhuma das duas páginas prova a rota do processo Python do SDK, nem que a Google aceitou a chave.

SOAX: proxies residenciais e móveis
SOAX: proxies residenciais e móveis3.9219

A SOAX vende proxies residenciais e móveis rotativos num pool compartilhado de créditos, com datacenter e ISP nos mesmos planos. O Builder começa em $200/mês + IVA (200 créditos); o tráfego Tier 1 é $3/GB no Builder.

85 países
US$ 3,00
por 1 GB
Oxylabs: proxies residenciais e de datacenter
Oxylabs: proxies residenciais e de datacenter4.0770

A Oxylabs vende proxies residenciais, de datacenter e móveis. Residencial self-serve começa em $6/GB para 5 GB/mês. Pagamentos de comprador: cartões, TED, AliPay, PayPal.

10 países
US$ 0,59
por 1 GB
Decodo (Smartproxy): proxies residenciais e de datacenter
Decodo (Smartproxy): proxies residenciais e de datacenter4.22106

A Decodo (antes Smartproxy) vende proxies residenciais e de datacenter. Residencial: $4/GB sem plano mensal, ou pacotes mensais a partir de $3.75/GB para 3 GB. Pagamentos: cartões, PayPal, Alipay, Google/Apple Pay, cripto (com limites).

83 países
US$ 0,38
por 1 GB

As fichas publicadas SOAX, Oxylabs e Decodo anunciam HTTP ou HTTP(S). A documentação primária descreve usuário e senha no proxy HTTP: autenticação SOAX, início rápido Oxylabs e início rápido residencial Decodo. A ficha PT de Decodo ainda usa o slug smartproxy-com. Esse recorte documentado casa com HTTPS_PROXY em http://USUARIO:SENHA@host:porta. Não medimos esses provedores com o SDK pago nem com cota Google. SOCKS5 nas mesmas fichas não foi o transporte medido neste cliente.

03Como conferir o roteamento local sem pagar a API

Uma prova genérica de TCP não é sucesso do SDK. O laboratório subiu um origin HTTPS em 127.0.0.1 com certificado emitido na hora e um proxy CONNECT na porta seguinte. O Client recebeu http_options.base_url apontando para esse origin. A resposta 200 era JSON simulado. O texto resposta-simulada-loopback não vale como cota, modelo nem elegibilidade da Google.

  1. Rode um generate_content curto contra o destino que você controla, com HTTPS_PROXY e SSL_CERT_FILE já definidos. No caso https_proxy_connect_simulated_200 o proxy registrou um CONNECT, o origin recebeu um POST e o SDK devolveu o texto simulado. Caminho observado: /v1beta/models/gemini-flash-latest:generateContent. Sem chamada paga. Sem verify=False.
Client com base_url de loopback e generate_content
POST simulado 200, um CONNECT, um hit de origin

Dependências do laboratório: Python 3.12, pip install google-genai==2.30.1, OpenSSL na PATH para emitir o CA de um dia. O openssl version da máquina foi LibreSSL 3.3.6. O módulo ssl do interpretador reportou OpenSSL 3.6.3. Se você for reproduzir o certificado local, precisa do CLI. Se você só aponta o SDK para um proxy e um destino já confiáveis, o CLI não entra.

Feche os sockets que você mesmo abriu. O laboratório chamou shutdown e server_close no origin e no proxy que ele próprio iniciou. Não reinicie um servidor que nunca chegou a escutar. Não mexa em serviço de produção.

04Como manter o TLS e esconder senha

O README pede SSL_CERT_FILE='client.pem' junto com o proxy. O HTTPX 0.28.1, com verify=True e trust_env=True, carrega SSL_CERT_FILE no lugar do CA padrão. Isso está na página de variáveis de ambiente do HTTPX. Este SDK não usa esse caminho nativo. No _api_client.py 2.30.1 o cliente pré-computa ssl.create_default_context(cafile=os.environ.get('SSL_CERT_FILE', certifi.where())) na inicialização e passa esse SSLContext em verify=. Com verify já preenchido, a leitura nativa do HTTPX não entra. A variável precisa existir antes de Client(). Trocar o ambiente depois não recria o contexto.

  1. Deixe a verificação ligada. No caso tls_without_ssl_cert_file o proxy ainda autenticou o CONNECT, proxy_connects foi 1, e o origin ficou em 0 hits. O HTTPX levantou ConnectError com [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate. O túnel abriu. O TLS recusou o certificado de laboratório porque o CA não estava em SSL_CERT_FILE. Isso é o comportamento que você quer fora de um CA controlado: falha visível, não verify=False.
TLS sem SSL_CERT_FILE, verificação permanece
CONNECT ok e CERTIFICATE_VERIFY_FAILED no caso tls_without_ssl_cert_file

Se o seu proxy corporativo intercepta TLS, o arquivo em SSL_CERT_FILE é o CA que assina o certificado apresentado ao cliente. Não importe esse CA no chaveiro do macOS só para um script. Não desligue verify. Redija usuário, senha e chave em log. O laboratório substituiu a senha por REDACTED e usou lab-dummy-key-redacted como valor dummy, nunca uma chave viva.

HttpOptions.timeout no 2.30.1 está em milissegundos. Se você não passa timeout, o SDK coloca timeout=None nos argumentos do HTTPX. Não invente um padrão de 5 segundos. Não medimos deadline neste texto.

05Como separar recusa de proxy de erro da API

O guia de troubleshooting da Gemini API manda tratar 429 RESOURCE_EXHAUSTED e 503 UNAVAILABLE como candidatos a retry com backoff, e não repetir 400, 402 ou 403. Isso é política da API. O cliente instalado é mais estreito: retry_options default é None, e retry_args devolve stop_after_attempt(1). Sem HttpRetryOptions o 2.30.1 não retria sozinho. O caso api_429_single_attempt confirmou um único hit no origin.

  1. Leia a classe da exceção e o contador de CONNECT antes de culpar a chave. Porta recusada no proxy virou httpx.ConnectError com [Errno 61] Connection refused, zero CONNECT no nosso proxy, zero POST no origin. 407 sem usuário virou httpx.ProxyError. 401 simulado depois de CONNECT virou google.genai.errors.ClientError com 401 UNAUTHENTICATED. 429 simulado virou ClientError com 429 RESOURCE_EXHAUSTED. Transporte e API não compartilham a mesma classe.
401 simulado depois de CONNECT autenticado
Caso api_401_after_connect: ClientError, um CONNECT, um hit
Caso no proof.jsonO que o proxy viuO que o origin viuClasse observada
https_proxy_connect_simulated_2001 CONNECT, Basic ok1 POST 200 simuladonenhuma, texto simulado
proxy_port_refused0 CONNECT0httpx.ConnectError Errno 61
proxy_407_missing_auth1 CONNECT, Basic recusado0httpx.ProxyError 407
tls_without_ssl_cert_file1 CONNECT, Basic ok0httpx.ConnectError CERTIFICATE_VERIFY_FAILED
api_401_after_connect1 CONNECT, Basic ok1 POST 401 simuladogoogle.genai.errors.ClientError
api_429_single_attempt1 CONNECT, Basic ok1 POST 429 simuladogoogle.genai.errors.ClientError, 1 tentativa

A linha 401 e a linha 429 são JSON de laboratório. Elas ensinam a ler a classe depois que o salto já existiu. Não são status reais da Google, não medem cota da sua conta e não autorizam retry cego em produção. Se você quiser o backoff do guia oficial, passe retry_options de propósito e meça de novo. Este artigo não fez isso.

base_url customizado no README serve a um API gateway. No laboratório ele só desviou o host para 127.0.0.1. Em produção, um base_url errado muda o destino. Não use loopback como atalho para “provar” a API paga.

06Qual protocolo e autenticação combinam com este cliente

  1. Fique no HTTP CONNECT com usuário e senha no userinfo se o seu provedor publica HTTP ou HTTPS. Sem userinfo, o caso proxy_407_missing_auth parou no proxy: Proxy-Authenticate: Basic realm="gemini-pt-lab", origin intocado. Com userinfo correto, o mesmo processo chegou ao POST. Esse é o recorte útil. IP allowlist sem senha não foi medido. mTLS de cliente Google não foi medido.
HTTPS_PROXY sem userinfo
Caso proxy_407_missing_auth: ProxyError 407, origin_hits 0

Se o provedor só entrega SOCKS5, este cliente 2.30.1 não foi demonstrado. Instalar httpx[socks] e passar client_args é outro experimento. Se o provedor só entrega um proxy de sistema no browser, o SDK não herda essa sessão. O verificador prova o endpoint informado no servidor. Meu IP prova o endereço de entrada do navegador. No processo Python, olhe CONNECT, TLS e status HTTP como na tabela. São caminhos distintos.

Custo de tráfego no Brasil costuma aparecer em dólar por GB nas fichas do catálogo, não em reais fixos neste texto. Confira a unidade na ficha do serviço antes de estimar. Pix só importa se a ficha pública listar Pix. Este guia não compra proxy e não dispara a API faturada.

O que este laboratório não mostra: conta Gemini válida, cota, região efetiva no servidor da Google, stream, async, SOCKS5, timeout numérico padrão, retry automático, confiança do macOS alterada. Sucesso de mock local não é sucesso de produção.

O HTTPS_PROXY configura o app Gemini no celular?

Não. Este guia cobre o SDK Python google-genai 2.30.1. O app e o site de consumidor não leem a variável do seu processo.

Ver o IP no navegador prova que o SDK saiu pelo proxy?

Não. O verificador testa no servidor o endpoint de proxy que você informa. Meu IP mostra o endereço de entrada do navegador. O SDK só fica provado se o processo Python fez CONNECT, TLS e o POST para o host configurado.

Proxy residencial libera a Gemini API no Brasil?

Não. A lista oficial inclui Brazil como região do produto. Roteamento e elegibilidade de conta são coisas distintas. O laboratório não chamou a API paga.

Preciso de SOCKS5 no google-genai 2.30.1?

Não neste recorte. O README documenta HTTPS_PROXY HTTP CONNECT. SOCKS5 pede httpx[socks] e client_args, não executados aqui.

O SDK retria 429 sozinho?

No 2.30.1, retry_options default é None e a prova api_429_single_attempt teve um único hit. O guia oficial da API fala em backoff para 429 e 503. Isso não ligou sozinho.

Posso desligar o TLS para o proxy corporativo?

Não neste guia. Sem SSL_CERT_FILE o laboratório falhou com CERTIFICATE_VERIFY_FAILED depois do CONNECT. Aponte o CA em SSL_CERT_FILE antes do Client.

Qual erro aparece se a senha do proxy está ausente?

httpx.ProxyError com 407 Proxy Authentication Required, origin sem POST. Não confunda com ClientError 401 da API simulada.