Emitir pedidos HTTP(S)

ID da região

O REGION_ID é um código abreviado que a Google atribui com base na região que seleciona quando cria a sua app. O código não corresponde a um país ou uma província, embora alguns IDs de regiões possam parecer semelhantes aos códigos de países e províncias usados frequentemente. Para apps criadas após fevereiro de 2020, REGION_ID.r está incluído nos URLs do App Engine. Para apps existentes criadas antes desta data, o ID da região é opcional no URL.

Saiba mais acerca dos IDs de regiões.

Esta página descreve como emitir pedidos HTTP(S) a partir da sua app do App Engine.

Por predefinição, o App Engine usa o serviço URL Fetch para emitir pedidos HTTP(S) de saída.

Para ver detalhes sobre os limites de tamanho dos pedidos e os cabeçalhos enviados num pedido de obtenção de URL, consulte o artigo Pedidos de saída.

Se tiver configurado o acesso VPC sem servidor ou se usar a API Sockets, tem de impedir que a obtenção de URLs processe pedidos. A obtenção de URLs faz com que os pedidos à sua rede VPC ou à API Sockets falhem. Depois de desativar a obtenção de URLs, a biblioteca Python padrão processa os pedidos HTTP. Se precisar das funcionalidades fornecidas pela obtenção de URLs para pedidos específicos, pode usar a biblioteca urlfetch diretamente para esses pedidos específicos.

Emitir um pedido HTTP

Para emitir um pedido HTTP de saída, use o método urlfetch.fetch. Para melhorar a portabilidade do código, também pode usar as bibliotecas padrão do Python urllib, urllib2 ou httplib para emitir pedidos HTTP. Quando usa estas bibliotecas no App Engine, estas fazem pedidos HTTP através do serviço URL Fetch do App Engine. Também pode usar a biblioteca de terceiros requests, desde que a configure para usar o URLFetch.

urlfetch

Os fragmentos seguintes demonstram como executar um pedido HTTP GET básico usando urlfetch. Primeiro, importe a biblioteca urlfetch do SDK do App Engine:

from google.appengine.api import urlfetch

Em seguida, use urlfetch para fazer o pedido GET:

url = 'http://www.google.com/humans.txt'
try:
    result = urlfetch.fetch(url)
    if result.status_code == 200:
        self.response.write(result.content)
    else:
        self.response.status_code = result.status_code
except urlfetch.Error:
    logging.exception('Caught exception fetching url')

O fragmento seguinte demonstra como fazer um pedido mais avançado, enviando dados de um formulário Web através de um pedido HTTP POST usando urlfetch:

try:
    form_data = urllib.urlencode(UrlPostHandler.form_fields)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    result = urlfetch.fetch(
        url='http://localhost:8080/submit_form',
        payload=form_data,
        method=urlfetch.POST,
        headers=headers)
    self.response.write(result.content)
except urlfetch.Error:
    logging.exception('Caught exception fetching url')

urllib2

Os fragmentos seguintes demonstram como executar um pedido HTTP GET básico usando urllib2. Primeiro, importe a biblioteca urllib2:

import urllib2

Em seguida, use urllib2 para fazer o pedido GET:

url = 'http://www.google.com/humans.txt'
try:
    result = urllib2.urlopen(url)
    self.response.write(result.read())
except urllib2.URLError:
    logging.exception('Caught exception fetching url')

pedidos

Para usar pedidos, tem de instalar o requests e o requests-toolbelt através das instruções de fornecimento.

Depois de instalado, use o módulo requests_toolbelt.adapters.appengine para configurar os pedidos de modo a usar o URLFetch:

import requests
import requests_toolbelt.adapters.appengine

# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt.adapters.appengine.monkeypatch()

Depois de configuradas, pode usar as solicitações normalmente:

url = 'http://www.google.com/humans.txt'
response = requests.get(url)
response.raise_for_status()
return response.text

Para mais informações sobre o suporte de pedidos para o Google App Engine, consulte a documentação de urllib3.contrib.appengine e requests_toolbelt.appengine

Defina um limite de tempo do pedido

Pode ajustar o prazo predefinido através da função urlfetch.set_default_fetch_deadline(). Esta função armazena o novo prazo predefinido numa variável local do segmento, pelo que tem de ser definida para cada pedido, por exemplo, num middleware personalizado.

Desative os redirecionamentos

