Py2Exe local server does not execute CGI - python

I have a certain Python program that relies on a CGI script, which works when I launch a Python BaseHTTPServer with a CGIHTTPServer. But I would like all this to be run without installing Python, so I used Py2Exe.
I manage to create a .exe from my script, which indeed creates a working local web server when executed. CGI scripts, however, are just shown as code and not executed.
Here's the whole server script, which also launches the default browser:
#!/usr/bin/env python
import webbrowser
import BaseHTTPServer
import CGIHTTPServer
server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
server_address = ("", 8008)
handler.cgi_directories = ["/cgi"]
httpd = server(server_address, handler)
webbrowser.open_new("http://localhost:8008/cgi/script.py");
httpd.serve_forever()
However, that script.py is just shown and not executed. I can't figure out why, and I have tried a few different versions in handler.cgi_directories, just in case...

problem is py2exe only converts your server script to exe, all cgi scripts are still .py and they require python installation to run. try converting each and every script in 'cgi' directory.
Assuiming you have server.py in root dir and cgi scripts at wwwroot\cgi-bin your setup.py should look like
#!usr/bin/env python
from distutils.core import setup
import py2exe, os
setup(name='server',
console=['server.py'],
options={
"py2exe":{
"unbuffered": True,
"packages": "cgi, glob, re, json, cgitb", # list all packages used by cgi scripts
"optimize": 2,
"bundle_files": 1
}},
zipfile="library.zip")
os.rename("dist\\library.zip","dist\\library.zip.bak") # create backup of the library file
files=[]
for f in os.listdir("wwwroot\\cgi-bin"): # list all cgi files with relative path name
files.append("wwwroot\\cgi-bin\\"+f)
setup(name='cgi',
console= files,
options={
"py2exe":{
"dist_dir": "dist\\wwwroot\\cgi-bin",
"excludes": "cgi, glob, re, json, cgitb", # we are going to discard this lib, may as well reduce work
"bundle_files": 1
}
},
zipfile="..\\..\\library.zip") # make sure zipfile points to same file in both cases
os.remove("dist\\library.zip") # we don't need this generated library
os.rename("dist\\library.zip.bak","dist\\library.zip") # we have already included everything in first pass

Related

How to activate a Python virtual environment and execute a script at the same time?

I am trying to load automatically my Python virtual environment and execute a python query at the same time in Powershell but I am not getting any luck at it. This is the code I have:
# my_testing_file.py
# Activate the virtual environment
import os
script_directory = os.path.dirname(os.path.abspath(__file__))
activate_this_file = os.path.join(script_directory, 'C:\Temp\Development\Python_scripts\env\Scripts\activate_this.py')
# Start executing the main code
import pypyodbc
from openpyxl.workbook import Workbook
def main():
cursor = initiate_connection_db()
unposted_hours_results = retrieve_results_query(cursor)
...
if __name__ == "__main__":
main()
All the code is in 1 single file and basically I want to do in Powershell python my_testing_file.py so it loads the virtual environment and executes the rest of the code.
When this code gets executed from Powershell, a command prompt appears for a few seconds and then it shuts down and the rest of the code never gets executed. Any help for fixing this code would be greatly appreciated.
As #dfundako indicated, a post-activate script could have done the trick to activate the virtual environment and execute the script all at once, however, I found another alternative which I believe it is not the best but it performed what I needed to achieve. I had to pack the python script and its libraries in an .exe file so once a user clicks on it, the program executes the desired task.
Inside of my virtual environment, I executed this file called setup.py to build my_testing_file.py to an .exe:
# Python 3.6.7
# The cx_Freeze library did the trick to pack all the libraries and the script.
# Put down all the scripts that your
import sys, os
import openpyxl
import cx_Freeze
import my_testing_file.py
from subprocess import call
base = None
if sys.platform == 'win32':
base = "Win32GUI"
# my_testing_file is the main script that executes my desired task.
executables = [cx_Freeze.Executable("my_testing_file.py", base=base)]
cx_Freeze.setup(
name = "Testing Deploy",
options = {"build_exe":
{"packages":
["openpyxl", "subprocess"]
}
},
version = "0.01",
description = " Testing executable alternative",
executables = executables
)
I believe something similar could have been done with Docker as well but I lack the required knowledge to achieve the same goal. Feel free to improve this answer or put the code for the Docker alternative or the aforementioned post-activate script.

15 Python scripts into one executable?

