"¿Necesitas conectar tu script Python a un servidor Exchange? Te mostraremos una forma sencilla de hacerlo utilizando una herramienta llamada Connect Bridge"."
Introducción
Este artículo describe cómo hacer que Python se conecte al Exchange, es decir, cómo leer el correo de un servidor Microsoft Exchange (Exchange 2010, 2013, 2016, 2019, Online) utilizando un script de lenguaje Python.
Las transferencias de datos se realizan a través de la layer ODBC, por lo que desde el punto de vista de las secuencias de comandos es exactamente igual que si se utilizara Python para acceder a Microsoft SQL Server o para acceder a cualquier base de datos a través de ODBC. Simplemente se utiliza el módulo pyodbc (usamos la versión 3.7 de Python y la versión 4.0.26 de pyodbc). La integración del API se realiza mediante una herramienta llamada Connect Bridge y luego en su script de Python se leen los datos como si se tratara de una base de datos.
Tenga en cuenta que el Connect Bridge es un producto comercial. Puede obtener una prueba gratuita para ello, así que puedes probar este enfoque por ti mismo sin costo alguno.
¿Qué es eso de “Connect Bridge”?
Connect Bridge es una plataforma de integración desarrollada por Connecting Software. Permite que tu script conecte cualquier software a través de drivers ODBC, drivers JDBC o Servicios Web... ¡evitando la necesidad de estudiar y aprender la API del programa al que te quieres conectar!
En este artículo específico, estamos utilizando Connect Bridge para conectar con Microsoft Exchange, pero también se pueden obtener datos de Microsoft SharePoint o de un CRM como Salesforce o Dynamics entre muchos otros. Y las transferencias de datos pueden ser realmente bidireccionales. Es decir, también puedes poner datos a estos sistemas, aunque en esta ocasión nos estamos centrando en la lectura de datos.
¿Por dónde empiezo?
Nuestro objetivo es crear un simple script Python que acceda a un servidor Exchange y lea el correo electrónico desde él. Asumimos que la instancia Exchange ya existe. Estos son unos pasos sencillos que hay que seguir:
1. Asegúrate de tener a mano tus credenciales de acceso a Exchange
2. Solicite una prueba gratuita e instale Connect Bridge
3. Instalar Python para Windows ver. 3.7+. Puedes usar el editor que prefieras para escribir el script.
4. Instalar el módulo 4.0.26+ de pyodbc
5. Ejecute Connect Bridge Management Studio y:
5.1. Añada una cuenta para el Exchange (Cuentas - Añadir cuenta). Para añadir la cuenta, debe seleccionar el conector MGEXPlugin2010 y utilizar las credenciales mencionadas en el punto 1.
5.2. Abre la opción New Query y luego el Connection Browser. Encuentra el conector Exchange y expándelo hasta que veas la DefaultConnection. Haga clic con el botón derecho del ratón en DefaultConnection y elija la cadena Get Connection. Copie la cadena de conexión ODBC, ya que la necesitará para pasarla al script.
5.3. Usa la opción New Query para probar una consulta que acceda a lo que necesitas en Exchange.

