Tag Archives: Python

Sencillo parser para Apache mod_status en Python

Cuánto hace que no actualizo este blog!! Hoy estuve jugando un poco con Python y me puse a hacer un pequeño script que supongo que a otros les podrá servir como base para hacer algo más interesante. Precisamente, tengo planes para hacer algo más interesante, pero como recién están en veremos, les voy pasando esta pequeña base a ver si alguien me gana de mano :-)

Como muchos sabrán, Apache (y otros web servers) tiene un módulo llamado mod_status que nos permite ver en tiempo real el estado del servidor (los requests que se están procesando, el uso del CPU, el estado de las conexiones, etc.). Esta información puede ser muy útil para hacer diagnósticos cuando está habiendo algún tipo de problema, para hacer monitoreo, etc. El módulo nos muestra una página web con la información y tiene dos interfaces: una está pensada para ser vista por seres humanos y otra para ser consultada por scripts (para ver esta segunda sólo hace falta pasarle el parámetro “?auto” en la URL). El problema es que esta segunda interfaz no nos muestra a qué dominios (virtual hosts) están dirigidos los requests que se están procesando (o si hay forma de que lo muestre yo no la encontré). Entonces me puse a hacer un sencillo script en Python para parsear la página “para seres humanos”.

Por suerte Python nos ofrece muchas herramientas muy útiles para este tipo de cosas, así que no me tuve que esforzar demasiado. En este caso utilicé urllib2 para acceder a la página de mod_status y BeautifulSoup para parsear el HTML. Por si no lo conocen, BeautifulSoup es un muy poderoso parser para XML/HTML hecho en Python. No viene con el código fuente sino que hay que instalarlo, pero hacerlo es muy fácil:

En Debian/Ubuntu:

apt-get install python-beautifulsoup

En CentOS/RedHat:

yum install python-BeautifulSoup

Con easy_install:

easy_install BeautifulSoup

El código tiene una clase Status que es la que hace la magia y una función main() que utiliza la clase para parsear una URL e imprimir algunos datos a modo de ejemplo.

import sys
import urllib2
from operator import itemgetter
from BeautifulSoup import BeautifulSoup

class Status (object):
    _url = None

    def __init__ (self, url):
        self._url = url

    def fetch (self):
        return urllib2.urlopen(self._url).read()

    def parse (self):
        html = self.fetch()
        soup = BeautifulSoup(html)
        status = {}
        status[‘server_info’] = [i.string.strip() for i in soup.findAll(‘dt’)]
        status[‘requests’] = []
        requests = soup.find(‘table’).findAll(‘tr’)
        keys = [i.string for i in requests.pop(0)]
        for tr in requests:
            req = {}
            for n, td in enumerate(tr):
                req[keys[n]] = td.string
            status[‘requests’].append(req)
        return status

def main (argv):
    if len(argv) < 2:
        print "Usage %s "%argv[0]
        return 1

    status = Status(argv[1])
    data = status.parse()
    print "SERVER INFORMATION"
    print "=================="
    for v in data[‘server_info’]:
        print v

    print "REQUESTS BY VHOST"
    print "================="
    entries = [i[‘VHost’] for i in data[‘requests’]]
    requests = sorted([(entries.count(i), i) for i in list(set(entries))], reverse=True)
    print "\n".join(["%d: %s"%(a,b) for a,b in requests])

if __name__ == "__main__":
    sys.exit(main(sys.argv))

La forma de uso es:

python status.py "http://localhost/server-status"

Y en este caso la salida del script es algo así:

SERVER INFORMATION
==================
Server Version: Apache/2.2.19 (Unix) mod_ssl/2.2.19 OpenSSL/0.9.8e-fips-rhel5 DAV/2
Server Built: May 26 2011 15:14:47
Current Time: Sunday, 31-Jul-2011 00:53:59 ART
Restart Time: Saturday, 30-Jul-2011 12:07:12 ART
Parent Server Generation: 0
Server uptime:  12 hours 46 minutes 47 seconds
Total accesses: 407813 - Total Traffic: 3.7 GB
CPU Usage: u2.05 s3.23 cu52 cs0 - .125% CPU load
8.86 requests/sec - 85.0 kB/second - 9.6 kB/request
10 requests currently being processed, 8 idle workers
REQUESTS BY VHOST
=================
9: www.tail-f.com.ar
5: www.otro-dominio.com.ar
4: www.not-a-domain.com.ar
3: www.algunlado.com.ar
2: subdominio.dominio.com.ar
1: www.pepe.com.ar
1: www.no-votes-a-macri.com.ar
1: www.asd.com.ar
1: localhost

