Python Falcon on Webfaction - python-2.7

I'm trying to get Falcon up and running on Webfaction. I'm not exactly a network guru, so I'm having a tough time wrapping my head around how these applications are served.
My Webfaction App is set up as mod_wsgi 4.5.3/Python 2.7
To my understanding, Falcon will run on any WSGI server. When I swet up my mod_wsgi server, is it automatically configured for something like Falcon to run on? Or do I still need to install something like Gunicorn?
When I set up my webfaction app, I received a directory structure like this:
app/htdocs/index.py
And inside the index.py file, I put the example found at Falcon Tutorial
import falcon
class ThingsResource(object):
def on_get(self, req, resp):
"""Handles GET requests"""
resp.status = falcon.HTTP_200
resp.body = 'Hello world!'
# falcon.API instances are callable WSGI apps
wsgi_app = api = falcon.API()
# Resources are represented by long-lived class instances
things = ThingsResource()
# things will handle all requests to the '/things' URL path
api.add_route('/things', things)
I understand there are also instructions for running WSGI, but that is where my confusion is at - is the webfaction server already running WSGI, or do I still need something like Gunicorn, and if so - what is the best way to configure? Do I need a cron to keep running Gunicorn?
Thanks!
Update:
I checked error logs and received a WSGI error about not having a variable named "application",
So I changed:
wsgi_app = api = falcon.API()
to:
application = falcon.API()
This cleared out the error, but now when I visit mydomain.com/things, I get an error 404 (Not found / Does not exist).
So, this brings me back to my original question of what the next steps are? It seems as if the url isn't being routed correctly, so it is most likely something to do with httpd.conf file or similar - again, this is my first go at getting something like this set up live.

Here is the answer (at least for the initial question, I'm willing to bet I'll mess up something else in the near future on the same project).
Essentially, I was able to put the tutorial code in the index.py file that Webfaction generates when setting up an app & mounting on a domain. So, my tutorial code looks something like this:
import falcon
class ThingsResource(object):
def on_get(self,req,resp):
resp.status = falcon.HTTP_200
resp.body = 'Hello World!'
api = application = falcon.API()
things = ThingsResource()
api.add_route('/things', things)
Since I couldn't find much info for launching a Falcon app on Webfaction, I looked at how similar applications run on Webfaction (Flask in this example). That being said, I found a snippet on the Flask docu showing how to get set up on webfaction. I'm not sure if this means my entire application will work, but I do know that the Falcon tutorial code at least works. Essentially, I just had to edit the httpd.conf file per the instructions found here: Flask Webfaction
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>
I hope this helps anybody with a similar issue.

Related

Static (admin) files do not seem to be served correctly

