"Вам нужно подключить ваш Python-скрипт к серверу Exchange? Мы покажем вам простой способ сделать это с помощью инструмента под названием Connect Bridge."
Введение
В этой статье описывается, как заставить Python подключиться к Exchange, то есть как читать почту с сервера Microsoft Exchange (Exchange 2010, 2013, 2016, 2019, Online) с помощью скрипта языка Python.
Передача данных осуществляется через уровень ODBC, поэтому со стороны сценария она точно такая же, как если бы вы использовали python для доступа к Microsoft SQL Server или для доступа к любой базе данных через ODBC. Вы просто используете модуль пиодбк (мы использовали питон версии 3.7 и пиодбк версии 4.0.26.). Интеграция с API осуществляется с помощью инструмента под названием Connect Bridge, а затем на вашем Python скрипте вы читаете данные так, как будто читаете базу данных.
Пожалуйста, обратите внимание, что Connect Bridge является коммерческим продуктом. Вы можете получить бесплатную пробную версию для этого, так что вы можете попробовать этот подход для себя бесплатно.
Что это за “Connect Bridge”?
Connect Bridge это интеграционная платформа, разработанная компанией Connecting Software. Она позволяет вашему скрипту подключать любое программное обеспечение через драйверы ODBC, JDBC или веб-сервисы... избегая необходимости изучать и осваивать API программы, к которой вы пытаетесь подключиться!
В этой конкретной статье мы используем Connect Bridge для подключения к Microsoft Exchange, но вы также можете получать данные из Microsoft SharePoint или CRM, например, Salesforce или Dynamics, а также многих других. И передача данных может быть двунаправленной. То есть, вы также можете передавать данные в эти системы, хотя в этот раз мы сосредоточимся на чтении данных.
С чего мне начать?
Нашей целью является создание простого Python скрипта, который получает доступ к серверу Exchange и читает с него электронную почту. Мы предполагаем, что экземпляр Exchange уже существует. Это простые шаги, которым вам нужно следовать:
1. Убедитесь, что у вас под рукой есть учетные данные для входа Exchange.
2. Запросите бесплатную пробную версию и установите Connect Bridge.
3. Установите Python для Windows ver. 3.7+. Вы можете использовать редактор по вашему выбору для написания скрипта.
4. Установить модуль пиодбк 4.0.26+
5. Запустите Connect Bridge Management Studio и:
5.1. Добавьте учетную запись для Exchange (Учетные записи - Добавить учетную запись). Для добавления учетной записи необходимо выбрать коннектор MGEXPlugin2010 и использовать учетные данные, указанные в пункте 1.
5.2. Откройте опцию Новый запрос, а затем Браузер соединений. Найдите коннектор Exchange и разверните его до тех пор, пока не увидите DefaultConnection. Щелкните правой кнопкой мыши на DefaultConnection и выберите строку Get Connection (Получить соединение). Скопируйте строку ODBC соединения, так как она вам понадобится, чтобы передать её в скрипт.
5.3. Используйте опцию Новый запрос, чтобы протестировать запрос, который получит доступ к тому, что вам нужно в Exchange.

