Messages from PsychoPy to Slack – SSL Certificate Verify Failed

OS (e.g. Win10): Mac OS Big Sur Version 11.6
PsychoPy version (e.g. 1.84.x): 2022.1.1
Standard Standalone? (y/n) y

Hello, I am trying to send messages to Slack from PsychoPy. I’ve been trying to do this by using the Python Slack SDK package (Python Slack SDK — Python Slack SDK), which I’ve used to make a simple app in Slack. I’ve then used the code below to create a message and send it to a Slack channel using the app. The code works correctly outside of PsychoPy using Python 3.8.

logging.basicConfig(level=logging.DEBUG)

import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

#token from Slack API website for app
slack_token = ‘Slack Bot OAuth Token’ #actual token removed for privacy
client = WebClient(token=slack_token)

#function to be used in psychopy for sending participant and accuracy information to slack
def connectSlack(acc_alert, participant, room, natural_response, task, num_try, ```num_corr_total, num_corr_sec):
    message = ('%s'
        'Participant: %s\n'
        '- Room: %s\n'
        '- Natural Response (f or j): %s\n'
        '- Task: %s\n'
        '\t- Number of Tries/Section Number: %d\n'
        '\t- Total Correct: %d\n'
        '\t- Section Correct: %d\n'
        % (acc_alert, participant, room, natural_response, task, num_try, num_corr_total, num_corr_sec))

    # Send a message to #accuracy channel
    try:
        response = client.chat_postMessage(
            #identification number for the slack channel
            channel = "channel", #channel ID removed for privacy
            text = message
        )
    except SlackApiError as e:
        # You will get a SlackApiError if "ok" is False
        assert e.response["error"]    # str like 'invalid_auth', 'channel_not_found'

    return

#test values for function
acc_alert = 'Test'
participant = 's000'
room = 'A'
natural_response = 'J'
task = 'Practice'
num_try = 1
num_corr_total = 1
num_corr_sec = 1

connectSlack(acc_alert, participant, room, natural_response, task, num_try, num_corr_total, num_corr_sec)

To incorporate this into PsychoPy, I’ve pasted my code into a code component in the builder. I’ve include the Slack SDK package in the paths for PsychoPy. However, when I run the script and it gets to the point where I call function to send a message to Slack, I get the error output below. Does anyone know how to potentially solve this issue?

INFO:slack_sdk.web.base_client:A retry handler found: ConnectionErrorRetryHandler for POST https://www.slack.com/api/chat.postMessage - <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)>
INFO:slack_sdk.web.base_client:Going to retry the same request: POST https://www.slack.com/api/chat.postMessage
ERROR:slack_sdk.web.base_client:Failed to send a request to Slack API server: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)>
Traceback (most recent call last):
  File "urllib/request.pyc", line 1354, in do_open
  File "http/client.pyc", line 1252, in request
  File "http/client.pyc", line 1298, in _send_request
  File "http/client.pyc", line 1247, in endheaders
  File "http/client.pyc", line 1007, in _send_output
  File "http/client.pyc", line 947, in send
  File "http/client.pyc", line 1421, in connect
  File "ssl.pyc", line 500, in wrap_socket
  File "ssl.pyc", line 1040, in _create
  File "ssl.pyc", line 1309, in do_handshake
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/ClearCat_V1_lastrun.py", line 518, in <module>
    connectSlack(acc_alert, participant, room, natural_response, task, num_try, num_corr_total, num_corr_sec)
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/ClearCat_V1_lastrun.py", line 138, in connectSlack
    response = client.chat_postMessage(
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/client.py", line 2080, in chat_postMessage
    return self.api_call("chat.postMessage", json=kwargs)
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/base_client.py", line 145, in api_call
    return self._sync_send(api_url=api_url, req_args=req_args)
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/base_client.py", line 182, in _sync_send
    return self._urllib_api_call(
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/base_client.py", line 297, in _urllib_api_call
    response = self._perform_urllib_http_request(url=url, args=request_args)
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/base_client.py", line 504, in _perform_urllib_http_request
    raise err
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/base_client.py", line 412, in _perform_urllib_http_request
    resp = self._perform_urllib_http_request_internal(url, req)
  File "/Users/bomangroff/Documents/Professional/Research/Projects/ClearCat/Task/ClearCat_V1/python-slack-sdk/slack_sdk/slack_sdk/web/base_client.py", line 537, in _perform_urllib_http_request_internal
    resp = urlopen(  # skipcq: BAN-B310
  File "urllib/request.pyc", line 222, in urlopen
  File "urllib/request.pyc", line 525, in open
  File "urllib/request.pyc", line 542, in _open
  File "urllib/request.pyc", line 502, in _call_chain
  File "urllib/request.pyc", line 1397, in https_open
  File "urllib/request.pyc", line 1357, in do_open
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)>
################ Experiment ended with exit code 1 [pid:21362] #################

We were able to resolve this issue by making the following changes to the code above:

# at the top where you are initializing other packages...
# (both of these should have been installed with psycopy so you shouldn't need to install anything - if you get an error about not finding the package let me know)
import ssl
import certifi

# add this line to point to your certificate path
ssl_context = ssl.create_default_context(cafile=certifi.where())

# next replace the previous line where you call the WebClient with the new line:
client = WebClient(token=slack_token, ssl=ssl_context)