Aquí haremos una consulta de ejemplo, pero aquí es donde debe poner lo que está buscando en Exchange. Una vez que haya hecho clic en Nueva Consulta, abra el Navegador de Conexiones, a la izquierda. Busca el Conector Exchange (MGEXPlugin2010) y ábrelo hasta que aparezca la opción Tablas. Podemos ver que el esquema contiene una “tabla” llamada Message por lo que podemos construir nuestra consulta como SELECT * FROM Message WHERE CreationDate >= '2019-01-01 00:00:00' LIMIT 10; para seleccionar 10 entradas de la lista de mensajes de correo electrónico del Exchange que se crearon después del 1 de enero de 2019. De nuevo, ten en cuenta que aunque parezca que estamos utilizando directamente una base de datos, no es así. Connect Bridge está accediendo a la API y luego la presenta como si fuera una base de datos. Una vez que tenga su consulta, cópiela, ya que necesitará pasarla al script.
¡Manos a la obra!
Nuestra solución sólo tiene un archivo: CBExchange.py. El código fuente completo está abajo. Por favor, enfóquese en las líneas 70-92 que representan la solución principal. Una descripción completa de cómo funciona este script está abajo.
#!/usr/local/bin/python3.7
# encoding: utf-8
'''
CBExchange -- query data from, write data to Exchange
CBExchange is a script that allows to read Exchange mail using SQL queries via Connect Bridge's ODBC driver
@author: Ana Neto
@copyright: 2019
@contact: ana@connecting-software.com
@deffield updated: 22.07.2019
'''
import sys
import os
import pyodbc
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
__all__ = []
__version__ = 0.2
__date__ = '2019-07-22'
__updated__ = '2019-07-22'
DEBUG = 1
TESTRUN = 0
PROFILE = 0
class CLIError(Exception):
'''Generic exception to raise and log different fatal errors.'''
def __init__(self, msg):
super(CLIError).__init__(type(self))
self.msg = "E: %s" % msg
def __str__(self):
return self.msg
def __unicode__(self):
return self.msg
def main(argv=None): # IGNORE:C0111
'''Command line options.'''
if argv is None:
argv = sys.argv
else:
sys.argv.extend(argv)
program_name = os.path.basename(sys.argv[0])
program_version = "v%s" % __version__
program_build_date = str(__updated__)
program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
program_shortdesc = __import__('__main__').__doc__.split("n")[1]
program_license = '''%s
Created by Ana Neto on %s.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
''' % (program_shortdesc, str(__date__))
try:
# Setup argument parser
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
parser.add_argument('connstr')
parser.add_argument('query')
# Process arguments
args = parser.parse_args()
query = args.query
connstr = args.connstr
conn = pyodbc.connect(connstr)
cursor = conn.cursor()
cursor.execute(query)
while 1:
row = None
try:
row = cursor.fetchone()
except:
print(sys.exc_info()[1])
break
if not row:
break
print(row)
except KeyboardInterrupt:
### handle keyboard interrupt ###
return 0
except:
print(sys.exc_info()[1])
#indent = len(program_name) * " "
#sys.stderr.write(program_name + ": " + repr(e) + "n")
#sys.stderr.write(indent + " for help use --help")
return 2
if __name__ == "__main__":
if TESTRUN:
import doctest
doctest.testmod()
if PROFILE:
import cProfile
import pstats
profile_filename = 'CBExchange_profile.txt'
cProfile.run('main()', profile_filename)
statsfile = open("profile_stats.txt", "wb")
p = pstats.Stats(profile_filename, stream=statsfile)
stats = p.strip_dirs().sort_stats('cumulative')
stats.print_stats()
statsfile.close()
sys.exit(0)
sys.exit(main())
Aquí hay un poco sobre las variables que estamos usando:
- se utiliza para analizar los argumentos que recibimos de la línea de comandos
- args contiene esos argumentos
- query contiene la consulta que queremos ejecutar y que viene como argumento
- connstr contiene la cadena de conexión ODBC que viene como argumento y que pasamos al módulo pyodbc para crear una conexión ODBC
- conn es la conexión ODBC
Y esto es lo que nuestro script está haciendo
- En las líneas 70 a 78, el objetivo es obtener las variables connstr y query de la entrada de argumentos de la línea de comandos. Se ha utilizado la plantilla de script argparse de pydev por simplicidad
- En la línea 80, abrimos un cursor de base de datos utilizando conn
- En la línea 82, ejecutamos la consulta SQL que obtuvimos de la línea de comandos
- En las líneas 83 a 92, recorremos los resultados y los leemos del cursor fila a fila.
-Cuando cursor.fetchone devuelve None, rompemos el bucle
- Si se produce una excepción durante la obtención ODBC, también rompemos el bucle e imprimimos el problema en la salida
- Si el método fetchone tiene éxito y devuelve una fila de datos, imprimimos la fila de datos tal cual a la salida. Esto se hace porque es suficiente para propósitos de demostración, pero naturalmente en una situación del mundo real podrías formatear como xml, json, csv... o cualquier otro tipo de formato de intercambio de datos. O también podrías simplemente utilizar el objeto fila de datos en bruto para realizar tareas personalizadas en código posterior.
¿Cómo puedo ejecutar el script CBExchange.py?
El script CBExchange.py acepta dos argumentos de línea de comandos posicionales: connstr y query.
Necesitamos copiarlos de Connect Bridge Management Studio como se explicó anteriormente (punto 5.2). Cuando los tenga a mano, abra una línea de comandos, cd en la carpeta en la que guardó el script y ejecuta tu script Python... pasándole los 2 parámetros.

¿Qué más puedo hacer? Explorar más...
Como se mencionó antes, se pueden construir queries más sofisticadas para que recibas los correos electrónicos que quieras. Por ejemplo, si sólo quieres recibir los correos electrónicos con archivos adjuntos y con una fecha de creación específica, la consulta sería
SELECT * FROM Message
WHERE [HasAttachment] = true y [CreationDate] >= '2019-07-01 00:00:00';
También puedes explorar los "Stored Procedures" disponibles. Busque el conector Exchange (MGEXPlugin2010) y expándalo hasta que pueda ver la opción "Stored Procedures". De nuevo, estos Stored Procedures son la integración de la API de Connect Bridge, no procedimientos almacenados en la base de datos real. Pero la forma de trabajar con ellos es la misma que si lo fueran.
Algunos de los Stored Procedures disponibles son visibles en esta captura de pantalla:

Restricciones
La herramienta Connect Bridge sólo está disponible para sistemas operativos Windows, porque no hay ninguna biblioteca cliente ODBC Linux disponible. Así que, para que esto funcione, necesitará una máquina Windows.
Conclusión
Hemos visto cómo acceder a los datos de Exchange en Python puede hacerse fácilmente utilizando la plataforma de integración Connect Bridge. ¡Ahora imagine que lo que ha visto en este artículo es posible también con Microsoft Dynamics CRM y Microsoft Exchange! Sí, con Connect Bridge esto es posible y la forma de hacerlo es similar... sólo tienes que elegir el conector para el software específico que quieres y seguir con él.
Si quieres explorar los conectores actualmente disponibles en Connect Bridge, el lugar para ir es https://www.connecting-software.com/connectors/

Si tiene curiosidad por saber cuáles son los conectores más nuevos de este gran conjunto, eche un vistazo a los de Connect Bridges Dynamics 365 Finance & Operations y Dynamics 365 Business Central ambos basados en el protocolo OData. O echa un vistazo al conector OPC UA. Sí, sé que parece un caso de uso totalmente diferente.... Pero la verdad es que puedes acceder a servidores OPC UA usando la misma herramienta. Sólo para darte una idea de lo que puede resultar de este tipo de integración, echa un vistazo a Connect Bridge's IIoT showcase de Connect Bridge.
Esperamos que este artículo le haya resultado útil.
Aquí hay más publicaciones que tenemos en nuestro blog en las que se habla de otras posibilidades de integración:
Sobre el autor

Por Ana Neto, asesor técnico en Connecting Software.
"Soy ingeniero informático desde 1997, con una afición más reciente por escribir y hablar en público. ¿Tiene alguna pregunta o comentario sobre este artículo? Me encantaría conocer tu opinión, ¡deja un comentario a continuación!"



