viernes, 23 de noviembre de 2012

Consultas a URLS a través de Python

Algunas veces surge la necesidad de hacer consultas a una URL desde un programa, y no desde un navegador Web. La ventaja de hacer este tipo de consultas a través de una aplicación es que se pueden aplicar acciones automatizadas, repetitivas o programadas, contrario a las consultas que los usuarios realizan a través de un navegador.

De esta forma, es posible hacer consultas sobre bases de datos o servicios en la Web, de forma automática. A continuación se mostrará la forma de hacer este tipo de consultas desde una aplicación de Python, y se mostrará una aplicación en específico para recuperar datos de geocodificación inversa desde el servicio Nominatim de OpenStreet. Además, se mostrará la forma de pasar argumentos para consultas tipo GET o POST, con las cuales se puede acceder a bases de datos u otros servicios que requieran llenar campos de parámetros o autenticación.

La librería que permite hacer este tipo de consultas es la urllib. La función que usará de esta librería se llama urlretrieve, y permite descargar toda la información contenida en la URL, en un archivo local. La URL puede apuntar a un archivo de cualquier tipo, incluyendo HTML y XML.

En el ejemplo que se mostrará a continuación, para realizar reverse geocoding, se hace uso de la librería json de Python, mediante la cual es posible procesar archivos en formato json, los cuales son útiles para transmisión de información y parámetros específicos.

Este es el código fuente:

import urllib
import json

# Función para recuperar información de reverse geocoding desde openstreetmaps
def reverse_geocode_OSM(latitud,longitud):

  # Definición de parámetros del request GET
  params=urllib.urlencode({'format':'json','lat':latitud,'lon':longitud,'zoom':18,'addressdetails':0})
  
  # Se consulta la URL y se guarda el archivo en una ruta temporal dada por a[0]
  a=urllib.urlretrieve("http://nominatim.openstreetmaps.org/reverse?%s" % params)
  
  # Se abre el archivo recuperado
  archivo=open(a[0],'r')
  
  # Se convierte el objeto json a diccionario de python
  d=json.load(archivo)
  
  # Se cierra le archivo
  archivo.close()

  # Se devuelve el parámetro "display_name" desde la respuesta del servidor
  return d["display_name"]


# Ejecución de la función
print reverse_geocode_OSM(4.679,-74.048)

El anterior ejemplo hace una consulta de dirección para las coordenadas (4.679,-74.048), para lo cual devuelve la siguiente dirección "Home Baked, Carrera 13, Chapinero, Bogotá, D.C., Bogotá, 110111, Colombia".

El anterior ejemplo hace una solicitud de tipo GET. Es posible hacer solicitudes de tipo POST cambiando la línea de urlretrieve por: 

a=urllib.urlretrieve("http://url.ejemplo",params)

En el anterior ejemplo no es posible usar POST, ya que el servidor Nominatim de OpenStreet no lo soporta.

Espero que les haya sido de utilidad este aporte, y puedan sacarle buen provecho. Una última anotación: Se debe hacer buen uso de esta herramienta, ya que consultas repetitivas y descontroladas a servidores pueden provocar un bloqueo de la IP de origen de las solicitudes.

martes, 3 de julio de 2012

Desarrollo en JavaScript

JavaScript es un lenguaje de programación interpretado, similar a lenguaje C y con algunas similitudes con el lenguaje Java. Es orientado a objetos, y fue diseñado especialmente para ser ejecutado en entornos de páginas Web en el lado del cliente. 

Actualmente, todos los navegadores tienen compatibilidad con este lenguaje, y pueden ejecutar scripts embebidos en páginas Web.

JavaScript es muy útil para creación de efectos, animaciones, apariencia e interacciones en páginas Web. Para esta aplicación existe un paquete muy completo, llamado JQuery, con el cual es posible desarrollar una gran cantidad de interacciones para una página Web, sin necesidad de complementos adicionales. Más adelante se mostrará un ejemplo que hace uso de esta herramienta.

Por otra parte, otra aplicación que se le puede dar al lenguaje JavaScript es la de hacer cálculos matemáticos y operaciones complejas dentro de una página Web.

Finalmente, una de las aplicaciones más importantes de JavaScript hoy en día es la interacción con las APIs de los principales servidores de mapas y de cartografía existentes (Google, OpenStreet, Yahoo, Bing, entre otros). De esta forma, a través de un paquete libre, llamado OpenLayers, es posible insertar un mapa dentro de cualquier página Web, sin necesidad de tener un servidor de mapas propio, y de una forma muy sencilla y directa.