Ive been tinkering around all day with solutions from here and here:
How would I combine multiple .py files into one .exe with Py2Exe
Packaging multiple scripts in PyInstaller
but Its not quite working the way I thought it might.
I have a program that Ive been working on for the last 6 months and I just sourced out one of its features to another developer who did his work in Python.
What I would like to do is use his scripts without making the user have to download and install python.
The problem as I see it is that 1 python script calls the other 14 python scripts for various tasks.
So what I'm asking is whats the best way to go about this?
Is it possible to package 15 scripts and all their dependencies into 1 exe that I can call normally? or is there another way that I can package the initial script into an exe and that exe can call the .py scripts normally? or should I just say f' it and include a python installer with my setup file?
This is for Python 2.7.6 btw
And this is how the initial script calls the other scripts.
import printSub as ps
import arrayWorker as aw
import arrayBuilder as ab
import rootWorker as rw
import validateData as vd
etc...
If this was you trying to incorporate these scripts, how would you go about it?
Thanks
You can really use py2exe, it behaves the way you want.
See answer to the mentioned question:
How would I combine multiple .py files into one .exe with Py2Exe
Usually, py2exe bundles your main script to exe file and all your dependent scripts (it parses your imports and finds all nescessary python files) to library zip file (pyc files only). Also it collects dependent DLL libraries and copies them to distribution directory so you can distribute whole directory and user can run exe file from this directory. The benefit is that you can have a large number of scripts - smaller exe files - to use one large library zip file and DLLs.
Alternatively, you can configure py2exe to bundle all your scripts and requirements to 1 standalone exe file. Exe file consists of main script, dependent python files and all DLLs. I am using these options in setup.py to accomplish this:
setup(
...
options = {
'py2exe' : {
'compressed': 2,
'optimize': 2,
'bundle_files': 1,
'excludes': excludes}
},
zipfile=None,
console = ["your_main_script.py"],
...
)
Working code:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {
'py2exe' : {
'compressed': 1,
'optimize': 2,
'bundle_files': 3, #Options 1 & 2 do not work on a 64bit system
'dist_dir': 'dist', # Put .exe in dist/
'xref': False,
'skip_archive': False,
'ascii': False,
}
},
zipfile=None,
console = ['thisProject.py'],
)
Following setup.py (in the source dir):
from distutils.core import setup
import py2exe
setup(console = ['multiple.py'])
And then running as:
python setup.py py2exe
works fine for me. I didn't have to give any other options to make it work with multiple scripts.

Py2Exe generate log file

My problem is that py2exe is generating a log file when I run. It doesn't generate because I have an error when running the program. At the log file there is the standard console print out!
How can I do it that no log file would generate?
here my py2exe setup code:
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {'py2exe': {'bundle_files': 1, 'compressed': True}},
windows = [{'script': "run.py"}],
zipfile = None
)
In GUI applications, Py2exe redirects sys.stderr to a log file and sys.stdout to an object that ignores all writes. To avoid the log file, do this in your program at the top of the main module:
import sys
sys.stderr = sys.stdout
Or, let py2exe create a console application by using the console keyword instead of windows in setup.py.
Probably you can remove the content of the file! It can work, but you must see if your programm needs some function defined there and then it can get errors!
At the chat you said that you want to use Python 3 but Py2Exe isn't there... Why don't you use cx_Freeze? It generates a bin and an .exe file. You can make an Installation with InnoSetup and you Game is perfect!

Packaging a twistd plugin using pyinstaller