Obviamente esto no es una aplicación funcional, sino un ejemplo que espero que les sirva para hacer algo más copado. Yo seguiré jugando y si hago algo un poco más interesante, ya se los mostraré.

Ya salió PET: English Translation!

Hace unos días comenté la salida del primer número de la revista PET: Python Entre Todos. Como también adelanté en esa oportunidad, se descubrió que se trataba de la única revista de Python en el mundo (activa por lo menos). Así que luego de varios días de esfuerzo se tradujo el primer número y salió PET: English Translation.

PET: English Translation

PET: English Translation

Los artículos de este número son:

Como también ya les había adelantado, en este número tuve oportunidad de participar traduciendo dos artículos. PyAr, The History de Facundo Batista y How is this magazine made? de Roberto Alsina.

Además, aprovechando la ampliación del público de la revista, se ha agregado la posibilidad de hacer donaciones para la comunidad PyAr, de manera de solventar futuras actividades como impresiones del tutorial de Python, compra de materiales, charlas, etc.

Notificaciones de mails Prioritarios de Gmail en nuestro escritorio

GMail

GMail

En estos días GMail empezó a implementar la Priority Inbox, o Prioritarios en su versión en castellano. No es nada demasiado novedoso, en realidad es una etiqueta que define a un mensaje como prioritario. Lo más interesante es que Gmail no solamente te puede mostrar por separado los mails con prioridad de los otros, sino que nos promete ir “aprendiendo” a determinar cuáles son prioritarios y cuáles no.

En estos días estuve probando el feature y me viene bien. Yo recibo muchos mails por día, la mayoría de distintas listas de correo. Y como soy muy obsesivo, cada vez que tengo un mensaje nuevo voy a ver de qué se trata y “marcarlo como leído”. Este feature me permite perocuparme solamente por los prioritarios y dejar los menos importantes (como los de las listas) para más tarde.

Hoy pensé: “qué bueno estaría tener una aplicación que me notifique solamente de los mails importantes”. Ya existen varios notifiers para Gmail, tanto de Google o de terceros, para Firefox o para el Desktop. Pero supongo que todavía no habrán implementado esta posibilidad de solamente avisarte de los mensajes prioritarios. Así que lo que hice fue hacerlo en Python que es muuuy fácil.

En su versión simplificada, ver si hay mails “Importantes” y notificarlo es tan sencillo como esto:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import imaplib
import pynotify
from email.header import decode_header
from email.parser import Parser

host = ‘imap.gmail.com’
port = 993
username = ‘usuario@gmail.com’
password = ‘passwordsupersecreto’

def get_header (msg, header):
        """Gets a header from a message"""
        header = decode_header(msg.get(header))
        if (header[0][1]):
            return unicode(header[0][0], header[0][1]).encode(‘utf8′)
        else:
            return header[0][0]

if not pynotify.init("GMail Important Messages"):
    print "Failed to initialize pynotify"
    sys.exit(1)

client =  imaplib.IMAP4_SSL(host, port)
if not client.login(username, password):
    print "Failed to login"
    sys.exit(1)

status, data = client.select(‘[Gmail]/Important’)
if status != ‘OK’:
    print "Failed to select Important label"
    sys.exit(1)

status, data = client.search(None, ‘(UNSEEN)’)
if status == ‘OK’ and data[0] != :
    for msg_id in sorted(data[0].split()):
        if msg_id != :
            status, data = client.fetch(msg_id, ‘(RFC822)’)
            if status == ‘OK’:
                msg = Parser().parsestr(data[0][1])
                pynotify.Notification(get_header(msg, ‘From’), \
                                       get_header(msg, ‘Subject’)).show()
            else:
                print "Failed to fetch message #%s" % str(msg_id)

Ese código lo que hace es inicializar pynotify, conectarse al servidor IMAP de GMail usando imaplib, autenticarse con el user y password provisto, seleccionar la etiqueta “[Gmail]/Important” y ver si hay mensajes sin leer. En caso de que haya itera sobre ellos, obtiene su contenido (para sacar el remitente y el asunto) y lanza un mensaje de notificación.

Para convertir eso en una aplicación básicamente hace falta meterlo en un while y corregir un detalle que es que el fetch del mensaje lo marca como leído (y eso no es algo que queramos en un simple notificador), así que hay que volver a marcarlo como no leído. Eso y algunos toques cosméticos es lo que hice en el script completo.