Ayuda de calendario usando JQuery

Muchas veces es necesario insertar dentro de un formulario una fecha; sin embargo, existen una gran cantidad de formatos para el ingreso de la misma, y puede llegar a ser muy tedioso para el usuario. La forma más sencilla para solucionar esta situación, es que el usuario pueda buscar la fecha en un calendario, y al hacer clic sobre la misma, se llene automáticamente el formulario.

El código HTML para esta aplicación es el siguiente:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='utf-8' />
  <title>Ejemplo jquery</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.8.21/themes/base/jquery-ui.css" type="text/css" media="all" />
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
  <script src="http://code.jquery.com/ui/1.8.21/jquery-ui.min.js" type="text/javascript"></script>
  <script src="http://jquery-ui.googlecode.com/svn/tags/latest/ui/minified/i18n/jquery-ui-i18n.min.js" type="text/javascript"></script>
  
  <script>
    $(function() {
        $( "#datepicker" ).datepicker($.datepicker.regional['es']);
    });
  </script>

</head>

<body>

<p>Fecha: <input type="text" id="datepicker"></p>


</body>
</html>

Como se puede ver, el código es bastante simple. En este ejemplo se llaman unos archivos de estilo CSS y los archivos .js, los cuales se pueden descargar de la página de JQuery de forma libre.

Se adiciona un Script en el head de la página, con el cual se crea el objeto tipo datepicker, y se relaciona al cuadro de texto con id "datepicker".

Finalmente en el body de la página, se inserta una entrada de tipo texto, con la cual se activará el calendario para la selección de fecha.

En la página oficial de JQuery se pueden encontrar muchos más ejemplos útiles para el uso de esta librería de JavaScript.

lunes, 7 de mayo de 2012

Manejo de matrices de puntos con microcontroladores

En esta entrada de blog se mostrará cómo controlar 2 displays de matrices de puntos de 5x7, usando un microcontrolador PIC16F1937, drivers de corriente ULN 2803 y resistencias.

Los displays de matrices de puntos siempre necesitan de un controlador para poder funcionar adecuadamente. Los pines de las matrices de puntos permiten controlar las filas y las columnas. Para poder efectuar una correcta visualización, siempre es necesario realizar un barrido ya sea por filas o por columnas. Por ejemplo, si es un barrido por filas, en cada instante de tiempo solo habrá una fila encendida, con los correspondientes píxeles, luego se enciende la siguiente fila, y luego la siguiente. Este barrido se realiza de forma muy rápida, y gracias al efecto de retención del ojo, pareciera que todas las filas se encuentran encendidas al mismo tiempo.

Cuando se usan displays de matrices de puntos, generalmente es recomendable diseñar el circuito con transistores o drivers de corriente, para que el microcontrolador no tenga que entregar mucha corriente. Para el ejemplo que se mostrará a continuación, se hace uso de 3 drivers ULN2803 (1 para filas y 2 para las columnas). El barrido se efectúa por filas.

Adicionamente, en el ejemplo que se muestra, se configuró el microcontrolador para que reciba a través del módulo UART los siguientes números en hexadecimal, los cuales se visualizarán en las dos matrices de puntos: 0x30, 0x31, 0x32 y 0x33, correspondientes a los caracteres '0', '1', '2' y '3'.

A continuación se muestra el diagrama esquemático del circuito:

En el anterior diagrama esquemático, se hace uso de la red de resistencias RN1 para que la simulación funcione de forma adecuada, ya que el modelo del ULN2803 se encuentra con algunos fallos.

Por su parte, el programa con el cual se debe realizar el control del sistema, debe estar constantemente en un ciclo de actualización y barrido por filas. Además, el programa debe contar con una tabla, en la cual exista el mapeo, píxel por píxel, de los caracteres que se visualizarán en las matrices.

A continuación se muestra el código en C para el compilador CCS para el circuito mostrado anteriormente.

El programa principal es el siguiente:

#include <pruebaleds.h>

int8 dato=48;

#INT_RDA
void inputSerial()  
{  
      dato=fgetc(PORT1);
}