I created a nice python Twisted app with a plugin for the twistd runner, as specified in the Twisted Documentation: http://twistedmatrix.com/documents/current/core/howto/tap.html. I am having problems packaging this with PyInstaller: my twistd plugin is not found during execution of the frozen application.
To ship my project, I created my own top-level startup script using the twistd runner modules, e.g.
#!/usr/bin/env python
from twisted.scripts.twistd import run
from sys import argv
argv[1:] = [
'--pidfile', '/var/run/myapp.pid',
'--logfile', '/var/run/myapp.log',
'myapp_plugin'
]
run()
Next, I use PyInstaller to freeze this as a single directory deployment. Executing the frozen script above fails as it cannot find my twistd plugin (edited for brevity):
~/pyinstall/dist/bin/mystartup?16632/twisted/python/modules.py:758:
UserWarning: ~/pyinstall/dist/mystartup?16632 (for module twisted.plugins)
not in path importer cache (PEP 302 violation - check your local configuration).
~/pyinstall/dist/bin/mystartup: Unknown command: myapp_plugin
Normally, Twistd inspects the Python system path to discover my plugin in twisted/plugins/myapp_plugin.py. If I print the list of twistd plugins in my startup script, the list is empty in the executable resulting from PyInstaller, e.g.
from twisted.plugin import IPlugin, getPlugins
plugins = list(getPlugins(IPlugin))
print "Twistd plugins=%s" % plugins
I use a somewhat default PyInstaller spec file, no hidden imports or import hooks specified.
I like the functionality of twistd with logging, pid files, etc, so I would like to avoid having to abandon the twistd runner altogether to circumvent the plugin issue.
Is there a way to ensure my twistd plugin is found in the frozen executable?
I found a workaround by reverse engineering some of the twisted code. Here I hardcode the plugin import. This works fine with PyInstaller for me.
#!/usr/bin/env python
import sys
from twisted.application import app
from twisted.scripts.twistd import runApp, ServerOptions
import myapp_plugin as myplugin
plug = myplugin.serviceMaker
class MyServerOptions(ServerOptions):
"""
See twisted.application.app.ServerOptions.subCommands().
Override to specify a single plugin subcommand and load the plugin
explictly.
"""
def subCommands(self):
self.loadedPlugins = {plug.tapname:plug}
yield (plug.tapname,
None,
# Avoid resolving the options attribute right away, in case
# it's a property with a non-trivial getter (eg, one which
# imports modules).
lambda plug=plug: plug.options(),
plug.description)
subCommands = property(subCommands)
def run():
"""
Replace twisted.application.app.run()
To use our ServerOptions.
"""
app.run(runApp, MyServerOptions)
sys.argv[1:] = [
'--pidfile', '/var/run/myapp.pid',
'--logfile', '/var/run/myapp.log',
plug.tapname] + sys.argv[1:]
run()

running a python script as administrator

i'm writing an installer using py2exe which needs to run in admin to have permission to perform various file operations. i've modified some sample code from the user_access_controls directory that comes with py2exe to create the setup file. creating/running the generated exe works fine when i run it on my own computer. however, when i try to run the exe on a computer that doesn't have python installed, i get an error saying that the import modules (shutil and os in this case) do not exist. it was my impression that py2exe automatically wraps all the file dependencies into the exe but i guess that this is not the case. py2exe does generate a zip file called library that contains all the python modules but apparently they are not used by the generated exe. basically my question is how do i get the imports to be included in the exe generated by py2exe. perhaps modification need to be made to my setup.py file - the code for this is as follows:
from distutils.core import setup
import py2exe
# The targets to build
# create a target that says nothing about UAC - On Python 2.6+, this
# should be identical to "asInvoker" below. However, for 2.5 and
# earlier it will force the app into compatibility mode (as no
# manifest will exist at all in the target.)
t1 = dict(script="findpath.py",
dest_base="findpath",
uac_info="requireAdministrator")
console = [t1]
# hack to make windows copies of them all too, but
# with '_w' on the tail of the executable.
windows = [{'script': "findpath.py",
'uac_info': "requireAdministrator",
},]
setup(
version = "0.5.0",
description = "py2exe user-access-control",
name = "py2exe samples",
# targets to build
windows = windows,
console = console,
)
Try to set options={'py2exe': {'bundle_files': 1}}, and zipfile = None in setup section. Python will make single .exe file without dependencies. Example:
from distutils.core import setup
import py2exe
setup(
console=['watt.py'],
options={'py2exe': {'bundle_files': 1}},
zipfile = None
)
I rewrite your setup script for you. This will work
from distutils.core import setup
import py2exe
# The targets to build
# create a target that says nothing about UAC - On Python 2.6+, this
# should be identical to "asInvoker" below. However, for 2.5 and
# earlier it will force the app into compatibility mode (as no
# manifest will exist at all in the target.)
t1 = dict(script="findpath.py",
dest_base="findpath",
uac_info="requireAdministrator")
console = [t1]
# hack to make windows copies of them all too, but
# with '_w' on the tail of the executable.
windows = [{'script': "findpath.py",
'uac_info': "requireAdministrator",
},]
setup(
version = "0.5.0",
description = "py2exe user-access-control",
name = "py2exe samples",
# targets to build
windows = windows,
console = console,
#the options is what you fail to include it will instruct py2exe to include these modules explicitly
options={"py2exe":
{"includes": ["sip","os","shutil"]}
}
)

Categories