Esky not including sub-module - python

I have a medium-size PyQT5 desktop application that has been working fine with py2app. I want to incorporate Esky so that the app can update itself, but the app terminates during startup (before displaying the main window) with a log entry that says "HelloApp Error" (where "HelloApp" is the name of my application).
I've created a small test case that reproduces the problem that is available at https://github.com/markmont/esky-package-question
The test-case app has the following structure:
HelloApp/
HelloApp/
HelloApp.py
helloform
__init__.py
setup.py
setup.py contains:
from esky import bdist_esky
from distutils.core import setup
PY2APP_OPTIONS = {
'argv_emulation': True,
'includes': [ 'sip', 'PyQt5', 'helloform' ],
'qt_plugins': [ '*' ]
}
ESKY_OPTIONS = {
"freezer_module": "py2app",
"freezer_options": PY2APP_OPTIONS,
"includes": [ 'sip', 'PyQt5', 'helloform' ]
}
HelloApp = bdist_esky.Executable( "HelloApp/HelloApp.py", gui_only=True )
setup(
name='HelloApp',
version = "2014060301",
data_files=[],
options = { "bdist_esky": ESKY_OPTIONS },
scripts=[ HelloApp ]
)
HelloApp.py contains the statement from helloform import Form -- this appears to be what is causing the app to fail to start with the error "HelloApp Error", as if I remove that statement and paste in the contents of helloform/init.py the application starts up and works properly.
Also, if I move everything into a single directory and adjust the paths in setup.py, then the problem does not occur -- Esky finds helloform.py (formerly named helloform/init.py), includes it, and the application starts up and works properly:
HelloApp/
HelloApp.py
helloform.py # formerly ./HelloApp/helloform/__init__.py
setup.py
...but putting everything in single directory is not a scalable solution for a medium-to-large application.
There are no error messages in the output of python setup.py bdist_esky when the problem occurs, and I have not found the answer in the Esky documentation or in various examples on the web.
The full error from /var/log/system.log is:
2014-06-03 13:03:07.100 HelloApp[14968]: HelloApp Error
I'm assuming that I'm not using Esky's includes option properly in setup.py, but I've got no clue as to how to fix this -- can anyone help?
Other possibly relevant details: MacOS X 10.9 Mavericks, Python 2.7.6 (local build), qt-5.3.0 opensource, sip 4.16, PyQT 5.3.0 (GPL), py2app 0.8.1 patched to support PyQT5, and the latest version of Esky from GitHub.
Thanks in advance!

I've solved this problem -- the problem was due to my limited knowledge of Python distutils and setuptools. Since things "just worked" with py2app (which was using setuptools), I assumed that the problem was with how Etsy was configured when the problem was really with how I was using distutils.
The problem was that helloworld.py was not being copied into the frozen app.
The solution involved restructuring the files and changing the disutils configuration to explicitly add HelloApp as a package.
New file structure:
HelloApp/
hello.py # formerly HelloApp.py
HelloApp/
__init__.py
helloform.py
setup.py
New setup.cfg:
from esky import bdist_esky
from distutils.core import setup
PY2APP_OPTIONS = {
'argv_emulation': True,
'includes': [ 'sip', 'PyQt5' ],
'qt_plugins': [ '*' ]
}
ESKY_OPTIONS = {
"freezer_module": "py2app",
"freezer_options": PY2APP_OPTIONS,
"includes": [ 'sip', 'PyQt5' ]
}
HelloApp = bdist_esky.Executable( "hello.py", gui_only=True )
setup(
name='hello',
version = "2014060301",
data_files=[],
options = { "bdist_esky": ESKY_OPTIONS },
scripts=[ HelloApp ],
packages=[ 'HelloApp' ],
)

Related

Is it possible to use cx_freeze on a python 3 project using the pip module?

