0

I have a simple program that takes input from the user and then does scraping with selenium. Since the user doesn't have Python environment installed I would like to convert it to *.exe. I usually use cx_freeze for that and I have successfully converted .py programs to .exe. At first it was missing some modules (like lxml) but I was able to solve it. Now I think I only have problem with docx package.

This is how I initiate the new document in my program (I guess this is what causes me problems):

doc = Document()
#then I do some stuff to it and add paragraph and in the end...
doc.save('results.docx')

When I run it from python everything works fine but when I convert to exe I get this error:

Traceback (most recent call last):
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>

    exec(code, m.__dict__)
  File "tribunalRio.py", line 30, in <module>
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\api.py", line 25, in Document
    document_part = Package.open(docx).main_document_part
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\package.py", line 116, in open
    pkg_reader = PackageReader.from_file(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\pkgreader.py", line 32, in from_file
    phys_reader = PhysPkgReader(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\phys_pkg.py", line 31, in __new__
    "Package not found at '%s'" % pkg_file
docx.opc.exceptions.PackageNotFoundError: Package not found at 'C:\Users\tyszkap\Dropbox (Dow Jones)\Python Projects\build\exe.win-a
md64-3.4\library.zip\docx\templates\default.docx'

This is my setup.py program:

from cx_Freeze import setup, Executable

executable = Executable( script = "tribunalRio.py" )

# Add certificate to the build
options = {
    "build_exe": {'include_files' : ['default.docx'],
        'packages' : ["lxml._elementpath", "inspect", "docx", "selenium"]
    }
}

setup(
    version = "0",
    requires = [],
    options = options,
    executables = [executable])

I thought that explicitly adding default.docx to the package would solve the problem (I have even tried adding it to the library.zip but it gives me even more errors) but it didn't. I have seen this post but I don't know what they mean by:

copying the docx document.py module inside my function (instead of using Document()

Any ideas? I know that freezing is not the best solution but I really don't want to build a web interface for such a simple program...

EDIT:

I have just tried this solution :

def find_data_file(filename):
    if getattr(sys, 'frozen', False):
        # The application is frozen
        datadir = os.path.dirname(sys.executable)
    else:
        # The application is not frozen
        # Change this bit to match where you store your data files:
        datadir = os.path.dirname(__file__)

    return os.path.join(datadir, filename)

doc = Document(find_data_file('default.docx'))

but again receive Traceback error (but the file is in this location...):

Traceback (most recent call last):
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>

    exec(code, m.__dict__)
  File "tribunalRio.py", line 43, in <module>
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\api.py", line 25, in Document
    document_part = Package.open(docx).main_document_part
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\package.py", line 116, in open
    pkg_reader = PackageReader.from_file(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\pkgreader.py", line 32, in from_file
    phys_reader = PhysPkgReader(pkg_file)
  File "C:\Users\tyszkap\AppData\Local\Continuum\Anaconda3\lib\site-packages\docx\opc\phys_pkg.py", line 31, in __new__
    "Package not found at '%s'" % pkg_file
docx.opc.exceptions.PackageNotFoundError: Package not found at 'C:\Users\tyszkap\Dropbox (Dow Jones)\Python Projects\build\exe.win-a
md64-3.4\default.docx'

What am I doing wrong?

5
  • You will likely need to look at the code in the docx package to see what it is expecting. You may have fixed on problem but there is another expectation it has that you need to fulfil before it will be happy. :-) Sep 7, 2016 at 13:28
  • freezing is really a pain... :D
    – pawelty
    Sep 7, 2016 at 13:39
  • Yes, it is. Especially when those writing packages don't concern themselves with freezing in any way and make assumptions about where files are located on disk! Sep 7, 2016 at 17:05
  • cx_Freeze has problems with nested non-Python dependencies - i.e., when one resource depends on other resources, cx_Freeze cannot always walk the entire chain successfully and pull them all into the executable. It uses a Windows function that tells when a DLL/ resource depends on another DLL/resource, but it doesn't always work. Your error message names the file that's missing, so it's a good bet that cx_Freeze couldn't figure out that your program needs this file. You may need to copy this file specifically to your build directory in your setup script. Nasty problem. Good luck. Sep 7, 2016 at 19:48
  • Thank you guys! I gave up. Finally I have decided to write the results to txt file. The less packages I need to bundle the easier for cx_freeze. Thanks again.
    – pawelty
    Sep 8, 2016 at 12:27

2 Answers 2

0

I expect you'll find the problem has to do with your freezing operation not placing the default Document() template in the expected location. It's stored as package data in the python-docx package as docx/templates/default.docx (see setup.py here: https://github.com/python-openxml/python-docx/blob/master/setup.py#L37)

I don't know how to fix that in your case, but that's where the problem is it looks like.

0

I had the same problem and managed to get around it by doing the following. First, I located the default.docx file in the site-packages. Then, I copied it in the same directory as my .py file. I also start the .docx file with Document() which has a docx=... flag, to which I assigned the value: os.path.join(os.getcwd(), 'default.docx') and now it looks like doc = Document(docx=os.path.join(os.getcwd(), 'default.docx')). The final step was to include the file in the freezing process. Et voilà! So far I have no problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.