1

Ok there is a lot of information here but it's the result of me searching for days for this solution. I've seen so many people ask this question in various forms with no good answer and I think I'm really close to solving it!

I have a fully functioning python script that uses the smartsheet-python-sdk module but when I run it as an exe bundled with Pyinstaller, it reads the smartsheet objects as strings and I cannot access any of the attributes. The module has a sub-folder called "models" with another subfolder in that called "enums". I figured that I would need to create a hook to import these so I attempted to build one and still no luck. The hooks were read while compiling but they didn't work.

For reference here is the smartsheet package structure.

System info

Everything is the most up-to-date current version: Python 3.7 Pyinstaller 3.6 Smartsheet 2.86

Operating system: Windows 10

Attempts so far

Someone found a solution to the problem in this post but they didn't provide their solution so it wasn't much help. I have tried adding import statements as suggested here

This is the attempted hook I created for the smartsheet.models:

from PyInstaller.utils.hooks import collect_submodules

hiddenimports = collect_submodules('smartsheet.models')

Some possible reason it's not working

I think it has something to do with the information in the module init files but I am not sure how to deal with it. The init from the main module has this statement:

from .smartsheet import Smartsheet, fresh_operation, AbstractUserCalcBackoff  # NOQA

and the init from the models sub-module has statements to import the individual models found in the directory:

from __future__ import absolute_import

# import models into model package
from .access_token import AccessToken
from .account import Account
from .alternate_email import AlternateEmail
from .attachment import Attachment
from .auto_number_format import AutoNumberFormat
# This continues for other models

So I think that I need to somehow mimic this model import statement in my hook file but I don't know how to do it.

Code & Error Message:

It creates the main smartsheet object ok as it does not reference any of the sub-module items:

# Creates a smartsheet object for an account with an api access token
ss = smartsheet.Smartsheet(a_token)

But anything that references submodules within this object fails

ss.Sheets.get_sheet(residential_id)

This is the error message I get when I run the program:

ImportError! Could not load api or model class Users

# print statement I added to show the string object that is supposed to be a smartsheet object
<smartsheet.smartsheet.Smartsheet object at 0x00000292D4232408> 

Exception type: AttributeError 

Exception message: 'str' object has no attribute 'get_sheet' 

Stack trace:  
 File: sum_report.py
    Line: 516
    Function nameName: main 
    Message: 

 File: snow_functions.py
    Line: 437
    Function nameName: connect_smartsheet 
    Message: 

1 Answers1

0

I was running in to same issue. What I have found is that you have to add all the individual modules you need as hidden imports.

Open you .spec file that was created. If you have previous used pyinstaller script.py, look for the file script.spec in your script directory. Open it and modify the section:

hiddenimports=[
    'smartsheet.models'
    'smartsheet.sheets',
    'smartsheet.search',
    'smartsheet.users'  
    ]

Then run pyinstaller script.spec to use the spec file with the hidden imports. Try running your package again. You may need to added additional modules to the hidden imports array if your script fails again (just look at the module referenced in the error.)

I finally got mine working after adding models, sheets, and search.