spyce
         
home     documentation     download     Spyce logo


Documentation - Runtime

Prev: 3.5 - Command line Up: 3 - Runtime Next: 3.7 - Server utilities

3.6. Configuration

Since there are a variety of very different installation alternatives for the Spyce engine, effort has been invested in consolidating all the various runtime configuration options. By default, the Spyce engine will search for a file called spyceconf.py in its installation directory. An alternative file location may be specified via the --conf command-line option.

The spyce configuration file is a valid python module; any python code may be used. To avoid duplication, we recommend starting with "from spyceconf import *" and override only select settings. One thing you cannot do from the config module is access the Spyce server object spyce.getServer(), since it has not been initialized yet.

You may access the loaded configuration module from Spyce scripts and from Python modules using the config attribute of the server object. Or, simply as the spyceConfig module, regardless of it actual file name. For example:

examples/config.spy
[[\
  import spyceConfig
  home = spyceConfig.SPYCE_HOME
]]

[[= home ]]
Run this code

Below is the configuration file that this server is running. The length of the file is primarily due to the thoroughness of the comments:

# NOTE: do note write code that directly imports this module 
# (except when you are writing a custom configuration module.)
# This is a recipe for trouble, since spyce allows the user
# to specify the configuration module filename on the commandline.
# Instead, use import spyce; spyce.getServer().config.

import os, sys
import spycePreload

# Determine SPYCE_HOME dynamically.
# (you can hardcode SPYCE_HOME if you really want to, but it shouldn't be necessary.)
SPYCE_HOME = spycePreload.guessSpyceHome()

# The spyce path determines which directories are searched for when
# loading modules (with [[.import]]) and tag libraries (with [[.taglib]]
# and the globaltags configuration later in this file.
#
# By default, the Spyce installation directory is always searched
# first. Any directories in the SPYCE_PATH environment are also
# searched.
#
# If you need to import from .py modules in nonstandard locations
# (i.e., not in your python installation's library directory),
# you will want to add their directories to sys.path as well, as
# done here for the error module.  (However, Spyce automagically
# changes sys.path dynamically so you will always be able to import
# modules in the same directory as your currently-processing .spy file.)
#
# path += ['/usr/spyce/inc/myapplication', '/var/myapp/lib']
path = [os.path.join(SPYCE_HOME, 'modules'), os.path.join(SPYCE_HOME, 'contrib', 'modules')]
path.append(os.path.join(SPYCE_HOME, 'tags'))
path.append(os.path.join(SPYCE_HOME, 'contrib', 'tags'))
if os.environ.has_key('SPYCE_PATH'):
    path += os.environ['SPYCE_PATH'].split(os.pathsep)
# provide originalsyspath so if someone wants to maintain a config file via
# "from spyceconf import *"
# he can remove the above modifications if desired.
originalsyspath = list(sys.path)
sys.path.extend(path)

# The globaltags option specifies a group of tag libraries that will be autoloaded
# as if [[.taglib name=libname from=file as=prefix]] were specified in every .spy
# file.  (There is no performance hit if the library is not used on a page;
# the Spyce compiler optimizes it out.)
#
# The format is ('libname', 'file', 'prefix').
# For a 2.0-style tag library, the libname attribute is ignored.  Passing None is fine.
#
# globaltags.append(('mytag', 'mytaglib.py', 'my'))
# globaltags.append((None, 'taglib2.py', 'my2'))
globaltags = [
    ('core', 'core.py', 'spy'),
    ('form', 'form.py', 'f'),
    (None, 'render.spi', 'render'),
    ]

# The default parent template is the one that is used by <spy:parent>
# if no src attribute is given, specified as an absolute url.
defaultparent = "/parent.spi"

# The errorhandler option sets the server-level error handler.  These
# errors include spyce.spyceNotFound, spyce.spyceForbidden,
# spyce.spyceSyntaxError and spyce.pythonSyntaxError.  (file-level
# error handling is defined within Spyce scripts using the error module.)
#
# The server will call the error handler as errorhandler(request, response, error).
#
# Please look at the default function if you are considering writing your own
# server error handler.
import error
errorhandler = error.serverHandler

