using cx_freeze on flask app - python

I am using Flask to develop a python app. At the moment, I want this app to be run locally. It runs locally fine through python, but when I use cx_freeze to turn it into an exe for Windows, I can no longer use the Flask.render_template() method. The moment I try to execute a render_template, I get an http 500 error, exactly as if the html template I'm trying to render does not exist.
The main python file is called index.py. At first I tried to run: cxfreeze index.py. This did not include the "templates" directory from the Flask project in the cxfreeze "dist" directory. So then I tried using this setup.py script and running python setup.py build. This now includes the templates folder and the index.html template, but I still get the http: 500 error when it tries to render the template.
from cx_Freeze import setup,Executable
includefiles = [ 'templates\index.html']
includes = []
excludes = ['Tkinter']
setup(
name = 'index',
version = '0.1',
description = 'membership app',
author = 'Me',
author_email = 'me#me.com',
options = {'build_exe': {'excludes':excludes,'include_files':includefiles}},
executables = [Executable('index.py')]
)
Here is an example method from the script:
#app.route('/index', methods=['GET'])
def index():
print "rendering index"
return render_template("index.html")
If I run index.py then in the console I get:
* Running on http://0.0.0.0:5000/
rendering index
127.0.0.1 - - [26/Dec/2012 15:26:41] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [26/Dec/2012 15:26:42] "GET /favicon.ico HTTP/1.1" 404 -
and the page is displayed correctly in my browser, but if I run index.exe, I get
* Running on http://0.0.0.0:5000/
rendering index
127.0.0.1 - - [26/Dec/2012 15:30:57] "GET / HTTP/1.1" 500 -
127.0.0.1 - - [26/Dec/2012 15:30:57] "GET /favicon.ico HTTP/1.1" 404 -
and
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
in my browser.
If I return raw html, e.g.
#app.route('/index', methods=['GET'])
def index():
print "rendering index"
return "This works"
then it works fine. So a possible work around is to stop using Flask's templates and hardcode all the html logic into the main python file. This gets very messy though, so I'd like to avoid it if possible.
I'm using Python 2.7 32-bit, Cx_freeze for Python 2.7 32-bit, and Flask 0.9
Thanks for any help and ideas!

After many false trails trawling through the Flask and Jinga modules, I finally found the problem.
CXFreeze does not recognize that jinja2.ext is a dependency, and was not including it.
I fixed this by including import jinja2.ext in one of the python files.
CXFreeze then added ext.pyc to library.zip\jinja. (Copying it in manually after the build also works)
Just in case anyone else is mad enough to try use Flask to develop locally run apps :)

An alternative to import jinja2.ext in the source file is to specifically include jinja2.ext in the setup.py:
from cx_Freeze import setup,Executable
includefiles = [ 'templates\index.html']
includes = ['jinja2.ext'] # add jinja2.ext here
excludes = ['Tkinter']
setup(
name = 'index',
version = '0.1',
description = 'membership app',
author = 'Me',
author_email = 'me#me.com',
# Add includes to the options
options = {'build_exe': {'excludes':excludes,'include_files':includefiles, 'includes':includes}},
executables = [Executable('index.py')]
)

Related

Gunicorn 20 failed to find application object 'app.server' in 'index'

