# 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 = []
|