I have been trying to get Flask to work on my webfaction server for hours with no results.
I followed the instructions at http://flask.pocoo.org/snippets/65/
I have my index.py file stored under htdocs.
import sys
yourappname = "/home/<myusername>/webapps/myapp/htdocs"
if not yourappname in sys.path:
sys.path.insert(0, yourappname)
from yourappname import app as application
Then I have added this to my httpd.conf file:
WSGIPythonPath /home/yourusername/webapps/yourapp/htdocs/
#If you do not specify the following directive the app *will* work but you will
#see index.py in the path of all URLs
WSGIScriptAlias / /home/yourusername/webapps/yourapp/htdocs/index.py
<Directory /home/yourusername/webapps/yourapp/htdocs/>
AddHandler wsgi-script .py
RewriteEngine on
RewriteBase /
WSGIScriptReloading On
</Directory>
then i have myapp.py in the same htdocs directory next to index.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
I have my domain pointed to my project in webfaction. The default index.py was working prior to me overwriting with the new one as stated in the instructions. However, I only get the server 500. I apologize but I am a complete noob when it comes to linux and managing servers. I cannot even access my error log under users because it says I do not have permission.
I think that it has something to do with my installation of flask on the linux server, i installed it through easy install it says it installed all of the dependencies and did not give any errors.
A couple of suggestions:
Shouldn't you have myapp everywhere you have yourappname in your index.py?
Also, I am assuming that you have made the appropriate substitutions in `WSGIPythonPath /home/yourusername/webapps/yourapp/htdocs
Have you tried restarting the apache server by issuing a ~/webapps/<app_name>/apache2/bin/restart
Related
I'm really struggling here. I have a simple Python Flask REST API that I've developed. The API runs fine in my local development environment (Mac OS X) and when directly executed via the console on my EC2 instance.
I want to move this service into production and as such would like to host it behind Apache running on the EC2 instance. This is where I keep hitting a wall and I can't seem to get past the configurations and errors. I've research several articles online and questions here, none seem to be able to help me.
I'm hoping someone here can please provide me with step-by-step directions on how to deploy my service to production behind Apache running on an Amazon Linux EC2 instance.
Here are the steps I've taken:
Launched a basic Amazon Linux EC2 instance.
Apply updates to the instance, sudo yum update
Install Apache and WSIG, sudo yum install httpd24 mod24_wsgi
Start Apache, sudo service httpd start
Configure Apache to start automatically, sudo chkconfig httpd on
Test by hitting the DNS of my EC2 box. I successfully get the Amazon Linux AMI test page.
Adjust permissions on /var/www as follows
sudo groupadd www
sudo usermod -a -G www ec2-user
Logon/off and confirm membership, groups
sudo chown -R root:www /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
Test by hitting DNS of my EC2 box - still good so far.
Now that I know my instance is running, I would like to create two folders where I can test and run my Python Flask code. I do so as follows:
I create two folders, one for development and one for production.
/var/www/rest-dev/
/var/www/rest-prod/
I setup a virtual environment within each of the folders and install Flask.
virtualenv env
env/bin/pip install Flask
I then place a copy of my service in each folder.
Then I set permissions on app.py, chmod a+x app.py
I can successfully execute ./app.py and test the service by hitting the DNS name + port 5000. It works.
Now this is where I get tripped up. My goal is to be able to hit api.example.com and have my service's root load up. In the example code below, "Hello, World!" should simply display.
I've followed the tutorials found here with no luck.
http://peatiscoding.me/geek-stuff/mod_wsgi-apache-virtualenv/
http://webpy.org/cookbook/mod_wsgi-apache
http://www.jakowicz.com/flask-apache-wsgi/
After executing any of the steps in any of the articles above, I get an HTTP error page and nothing loads anymore, including the default Amazon Linux AMI test page. Below are the pieces of code and configurations that I've changed. I haven't changed my httpd.conf ... should I? There are probably several other things I'm missing.
Can someone please help me by providing me the necessary steps in detail to correct my mistakes?
Many thanks in advance!
When I view the error_log for HTTPD, it lists errors like this:
mod_wsgi (pid=8270): Target WSGI script '/var/www/rest-dev/deploy.wsgi' cannot be loaded as Python module.
mod_wsgi (pid=8270): Exception occurred processing WSGI script '/var/www/rest-dev/deploy.wsgi'.
Traceback (most recent call last):
File "/var/www/rest-dev/deploy.wsgi", line 16, in <module>
from app import app as application
File "/var/www/rest-dev/app.py", line 2, in <module>
from flask import Flask
ImportError: No module named flask
Here is my deploy.wsgi file, located in the rest-dev folder:
import os
import sys
import site
# Add virtualenv site packages
site.addsitedir(os.path.join(os.path.dirname(__file__), 'env/local/lib64/python2.7/site-packages'))
# Path of execution
sys.path.append('/var/www/rest-dev')
# Fired up virtualenv before include application
activate_env = os.path.expanduser(os.path.join(os.path.dirname(__file__), 'env/bin/activate_this.py'))
execfile(activate_env, dict(__file__=activate_env))
# import my_flask_app as application
from app import app as application
Here is my vhost.conf file located in /etc/httpd/conf.d/
<VirtualHost *:80>
ServerName api.example.com
WSGIDaemonProcess webtool user=ec2-user group=www threads=5 home=/var/www/rest-dev/
WSGIScriptAlias / /var/www/rest-dev/deploy.wsgi
<directory /var/www/rest-dev>
WSGIProcessGroup webtool
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Order deny,allow
Allow from all
</directory>
</VirtualHost>
Here is my app.py example service code for reference:
#!env/bin/python
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "Hello, World!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Turns out, in my deploy.wsgi file I'm referencing lib64 instead of just lib. All the site packages exist in lib.
After changing it and restarting Apache, I'm able to successfully hit my service from the URL.
I am trying to run webapp2 under Python with Apache and mod_wsgi - specifically: Wampserver for Windows 7 with Apache 2.2.22. So far, I have failed miserably. :-(
I used the following example from https://developers.google.com/appengine/docs/python/gettingstartedpython27/usingwebapp:
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
When I save this file as c:wamp\www\Python\hello.py, and browse to localhost/Python/hello.pyI get:
Not Found
The requested URL /python/hello.py was not found on this server.
However, let me state that mod_wsgi for Python within Apache seems to be running fine; the following code
def application(environ, start_response):
status = '200 OK'
output = 'Hello from Python!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
is located at c:\wamp\www\Python\test.py. When I go to localhost/Python/test.py, the browser says Hello from Python! as I would expect.
So far, I have only found out how to change the default name of the def (="application") to "something_else" by putting the line
WSGICallableObject something_else
into .htaccess.
But how can I get Apache to accept the variable app as a callable object? (So far, I have used Python mainly for programming outside of the web, so I hope this is not a dumb question.)
Any help is appreciated.
Update:
Graham asked me about the mod_wsgi configuration I am using in Apache configuration files and where I am adding it. I added
LoadModule wsgi_module modules/mod_wsgi.so
<Directory "c:/wamp/www/python">
Options +ExecCGI
AddHandler wsgi-script .py
Order allow,deny
Allow from all
</Directory>
to httpd.conf right at the end of all the "LoadModule" lines.
Some additional info on my configuration: I am using mod_wsgi-win32-ap22py27-3.3.so. (Of course I renamed it to mod_wsgi.so and placed it into c:\wamp\bin\apache\apache2.2.22\modules.) My Python command line says this about the version: Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32. The wamp server I am using is 32 bit. My operating system is Windows 7 Ultimate 64bit SP1.
Hope this helps with the diagnosis...
Install mod_wsgi from http://code.google.com/p/modwsgi/wiki/InstallationOnWindows and configure your httpd.conf properly.
I assume you have already added these 2 lines:
LoadModule wsgi_module modules/mod_wsgi.so
WSGICallableObject app
Install py-setuptools from http://pypi.python.org/pypi/setuptools then install Modules for your python
easy_install WebOb
easy_install Paste
easy_install webapp2
Create virtualhost
<VirtualHost *>
ServerAdmin admin#mydomain.com
DocumentRoot "/vhost/domains/mydomain/htdocs"
ServerName a.mydomain.net
WSGIScriptAlias / "/vhost/domains/mydomain/wsgi/main.py"
Alias /static/ "/vhost/domains/mydomain/htdocs/static/"
</VirtualHost>
File: main.py
import webapp2
class Hello(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html; charset=utf-8'
self.response.out.write('hello world!')
application = webapp2.WSGIApplication([
('/', Hello)
], debug=True)
1) You need to install webapp2, WebOb, Paste prerequisites modules on hosting environment using pip or easy_install
2) Create wsgi.py file under website’s root folder (/var/www/website/wsgi.py).
#/var/www/website/wsgi.py
import webapp2
class Index(webapp2.RequestHandler):
def get(self):
output = 'webapp2 running on apache2'
self.response.headers = [('Content-type','text/plain'),('Content-length',str(len(output)))]
self.response.out.write(output)
application = webapp2.WSGIApplication([('/',Index)], debug=True)
3) Create apache2 configuration file under sites-available folder (/etc/apache2/sites-available/website.conf)
<VirtualHost *:80>
ServerName website
WSGIScriptAlias / "/var/www/ website /wsgi.py"
</VirtualHost>
4) Add “website” alias to “/etc/hosts” file.
5) Run following command to enable “/etc/apache2/sites-available/website.conf”
a2ensite website.conf
6) Reload and restart apache2 web server
service apache2 reload
/etc/init.d/apache2 restart
7) Apache web-server will automatically load “website” configuration on restart webapp2.WSGIApplication instance will point to mod_wsgi "application".
Please note above example is tested on an Ubuntu 13.10 operating system.
Have you not tried:
WSGICallableObject app
You could also change your code to say:
application = webapp2.WSGIApplication([('/', MainPage)], debug=True)
and avoid needing to tell mod_wsgi to look for a different name.
I haven't tried it myself just yet, but have you created another Python module, say runme.py, with the following code:
def main():
run_wsgi_app(yourmodule.app)
if __name__ == '__main__':
main()
(Note: I got this from https://developers.google.com/appengine/docs/python/python27/migrate27#wsgi
Got it! The line
app = webapp2.WSGIApplication([('/', MainPage)], debug=True)
should be:
app = webapp2.WSGIApplication([('/Python/hello.py', MainPage)], debug=True)
and then everything works! Arghh!
Many thanks to Graham for patiently pushing me in the right direction: The problem was indeed within the bounds of webapp2, as soon as WSGICallableObject was set to "app"!
For the benefit of anyone being stuck on a similar routing problem with webapp2: Check out http://webapp-improved.appspot.com/guide/routing.html. The first example on "simple routes" made me rewrite my call to webapp.WSGIApplication within minutes!
Update
Unfortunately, the above solution doesn't seem to be reliable: Today, I sometimes got a correct response from webapp2, and sometimes I got a 404 from webapp2.
Without changing a single line of code since yesterday.
I can't reproduce under what condition I get the 404 or the correct response. I am giving up on this for now. Which is sad, since I think that Python is such a cool language.
#Graham: Again, thanks for your help.
I am a beginner programmer. I started using Python and Bottle for a small web app to print a form, so far so good. The real issue is configuring Apache and mod_wsgi, as my knowledge is almost none.
My problem: I keep getting this error:
Error 404: Not Found
Sorry, the requested URL /factura/ caused an error: Not found
In work they gave me and address redirecting to a IP:port; after some days of reading Apache docs and looking examples through the web I managed to set up the configuration so my VirtualHost doesn't breaks the others virtualhosts already running. The config looks like this (based on the bottle tutorial deployment section):
Listen port
NameVirtualHost IP:port
<VirtualHost IP:port>
ServerName IP:port
WSGIDaemonProcess factura processes=1 threads=5
WSGIScriptAlias / /var/www/factura/app.wsgi
<Directory /var/www/factura>
WSGIProcessGroup factura
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
My app.wsgi is almost the same as the one in the Bottle tutorial-deployment section. I only added the line sys.stdout = sys.stderr:
import sys, os, bottle
# Change working directory so relative paths (and template lookup) work again
sys.path = ['/var/www/factura'] + sys.path
os.chdir(os.path.dirname(__file__))
# Error output redirect
# Exception KeyError in 'threading' module
sys.stdout = sys.stderr
import factura
application = bottle.default_app()
Here is a bit of the python code which is related to Bottle:
from lib import bottle
app = bottle.Bottle()
#serves files in folder 'static'
#app.route('/static/:path#.+#', name='static')
def ...
#app.route("/factura")
#bottle.view("factura")
def ...
#app.route("/print_factura", method="POST")
def ...
I have read some of the others question similar to this, but I can't manage to see what I'mm missing. I suppose the problem is in app.wsgi?
UPDATE
file structure
/var/www/factura/ ## .py files
/views ## here is the web template
/static ## .css and .js of template
/lib ## package with bottle and peewee source files
/data ## inkscape file to play with
/bin ## backup stuff in repo, not used in code
Apache error log only shows
Exception KeyError: KeyError(-1211426160,) in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored
that is a warning from wsgi/python issues, harmless by wsgi issue 197
UPDATE 2 working
added #app.route("/factura/") notice the trail slash, that with the change in app import from factura import app as application those two together made it work
If you create your application explicitly:
app = bottle.Bottle()
then you should import it in your app.wsgi instead of application = bottle.default_app():
from factura import app as application
But what is far important is this. In your WSGI file, you do import bottle, yet in the app code file, you do from lib import bottle. As you have explained, you have two copies of Bottle: one installed server-wide, another under the lib directory.
That's why you were receiving 404 Not Found. You were actually working with one instance of the library (creating app), and then giving Apache a different (default_app) from a different instance of the library!
It started to work okay when you began to return the proper app.
Anybody know how to deploy a simple Flask application on Webfaction?
I know Webfaction support mod_wsgi and I read the guide on the Flask site but still I can't make my app working. Anybody have a working configuration?
UPDATE to answer a comment by Graham Dumpleton.
I get a 500 Internal server error. Apache does not show any error in the logs. The WSGI script is executed and seems to create the application correctly, but I keep getting a 500 error.
Thanks.
I got it working with the following procedure:
create and app named 'myapp' of type mod_wsgi 3.3/Python 2.7. Webfaction will create the following folders:
myapp
|- apache2
|- htdocs
Webfaction will also automatically create a simple script index.py in your htdocs directory. Check if the sample script work visiting the root of your newly created application (to do thin on Webfaction you need to "mount" the app on a website). If it's all OK modify the script deleting the content and adding:
from myapp import app as application
In apache2/conf/httpd.conf add the follwing lines:
WSGIPythonPath /home/username/webapps/myapp/htdocs/
#If you do not specify the next directive the app *will* work but you will
#see index.py in the path of all subdir
WSGIScriptAlias / /home/username/webapps/myapp/htdocs/index.py
<Directory /home/username/webapps/myapp/htdocs>
AddHandler wsgi-script .py
RewriteEngine on
RewriteBase /
WSGIScriptReloading On
</Directory>
Restart apache2
You need to set up a "Custom app (listening on port)" application. Make a note of the port that is assigned. Then in your Flask code, you need to put hardcode the port:
if __name__ == __main__:
app.run(host='0.0.0.0' port=XXXXXXX)
Where you substitute XXXXXXX with the port that is randomly assigned to your custom app.
Hope that helps.
EDIT:
Please use Raben's Answer, this way should not to be used in Production.
I am new in apache, linux and python world. I am trying to deploy django application on apache using WSGI (the recommended way).
My django project directory structure is as follows...
/
/apache/django.wsgi
/apps/ #I put all my apps in this directory
/apps/providers/
/apps/shopping/
/apps/...
/middleware/
...
In apache I have following settings....
LoadModule wsgi_module modules/mod_wsgi.so
WSGIScriptAlias / D:/Projects/project-name/apache/django.wsgi
<Directory "D:/Projects/project-name/apache/">
Allow from all
Order deny,allow
</Directory>
django.wsgi file has got following code...
import os
import sys
import settings
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..')
os.environ['DJANGO_SETTINGS_MODULE'] = 'project_name.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
On running I found this error in the appache's error.log...
Error occured on this line. from apps.providers.models import Provider
Import Error: No module named providers.models
I don't know why it is giving me this error. It should have loaded Provider from apps.providers.models but it is trying to load it from providers.model.
Any solution will be appreciated.
Thanks
Try this:
sys.path.insert(0, os.path.join(os.path.abspath(os.path.dirname(__file__)),'..'))
It puts your project folder at the first position and it uses os.path.join to go one directory up (which might be better on windows).
It might be the case that there is another "apps" module on your python path.