I'm using Gunicorn to deploy my Dash app. After upgrading to Gunicorn 20.0.0, it fails to find my application.
gunicorn --bind=0.0.0.0 --timeout 600 index:app.server
Failed to find application object 'app.server' in 'index'
[INFO] Shutting down: Master
[INFO] Reason: App failed to load.
This issue on Gunicorn's issue tracker seems to be related to the error, but I can't figure out what I'm supposed to do to fix it. How can I make Gunicorn 20 find my app?
index.py:
import os
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from pages import overview
from webapp import app
app.index_string = open(os.path.join("html", "index.html")).read()
app.layout = html.Div([
dcc.Location(id="url", refresh=False),
html.Div(id="page-content")
])
#app.callback(Output("page-content", "children"), [Input("url", "pathname")])
def display_page(pathname):
if pathname == "/a-service/overview":
return overview.layout
else:
return overview.layout
if __name__ == "__main__":
app.run_server(debug=True, port=8051)
webapp.py:
import dash
description = "a description"
title = "a title"
creator = "#altf1be"
app = dash.Dash(
__name__,
meta_tags=[
{"name": "viewport", "content": "width=device-width, initial-scale=1"},
{"name": "description", "content": description},
{"name": "twitter:description", "content": description},
{"property": "og:title", "content": description},
{"name": "twitter:creator", "content": creator}
]
)
server = app.server
app.config.suppress_callback_exceptions = True
Gunicorn 20 changed how it parses and loads the application argument. It used to use eval, which followed attribute access. Now it only does a simple lookup for a single name in the given module. The ability for Gunicorn to understand Python syntax such as attribute access was not documented or intended.
Dash's docs about deployment don't use the syntax you're using though. They say to do the following, which will work for any version of Gunicorn:
webapp.py:
server = app.server
$ gunicorn webapp:server
You're already adding the server alias in the webapp module, but your code layout is a bit off and making things confusing for you. You're ignoring the setup you do in webapp and using index as your entry point instead. You're putting everything in separate top-level modules rather than within a package.
If you want to split your app setup from your index views, you should follow the standard Flask pattern of defining the app, then importing the views after that, all within a package.
project/
myapp/
__init__.py
webapp.py
index.py
webapp.py:
app = dash.Dash(...)
server = app.server
# index imports app, so import it after app is defined to avoid a circular import
from myapp import index
$ gunicorn myapp.webapp:server
you should also import server from webapp.py to index.py and then use regular gunicorn procedure:
gunicorn index:server -b :8000
A Dash project that is structured as a multi-page app (https://dash.plotly.com/urls) will have app.py (named as webapp.py here) and index.py. As mentioned in the linked guide, the entry point should be index.py to prevent circular import.
Only two changes are needed to use index.py as the entry point:
Import both app and server into index.py
from webapp import app, server
Run gunicorn as follows
gunicorn -b localhost:8000 index:server

Bottle not routing to index html file

I'm using Bottle for a Python project and I've set the project to run on the localhost:8080 (Windows 10 laptop). I’ve coded the project on VS Code, however, when I start the debugger on VS Code’s integrated terminal,I am presented with Error 500 on my browser (Google Chrome).
The project worked fine on a TA's machine, however on my laptop, bottle isn't routing to the index page, even when I explicitly had it import it from the static_file and adding the root file to the ‘run’ function. I tried running the example from Bottlepy.org, and even that isn’t working.
The only thing that has worked was:
from bottle import run, route
#route('/')
def hello():
return "If you're seeing this message, then bottle is working"
run(host='localhost', port=8080)
Again, I’ve ran:
from bottle import run, route, template
#route('/')
def hello():
return template("index.html")
run(host='localhost', port=8080)
and
from bottle import run, route, static_file
#route('/static/')
def hello():
return static_file('index.html', root='static')
run(host='localhost', port=8080)
Including the example from bottlepy.org, to which resulted in:
Error 500 Template 'index.html' not found.
Or
Error 500 ‘Template ‘/’ not found
I don’t believe it’s a PATH issue with Python, but it could be a JSON file issue with VS code. All the Python packages on my machine are updated and I’m out of ideas at the moment. Your suggestions/recommendations would be appreciated. Thank you.
Probably the issue is because the integrated shell executes the code in some other directory where the file 'index.html' is.
To help solve the issue, replace the file name with an absolute path, e.g.
#route('/static/')
def hello():
return static_file(os.path.join(os.path.dirname(__file__), 'index.html'), root='static')

Django passenger_wsgi.py issue

I run Django on an A2 Hosting Linux shared hosting account. Previously, I was using an old version of Django and Python. I was also using FCGI. I recently changed to a new server and am now using Django 2.1.2, Python 3.6.0. and Phusion Passenger.
I can't get the passenger_wsgi.py to load my website and I can't find the error log to try and resolve the problem.
The .htaccess file is in the public_html directory.
My app files are stored in:
/home/username/example.com/
The folder/file structure in the example.com directory is:
-media
-mysite
--- init.py
--- settings.py
--- urls.py
--- wsgi.py
-public
-tmp
-manage.py
-passenger_wsgi.py
#
The contents of the passenger_wsgi.py file:
import os
import sys
import mysite.wsgi
application = mysite.wsgi.application
cwd = os.getcwd()
sys.path.append(cwd)
#sys.path.append(os.getcwd())
sys.path.append(cwd + '/mysite')
SCRIPT_NAME = os.getcwd()
class PassengerPathInfoFix(object):
"""
Sets PATH_INFO from REQUEST_URI since Passenger doesn't provide it.
"""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
from urllib.parse import unquote
environ['SCRIPT_NAME'] = SCRIPT_NAME
request_uri = unquote(environ['REQUEST_URI'])
script_name = unquote(environ.get('SCRIPT_NAME', ''))
offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
return self.app(environ, start_response)
application = PassengerPathInfoFix(application)
The site produces an error (image below). I've been trying to fix it all day by tinkering with the passenger_wsgi.py file.
I can't find the Passenger error log file. I don't have any experience with Passenger. I've run out of ideas of ways to try and resolve the issue.
When I run 'python passenger_wsgi.py' in SSH, no comments are produced.
If anyone could help me to either:
(1) Identify what is wrong with the passenger_wsgi.py content or
(2) How I can find the Passenger error log on a shared Linux hosting account.
Not sure it'll be possible to diagnose anything without logs, but I've had the similar issues on shared A2 Hosting finding logs. I was able to find some Passenger logs in the "Errors" section of cPanel.
On the cPanel home screen, scroll down to the "Metric" subheader. There will be a link for "Errors" in this section. You should be able to find critical Passenger logs there.
This structure of passenger_wsgi.py works for me on A2 Hosting:
import os
import sys
import MyApp.wsgi
SCRIPT_NAME = '/home/user/domain'
class PassengerPathInfoFix(object):
""" Sets PATH_INFO from REQUEST_URI because Passenger doesn't provide it. """
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
from urllib.parse import unquote
environ['SCRIPT_NAME'] = SCRIPT_NAME
request_uri = unquote(environ['REQUEST_URI'])
script_name = unquote(environ.get('SCRIPT_NAME', ''))
offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
return self.app(environ, start_response)
application = MyApp.wsgi.application
application = PassengerPathInfoFix(application)

Appstats are only working for one WSGIApplication

I've split handlers between 2 python files (main.py and main_cms.py). app.yaml defines the URLs that each python file will handle.
When I look at the Appstats, only the handlers from one of the 2 python files are profiled (the ones from main.py).
The 'magic' of webapp_add_wsgi_middleware(app) always used to work just fine, until the split. How can I make Appstats recording apply to all handlers?
appengine_config.py:
def webapp_add_wsgi_middleware(app):
from google.appengine.ext.appstats import recording
app = recording.appstats_wsgi_middleware(app)
return app
app.yaml:
builtins:
- appstats: on
...
- url: /services/.*
script: main.application
- url: /cms.*
script: main_cms.application
main.py and main_cms.py:
application = webapp2.WSGIApplication(url_mapping, config=config)
Running python2.7 / GAE 1.6.3, the dev_appserver.py shows Appstats correct for all handlers. The described problem is only seen in production.

CherryPy3 and IIS 6.0

I have a small Python web application using the Cherrypy framework. I am by no means an expert in web servers.
I got Cherrypy working with Apache using mod_python on our Ubuntu server. This time, however, I have to use Windows 2003 and IIS 6.0 to host my site.
The site runs perfectly as a stand alone server - I am just so lost when it comes to getting IIS running. I have spent the past day Googling and blindly trying any and everything to get this running.
I have all the various tools installed that websites have told me to (Python 2.6, CherrpyPy 3, ISAPI-WSGI, PyWin32) and have read all the documentation I can. This blog was the most helpful:
http://whatschrisdoing.com/blog/2008/07/10/turbogears-isapi-wsgi-iis/
But I am still lost as to what I need to run my site. I can't find any thorough examples or how-to's to even start with. I hope someone here can help!
Cheers.
I run CherryPy behind my IIS sites. There are several tricks to get it to work.
When running as the IIS Worker Process identity, you won't have the same permissions as you do when you run the site from your user process. Things will break. In particular, anything that wants to write to the file system will probably not work without some tweaking.
If you're using setuptools, you probably want to install your components with the -Z option (unzips all eggs).
Use win32traceutil to track down problems. Be sure that in your hook script that you're importing win32traceutil. Then, when you're attempting to access the web site, if anything goes wrong, make sure it gets printed to standard out, it'll get logged to the trace utility. Use 'python -m win32traceutil' to see the output from the trace.
It's important to understand the basic process to get an ISAPI application running. I suggest first getting a hello-world WSGI application running under ISAPI_WSGI. Here's an early version of a hook script I used to validate that I was getting CherryPy to work with my web server.
#!python
"""
Things to remember:
easy_install munges permissions on zip eggs.
anything that's installed in a user folder (i.e. setup develop) will probably not work.
There may still exist an issue with static files.
"""
import sys
import os
import isapi_wsgi
# change this to '/myapp' to have the site installed to only a virtual
# directory of the site.
site_root = '/'
if hasattr(sys, "isapidllhandle"):
import win32traceutil
appdir = os.path.dirname(__file__)
egg_cache = os.path.join(appdir, 'egg-tmp')
if not os.path.exists(egg_cache):
os.makedirs(egg_cache)
os.environ['PYTHON_EGG_CACHE'] = egg_cache
os.chdir(appdir)
import cherrypy
import traceback
class Root(object):
#cherrypy.expose
def index(self):
return 'Hai Werld'
def setup_application():
print "starting cherrypy application server"
#app_root = os.path.dirname(__file__)
#sys.path.append(app_root)
app = cherrypy.tree.mount(Root(), site_root)
print "successfully set up the application"
return app
def __ExtensionFactory__():
"The entry point for when the ISAPIDLL is triggered"
try:
# import the wsgi app creator
app = setup_application()
return isapi_wsgi.ISAPISimpleHandler(app)
except:
import traceback
traceback.print_exc()
f = open(os.path.join(appdir, 'critical error.txt'), 'w')
traceback.print_exc(file=f)
f.close()
def install_virtual_dir():
import isapi.install
params = isapi.install.ISAPIParameters()
# Setup the virtual directories - this is a list of directories our
# extension uses - in this case only 1.
# Each extension has a "script map" - this is the mapping of ISAPI
# extensions.
sm = [
isapi.install.ScriptMapParams(Extension="*", Flags=0)
]
vd = isapi.install.VirtualDirParameters(
Server="CherryPy Web Server",
Name=site_root,
Description = "CherryPy Application",
ScriptMaps = sm,
ScriptMapUpdate = "end",
)
params.VirtualDirs = [vd]
isapi.install.HandleCommandLine(params)
if __name__=='__main__':
# If run from the command-line, install ourselves.
install_virtual_dir()
This script does several things. It (a) acts as the installer, installing itself into IIS [install_virtual_dir], (b) contains the entry point when IIS loads the DLL [__ExtensionFactory__], and (c) it creates the CherryPy WSGI instance consumed by the ISAPI handler [setup_application].
If you place this in your \inetpub\cherrypy directory and run it, it will attempt to install itself to the root of your IIS web site named "CherryPy Web Server".
You're also welcome to take a look at my production web site code, which has refactored all of this into different modules.
OK, I got it working. Thanks to Jason and all his help. I needed to call
cherrypy.config.update({
'tools.sessions.on': True
})
return cherrypy.tree.mount(Root(), '/', config=path_to_config)
I had this in the config file under [/] but for some reason it did not like that. Now I can get my web app up and running - then I think I will try and work out why it needs that config update and doesn't like the config file I have...

Categories