# The pageerror option sets the default page-level error handler.
# "Page-level" means all runtime errors that occur during the
# processing of a Spyce script (i.e. after the compilation phase has
# completed successfully)
#
# The format of this option is one of:
#   ('string', 'MODULE', 'VARIABLE')
#   ('file', 'URL')
# (This format is used since the error template must be transformed into
# compiled spyce code, which can't be done before the configuration file
# is completely loaded.)
#
# Please refer to the default template to see how to define your own
# page-level error handlers.
#
# pageerrortemplate = ('file', '/error.spy')
pageerrortemplate = ('string', 'error', 'defaultErrorTemplate')

# The cache option affects the underlying cache mechanism that the
# server uses to maintain compiled Spyce scripts. Currently, Spyce
# supports two cache handlers:
#
#   cache = 'memory'
#   OR
#   cache = 'file'
#   cachedir = '/tmp' # REQUIRED: directory in which to store compiled files
#
# Why store the cache in the filesystem instead of memory?  The main
# reason is if you are running under CGI or mod_python.  Under
# mod_python, Apache will kick off a number of separate spyce
# processes; each would have its own memory cache; using the
# filesystem avoids wasteful duplication.  (Pointing the cachedir to a
# ramdisk makes it almost as fast as a memory cache.)  Under CGI of
# course, the python process isn't persistent so file caching is the
# only option to avoid expensive recompilation with each request.
#
# If you are running multiple Spyce instances on the same machine,
# they cannot share the same cachedir.  Give each a different cachedir,
# or use the in-memory cache type.
cache = 'memory'

# The check_mtime option affects the caching of compiled Spyce code.
# When True, Spyce will check file timestamps with each request and
# recompile if they have been modified.  Setting this to False can
# speed up a "production server" but you will have to restart the
# server and (if using a file cache) clear out the cachedir
# to have changes made in the spyce code take effect.
check_mtime = True

# The debug option turns on a LOT of logging to stderr.
debug = False

# The globals section defines server-wide constants. The hashtable is
# accessible as "pool" within any Spyce file (with the pool
# method loaded), or as self._api.getServerGlobals() within any Spyce
# module.
#
# globals = {'name': "My Website", 'four': 2+2}
globals = {}

# You may wish to pre-load various Python modules during engine initialization.
# Once imported, they will be in the python module cache.
#
# (You may of course use normal imports at any time in this configuration script;
# however, imports specified here are run after the Spyce server is
# completely initialized, making it safe to access the server internals via
# import spyce; spyce.getServer()...)
#
# imports = ['myModule', 'myModule2']
imports = []

# The root option defines the path from which Spyce requests are processed.
# I.e., when a request for http://yourserver/path/foo.spy arrives,
# Spyce looks for foo.spy in <root>/path/.
# 
# root = '/var/www/html'
root = os.path.join(SPYCE_HOME, 'www')
# feel free to comment this next line out if you don't have python modules (.py) in your web root
sys.path.append(root)

# some parts of spyce may need to create temporary files; usually the default is fine.
# BUT if you do override this, be sure to also override other parts of the config
# that reference it.  (currently just session_store)
import tempfile
tmp = tempfile.gettempdir()

# active tag to render form validation errors
validation_render = 'render:validation'


#####
# database connection
#####

from sqlalchemy.ext.sqlsoup import SqlSoup

# Examples:
# db = SqlSoup('postgres://user:pass@localhost/dbname')
# db = SqlSoup('sqlite:///my.db')
# db = SqlSoup('mysql://user:pass@localhost/dbname')
#
# SqlSoup takes the same URLs as an SqlAlchemy Engine.  See 
# http://www.sqlalchemy.org/docs/dbengine.myt#dbengine_establishing
# for more examples.
try:
  db = SqlSoup('sqlite:///www/demos/to-do/todo.db')
except:
  db = None

#####
# session options -- see docs/mod_session.html for details
#####

import session

session_store = session.DbmStore(tmp)
# session_store = session.MemoryStore()

session_path = '/'

session_expire = 24 * 60 * 60 # seconds

#####
# login options
#####

# The spyce login system uses the session storage
# defined above; a key called _spy_login will be added to each session.

# validators must be a function that takes login and password as
# arguments, and returns a pickle-able object (usually int or string)
# representing the ID of the logged in user, or None if login fails.
#
# You'll need to supply your own to hook into your database or other
# validation system; see the pyweboff config.py for an example of doing
# this.
def nevervalidator(login, password):
        return None

