Приложение slackclient не работает после сборки PyInstaller, но отлично работает из командной строки python

Я тестирую слабый API, используя slackclient, используя следующий код Python:

# pip install slackclient to install SlackClient library
from slackclient import SlackClient
import json
import time


def test_slack(sc):
    # use for debugging
    print("Testing API")
    print(80 * "=")
    print (sc.api_call("api.test"))


def get_channel_info(sc, channel):
    # get info about the channel
    print("Getting Channel Info")
    print(80 * "=")
    print (sc.api_call("channels.info", channel=channel))


def get_list_of_channels(sc):
    print("Getting List of Channels")
    print(80 * "=")
    # get list of channels
    channels = sc.api_call("channels.list")
    channels = json.dumps(channels)
    channels = json.loads(str(channels))
    print channels
    return channels


def display_channels(channels):
    print("Display Channels")
    print(80 * "=")
    for i in channels['channels']:
        print("Channel:", i['name'], i['id'])


def post_message(sc, text, channel, icon_url, username):
    print("Posting Message to Slack")
    print(80 * "=")
    # post a message into the #general channel
    print (sc.api_call("chat.postMessage", channel=channel, text=text, username=username, icon_url=icon_url,
                       unfurl_links="true"))


def get_users(sc):
    print("Get Users")
    print(80 * "=")
    # call the users.list api call and get list of users
    users = (sc.api_call("users.list"))
    print users
    users = json.dumps(users)
    users = json.loads(str(users))
    return users


def display_users(sc, users):
    print("User List")
    print(80 * "=")
    # display active users
    for i in users['members']:
        print users
        # don't display slackbot
        if i['profile']['real_name'] != "slackbot":
            # don't display deleted users
            if not i['deleted']:
                # display real name
                print (i['profile']['real_name'])


def main():
    # define variables
    token = "HERE YOUR SLACK TESTER TOKEN"
    channel = "general"
    username = "moderator"
    icon_url = ""
    # connect to Slack
    sc = SlackClient(token)
    # test slack
    test_slack(sc)
    # get channel info
    get_channel_info(sc, channel)
    # get list of channels
    channels = get_list_of_channels(sc)
    # display channels
    display_channels(channels)
    # post message
    post_message(sc, "Testing 123 testing 123.", channel, icon_url, username)
    # get users
    users = get_users(sc)
    # display users
    display_users(sc, users)

    if sc.rtm_connect():
        while True:
            for slack_message in sc.rtm_read():
                print slack_message
                message = slack_message.get("text")
                user = slack_message.get("user")
                if not message or not user:
                    continue
                print "User: ", user, message
            time.sleep(3)
    else:
        print "Connection Failed, invalid token?"

main()

Это отлично работает из среды PyCharm или из командной строки python. После создания исполняемого файла Windows с помощью PyInstaller приложение больше не может подключаться, поскольку rtm_connect() всегда возвращает False. Токен или что-то еще не было изменено.

Любые предложения о том, как отладить это или любые идеи, которые могут вызвать проблему с подключением?

Скрипт PyInstaller:

# -*- mode: python -*-

import os
from os.path import join

datas = []

# list of modules to exclude from analysis
excludes = ['Tkinter', '_tkinter', 'twisted', 'pygments']

# list of hiddenimports
hiddenimports = []

# binary data
bin_tocs = []

# assets
tocs = []

a = Analysis(['slacktest.py'],
             pathex=[os.getcwd()],
             binaries=None,
             datas=datas,
             hiddenimports=hiddenimports,
             hookspath=[],
             runtime_hooks=[],
             excludes=excludes,
             win_no_prefer_redirects=False,
             win_private_assemblies=False)

pyz = PYZ(a.pure, a.zipped_data)

exe1 = EXE(pyz,
          a.scripts,
          name='slacktest',
          exclude_binaries=True,
          debug=False,
          strip=False,
          upx=True,
          console=True)

coll = COLLECT(exe1,
               a.binaries,
               a.zipfiles,
               a.datas,
               *tocs,
               strip=False,
               upx=True,
               name='slacktest')

person Bill Bridge    schedule 27.08.2016    source источник


Ответы (1)


Просто для тех, кто заинтересован в решении, я публикую подробности решения, разработанного разработчиком по контракту.....

Проблема вызвана отсутствием папки websocket, содержащей файл «cacert.pem». Сценарий PyInstaller обновлен ниже, так что файл «cacert.pem» копируется в каталог распространения.

Это недостающая функция PyInstaller. Правильный способ решить эту проблему — отправить «hook-websocket.py» в хуки PyInstaller, чтобы его можно было включить в следующий выпуск PyInstaller. Хук-файл должен быть похож на hook-requests.py.

Кроме того, slackclient должен вызывать ошибку или регистрировать сообщение, а не просто возвращать False в методе rtm_connect.

# -*- mode: python -*-

import os
import websocket
from os.path import join, dirname, basename
from PyInstaller.compat import modname_tkinter

block_cipher = None
websocket_lib_path = dirname(websocket.__file__)
websocket_cacert_file_path = join(websocket_lib_path, 'cacert.pem')
analysis_data = [
    # For websocket library to find "cacert.pem" file, it must be in websocket
    # directory inside of distribution directory.
    # This line can be removed once PyInstaller adds hook-websocket.py
    (websocket_cacert_file_path, join('.', basename(websocket_lib_path)))
]


a = Analysis(['slacktest.py'],
             pathex=[os.getcwd()],
             binaries=None,
             datas=analysis_data,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[modname_tkinter],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='slacktest',
          debug=False,
          strip=False,
          upx=True,
          console=True)
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='slacktest')
person Bill Bridge    schedule 02.09.2016