¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Python 3
  3. Programación asíncrona: alternativas
Extrait - Python 3 Tratamiento de los datos y técnicas de programación
Extractos del libro
Python 3 Tratamiento de los datos y técnicas de programación
1 opinión
Volver a la página de compra del libro

Programación asíncrona: alternativas

Gevent

1. Introducción

La librería Gevent permite crear en Python subrutinas para gestionar de manera eficaz los problemas de red. Se basa en el uso de greenlet y un bucle orientado a eventos con buen rendimiento (libev o libuv). La instalación se hace de la siguiente manera:

$ pip install gevent 

Por lo tanto, la librería contiene un objeto socket que trabaja de manera concurrente y algunas funciones útiles, como se muestra en este ejemplo adaptado de la documentación oficial:

>>> from gevent import socket, spawn, joinall  
>>> urls = ["eni.fr", "www.inspyration.fr", "www.python.org"]   
>>> jobs = [spawn(socket.gethostbyname, url) for url in urls]  
>>> joinall(jobs, timeout=10)  
>>> [job.value for job in jobs]  
['185.42.28.200', '213.246.53.26', '151.101.40.223'] 

En este ejemplo, vamos a pedir la IP asociada a un nombre de host y vamos a crear varias tareas para cada host, para ponerlas de forma concurrente.

La función joinall permite esperar a que todas las tareas hayan terminado. La última línea permite recuperar el resultado de cada tarea.

2. DNS

Gevent incluye las herramientas necesarias para la resolución de nombre de dominio, como muestra el ejemplo anterior. Se trata de una reescritura iso-funcional parcial de las funcionalidades presentes en el módulo python socket. Por lo tanto, puede consultar la documentación oficial para saber cómo se deben utilizar estas funciones y lo que devuelven.

A continuación se muestra la lista de estas funciones:...

Twisted

1. Introducción

Twisted es una herramienta que permite crear un servidor internet y no solamente un servidor web. En otras palabras, no solo administra el protocolo HTTP, sino que puede hacer WebDav, FTP o implementar sus propios protocolos.

Para instalarla:

$ pip install twisted 

El objeto central es un reactor y este último va a hacer funcionar los protocolos, que son descripciones de los datos esperados y las respuestas a proporcionar. Estos protocolos se construyen sobre los transportes, tales como el transporte TCP o UDP.

2. Cliente/servidor TCP

A continuación se muestra un ejemplo de servidor TCP básico: devuelve un echo del dato que recibe. Vamos a empezar importando lo que necesitamos:

from twisted.internet import reactor  
from twisted.internet.protocol import Protocol, ServerFactory 

A continuación se muestra un ejemplo sencillo de protocolo que permite devolver el dato recibido:

class Echo(Protocol):  
    def dataReceived(self, data):  
        "As soon as any data is received, echo it back."  
        self.transport.write(data) 

Es suficiente con conocer las diferentes funciones a sobrecargar, para crear su propio protocolo y hacer lo que queremos.

Para que funcione este protocolo, hay que montar el reactor:

def main():  
    """This runs the protocol on port 8000"""  
    factory = ServerFactory()  
    factory.protocol = Echo  
    reactor.listenTCP(8000,factory)  
    reactor.run() 

Este código le debería resultar muy familiar, si ya ha leído el capítulo sobre la programación de red o incluso, el de la programación web.

Después hay que ejecutarlo:

if __name__ == '__main__':  
    main() 

Para la parte cliente, se escribe también un protocolo:

class EchoClient(protocol.Protocol):  
  
    def connectionMade(self):  
        self.transport.write(b"hello, world!")  
  
    def dataReceived(self, data):  
        print("Server said:", data)  
       ...

Trollius

Como sabe, asyncio está disponible solamente para Python 3.4 o superior. sin embargo, existe una alternativa para Python 2.7, cuya rama siempre está activa y lo estará incluso algunos años.

Como sucede con asyncio, trollius ofrece un bucle orientado a eventos, así como los transportes y protocolos entre los que se puede encontrar TCP, UDP o SSL como hemos presentado en el capítulo anterior. Sin embargo, atención, estos protocolos se basan en los de twisted, más que en los de asyncio. Es uno de los motivos por el que hemos introducido twisted justo antes.

También, este módulo le permitirá más básicamente, crear subrutinas y tareas y sincronizarlas.

A continuación se muestra un ejemplo de protocolo UDP (que se parece mucho a lo que hemos podido ver anteriormente):

class ServerUdpEchoProtocol:  
  
    def connection_made(self, transport):  
        print('{transport} started'.format(transport=transport))  
        self.transport = transport  
  
    def datagram_received(self, data, addr):  
        print('Data {data} received from {addr}'.format(data=data, 
addr=addr))  
       ...

HTTP asíncrona con aiohttp

1. Lado servidor

Ya se ha presentado bottlepy y mencionado la alternativa flask. Se trata de microframeworks web, que permiten responder a necesidades sencillas.

Hay una alternativa que sintácticamente es muy cercana y que presenta la ventaja de utilizar la programación asíncrona.

A continuación se muestra el ejemplo de introducción de aiohttp:

from aiohttp.web import  RouteTableDef, Response , Application,  
run_app  
  
routes = RouteTableDef()  
  
@routes.get('/')  
async def hello(request):  
    return Response(text="Hello World!")  
  
app = Application()  
app.add_routes(routes)  
run_app(app) 

Compárelo con un ejemplo similar con bottlepy:

from bottle import route, run, template  
  
@route('/')  
def index():  
    return "Hello World!"   
run(host="localhost", port=8080) 

o Flask:

from flask import Flask  
app = Flask("test App")  
  
@app.route("/")  
def hello():  
    return "Hello World!" 

Con aiohttp, los métodos se pueden escribir usando la programación asíncrona:

from aiohttp.web import json_response  
  
async...