void main()
{
   setup_oscillator( OSC_4MHZ );

   int8 i;
   byte const da[10][7]={14,17,17,17,17,17,14,4,6,5,4,4,4,31,15,16,16,15,1,1,31,15,16,16,15,16,16,15};
 
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   
   while(True)
   {
      for(i=0;i<7;i++)
      {
         output_a(~da[dato & 0x0F][i]);
         output_b(~da[(dato & 0xF0)>>4][i]);
         output_d(0x01 << i);
         delay_ms(1);
         output_d(0x00);
      }
   }   
}

El encabezado:

#include <16F1937.h>

#FUSES NOWDT                    //No Watch Dog Timer  
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOU
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,stream=PORT1)

Existe en el mercado un driver especializado para controlar matrices de puntos, su referencia es MAX6952. Lastimosamente es muy costoso (aprox 25 USD), pero puede llegar a ahorrar mucho tiempo y espacio, y si se tiene presupuesto, es completamente recomendable usarlo.

viernes, 27 de abril de 2012

USART en microcontroladores AVR

Como su nombre lo indica, el módulo USART soporta la transmisión sincrónica y la transmisión asincrónica, así como también soporta el modo de reloj maestro y esclavo.

En la USART, un baudio equivale a un bit por segundo y esta tasa de transferencia depende de la frecuencia de reloj y de los valores de configuración almacenados en los registros de control. Se pueden generar tramas de 5, 6, 7, 8 y 9 bits con uno o dos bits de parada que señalan el final de una trama (en la comunicación asincrónica) según la configuración que ingrese el usuario.

El bit de paridad es un bit de control opcional que se envía al final de una trama antes del bit de parada para verificar si existe algún error en la comunicación. Este bit se calcula contando el número de bits '1' que se envían: si se escoge paridad par, este bit será '1' si el número de '1's es par, y será '0' en caso contrario; si se escoge paridad impar, el bit de paridad será '0' si el número de '1's es par y '1' en caso contrario.

El bit de paridad se genera por hardware en el transmisor de la USART realizando una or exclusiva entre todos los bits de una trama; y es verificado en el receptor también por hardware. Este bit sirve para detectar si ocurrió un error en la comunicación, pero no sirve para asegurar que todos los bits llegaron correctamente.

En una transmisión asincrónica, una trama de datos inicia con un bit de arranque, seguido del bit menos significativo de información y cada uno de los siguientes bits hasta un máximo de 9, terminando con el bit más significativo. Si la paridad está habilitada, el bit de paridad se envía inmediatamente después de los datos, seguido de los bits de parada. Cuando se termina de enviar la trama, se puede enviar otra inmediatamente o se puede dejar el canal libre esperando otra trama.

A continuación se muestra un ejemplo de uso de transmisión y recepción serial entre el ATMEGA16.

Para realizar este ejemplo se creó una librería con funciones comunes de la USART: inicializar el módulo, transmitir un dato, recibir un dato y transmitir una cadena. Estas funciones se muestran en el código a continuación:

/* usart.h: Librería para el manejo del USART */
#ifndef USART_H
#define USART_H

#include<avr/io.h>

void USART_Init( unsigned int baud);
void USART_Transmit( unsigned char data);
unsigned char USART_Receive( void );
void USART_TransmitString(char cadena[]);