Здесь мы приведем пример запроса, но именно здесь вы должны указать, что именно вы ищете в Exchange. После нажатия кнопки New Query (Новый запрос) откройте браузер соединений (Connection Browser) слева. Найдите коннектор Exchange (MGEXPlugin2010) и откройте его, пока не появится опция Tables. Мы видим, что схема содержит “таблицу” под названием Message, поэтому мы можем построить наш запрос как SELECT * FROM Message WHERE CreationDate >= '2019-01-01 00:00:00' LIMIT 10; чтобы выбрать 10 записей из списка сообщений электронной почты Exchange, которые были созданы после 1 января 2019 года. И снова обратите внимание, что, хотя это выглядит так, как будто мы используем базу данных напрямую, это не так. Connect Bridge получает доступ к API и затем представляет его так, как будто это база данных. Как только вы получите запрос, скопируйте его, так как вам нужно будет передать его в скрипт.
Руки на сценарии!
Наше решение имеет только один файл: CBExchange.py. Полный исходный код приведен ниже. Пожалуйста, обратите внимание на строки 70-92, в которых представлено основное решение. Полное описание того, как работает этот скрипт, приведено ниже.
#!/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())
Вот немного о переменных, которые мы используем:
- парсер используется для разбора аргументов, которые мы получаем из командной строки
- args содержит эти аргументы
- query содержит запрос, который мы хотим выполнить, и он вводится в качестве аргумента
- connstr содержит строку соединения ODBC, которая передается в качестве аргумента и которую мы передаем в модуль pyodbc для создания соединения ODBC
- conn - это соединение ODBC
И вот что делает наш сценарий
- В строках с 70 по 78 цель - получить переменные connstr и query из входных аргументов командной строки. Для простоты был использован шаблон скрипта argparse от pydev.
- В строке 80 мы открываем курсор базы данных с помощью conn
- В строке 82 мы выполняем SQL-запрос, полученный из командной строки
- В строках с 83 по 92 мы перебираем результаты и считываем их из курсора строка за строкой.
-Когда cursor.fetchone возвращает None, мы прерываем цикл
- Если во время выборки данных из ODBC возникнет исключение, мы также прервем цикл и выведем проблему на экран
- Если метод fetchone работает успешно и возвращает строку данных, мы выводим ее в исходном виде. Этого достаточно для демонстрационных целей, но, естественно, в реальной ситуации вы можете отформатировать данные в xml, json, csv... или любой другой формат обмена данными. Или же вы можете просто использовать объект строки данных для выполнения пользовательских задач в последующем коде.
Как запустить сценарий CBExchange.py?
Скрипт CBExchange.py принимает два аргумента позиционной командной строки: connectstr и query.
Нам необходимо скопировать их из студии управления Connect Bridge, как описано выше (пункт 5.2). Когда они у вас под рукой, откройте командную строку, cd в папку, в которую вы сохранили скрипт и запустить твой Python-скрипт передавая ему 2 параметра.

Что еще я могу сделать? Исследуйте дальше...
Как уже упоминалось ранее, более сложные запросы могут быть построены таким образом, чтобы вы получали нужную вам электронную почту. Например, если вы хотите получать только письма с вложениями и с определенной датой создания, то запрос будет выглядеть следующим образом
ВЫБЕРИТЕ * ОТ СОВМЕСТНОГО СОВЕТА
WHERE [HasAttachment] = true и [CreationDate] >= '2019-07-01 00:00:00';
Вы также можете изучить доступные "Хранимые процедуры". Найдите коннектор Exchange (MGEXPlugin2010) и разверните его, пока не увидите опцию "Хранимые процедуры". Опять же, эти хранимые процедуры - это интеграция API Connect Bridge, а не реальные хранимые процедуры базы данных. Но способ работы с ними такой же, как если бы они были таковыми.
Некоторые из доступных хранимых процедур видны на этом скриншоте:

Ограничения
Инструмент Connect Bridge доступен только для операционных систем Windows, поскольку клиентская библиотека ODBC Linux недоступна. Поэтому, чтобы это работало, вам понадобится Windows-машина.
Заключение
Мы видели, как доступ к данным Exchange в Python можно легко получить с помощью интеграционной платформы Connect Bridge. А теперь представьте, что то, что вы увидели в этой статье, возможно также с Microsoft Dynamics CRM и Microsoft Exchange! Да, с Connect Bridge это возможно, и способ сделать это аналогичен... вам просто нужно выбрать коннектор для конкретного программного обеспечения, которое вам нужно, и идти с ним.
Если вы хотите изучить коннекторы, доступные в настоящее время на Connect Bridge, то вам следует обратить внимание на следующее https://www.connecting-software.com/connectors/

Если вам интересно, какие новейшие разъемы входят в этот большой набор, посмотрите на Connect Bridges 1ТП21Т Финансы и операции и Dynamics 365 Business Central коннекторы, оба построены на протоколе OData. Или посмотрите на коннектор OPC UA. Да, я знаю, что это кажется совершенно другим случаем использования..... Но на самом деле вы можете получить доступ к серверам OPC UA с помощью того же инструмента. Чтобы дать вам представление о том, что может получиться в результате такого типа интеграции, взгляните на Connect Bridge's витрина IIoT.
Мы надеемся, что эта статья была вам полезна!
Вот еще несколько постов в нашем блоге, в которых обсуждаются другие возможности интеграции:
Об авторе

По адресу Ана Нето, технический консультант в Connecting Software.
Я работаю инженером-программистом с 1997 года, а в последнее время полюбил писать и выступать публично". У вас есть вопросы или комментарии по поводу этой статьи? Я буду рад получить ваш отзыв, оставьте комментарий ниже!"