I have problems with Django serving static files on the admin panel.
Calling http://vbox.me/admin/ (where vbox.me is aliased to the VM's IP) results in a blank page without stylesheets.
Calling http://vbox.me/static/admin/css/base.css though, which is part of the stylesheets that should be loaded when opening http://vbox.me/admin/, brings up the correct file.
Here is some essential information:
I recently started experimenting with Django.
My current version of Django is 1.8.
I'm running nginx (on Arch Linux within a VirtualBox on Windows 7) that passes every non-static file to uwsgi
uwsgi and nginx run as service using systemd
Running the Django development server standalone does not result in the given weird behavior.
Nginx configuration file:
# ...
http {
sendfile on;
upstream django {
server unix:/tmp/uwsgi.sock;
}
server {
# ...
location /static {
# static directory of the django project
alias /home/martin/projects/django_test/static;
}
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
}
INI file for uwsgi:
[uwsgi]
chdir=/home/martin/projects/django_test
wsgi-file=django_test/wsgi.py
chmod-socket=666
socket=/tmp/uwsgi.sock
master=true
vacuum=true
Important parts from settings.py within the Django project:
STATIC_ROOT = '/home/martin/projects/django_test/static/'
# using vbox.me to make sure the browser does not make up some strange url.
STATIC_URL = 'http://vbox.me/static/'
I'm pretty much "left in the dark", I can only guess that I made some mistake in configuring uwsgi or Django, since nginx seems to server the static files perfectly (at least when explicitly requesting them...)
Thanks in advance!
Edit: I will do a fresh setup of all the tools I use to deploy my app to make sure I made no mistakes. Additionally, I will be using virtualenv this time (which I haven't used previously). I'll let you know if that works!
After doing a fresh install of everything following this tutorial, everything works just fine now. Looks like I made some mistakes in configuration.
I also used Django 1.7 here, so Django 1.8 might have been the cause to my problems as well (though thats really unlikely)

Deploying a Django App

I'm very sorry for such a simple question-- I'm new at WSGI development, and I'm grateful for any patience you can afford.
I made a Django app; it works great in development mode. I run:
python manage.py runserver
and then direct my browser to 127.0.0.1:8000, and voila, there is my app.
From here I absolutely cannot figure out how to run my app in production mode. I've read several pages like this and this and several others on StackOverflow. But I have no idea of where to even direct my browser to see if my page is working.
I've installed apache2, mod_python, etc., but I think the problem is that my misunderstanding is at such a more basic level. When I've done CGI programs in the past, I direct my browser to webroot/file.html with a form that calls cgi-bin/file.cgi, which generates html output. I don't know if I am supposed to navigate to a .wsgi page, etc.
Under the assumption that I'm supposed to navigate to a .wsgi file, I've also tried making a file containing:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
path = '/home/orserang/nonparametric-protein/src/www/mysite$'
if path not in sys.path:
sys.path.append(path)
and added
WSGIScriptAlias / /path/to/mysite/apache/django.wsgi
to my apache2/httpd.conf file, so that its contents are:
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
PythonPath "['/home/orserang/nonparametric-protein/src/www/mysite'] + ['/home/orserang/nonparametric-protein/src/'] + sys.path"
WSGIScriptAlias /mysite /home/orserang/nonparametric-protein/src/www/mysite/django.wsgi
</Location>
But when I restart apache, it says:
Syntax error on line 8 of /etc/apache2/httpd.conf:
WSGIScriptAlias not allowed here
Given that I don't even know where I should point my browser to get to a Django wsgi page, I figured there is something easy that I'm doing quite wrong.
Perhaps Django WSGI apps require something to run in the background, which will listen for requests (rather than go through apache)?
The online Django documentation on views and databases alone are substantial compared to the documentation for deployment; therefore, my best guess is that this is such a simple thing to do.
Thanks a lot for your help!
The Django Book 2.0 has an overview about this. It's not typically linked to in the Django docs:
Chapter 12: Deploying Django
Look at the "Using Django with Apache and mod_python" section.
You're mixing up mod_python and mod_wsgi deployment methods. Get rid of everything inside the Location directive except for the WSGIScriptAlias line.
I wrote shell script that deploys a django project on apache for linux,
https://github.com/mukulu/shell-scripts/blob/master/deploy-django.sh
You only need to configure couple of variables in first lines of the code,
and it'll figure out the rest.
It pretty much checks and install dependencies for django, writes apache configurations that deploys your project and restart the server.
I'm planning to re-write it in python(I wrote it in a hurry)
Feel free to re-use.
Variables are:
SITE_PREFIX="/djangoproject"
MEDIA_URL="/media"
ADMIN_MEDIA_PREFIX="/static/admin/"
MEDIA_ROOT=""
DJANGO_VERSION="1.3.1"
APACHE2_CONFIG="/etc/apache2/conf.d" #Apache configurations directory in yoru system.
This might be not for a novice, but you can take a look - http://packages.python.org/django-fab-deploy/
It's the library for automating the deploying process. It supports servers based primarily on Debian Lenny or Squeeze.

Push Server with Django/Apache

I'm trying to use server push with my Django app. Of all the different solutions I've seen, django-socketio seemed to be the easiest to implement, and I got it working when launching the server through manage.py. However, when it goes to production, I'd like it to be served through Apache. In the past, I've done this with wsgi, but django-socketio isn't playing nicely with the default wsgi script. Is there something simple I can just change in my django.wsgi that lets apache do the right thing? If not, what would be the suggested way to handle this?
EDIT: Here's the WSGI script I was normally using (without any kind of push server), plus a bit more explanation.
import os, sys
locale = os.path.realpath(__file__)
ROOT_DIR = locale[:locale.find('/server/apache/')]
sys.path.append(ROOT_DIR)
sys.path.append(ROOT_DIR+'/server')
os.environ['DJANGO_SETTINGS_MODULE'] = 'server.settings'
os.environ['PYTHON_EGG_CACHE'] = '/var/www/.python-eggs'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
sys.stdout = sys.stderr
The sys.stdout = sys.stderr is just to redirect any test print statements to apache's error log. The problem is, when I use this, I get an error complaining that request.environ doesn't have the key "socketio" or "DJANGO_SOCKETIO_PORT". I can add DJANGO_SOCKETIO_PORT easily enough (os.environ['DJANGO_SOCKETIO_PORT']="9000"), but from what I can tell, request.environ['socketio'] is set to an instance of SocketIOProtocol somewhere in django-socketio's internals. Also, after looking at the command that django-socketio added to manage.py, I noticed that it creates an instance of SocketIOServer, and calls serve_forever on it, but I have no idea where to put that in my code. Hopefully this will make it easier to see what I'm trying to get done.

Django tutorial on remote server: how to view in my browser?

I'm getting started with a Django tutorial, and I've run into a snag. Having created the sample "mysite" on my usual domain, I want to be able to display it in my browser. The tutorial points me to http://127.0.0.1:8000. However, that's not going to work, as I'm doing this remotely.
[background information]
What I have done, apparently successfully, is
django-admin.py startproject mysite
(created mysite directory containing four files)
python manage.py runserver
(Validating models... 0 errors found, etc.)
The absolute path is
/home/toewsweb/public_html/pythonlab/mysite
What URL should I be able to use to bring this up in my browser?
I also put mysite at
/home/toewsweb/mysite (since it's not supposed to go in a publicly accessible directory)
What URL should I be able to use in this case?
This is a virtual private server, so I have access to httpd.conf. I have downloaded and installed mod_wsgi and have added it to the Apache configuration. I actually did set a subdomain with a DocumentRoot of /home/toewsweb/public_html/pythonlab/mysite; however, when I point the browser to that subdomain, I just get the directory listing.
[/background information]
Right now, I just want to know how to view what I'm working on in my browser.
Thanks!
For development purposes, there's no need to mess about with configuring WSGI (although it's useful to know, as you will need to do it for production). Just start the dev server so that it listens to an external port:
./manage.py runserver 0:8000
This binds to the external IP address, so now you can access your Django site via port 8000 on that server:
http://whatever.my.ip.is:8000
You need to setup the apache WSGIScriptAlias directive in your VirtualHost to properly load python and your site. Django's docs have a great explanation on what you need to do.
Basic configuration
Once you’ve got mod_wsgi installed and activated, edit your httpd.conf file and add:
WSGIScriptAlias / /path/to/mysite/apache/django.wsgi
The first bit above is the url you want to be serving your application at (/ indicates the root url), and the second is the location of a "WSGI file" -- see below -- on your system, usually inside of your project. This tells Apache to serve any request below the given URL using the WSGI application defined by that file.
Next we'll need to actually create this WSGI application, so create the file mentioned in the second part of WSGIScriptAlias and add:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
If your project is not on your PYTHONPATH by default you can add:
path = '/path/to/mysite'
if path not in sys.path:
sys.path.append(path)
just below the import sys line to place your project on the path. Remember to replace 'mysite.settings' with your correct settings file, and '/path/to/mysite' with your own project's location.
OR
The other option is to run the dev server so it's accesible externally like so:
python manage.py runserver 0.0.0.0:80
though please DO NOT use this in production. The dev server is single-threaded, and has not been auditing for security.

django project with twisted and run as "Daemon"

Last two day I'm trying to find a way to run a working django project under twisted. After detailed searching I found several methods to configure it. But most of them are deal with how to run the app via command line not as a daemon.I want to run the django project as daemon.
I tried following links to implement this,
Twisted: Creating a ThreadPool and then daemonizing leads to uninformative hangs
http://www.robgolding.com/blog/2011/02/05/django-on-twistd-web-wsgi-issue-workaround/
But this also not working for me.By this method TCP server is not even listen to the given port.
Please help me to figure it out.
UPDATE
I'm sorry for the missing informations.Here is my objectives.
I'm beginner in twisted world, so first I'm trying to get my working django project configured under twisted,currently its working well on django testing server or apache via mod_wsgi.
To configure it with twisted I used the biding code given below, that code is a combination of two sample's found in the links that I given in the first post.
So in-order to integrate django app with twisted I used the following code, file name: "server.py".
import sys
import os
from twisted.application import internet, service
from twisted.web import server, resource, wsgi, static
from twisted.python import threadpool
from twisted.internet import reactor
from django.conf import settings
import twresource # This file hold implementation of "Class Root".
class ThreadPoolService(service.Service):
def __init__(self, pool):
self.pool = pool
def startService(self):
service.Service.startService(self)
self.pool.start()
def stopService(self):
service.Service.stopService(self)
self.pool.stop()
class Root(resource.Resource):
def __init__(self, wsgi_resource):
resource.Resource.__init__(self)
self.wsgi_resource = wsgi_resource
def getChild(self, path, request):
path0 = request.prepath.pop(0)
request.postpath.insert(0, path0)
return self.wsgi_resource
PORT = 8080
# Environment setup for your Django project files:
#insert it to first so our project will get first priority.
sys.path.insert(0,"django_project")
sys.path.insert(0,".")
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_project.settings'
from django.core.handlers.wsgi import WSGIHandler
def wsgi_resource():
pool = threadpool.ThreadPool()
pool.start()
# Allow Ctrl-C to get you out cleanly:
reactor.addSystemEventTrigger('after', 'shutdown', pool.stop)
wsgi_resource = wsgi.WSGIResource(reactor, pool, WSGIHandler())
return wsgi_resource
# Twisted Application Framework setup:
application = service.Application('twisted-django')
# WSGI container for Django, combine it with twisted.web.Resource:
# XXX this is the only 'ugly' part: see the 'getChild' method in twresource.Root
wsgi_root = wsgi_resource()
root = Root(wsgi_root)
#multi = service.MultiService()
#pool = threadpool.ThreadPool()
#tps = ThreadPoolService(pool)
#tps.setServiceParent(multi)
#resource = wsgi.WSGIResource(reactor, tps.pool, WSGIHandler())
#root = twresource.Root(resource)
#Admin Site media files
#staticrsrc = static.File(os.path.join(os.path.abspath("."), "/usr/haridas/eclipse_workplace/skgargpms/django/contrib/admin/media/"))
#root.putChild("admin/media", staticrsrc)
# Serve it up:
main_site = server.Site(root)
#internet.TCPServer(PORT, main_site).setServiceParent(multi)
internet.TCPServer(PORT, main_site).setServiceParent(application)
#EOF.
Using above code It worked well from command line using "twisted -ny server.py", but when we run it as daemon "twisted -y server.py" it will hang, but the app is listening to the port 8080. I can access it using telnet.
I found some fixes for this hanging issue from stackoverflow itself. It helped me to use the code sections given below, which is commented in the above server.py file.
multi = service.MultiService()
pool = threadpool.ThreadPool()
tps = ThreadPoolService(pool)
tps.setServiceParent(multi)
resource = wsgi.WSGIResource(reactor, tps.pool, WSGIHandler())
root = twresource.Root(resource)
and :-
internet.TCPServer(PORT, main_site).setServiceParent(multi)
instead of using the:-
wsgi_root = wsgi_resource()
root = Root(wsgi_root)
and :-
internet.TCPServer(PORT, main_site).setServiceParent(application)
The modified method also didn't helped me to avoid the hanging issue.Is any body out there who successfully run the django apps under twisted daemon mode?.
I maid any mistakes while combining these codes?, Currently I'm only started to learn the twisted architectures in detail. Please help me to solve this problem
Thanks and Regards,
Haridas N.
Note:- Im looking for the Twisted Application configuration (TAC) file, which integrate django app with twisted and run with out any problem in the daemon mode also.
Thank you,
Haridas N.
twistd is the Twisted Daemonizer. Anything you run with twistd will be easy to daemonize. All you have to do is not pass the --nodaemon option.
As far as why your code is "not working", you need to provide more details about what you did, what you expected to happen, and how what actually happened differed from your expectations. Otherwise, only a magician can answer your question.
Since you said the TCP port doesn't even get set up, the only guess I can think of is that you're trying to listen on a privileged port (such as 80) without having permissions to do so (ie, you're not root and you're not using authbind or something similar).