Emitir solicitudes HTTP(S)

ID de región

REGION_ID es un código abreviado que Google asigna en función de la región que eliges cuando creas la app. El código no corresponde a un país ni a una provincia, aunque algunos ID de región puedan parecer similares a los códigos de país y provincia que se suelen usar. En el caso de las apps creadas después de febrero de 2020, REGION_ID.r se incluye en las URL de App Engine. En el caso de las apps existentes creadas antes de esta fecha, el ID de región es opcional en la URL.

Obtén más información acerca de los ID de región.

Esta página describe cómo emitir solicitudes HTTP(S) desde tu aplicación de App Engine.

De forma predeterminada, App Engine usa el servicio de recuperación de URL para emitir solicitudes HTTP(S) salientes.

Para obtener más información sobre cuáles son los límites de tamaño de las solicitudes y qué encabezados se envían en una solicitud de recuperación de URL, consulta Solicitudes salientes.

Si configuraste el acceso a VPC sin servidores o si usas la API de sockets, debes detener la recuperación de URL del control de solicitudes. La recuperación de URL hace que las solicitudes a tu red de VPC o a la API de Sockets no funcionen. Después de inhabilitar la recuperación de URL, la biblioteca estándar de Python manejará las solicitudes HTTP. Si necesitas las funciones que proporciona la recuperación de URL para solicitudes específicas, puedes usar la biblioteca urlfetch directamente para esas solicitudes específicas.

Emite una solicitud HTTP

Para emitir una solicitud HTTP saliente, usa el método urlfetch.fetch. Para mejorar la portabilidad del código, también puedes usar las bibliotecas estándar de Python urllib, urllib2 o httplib para emitir solicitudes HTTP. Cuando usas estas bibliotecas en App Engine, realizan solicitudes HTTP con el servicio de recuperación de URL de App Engine. También puedes usar la biblioteca requests de terceros, siempre que la configures para usar URLFetch.

urlfetch

En los siguientes fragmentos, se demuestra cómo realizar una solicitud HTTP básica GET con urlfetch. Primero, importa la biblioteca urlfetch del SDK de App Engine:

from google.appengine.api import urlfetch

A continuación, usa urlfetch para realizar la solicitud 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')

En el siguiente fragmento, se muestra cómo realizar una solicitud más avanzada, mediante el envío de datos desde un formulario web a través de una solicitud POST HTTP con 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

En los siguientes fragmentos, se demuestra cómo realizar una solicitud HTTP básica GET con urllib2. Primero, importa la biblioteca urllib2:

import urllib2

A continuación, usa urllib2 para realizar la solicitud 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')

solicitudes

Para usar las solicitudes, deberás instalar requests y requests-toolbelt con las instrucciones de vendoring.

Una vez instalados, usa el módulo requests_toolbelt.adapters.appengine para configurar que las solicitudes usen 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()

Una vez configuradas, puedes usarlas de manera normal:

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

Para obtener más información sobre la compatibilidad de las solicitudes con Google App Engine, consulta la documentación de urllib3.contrib.appengine y requests_toolbelt.appengine

Configura el tiempo de espera de una solicitud

Puedes configurar el plazo predeterminado con la función urlfetch.set_default_fetch_deadline(). Esta función almacena este plazo nuevo predeterminado en una variable local de conversación, así que debe configurarse en cada solicitud, por ejemplo, en un middleware personalizado.

Inhabilita los redireccionamientos

Si usas la recuperación de URL, el servicio de recuperación de URL subyacente sigue hasta cinco redireccionamientos de forma predeterminada. Estos redireccionamientos podrían reenviar información sensible, como los encabezados de autorización, al destino redireccionado. Si tu app no requiere redireccionamientos HTTP, se recomienda que los inhabilites.

Para indicarle al servicio de recuperación de URL que no siga los redireccionamientos, configura el parámetro follow_redirects del método fetch en False.

Cómo emitir una solicitud HTTPS

Para emitir una solicitud HTTPS, configura el parámetro validate_certificate en true cuando llames al método urlfetch.fetch().

Emite una solicitud asíncrona

Las solicitudes HTTP(S) son síncronas de manera predeterminada. Para emitir una solicitud asíncrona, tu aplicación debe hacer lo siguiente:

  1. Crea un objeto RPC nuevo con urlfetch.create_rpc(). Este objetivo representará tu llamada asíncrona en las llamadas de método subsecuentes.
  2. Llama a urlfetch.make_fetch_call() para realizar la solicitud. Este método toma tu objeto RPC y la URL de destino de la solicitud como parámetros.
  3. Llamar al método get_result() del objeto RPC. Este método muestra el objeto resultante si la solicitud es correcta y genera una excepción si ocurre un error durante la solicitud.

Los fragmentos siguientes muestran cómo realizar una solicitud asíncrona básica desde una aplicación de Python. Primero, importa la biblioteca urlfetch del SDK de App Engine:

from google.appengine.api import urlfetch

A continuación, usa urlfetch para realizar la solicitud asíncrona:

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')

Configura el tiempo de espera de una solicitud

Para configurar el tiempo de espera de tu solicitud, configura el parámetro deadline del método urlfetch.create_rpc() cuando crees el objeto RPC.

Emplea una función de devolución de llamada

Puedes definir una función de devolución de llamada para tu objetivo de RPC. Se llamará a la función cuando tu aplicación llame a un método del objetivo, como wait(), checksuccess() o get_result(), que haga que el objetivo espere a que se complete la solicitud.

Para usar una función de devolución de llamada que controle el resultado de tu llamada de recuperación, haz lo siguiente:

  1. Crea una función auxiliar que defina el alcance de la devolución de llamada.
  2. Crea una función controladora que maneje el resultado de tu llamada de recuperación.
  3. Configura el atributo callback de tu objeto RPC en la función auxiliar.

El fragmento siguiente muestra cómo invocar una función de devolución de llamada:

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')

Emite una solicitud dirigida a otra app de App Engine

Cuando se emite una solicitud a otra app de App Engine, la tuya debe afirmar su identidad; para eso, se agrega el encabezado X-Appengine-Inbound-Appid a la solicitud. Si le indicas al servicio de recuperación de URL que no siga los redireccionamientos, App Engine agregará este encabezado a las solicitudes de manera automática.

Consulta Inhabilita redireccionamientos para obtener más orientación.

¿Qué sigue?

Obtén más información sobre el servicio de recuperación de URL, como los encabezados que se envían en una solicitud de recuperación de URL, en Solicitudes de salida.