Se estiver a usar a obtenção de URL, o serviço de obtenção de URL subjacente segue até cinco redirecionamentos por predefinição. Estes redirecionamentos podem encaminhar informações confidenciais, como cabeçalhos de autorização, para o destino redirecionado. Se a sua app não requerer redirecionamentos HTTP, recomendamos que os desative.

Para indicar ao serviço de obtenção de URLs que não siga os redirecionamentos, defina o parâmetro follow_redirects do método fetch como False.

Emitir um pedido HTTPS

Por predefinição, o serviço URL Fetch subjacente valida o certificado do anfitrião que contacta e rejeita pedidos se o certificado não corresponder. Não precisa de proteger explicitamente o seu pedido.

Desative a validação de certificados de anfitrião

Para desativar a validação automática de certificados de anfitrião na obtenção de URLs, envie um pedido HTTPS e defina o parâmetro validate_certificate como False quando chamar o método urlfetch.fetch().

Emita um pedido assíncrono

Os pedidos HTTP(S) são síncronos por predefinição. Para emitir um pedido assíncrono, a sua aplicação tem de:

  1. Crie um novo objeto RPC com urlfetch.create_rpc(). Este objeto representa a sua chamada assíncrona em chamadas de métodos subsequentes.
  2. Ligue para urlfetch.make_fetch_call() para fazer o pedido. Este método usa o objeto RPC e o URL do destino do pedido como parâmetros.
  3. Chame o método get_result() do objeto RPC. Este método devolve o objeto de resultado se o pedido for bem-sucedido e gera uma exceção se ocorrer um erro durante o pedido.

Os fragmentos seguintes demonstram como fazer um pedido assíncrono básico a partir de uma aplicação Python. Primeiro, importe a biblioteca urlfetch do SDK do App Engine:

from google.appengine.api import urlfetch

Em seguida, use urlfetch para fazer o pedido assíncrono:

rpc = urlfetch.create_rpc()
urlfetch.make_fetch_call(rpc, 'http://www.google.com/')

# ... do other things ...
try:
    result = rpc.get_result()
    if result.status_code == 200:
        text = result.content
        self.response.write(text)
    else:
        self.response.status_int = result.status_code
        self.response.write('URL returned status code {}'.format(
            result.status_code))
except urlfetch.DownloadError:
    self.response.status_int = 500
    self.response.write('Error fetching URL')

Defina um limite de tempo do pedido

Para definir um limite de tempo para o seu pedido, defina o parâmetro deadline do método urlfetch.create_rpc() quando criar o objeto RPC.

Use uma função de chamada de retorno

Pode definir uma função de retorno de chamada para o seu objeto RPC. A função é chamada quando a sua aplicação chama um método no objeto, como wait(), checksuccess() ou get_result(), que faz com que o objeto aguarde a conclusão do pedido.

Para usar uma função de chamada de retorno para processar o resultado da sua chamada de obtenção:

  1. Crie uma função auxiliar para definir o âmbito da devolução de chamada.
  2. Crie uma função de controlador para processar o resultado da sua chamada de obtenção.
  3. Defina o atributo callback do objeto RPC para a função auxiliar.

O fragmento seguinte demonstra como invocar uma função de chamada de retorno:

def handle_result(rpc):
    result = rpc.get_result()
    self.response.write(result.content)
    logging.info('Handling RPC in callback: result {}'.format(result))

urls = ['http://www.google.com',
        'http://www.github.com',
        'http://www.travis-ci.org']
rpcs = []
for url in urls:
    rpc = urlfetch.create_rpc()
    rpc.callback = functools.partial(handle_result, rpc)
    urlfetch.make_fetch_call(rpc, url)
    rpcs.append(rpc)

# ... do other things ...

# Finish all RPCs, and let callbacks process the results.

for rpc in rpcs:
    rpc.wait()

logging.info('Done waiting for RPCs')

Emitir um pedido para outra app do App Engine

Quando emite um pedido para outra app do App Engine, a sua app do App Engine tem de afirmar a sua identidade adicionando o cabeçalho X-Appengine-Inbound-Appid ao pedido. Se instruir o serviço URL Fetch para não seguir redirecionamentos, o App Engine adiciona este cabeçalho aos pedidos automaticamente.

Consulte o artigo Desativar redirecionamentos para obter orientações sobre como desativar redirecionamentos.

O que se segue?

Saiba mais sobre o serviço de obtenção de URL, como os cabeçalhos que são enviados num pedido de obtenção de URL em Pedidos de saída.