Emitir solicitudes HTTP(S)

ID de región

El REGION_ID es un código abreviado que Google asigna en función de la región que selecciones al crear tu aplicación. El código no corresponde a un país o provincia, aunque algunos IDs de región pueden parecerse a los códigos de país y provincia que se usan habitualmente. En las aplicaciones creadas después de febrero del 2020, REGION_ID.r se incluye en las URLs de App Engine. En las aplicaciones creadas antes de esa fecha, el ID de región es opcional en la URL.

Más información sobre los IDs de región

En esta página se describe cómo enviar solicitudes HTTP(S) desde tu aplicación de App Engine.

De forma predeterminada, App Engine usa el servicio de obtención de URLs para enviar solicitudes HTTP(S) salientes.

Para obtener información sobre los límites de tamaño de las solicitudes y los encabezados que se envían en una solicitud de obtención de URL, consulta Solicitudes salientes.

Si has configurado el acceso a VPC sin servidor o usas la API Sockets, debes impedir que URL Fetch gestione las solicitudes. URL Fetch provoca que las solicitudes a tu red de VPC o a la API Sockets fallen. Después de inhabilitar Obtención de URLs, la biblioteca estándar de Python gestionará las solicitudes HTTP. Si necesitas las funciones que proporciona URL Fetch para solicitudes específicas, puedes usar la biblioteca urlfetch directamente para esas solicitudes.

Enviar una solicitud HTTP

Para enviar una solicitud HTTP de salida, 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 enviar solicitudes HTTP. Cuando usas estas bibliotecas en App Engine, realizan solicitudes HTTP mediante el servicio de obtención de URLs de App Engine. También puede usar la biblioteca de terceros requests siempre que la configure para que use URLFetch.

urlfetch

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

from google.appengine.api import urlfetch

A continuación, usa urlfetch para hacer 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, enviando datos de un formulario web a través de una solicitud HTTP POST mediante 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 muestra cómo realizar una solicitud HTTP GET básica con urllib2. Primero, importa la biblioteca urllib2:

import urllib2

A continuación, usa urllib2 para hacer 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, tendrás que instalar requests y requests-toolbelt siguiendo las instrucciones de proveedor.

Una vez instalado, usa el módulo requests_toolbelt.adapters.appengine para configurar las solicitudes de forma que 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 configurado, puedes usar las solicitudes de forma habitual:

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.

Definir un tiempo de espera de las solicitudes

Puedes ajustar la fecha límite predeterminada con la función urlfetch.set_default_fetch_deadline(). Esta función almacena el nuevo plazo predeterminado en una variable local del hilo, por lo que debe definirse para cada solicitud (por ejemplo, en un middleware personalizado).

Inhabilitar redirecciones

Si usas URL Fetch, el servicio subyacente de URL Fetch sigue hasta cinco redirecciones de forma predeterminada. Estas redirecciones podrían reenviar información sensible, como encabezados de autorización, al destino de la redirección. Si tu aplicación no requiere redirecciones HTTP, te recomendamos que las inhabilites.

Para indicar al servicio de obtención de URLs que no siga las redirecciones, asigna el valor False al parámetro follow_redirects del método fetch.

Emitir una solicitud HTTPS

De forma predeterminada, el servicio URL Fetch subyacente valida el certificado del host con el que se pone en contacto y rechaza las solicitudes si el certificado no coincide. No es necesario que protejas explícitamente tu solicitud.

Inhabilitar la validación de certificados de host

Para inhabilitar la validación automática de certificados de host en URL Fetch, emite una solicitud HTTPS y asigna el valor False al parámetro validate_certificate al llamar al método urlfetch.fetch().

Enviar una solicitud asíncrona

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

  1. Crea un objeto RPC con urlfetch.create_rpc(). Este objeto representa tu llamada asíncrona en llamadas de método posteriores.
  2. Llama al urlfetch.make_fetch_call() para hacer la solicitud. Este método usa tu objeto RPC y la URL del destino de la solicitud como parámetros.
  3. Llama al método get_result() del objeto RPC. Este método devuelve el objeto de resultado si la solicitud se realiza correctamente y genera una excepción si se produce un error durante la solicitud.

En los siguientes fragmentos se muestra cómo hacer 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 hacer 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')

Definir un tiempo de espera de las solicitudes

Para definir un tiempo de espera para tu solicitud, asigna el parámetro deadline del método urlfetch.create_rpc() al crear tu objeto RPC.

Usar una función de retrollamada

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

Para usar una función de retrollamada que gestione el resultado de tu llamada de obtención, haz lo siguiente:

  1. Crea una función auxiliar para definir el ámbito de la devolución de llamada.
  2. Crea una función de controlador para gestionar el resultado de la llamada de obtención.
  3. Asigna el atributo callback del objeto RPC a la función auxiliar.

En el siguiente fragmento se muestra cómo invocar una función de retrollamada:

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

Enviar una solicitud a otra aplicación de App Engine

Cuando envíes una solicitud a otra aplicación de App Engine, tu aplicación de App Engine debe afirmar su identidad añadiendo el encabezado X-Appengine-Inbound-Appid a la solicitud. Si le indicas al servicio de obtención de URLs que no siga las redirecciones, App Engine añadirá automáticamente este encabezado a las solicitudes.

Consulta Inhabilitar redirecciones para obtener información sobre cómo inhabilitar redirecciones.

Siguientes pasos

Consulta información sobre el servicio de obtención de URLs, como los encabezados que se envían en una solicitud de obtención de URLs en Solicitudes salientes.