Search code examples
pythonamazon-web-servicesamazon-sqscx-freezeboto3

How to cx Freeze Boto3


I created this simple python program that sends a message to SQS and then retrieves it. It works using python 2.7.11.

import boto3 
sqs = boto3.client('sqs')
queue = sqs.get_queue_by_name(QueueName='some-que-name')
queue.send_message(MessageBody='{"phrase": "It\'s the end of the world    as we know it" }' )
for message in queue.receive_messages():
    print message.body

I then cxFreeze it with this script:

from cx_Freeze import setup, Executable

include_mods = []

excludes = ['tkinter', 'cltk']

buildOptions = dict(packages=[], excludes=excludes, includes=include_mods)


executables = [
     Executable('./frozen_boto_3_test.py', 'Console')
]

setup(name='Boto3FrozenTest',
  version='1',
  description='A test to make sure boto3 is working well when frozen',
  options=dict(build_exe=buildOptions),
  executables=executables)

I then get this error when I try to run the frozen code

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/cx_Freeze/initscripts/Console.py", line 27, in <module>
    exec(code, m.__dict__)
  File "./frozen_boto_3_test.py", line 1, in <module>
    import boto3 
  File "/usr/local/lib/python2.7/site-packages/boto3/__init__.py", line 16, in <module>
    from boto3.session import Session
  File "/usr/local/lib/python2.7/site-packages/boto3/session.py", line 17, in <module>
    import botocore.session
  File "/usr/local/lib/python2.7/site-packages/botocore/session.py", line 25, in <module>
    import botocore.configloader
  File "/usr/local/lib/python2.7/site-packages/botocore/configloader.py", line 18, in <module>
    from six.moves import configparser
  File "/usr/local/lib/python2.7/site-packages/six.py", line 203, in load_module
    mod = mod._resolve()
  File "/usr/local/lib/python2.7/site-packages/six.py", line 115, in _resolve
    return _import_module(self.mod)
  File "/usr/local/lib/python2.7/site-packages/six.py", line 82, in _import_module
    __import__(name)
ImportError: No module named ConfigParser

In addition to this problem, the library seem to dynamically load services that are not s3, dynamo, or one other service.

Is there a recipe to freezing boto3 ?


Solution

  • The error shows that a hidden (dynamic) import is taking place. If you include the module it is looking for (ConfigParser) in the list of modules you tell cx_Freeze to include, it should work. You may have to do this multiple times.

    executables = [cx_Freeze.Executable("MyScript.py")]
    includes = ["ConfigParser"]
    buildOptions = dict(includes = includes)
    cx_Freeze.setup(name, description, options = dict(build_exe = buildOptions),
            executables = executables)
    

    Once you have a working program, you can also do this instead of manipulating your specific setup.py. You can add an entry into the cx_Freeze.hooks module that looks something like this:

    def load_boto3(finder, module):
        finder.IncludeModule("ConfigParser")
    

    Include any others that you discover along the way. Then create a pull request or issue over here:

    https://bitbucket.org/anthony_tuininga/cx_freeze