Python Twilio module errors after compilation

I wrote a simple program that opens a csv file and the text of all the numbers in it. I am using Twilio ( twilio-python ) as a service provider. My code works fine like a python script. However, when I compile the script (using py2exe), the exe file errors. This is the error I get from the log file ....

Traceback (most recent call last): File "sms.py", line 39, in <module> File "twilio\rest\resources\messages.pyc", line 112, in create File "twilio\rest\resources\base.pyc", line 352, in create_instance File "twilio\rest\resources\base.pyc", line 204, in request File "twilio\rest\resources\base.pyc", line 129, in make_twilio_request File "twilio\rest\resources\base.pyc", line 101, in make_request File "httplib2\__init__.pyc", line 1570, in request File "httplib2\__init__.pyc", line 1317, in _request File "httplib2\__init__.pyc", line 1252, in _conn_request File "httplib2\__init__.pyc", line 1021, in connect File "httplib2\__init__.pyc", line 80, in _ssl_wrap_socket File "ssl.pyc", line 387, in wrap_socket File "ssl.pyc", line 141, in __init__ ssl.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib 

I do not get this error when I use non-compiled code (below)

  import sys #2 params --- /path/to/contact/file --- up to 160 char msg import csv import time from twilio.rest import TwilioRestClient ACCOUNT_SID = "**************************" AUTH_TOKEN = "**************************" client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN) sys.argv.pop(0) contactFile = sys.argv[0] sys.argv.pop(0) msg = (' ').join(sys.argv) print contactFile print " " print msg info = [] with open(contactFile,'rb') as csvfile: reader = csv.reader(csvfile, delimiter=',', quotechar='|') for row in reader: info.append(row) contactCount = len(info)-1 if contactCount > 0: #remove first item from list because its not a value that is needed.... info.pop(0) for i in info: print " " contactName = i[0] phoneNumber = i[1] print "Texting " + contactName + "... \n" client.messages.create( to=phoneNumber, from_="+14782856136", body=msg ) time.sleep(1.5) else: print("SMSify Error \n The contact file doesn't have any contacts in it.") 

Any thoughts on what's going on?

EDIT:

Here is my setup.py file

 from distutils.core import setup import py2exe, sys, os sys.argv.append('py2exe') Mydata_files = [('cacert.pem', ['C:\\Python27\\Lib\\site- packages\\twilio\\conf\\cacert.pem'])] setup( console=['sms.py'], data_files = Mydata_files, options={ "py2exe":{ "bundle_files": 1, "compressed": True } } ) 
+4
python sms twilio
source share
3 answers

This happened because the self-signed certificate file was missing from the bundle.

This problem is the same for requests and httplib2 .

For example, if you have a file called req_example.py that uses the request module:

 import requests url = 'https://google.com/' requests.get(url) 

It works when you run it as python req_example.py , but when it binds it, it does not work.

Or, if you have a file called http2_example.py that uses the http2 module:

 import httplib2 url = 'https://google.com/' http = httplib2.Http() http.request(url) 

It works when you run it as python http2_example.py , but when it contacts it, it does not work.

To fix this, you have two options: one bad and one good .

  • Disable SSL certificate verification:

    To do this for the requests module:

     import requests url = 'https://google.com/' requests.get(url, verify=False) 

    And for the httplib2 module:

     import httplib2 http = httplib2.Http(disable_ssl_certificate_validation=True) http.request(url) 
  • Add the self-signed certificate file to the package:

    For the requests module, the cacert.pem file is located in:

    .../PythonXX/lib/site-packages/requests/cacert.pem

    And for the httplib2 module httplib2 is:

    .../PythonXX/lib/site-packages/httplib2/cacerts.txt

    For each of them, you can copy it to your project (or just contact it),

    And config setup.py to enable:

     setup(console=['temp.py'], # for `requests` module data_files=['cacert.pem'] ) # or data_files=['cacerts.txt'] ) for `httplib2` 

    And change your code to use it, for the request module:

     import os import requests url = 'https://google.com/' cert ='cacert.pem' # or os.environ['REQUESTS_CA_BUNDLE'] = cert os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(os.getcwd(), cert) requests.get(url) 

    And for the httplib2 module:

     import httplib2 cert = 'cacerts.txt' http = httplib2.Http(ca_certs=cert) http.request(url) 

    Or, if your version is httplib2 0.8 , you can create a file that should be named ca_certs_locater.py and define a get function that returns the path to the ca_certs file.

     def get(): return 'cacerts.txt' 

Ok, now for your error and for the twilio module, use httplib2 and cacert.pem is in:

.../twilio/conf/cacert.pem

Therefore, you need to add this file to setup.py as described above.

But twilio itself has a function called get_cert_file , which transfers the ca_cert file to httplib2 .

I think if you use ca_certs_locater.py described above, it will also work for this, but if not, you still have the ugly option, so you can use the twilio function for the twilio monkey:

 from twilio.rest.resources.base import get_cert_file get_cert_file = lambda: 'cacert.pem' 

Note that this may be a problem for twilio or even for py2exe or PyInstaller .

+14
source share

I had the same problem with twilio and pyinstaller, and I was able to fix it by changing the base.py module in twilio \ rest \ resources:

  def get_cert_file(): """ Get the cert file location or bail """ # XXX - this currently fails test coverage because we don't actually go # over the network anywhere. Might be good to have a test that stands up a # local server and authenticates against it. try: # Apparently __file__ is not available in all places so wrapping this # in a try/catch current_path = os.path.realpath(__file__) #ca_cert_path = os.path.join(current_path, "..", "..", "..", (old path) # "conf", "cacert.pem") ca_cert_path = os.getcwd() + '\Config\cacert.pem' (my new path) return os.path.abspath(ca_cert_path) 

(I save the cacert.pem file in the Config folder from my main script directory)

+2
source share

It is probably possible for py2exe to compile non-Python files, such as templates, or in this case the SSL certificate stored in cacert.pem. This is usually done automatically with MANIFEST.in, but I'm not sure how this project handles this. Check the documentation for more information.

+1
source share

All Articles