/* Función inicializar USART */
void USART_Init( unsigned int baud )
{
    // Se establece la tasa de baudios con el valor ingresado a
    // la funcion
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    // Se habilita la recepción y la transmisión de datos
    UCSRB = (1<<RXEN)|(1<<TXEN);
    // Se establece el formato de la trama: 8 bits de datos, 
    // 2 bits de parada, sin bits de paridad
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

/* Función transmitir datos */
void USART_Transmit( unsigned char data )
{
    // Espera hasta que el buffer esté vacio
    while ( !( UCSRA & (1<<UDRE)) );
    // Pone el dato en el buffer de transmisión, envía el dato
    UDR = data;
}

/* Función recibir datos */
unsigned char USART_Receive( void )
{
    // Espera a recibir datos
    while ( !(UCSRA & (1<<RXC)) );
    // Devuelve el dato leido
    return UDR;
}

/* Transmitir una cadena */
void USART_TransmitString(char cadena[])
{
    int i; // Índice

    for(i=0;cadena[i]!='\0';i++) // Recorre la cadena
        USART_Transmit(cadena[i]); // Transmite el dato
}
#endif

El programa principal se muestra a continuación:

//***************************************************************
// Programa de prueba de envío y recepción de datos por USART
//
// Descripción: Este programa inicializa el módulo USART, envía
// datos caracter por caracter para formar la cadena "hola". 
// Luego envía una cadena de prueba y a continuación queda en un 
// ciclo infinito a la espera de los datos que ingresa el usuario
// y los envía nuevamente por el USART.
//    
// Creado:        04/06/2010
// Modificado:    21/06/2010
// Autor:         L.A. Mongua - A.F. Quiceno
//***************************************************************

// Dispositivo = ATMEGA16
// Fclk = 8.0MHz
#include "usart.h" // Librería con las funciones del USART

int main()
{
    // Se declaran las variables en las que se almacenarán los
    // datos recibidos
    unsigned char recibido;
    // Se ajusta la tasa de baudios en 9600
    USART_Init(51); //Tabla 70 hoja de datos ATMEGA16 (pag. 164)
    // Se transmite la cadena "hola"
    USART_Transmit('h');
    USART_Transmit('o');
    USART_Transmit('l');
    USART_Transmit('a');
    USART_Transmit(' '); // Se transmite un espacio
    USART_TransmitString("esto es una prueba");
    USART_Transmit(13); //Fin de línea
    while(1){
        // Cada vez que se reciba un dato
        recibido=USART_Receive();  
        // Se transmite nuevamente el mismo dato
        USART_Transmit(recibido);
    }    // El programa se queda esperando a que un nuevo dato 
        // sea recibido
}

lunes, 9 de abril de 2012

Plataforma de proyectos Redmine


Redmine es un aplicativo Web que permite la administración y gestión de proyectos de todo tipo, pero se encuentra enfocado especialmente a proyectos de ingeniería y de sistemas. El lenguaje de programación sobre el que corre la plataforma es Ruby. Ruby es un lenguaje interpretado que ha tomado un gran auge en los últimos años, en especial por su alta funcionalidad en aplicativos tipo Web.


La plataforma tiene un motor de base de datos que permite almacenar toda la información de manera estructurada y organizada. Dicho motor de base de datos no solo le va a brindar mayor seguridad a la información de la plataforma (ya sea información del aplicativo o información del usuario), sino que prestará mayor rapidez al usuario final.

La plataforma tiene la ventaja de ser una herramienta web: lo anterior garantiza su ubicuidad, ya que actualmente casi todo equipo de cómputo tiene un navegador web y está conectado a internet. La plataforma se puede trabajar concurrentemente por múltiples usuarios en múltiples equipos y la limitación sólo radicará en el hardware empleado para el montaje de la plataforma y la conexión del mismo con internet.

La aplicación Redmine incluye los siguientes módulos por defecto:

Vistazo

En vistazo, el usuario puede darse una rápida impresión del alcance del proyecto, ya que allí se informa de manera gráfica los usuarios del proyecto discriminados en los diferentes grupos que lo componen, los subproyectos del mismo y un resumen de las peticiones.

Actividad

En actividad se puede ver un histórico de las modificaciones hechas al proyecto, donde además se muestra quién lo hizo y qué hizo. Esto puede contribuir significativamente en la trazabilidad rápida del proyecto ya que informa sobre los cambios  específicos sin tener que incurrir en una revisión minuciosa de todo lo documentado.

Peticiones

Las peticiones son una herramienta valiosísima de la plataforma, ya que permiten segmentar los problemas y proyectos en unidades mucho más básicas que puedan ser resueltas por uno o por varios usuarios y que, además, puedan ser asignadas, revisadas, auditadas por otros usuarios del proyecto. Las peticiones tienen muchos campos que ofrecen una gran cantidad de información sobre el desarrollo de las mismas, tales como asignado, tiempo estimado, tiempo total, prioridad, etc.

Cuando se ha dividido el proyecto en peticiones, se puede apreciar un diagrama de tiempos donde aparezca cada una de ellas con su respectivo porcentaje de realización, así como también se puede observar en un calendario qué peticiones están activas por usuario.

Noticias

Al llevar a cabo varios proyectos que incluyan diferentes desarrolladores en cada uno, el módulo noticias permite informar sobre los asuntos relevantes a todos aquellos incluidos en la plataforma, de tal modo que todos se puedan enterar de los avances de cada proyecto sin necesidad de entrar en el detalle netamente técnico. Las noticias buscan siempre la información global sobre la particular.

Documentos

De la gestión documental de un proyecto depende su éxito. Manejar el proceso de documentación sobre la plataforma es muy sencillo. Existen 3 módulos que permiten dividir la información de manera concreta como lo son Documentos, Wiki y Archivos. En documentos existe la posibilidad de adjuntar archivos a la plataforma de la forma de un anexo, es decir, un documento posiblemente de otros autores o que por no estar tan relacionado con el proyecto no se incluye dentro del cuerpo del mismo. Allí se puede hacer una descripción del documento y se puede crear una sección completa relacionada con el mismo, todo en formato wiki.

Wiki

Hoy día se habla mucho de wikis por la alta penetración al mercado de internet. Una wiki es una herramienta de edición colaborativa de textos dónde no se requiere mucho conocimiento de herramientas ni de formatos, ya que todo puede ser editado con texto plano y con simples interfaces web. El objetivo de esto es que de manera rápida se puedan modificar los archivos y hacer documentos que no requieran descargas locales sino que se puedan trabajar siempre desde el modo web. A la hora de generar informes, se puede exportar los creado a formato html y a formato txt.

Archivos

En archivos se puede montar toda aquella información que no tenga una relevancia muy alta y que no requiera texto que la acompañe, por ejemplo imágenes que pudieran llegar a ser útiles pero que no hagan parte de los anexos, versiones intermedias de documentos, etc.

Adicional a los módulos que vienen preinstalados por defecto en la aplicación Redmine, es posible incluir muchos más plugins que le pueden brindar capacidades adicionales a la plataforma. Entre los plugins más útiles encontramos:

DMSF

Este plugin es una evolución del módulo "Archivos" que viene preinstalado por defecto. DMSF permite organizar archivos por carpetas, control de cambios por autor y por versiones, registros de descarga de los archivos y envío por correo de los mismos.

HALTR

Este es un módulo desarrollado para la generación de facturas e información de empresas. Es útil para generar todo tipo de información contable de una compañía, y permite exportar las facturas a formato PDF, incluyendo impuestos, moneda del país y logotipo de la empresa.

A continuación les dejo unas cuantas capturas de pantalla del aplicativo. Se puede encontrar mayor información en la página Web del proyecto (http://www.redmine.org/).






Si siguen estos links, se encontrarán con sitios implementados en Redmine:

lunes, 2 de abril de 2012

Recepción de correo en Python por IMAP

En la entrada de blog anterior se explicó como realizar envíos de correo de forma automática a través de un script en Python. En este caso, voy a explicar en qué consiste el protocolo IMAP (Internet Message Access Protocol), y mostraré un ejemplo de acceso a la cuenta de correo, búsqueda de un mensaje en la bandeja de entrada e imprimirlo en la pantalla de la consola.

El protocolo IMAP permite acceder a mensajes de correo electrónico que se encuentran almacenados en un servidor. A diferencia del protocolo POP, el cual también es usado para acceder a mensajes de correo electrónico de un servidor, permite especificar carpetas, y visualizar los mensajes sin necesidad de descargarlos, como en el caso de POP.

El protocolo IMAP generalmente es escuchado por el servidor en el puerto 143.

Código ejemplo

En el código que se muestra a continuación se hace uso de la librería imaplib de Python, la cual permite conectarse a un servidor IMAP (para este caso el de Gmail), e incluye funciones para búsqueda y recuperación de mensajes recibidos.

En este caso, el programa ejemplo se autenticará a una cuenta de Gmail, se dirigirá a la bandeja de entrada, y buscará los mensajes que contengan en el campo “Asunto”, la cadena que se asigne a la variable string_busqueda. Finalmente, contará los mensajes que cumplen con el criterio de búsqueda, e imprimirá el más reciente en la consola.

Se debe tener en cuenta que si el mensaje contiene imágenes o archivos adjuntos, se mostrará el binario de los mismos, representado en caracteres. Adicionalmente, se imprimirán encabezados y otra información de los mensajes, la cual generalmente no se muestra en los aplicativos Web para acceso al correo.


# vim: set fileencoding=utf-8 :

# Importación de librerías
import imaplib
import email

# Conexión a la cuenta de correo
mail = imaplib.IMAP4_SSL('imap.gmail.com') # Servidor IMAP de GMAIL
mail.login('pepito.perez', 'passxxx')    # Usuario y contraseña

# Lista mensajes de correo electrónico
mail.list()

# Selección de bandeja de entrada por defecto
mail.select()

# String de búsqueda
string_busqueda="Informe"

# Búsqueda de mensajes con el anterior criterio en el campo "Asunto"
typ, resBusq = mail.search(None, '(ALL SUBJECT "' + string_busqueda + '")')

# Se muestran resultados de la búsqueda
if resBusq[0] == '':
  print 'No se encontraron mensajes con la cadena "%s" en asunto' % (string_busqueda)
else:
  resBusq = resBusq[0].split(' ')
  print 'Se encontraron %s mensajes con la cadena "%s" en asunto' % (len(resBusq), string_busqueda)

# Se recupera el mensaje más reciente que cumpla con el criterio de búsqueda
typ, data = mail.fetch(resBusq[-1], '(RFC822)')

# Se convierte el mensaje de String a mensaje de la clase email
msg = email.message_from_string(data[0][1])

# Se imprime en pantalla el mensaje
print msg

# Cierra sesión en la cuenta de correo
mail.logout()

lunes, 27 de febrero de 2012

Envío de correo en Python por SMTP

Cuando se desarrollan aplicaciones de software, muchas veces se hace necesario interactuar de forma automática con cuentas de correo, tanto para enviar, como para recibir y procesar mensajes. Por  ejemplo cuando se diseña un sistema que genera reportes automáticos y necesitamos enviarlos a través de correo electrónico, y cuando llega información y datos al correo, y es necesario que un programa los analice de forma automática.

En esta publicación explicaré como se envían correos a través del protocolo SMTP y se incluirá un código ejemplo para ilustrar el uso de la librería smtplib de Python. Dejaré para una próxima publicación la revisión de mensajes de entrada y el procesamiento de los mismos.

Protocolo SMTP (Simple Mail Transfer Protocol)

Este protocolo usa el modelo cliente-servidor, y permite que un cliente envíe un mensaje a uno o más receptores. La comunicación entre el cliente y el servidor se hace a través de líneas de texto en caracteres ASCII. Las respuestas del servidor constan de un código numérico seguido de un texto descriptivo, el carácter de separación entre órdenes es CRLF. Este protocolo de la capa de aplicación se funciona sobre el protocolo TCP y hace uso del puerto 25 en el servidor para el establecimiento de la conexión.

Código ejemplo

A continuación se muestra el código ejemplo de un mensaje de correo electrónico enviado a través de una cuenta de correo de gmail, desde la cuenta remitente@gmail.com a la dirección de correo destinatario@hotmail.com. Este código se puede usar para cualquier servidor de correo, siempre y cuando se tenga el nombre del servidor smtp (smtp.gmail.com para el caso de gmail) y una cuenta en el mismo para envío de correo.

Para la construcción del mensaje del ejemplo, se hace uso de la librería email.mime de Python, la cual incluye funciones para la correcta construcción de mensajes que se enviarán a través de correo electrónico. En este caso únicamente se incluye texto en el mensaje, sin embargo la librería permite incluir también archivos adjuntos en el correo.

# -*- coding:utf-8 -*-

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# Datos de cuenta para envío
usuario_gmail = 'remitente'
password = 'passwordxxx'

# Correos de remitente y destinatario
origen = usuario_gmail + '@gmail.com'
destino = 'destinatario@hotmail.com'

# Creación del mensaje
msg = MIMEMultipart()
msg['Subject'] = "Prueba de envío SMTP"        # Asunto
msg['From'] = origen                # Remitente
msg['To'] = destino                # Correo destinatario

# Contenido del mensaje
msg.attach(MIMEText("Hola"))
msg.attach(MIMEText("Este mensaje es una prueba"))
msg.attach(MIMEText("Adiós"))

# Conexión con servidor smtp
sender = smtplib.SMTP('smtp.gmail.com')
sender.ehlo()
sender.starttls()

# Autenticación
sender.login(usuario_gmail, password)

sender.sendmail(origen, destino, msg.as_string())
sender.close()
    
print "Mensaje enviado correctamente"

Espero que este código les haya sido de mucha utilidad. En la entrada de la semana entrante ilustrare la forma de revisar correo y recuperar mensajes que llegan a la bandeja de entrada de la cuenta.