def testvalidator(login, password):
    if login == 'spyce' and password == 'spyce':
        return 2
    return None

login_defaultvalidator = testvalidator

# How to store login tokens.  FileStorage comes with Spyce,
# but it's easy to create your own Storage class if you want to put them
# in your database, for instance.
from _coreutil import FileStorage
# It's not a good idea to put login-tokens off of www/ in production!
# It's just done this way here to keep the spyce source tree relatively clean.
login_storage = FileStorage(os.path.join(SPYCE_HOME, 'www', 'login-tokens'))

# tags to render login form; must be visible in the globaltags search space.
# These come from tags/render.spi; to make your own, just create a tag 
# that takes the same parameters and add the library to the globaltags list above.
login_render = 'render:login'
loginrequired_render = 'render:login_required'

######
# webserver options -- does not affect mod_python or *CGI configurations
######

# indexFiles specifies a list of files to look for
# in a directory if directory itself is requested.
# The first matching file will be selected.
# If empty, a directory listing will be served instead.
#
# indexFiles = ['index.spy', 'index.html', 'index.txt']
indexFiles = ['index.spy', 'index.html']

# The Spyce webserver uses a threaded concurrency model.  (Historically,
# it also offered "no concurrency" and forking.  If for some strange
# reason you really want no concurrency, set minthreads=maxthreads=1.
# Forking was removed entirely because it performed over 10x slower
# than threading on Linux and Windows.)
#
# Do note that because of the Python GIL (global interpeter lock),
# only one CPU of a multi-CPU machine can execute Python code at a time.
# If this is your situation, mod_python may be a better option for you.
minthreads = 5
maxthreads = 10
# number of pending requests to accept
maxqueuesize = 50

# Restart the webserver if a python module changes.
# Spyce does this by running the "real" server in a subprocess; when that
# server detects changed modules, it exits and Spyce starts another one.
#
# Spyce will check for changes every second, or when a request
# is made, whichever comes first.
#
# It's highly recommended to turn this off for "production" servers,
# since checking each module for each request is a performance hit.
check_modules_and_restart = True

# The ipaddr option defines which IP addresses the server will listen on.
# empty string for all.
ipaddr = ''

# The port option defines which TCP port the server will listen on.
port = 8000
# Port that provides an interactive Python console interface to
# the webserver's guts.  Currently no password protection is offered;
# don't expose this to the outside world!
adminport = None

# The mime option is a list of filenames. The files should
# be definitions of mime-types for common file extensions in the
# standard Apache format.
#
# mime: ['/etc/mime.types']
mime = [os.path.join(SPYCE_HOME, 'spyce.mime')]

# The www_handlers option defines the hander used for files of
# arbitrary extensions.  (The None key specifies the default.)
# The currently supported handlers are:
#   spyce     - process the file at the requested path as a spyce script
#   directory - display directory listing
#   dump      - transfer the file at the requested path verbatim, 
#     providing an appropriate "Content-type" header, if it is known.
# (It's difficult to use the actual instance methods here since we
# don't have a handle to the WWW server object.  So, we use strings
# and let spyceWWW eval them later.)
www_handlers = {
  'spy': 'spyce',
  '/':   'directory',
  None:  'dump'
}


######
# (F)CGI options
######

# Forbid direct requests to the cgi script and discard command line arguments.
#
# Reason: http://www.cert.org/advisories/CA-1996-11.html
#
# You may need to disable this for
#  1) non-Apache servers that do not set the REDIRECT_STATUS environment
#     variable.
#  2) when using the alternative #! variant of CGI configuration
cgi_allow_only_redirect = False


######
# standard module customization
######

# (request module)

# param filters and file filters are lists of functions that are called
# for all GET and POST parameters or files, respectively.
# Each callable should expect two arguments: a reference to the
# request object/spyce module, and the dictionary being filtered.
# (Thus, each callable in param_filters will be called twice; once for the
# GET dict and once for POST. Each callable in file_filters will only be called once.)
param_filters = []
file_filters = []


Prev: 3.5 - Command line Up: 3 - Runtime Next: 3.7 - Server utilities


Spyce logo
Python Server Pages
version 2.1.3
Spyce Powered SourceForge Logo