Browse Source

Improve WSGI application support, fix docs

tags/nilmdb-1.4.4
Jim Paris 11 years ago
parent
commit
77ef87456f
3 changed files with 60 additions and 21 deletions
  1. +20
    -12
      docs/wsgi.md
  2. +1
    -1
      nilmdb/client/httpclient.py
  3. +39
    -8
      nilmdb/server/server.py

+ 20
- 12
docs/wsgi.md View File

@@ -1,20 +1,28 @@
WSGI Application in Apache
--------------------------

Install `apache2`, `libapache2-mod-wsgi`
Install `apache2` and `libapache2-mod-wsgi`

Apache configuration should look something like:
We'll set up the database server at URL `http://myhost.com/nilmdb`.
The database will be stored in `/home/nilm/db`, and the process will
run as user `nilm`.

First, create a WSGI script `/home/nilm/nilmdb.wsgi` containing:

import nilmdb.server
application = nilmdb.server.wsgi_application("/home/nilm/db")

Then, set up Apache with a configuration like:

<VirtualHost>
WSGIScriptAlias /nilmdb /home/nilmdb/nilmdb.wsgi
WSGIApplicationGroup nilmdb
WSGIScriptAlias /nilmdb /home/nilm/nilmdb.wsgi
WSGIProcessGroup nilmdb
WSGIDaemonProcess nilmdb threads=32
</VirtualHost>
where `/home/nilmdb/nilmdb.wsgi` is a file containing:
WSGIDaemonProcess nilmdb threads=32 user=nilm

import nilmdb.server
application = nilmdb.server.wsgi_application("/home/nilmdb/db")
where `/home/nilmdb/db` is the path to the database.
# Access control example:
<Location /nilmdb>
Order deny,allow
Deny from all
Allow from 1.2.3.4
</Location>
</VirtualHost>

+ 1
- 1
nilmdb/client/httpclient.py View File

@@ -16,7 +16,7 @@ class HTTPClient(object):
reparsed = urlparse.urlparse(baseurl).geturl()
if '://' not in reparsed:
reparsed = urlparse.urlparse("http://" + baseurl).geturl()
self.baseurl = reparsed
self.baseurl = reparsed.rstrip('/') + '/'

# Build Requests session object, enable SSL verification
self.session = requests.Session()


+ 39
- 8
nilmdb/server/server.py View File

@@ -14,6 +14,7 @@ import os
import simplejson as json
import decorator
import psutil
import traceback

class NilmApp(object):
def __init__(self, db):
@@ -466,7 +467,8 @@ class Server(object):
stoppable = False, # whether /exit URL exists
embedded = True, # hide diagnostics and output, etc
fast_shutdown = False, # don't wait for clients to disconn.
force_traceback = False # include traceback in all errors
force_traceback = False, # include traceback in all errors
basepath = '', # base URL path for cherrypy.tree
):
# Save server version, just for verification during tests
self.version = nilmdb.__version__
@@ -526,7 +528,7 @@ class Server(object):
if stoppable:
root.exit = Exiter()
cherrypy.tree.apps = {}
cherrypy.tree.mount(root, "/", config = { "/" : app_config })
cherrypy.tree.mount(root, basepath, config = { "/" : app_config })

# Shutdowns normally wait for clients to disconnect. To speed
# up tests, set fast_shutdown = True
@@ -536,7 +538,7 @@ class Server(object):
else:
cherrypy.server.shutdown_timeout = 5

def get_application(self):
def get_application(self): # pragma: no cover
"""Return a WSGI application object"""
def app(environ, start_response):
if environ['wsgi.multiprocess']:
@@ -611,9 +613,38 @@ class Server(object):
def stop(self):
cherrypy.engine.exit()

def wsgi_application(dbpath):
def wsgi_application(dbpath, basepath): # pragma: no cover
"""Return a WSGI application object with a database at the
specified path."""
db = nilmdb.utils.serializer_proxy(nilmdb.server.NilmDB)(dbpath)
server = nilmdb.server.Server(db, embedded = True)
return server.get_application()
specified path.

'dbpath' is a filesystem location, e.g. /home/nilm/db

'basepath' is the URL path of the application base, which
is the same as the first argument to Apache's WSGIScriptAlias
directive.
"""
try:
db = nilmdb.utils.serializer_proxy(nilmdb.server.NilmDB)(dbpath)
server = nilmdb.server.Server(db, embedded = True,
basepath = basepath.rstrip('/'))
application = server.get_application()
except Exception:
# If we can't make the DB or server, serve up the exception text
# with a mini WSGI app.
output = sprintf("Initializing database at path '%s' failed:\n\n",
dbpath)
output += traceback.format_exc()
try:
import pwd
import grp
output += sprintf("\nRunning as: uid=%d (%s), gid=%d (%s)\n",
os.getuid(), pwd.getpwuid(os.getuid())[0],
os.getgid(), grp.getgrgid(os.getgid())[0])
except ImportError:
pass
def application(environ, start_response):
headers = [ ('Content-type', 'text/plain'),
('Content-length', str(len(output))) ]
start_response("500 Internal Server Error", headers)
return [output]
return application

Loading…
Cancel
Save