"Avete bisogno di collegare il vostro script Python a un server Exchange? Vi mostreremo un modo semplice per farlo utilizzando uno strumento chiamato Connect Bridge"."
Introduzione
Questo articolo descrive come far connettere Python a Exchange, cioè come leggere la posta da un Server Microsoft Exchange (Exchange 2010, 2013, 2016, 2019, Online) utilizzando uno script in linguaggio Python.
I trasferimenti di dati vengono effettuati tramite lo strato ODBC, quindi dal lato dello scripting è esattamente come se si utilizzasse python per accedere a Microsoft SQL Server o per accedere a qualsiasi database tramite ODBC. Si usa semplicemente l'opzione modulo pyodbc (abbiamo usato la versione 3.7 del pitone e la versione 4.0.26 del pyodbc). L'effettiva integrazione delle API è fatta da uno strumento chiamato Connect Bridge e poi sul vostro script Python leggete i dati come se steste leggendo un database.
Si prega di notare che Connect Bridge è un prodotto commerciale. È possibile ottenere una prova gratuita per questo, in modo che possiate provare questo approccio per voi stessi senza alcun costo.
Che cos'è questo “Connect Bridge”?
Connect Bridge è una piattaforma di integrazione sviluppata da Connecting Software. Permette al tuo script di connettere qualsiasi software attraverso driver ODBC, driver JDBC o Web Services... evitando la necessità di studiare e imparare l'API del programma a cui stai cercando di connetterti!
In questo articolo specifico, stiamo usando Connect Bridge per connetterci a Microsoft Exchange, ma potete anche prendere dati da Microsoft SharePoint o da un CRM come Salesforce o Dynamics tra molti altri. E i trasferimenti di dati possono effettivamente essere bidirezionali. Cioè, potete anche mettere dati a questi sistemi, anche se questa volta ci stiamo concentrando sulla lettura dei dati.
Da dove comincio?
Il nostro obiettivo è quello di creare un semplice script Python che acceda ad un server Exchange e legga la posta elettronica da esso. Supponiamo che l'istanza Exchange esista già. Questi sono semplici passi da seguire:
1. Assicuratevi di avere a portata di mano le vostre credenziali di accesso Exchange
2. Richiedi una prova gratuita e installa Connect Bridge
3. Installare Python per Windows ver. 3.7+. Per la scrittura dello script potete utilizzare l'editor di vostra scelta.
4. Installare il modulo pyodbc 4.0.26+
5. Eseguire Connect Bridge Management Studio e:
5.1. Aggiungere un account per Exchange (Accounts - Add account). Per aggiungere l'account, dovresti selezionare il connettore MGEXPlugin2010 e usare le credenziali menzionate al punto 1.
5.2. Aprire l'opzione Nuova Query e poi il Browser di connessione. Trovare il Connettore Exchange ed espanderlo fino a visualizzare la DefaultConnection. Fare clic con il tasto destro del mouse sulla DefaultConnection e scegliere la stringa Get Connection. Copiare la stringa di connessione ODBC, in quanto ne avrete bisogno per trasmetterla allo script.
5.3. Utilizzare l'opzione New Query per testare una query che accederà a ciò di cui si ha bisogno in Exchange.