I am writing an installation program for a larger program I am writing, and I am using CxFreeze to convert it to an executable file, however, when I run the .exe file, it crashes with the line "import pip", and brings up (as shown below), so basically my question is: Is it possible to use CxFreeze on an application with pip imported?
Edit:
Here are all the files I am using:
setup.py (V1):
from cx_Freeze import *
import os, pip
setup(name=("ARTIST"),
version = "1",
description = "ARTIST installation file",
executables = [Executable("Install ARTIST.py"), Executable("C:\\Python34\\Lib\\site-packages\pip\\__init__.py")],
)
This brings up the error:
setup.py (V2):
from cx_Freeze import *
import os, pip
setup(name=("ARTIST"),
version = "1",
description = "ARTIST installation file",
executables = [Executable("Install ARTIST.py"],
options = {"build_exe": {"packages":[pip]}}
)
This brings up an error in the setup.bat file:
Edit:
If anyone wants to look at the website where I am publishing the larger program, here is the link:
alaricwhitehead.wix.com/artist
Edit2:
this is the error i get when i use py2exe:
Edit3:
here is a copy of the code:
https://www.dropbox.com/s/uu46iynm8fr8agu/Install%20ARTIST.txt?raw=1
please note: I didn't want to have to post a link to it, but it was too long to post directly.
The are two problems in your setup script. The first problem is that you specified extra modules to include in your frozen application under the packages option of the build_exe command: packages is for specifying which packages of your application you need to include, for the external modules (such as pip) you need to use includes. The second problem is that you need to pass to includes a list of strings of modules and not the module itself:
setup(
name=("ARTIST"),
version="1",
description="ARTIST installation file",
options={
'build_exe': {
'excludes': [], # list of modules to exclude
'includes': ['pip'], # list of extra modules to include (from your virtualenv of system path),
'packages': [], # list of packages to include in the froze executable (from your application)
},
},
executables=[
Executable(
script='run.py', # path to the entry point of your application (i.e: run.py)
targetName='ARTIST.exe', # name of the executable
)
]
)

Python Flask - Building the Server as Executable (Py2exe)

I have a flask project, everything appears to be working fine. When using py2exe to build the package, (target server is a windows server ugh), the executable can execute, but leaves me with a ImportError: No module named 'jinja2.ext'
I have the module, and the website works fine with no ImportError when not executing from the .exe
I am pretty new at packaging and delivering, and not sure whats wrong with the setup that is causing the break from .py -> .exe conversion.
Setup.py
from setuptools import setup, find_packages
import py2exe
NAME = "WorkgroupDashboard"
VERSION = "1.0"
setup(
name=NAME,
version=VERSION,
description="Provides real time ISIS connection data",
long_description="",
# Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
classifiers=[],
author="Test User",
author_email='',
url='',
license='Free',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
include_package_data=True,
zip_safe=False,
install_requires=[
'flask >= 0.10.1',
'SQLAlchemy>=0.6'
],
console=['DashboardBack.py']
)
The idea is in order to turn the server on, just execute the .exe. Server will not have python on it. I am using Python 3.4 64 bit.
Edit: build cmd = python setup.py py2exe
Figured it out it seems, Setup commands go inside the py2exe optuons=[]
Working Setup.py
__author__ = ''
import sys
from glob import glob # glob will help us search for files based on their extension or filename.
from distutils.core import setup # distutils sends the data py2exe uses to know which file compile
import py2exe
data_files = []
setup(
name='WorkgroupDashboard',
console=['DashboardBack.py'], # 'windows' means it's a GUI, 'console' It's a console program, 'service' a Windows' service, 'com_server' is for a COM server
# You can add more and py2exe will compile them separately.
options={ # This is the list of options each module has, for example py2exe, but for example, PyQt or django could also contain specific options
'py2exe': {
'packages':['jinja2'],
'dist_dir': 'dist/test', # The output folder
'compressed': True, # If you want the program to be compressed to be as small as possible
'includes':['os', 'logging', 'yaml', 'flask', 'sqlalchemy'], # All the modules you need to be included, because py2exe guesses which modules are being used by the file we want to compile, but not the imports
}
},
data_files=data_files # Finally, pass the
)
I'd convert mine to EXE and deploy is over a host. Just get "Auto Py To Exe" application. Download it locally. Open the app, insert your project location, do some setup if you want, and then click "Convert". There you go. Flask in EXE format. Plug-in anywhere that you like without the need to have Python Interpreter.

multiple custom plugins in py.test

My question is regarding multiple custom plugins in pytest.
I have two (or more) pytest plugins that I created which are installed using setuptools and pytest11 entry point, each plugin has its own setup.py. It seems like only the first installed plugin is active. I have verified this via print statements in the pytest_configure hook. If the first installed plugin is uninstalled, then only the second configure hook for the second plugin seems to get called. Also, the same behavior is observed with the addoption hook, options for the plugin installed second is unrecognized.
I'm thoroughly confused because I've used third party plugins and they seem to work just fine. Aren't hooks for all the installed plugins supposed to be called ?
Could this be a problem with the way plugins are installed, i.e. with setuptools ? (the command I use is python setup.py -v install). Pip correctly shows all the plugin modules as installed.
Edit:
Names are different, below are the setup files:
from setuptools import setup
setup(
name="pytest_suite",
version="0.1",
packages=['suite_util'],
# the following makes a plugin available to pytest
entry_points={
'pytest11': [
'name_of_plugin = suite_util.conftest',
]
},
)
and
from setuptools import setup
setup(
name="pytest_auto_framework",
version="0.1",
packages=['automation_framework'],
# the following makes a plugin available to pytest
entry_points={
'pytest11': [
'name_of_plugin = automation_framework.conftest',
]
},
)
If your pytest entry points both have the same name (as they do in your example above), only the first one will be loaded by pytest.
Note that this is not an inherent limitation of pkg_resources entry points but due to they way plugins are registered in pytest. There can only be one plugin with the same name - which makes sense imho.
The Pytest official document is ambiguous. The reason why your code don't work is because you followed that doc when you writing your both setup.py with same plugin name:
In this code:
entry_points={
'pytest11': [
'name_of_plugin = automation_framework.conftest',
]
the name_of_plugin is customizble and should be unique, otherwise pytest will load one of all plugins with same name (I guess is the last one with same name)
So, the solution to your question is:
setup.py 1:
from setuptools import setup
setup(
name="pytest_auto_framework",
version="0.1",
packages=['automation_framework'],
# the following makes a plugin available to pytest
entry_points={
'pytest11': [
'automation_framework = automation_framework.conftest',
]
},
)
setup.py 2:
from setuptools import setup
setup(
name="pytest_suite",
version="0.1",
packages=['suite_util'],
# the following makes a plugin available to pytest
entry_points={
'pytest11': [
'suite_util = suite_util.conftest',
]
},
)
POC
2 entry points with same plugin name left hand value
2 engry points with different plugin name

Bundle sqldrivers into .exe using py2exe

In my first attempts, my pyQt application bundled with py2exe refused to connect to the sqlite database although it was working in its python version.
I guessed that it was a problem of libraries not loaded into the .exe application. I solved that problem by including the full path to the sqlite DLL into the setup.py file and thus copying this DLL to the executable folder.
Now I would like to include this DLL into the .exe file in order to "hide" this DLL to my users. Do you have a clue how to do that ?
my current setup.py:
from distutils.core import setup
import py2exe
setup(
windows=[{
"script": 'myscript.py'
}],
options={
'py2exe': {
"dll_excludes": [
"MSVCP90.dll",
"MSWSOCK.dll",
"mswsock.dll",
"powrprof.dll",
],
'includes': [
'sip',
'PyQt4.QtNetwork',
],
'bundle_files': 1,
}
},
data_files = [
'config.ini',
'template.htm',
# This is the File that I wish to be "hidden"
('sqldrivers', ('C:\Python27\Lib\site-packages\PyQt4\plugins\sqldrivers\qsqlite4.dll',)),
zipfile=None,
)
I ran into the same problem and you are half way to solving the issue. The first part of the problem is as you identified, getting the file into the EXE. I can't speak to the correctness of your py2exe solution as I am using pyinstaller, but that is the general idea. You need to get the qsqlite4.dll into a sqldrivers directory within your single file app.
The second part is that your main .py needs to have the path added to its running directory which will now contain that sqldrivers folder. What you will need to do is get the relative path to where your main .py is running and set that directory as your library path in your QT application. I use the standard resource_path() function for pyinstaller, but using something like this should work for py2exe:
def resource_path(relative_path)
if sys.frozen:
base_path = os.path.dirname(sys.executable)
else:
base_path = os.path.dirname(__file__)
return os.path.join(base_path, relative_path)
Then you can use this code in the main function of your application
app = QApplication(sys.argv)
new_lib_path = app.libraryPaths()
new_lib_path.append(resource_path(''))
app.setLibraryPaths(new_lib_path)
. . .
With logging added, here is my app.libraryPaths() before and after:
08/25/2014 01:33:24 AM CRITICAL: Before[u'C:/dev/WORKSP~1/db/dist']
08/25/2014 01:33:24 AM CRITICAL: After[u'C:/dev/WORKSP~1/db/dist', u'C:\\Users\\jeff\\AppData\\Local\\Temp\\_MEI2042\\']
You could replace the '\' with '/' but I didn't bother, it still works with windows separators.

Compiling docx with py2exe

I'm compiling a python script to .exe via py2exe. I originally started compiling it and the entire program ran fine aside from the Word document creation.
My logfile would give me: ERROR: Could not close or save Word Document 'docName.docx' :, so where I am supposed to be supplied an error message - I am not.
I started to think it could do with the missing modules in py2exe, reported as:
The following modules appear to be missing
['ICCProfile', '_imaging_gif', '_scproxy', '_sysconfigdata']
And then I noticed many people didn't care too much about these errors.
I looked in the docx package, located in C:\Python27\Lib\site-packages\docx-0.2.4-py2.7.egg\, as installed by easy_install, and saw this docx-templates folder, which I am certain was not imported, so I wrote my setup.py referencing the docx-template I put in my build folder manually:
from distutils.core import setup
from glob import glob
import os
import py2exe
#templatePath = 'C:/Python27/Lib/site-packages/docx-0.2.4-py2.7.egg/docx-template'
setup(
console=['xmlpolicydocx-0.4.py'],
options={
'py2exe':
{
'includes': ['docx', 'PIL', 'lxml.etree', 'lxml._elementpath', 'gzip']
}
},
packages=[
'docx-template'
],
package_data={
'docx-template': [
'_rels/*',
'docProps/*',
'word/theme/*.xml',
'word/*.xml'
],
},
)
Yet I still have no luck in getting docx to work when compiled via py2exe. Any suggestions or methods of debugging I can take to take another look at solving this problem?

Categories

Resources