Por supuesto se trata solo de una prueba de concepto y a una aplicación completamente funcional deberían hacersele algunas correcciones más. Pero creo que es una idea divertida como para que otros puedan hacer algo mejor.

PET: Python Entre Todos, primera revista de Python

A esta altura ya es una noticia vieja, pero quizás alguno no se haya enterado de que la semana pasada salió publicada la revista PET: Python Entre Todos.

La revista es una producción colaborativa de la Comunidad PyAr, con artículos de muy alto nivel de distintos participantes de la lista y el esfuerzo especial de sus dos editores, Roberto Alsina y Emiliano Dalla Verde Marcozzi.

PET: Python Entre Todos Num. 1

PET: Python Entre Todos Num. 1

Los artículos incluidos en la revista son:

  • PET First Shot
  • Cómo contribuir a PET
  • PyAr, la historia
  • from gc import commonsense – Finish Him!
  • Concurrencia Indolora: el módulo processing
  • Introducción a Unit Testing con Python
  • Taint Mode en Python
  • Dinamismo Aplicado
  • Decorando Código (Parte 1)
  • Web2Py Para Todos
  • ¿Cómo Está Hecha Esta Revista?
  • Desafío PET
  • Un poco de xkcd

La publicación fue todo un éxito porque se dinfundió rápidamente por Internet con la ayuda de diversos medios: blogs, twitter, barrapunto, etc. En mi opinión esta buena recepción se debió dos factores clave: la calidad del contenido que es realmente muy alta y que gracias a las tecnologías de software libre utilizadas para la edición de la revista, la misma pudo ser publicada en múltiples formatos: HTML online, PDF en distintos layouts y para e-book readers en ePub y Mobi. A todos ellos se puede acceder en la página del primer número de la revista.

Además, al poco tiempo de publicada la revista, Roberto descubrió que PET es la primera revista de Python… en el mundo!. Esto animó a la comunidad a crear una versión en inglés para poder difundirla a un mayor público. Personalmente tuve la opotunidad de colaborar traduciendo dos artículos, “PyAr, la historia” de Facundo Batista y “¿Cómo Está Hecha Esta Revista?” de Roberto Alsina. De esta manera, si no puedo aportar con un artículo interesante, por lo menos puedo colaborar para que las cosas interesantes que escriben otros puedan llegar a un público más amplio.

Así que seguramente pronto estemos anunciando la versión en inglés del número 1 de PET. Y en el futuro, según entiendo, la idea es poder incorporar artículos de colaboradores internacionales en ambas versiones de la revista.

Una vueltita por las Charlas Abiertas de Python en La Tribu

Charlas Abiertas de Python en La Tribu

Hoy pude darme una vuelta, por primera vez, por las Charlas Abiertas de Python en La Tribu. Le robé un tiempo al estudio y me dirigí a Lambaré 873 junto a un amigo, a ver qué tal estaban esas charlas.

No esperaba encontrar grandes revelaciones porque la charla a la que iba era la de Introducción al Desarrollo Web I, a cargo de Alejandro Cura, y yo ya trabajo en el rubro hace algunos años. Sin embargo me interesaba verle las caras a algunos miembros de la comunidad por quienes tengo un gran respeto.

Me encontré con un ámbito muy amigable, lleno de gente deseosa de aprender. Me alegró mucho encontrar algunas personas “mayores” (por lo menos mayores al tipo de gente que uno suele conocer en este acotado segmento del mercado laboral), muy interesadas y participativas. La charla estuvo muy bien, era una introducción para quienes no tienen idea de en qué consiste hacer un sitio web (y preparatoria para la próxima charla que dará algunos conceptos básicos de Web2Py). Me pareció muy copado que se le diera un poco de bola al protocolo HTTP y cómo funciona, porque en mi experiencia laboral me he encontrado con desarrolladores que pueden manejar muy bien algunos lenguajes como PHP, Javascript o HTML pero no tienen idea de cómo llegan esas cosas “a la mesa” del browser.

Incluso me encontré aprendiendo una cosita de CSS que no sabía y era la posibilidad de incluir tipografías externas (que quisiera ver qué tan compatible es con la bosta de IE, pero que me resultó muy útil).

Me hubiera gustado quedarme a la charla siguiente del eminente Roberto Alsina, pero lamentablemente tenía que volver a la cueva a estudiar.

Felicito desde este humilde lugar el enorme trabajo que está realizando la comunidad PyAr organizando estas charlas que permiten acercar herramientas a la sociedad para conocer y apropiarse de las nuevas tecnologías asociadas a la informática e Internet.