Qui faremo un esempio di query, ma è qui che si deve inserire ciò che si sta cercando in Exchange. Dopo aver fatto clic su Nuova query, aprire il Browser delle connessioni, a sinistra. Individuare il connettore Exchange (MGEXPlugin2010) e aprirlo fino a visualizzare l'opzione Tabelle. Possiamo vedere che lo schema contiene una “tabella” chiamata Messaggio, quindi possiamo costruire la nostra query come SELECT * FROM Messaggio WHERE CreationDate >= '2019-01-01 00:00:00' LIMIT 10; per selezionare 10 voci dall'elenco dei messaggi di posta elettronica dell'Exchange creati dopo il 1° gennaio 2019. Anche in questo caso, si noti che, sebbene sembri che stiamo utilizzando direttamente un database, non è così. L'Connect Bridge accede all'API e la presenta come se fosse un database. Una volta ottenuta la query, copiarla, poiché sarà necessario passarla allo script.
Mani sullo scripting!
La nostra soluzione ha un solo file: CBExchange.py. Il codice sorgente completo è riportato di seguito. Si prega di concentrarsi sulle linee 70-92 che rappresentano la soluzione di base. Una descrizione completa di come funziona questo script è riportata di seguito.
#!/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())
Qui c'è qualcosa sulle variabili che stiamo usando:
- è usato per analizzare gli argomenti che riceviamo dalla riga di comando
- args contiene gli argomenti
- query contiene la query che vogliamo eseguire e che viene fornita come argomento
- connstr contiene la stringa di connessione ODBC che viene fornita come argomento e che viene passata al modulo pyodbc per creare una connessione ODBC.
- conn è la connessione ODBC
Ed ecco cosa sta facendo il nostro copione
- Nelle righe da 70 a 78, l'obiettivo è ottenere le variabili connstr e query dall'input degli argomenti della riga di comando. Il modello di script argparse di pydev è stato utilizzato per semplicità
- Alla riga 80, si apre un cursore del database usando conn
- Alla riga 82, si esegue la query SQL ottenuta dalla riga di comando
- Nelle righe da 83 a 92, si esegue il loop dei risultati e li si legge dal cursore riga per riga.
-Quando cursor.fetchone restituisce None, si interrompe il ciclo
- Se si verifica un'eccezione durante il fetch ODBC, interrompiamo anche il ciclo e stampiamo il problema in output
- Se il metodo fetchone ha successo e restituisce una riga di dati, si stampa la riga di dati grezza così com'è nell'output. Questo è sufficiente a fini dimostrativi, ma naturalmente in una situazione reale si potrebbe formattare come xml, json, csv... o qualsiasi altro tipo di formato di scambio dati. Oppure si può semplicemente utilizzare l'oggetto riga di dati grezzi per eseguire operazioni personalizzate nel codice successivo.
Come si esegue lo script CBExchange.py?
Lo script CBExchange.py accetta due argomenti a riga di comando posizionale: connstr e query.
Dobbiamo copiarli da Connect Bridge Management Studio come spiegato sopra (punto 5.2). Quando li avete a portata di mano, aprite una riga di comando, cd nella cartella in cui avete salvato lo script e Esegui il tuo script Python passandogli i 2 parametri.

Cos'altro posso fare? Esplorare ulteriormente...
Come accennato in precedenza, è possibile costruire query più sofisticate in modo da ottenere le e-mail che si desidera. Ad esempio, se si desidera ottenere solo le e-mail con allegati e con una data di creazione specifica, la query sarebbe
SELEZIONA * DA Messaggio
WHERE [HasAttachment] = true e [CreationDate] >= '2019-07-01 00:00:00';
Potete anche esplorare le "Stored Procedures" disponibili. Trovate il connettore Exchange (MGEXPlugin2010) ed espandete fino a che non vedete l'opzione "Stored Procedures". Di nuovo, queste Stored Procedures sono l'integrazione API di Connect Bridge, non vere e proprie stored procedure di database. Ma il modo di lavorare con loro è lo stesso come se lo fossero.
Alcune delle Stored Procedure disponibili sono visibili in questa schermata:

Vincoli
Lo strumento Connect Bridge è disponibile solo per sistemi operativi Windows, perché non è disponibile alcuna libreria client ODBC Linux. Quindi, perché questo funzioni, è necessaria una macchina Windows.
Conclusione
Abbiamo visto come l'accesso ai dati Exchange in Python può essere fatto facilmente usando la piattaforma di integrazione Connect Bridge. Ora immaginate che quello che avete visto in questo articolo sia possibile anche con Microsoft Dynamics CRM e Microsoft Exchange! Sì, con Connect Bridge questo è possibile e il modo di farlo è simile... devi solo scegliere il connettore per il software specifico che vuoi e andare con quello.
Se volete esplorare i connettori attualmente disponibili a Connect Bridge, il posto dove andare è https://www.connecting-software.com/connectors/

Se siete curiosi di sapere quali sono i connettori più recenti di questo grande insieme, date un'occhiata a Connect Bridges Dynamics 365 Finanza & Operazioni e Dynamics 365 Business Central entrambi basati sul protocollo OData. Oppure date un'occhiata al connettore OPC UA. Sì, so che sembra un caso d'uso completamente diverso.... Ma la verità è che si può accedere ai server OPC UA usando lo stesso strumento. Per dare un'idea di ciò che può scaturire da questo tipo di integrazione, date un'occhiata a Connect Bridge Vetrina IIoT.
Speriamo che questo articolo ti sia stato utile!
Qui ci sono altri post che abbiamo sul nostro blog che discutono altre possibilità di integrazione:
Sull'autore

Da Ana Neto, consulente tecnico a Connecting Software.
"Sono un ingegnere informatico dal 1997, con un amore più recente per la scrittura e il public speaking". Avete domande o commenti su questo articolo? Mi piacerebbe avere il vostro feedback, lasciate un commento qui sotto!"



