summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2011-07-06 01:32:52 -0500
committerMichael Merickel <michael@merickel.org>2011-07-06 01:37:10 -0500
commit828384c14b07aa4f50a70f44f789ce4b1b1e34f6 (patch)
tree264bdacb5061bd8c7586e646ba3a1fd3d5f487c3
parent6b01adc58935e95908c42bc982803b20ceaf60e2 (diff)
downloadpyramid-828384c14b07aa4f50a70f44f789ce4b1b1e34f6.tar.gz
pyramid-828384c14b07aa4f50a70f44f789ce4b1b1e34f6.tar.bz2
pyramid-828384c14b07aa4f50a70f44f789ce4b1b1e34f6.zip
Added [pshell] support to INI files and the ability to load generic wsgi apps.
Generic WSGI apps can now be loaded without exposing the 'registry' and 'root' objects. When an app is loaded, extra variables will be exposed to the environment from a special [pshell] section of the INI file. These variables are of the format "name = asset.path.to.object".
-rw-r--r--pyramid/paster.py93
1 files changed, 89 insertions, 4 deletions
diff --git a/pyramid/paster.py b/pyramid/paster.py
index f670ae618..9683da043 100644
--- a/pyramid/paster.py
+++ b/pyramid/paster.py
@@ -1,13 +1,16 @@
import os
+import re
import sys
from code import interact
import zope.deprecation
from paste.deploy import loadapp
+from paste.script.command import BadCommand
from paste.script.command import Command
from pyramid.scripting import get_root
+from pyramid.util import DottedNameResolver
from pyramid.scaffolds import PyramidTemplate # bw compat
zope.deprecation.deprecated(
@@ -79,6 +82,45 @@ class PShellCommand(PCommand):
dest='disable_ipython',
help="Don't use IPython even if it is available")
+ _pshell_section_re = re.compile(r'^\s*\[\s*pshell\s*\]\s*$')
+ _section_re = re.compile(r'^\s*\[')
+
+ def pshell_file_config(self, filename):
+ vars = {
+ 'here': os.path.dirname(filename),
+ '__file__': filename,
+ }
+ f = open(filename)
+ lines = f.readlines()
+ f.close()
+ lineno = 1
+ # find the pshell section
+ while lines:
+ if self._pshell_section_re.search(lines[0]):
+ lines.pop(0)
+ break
+ lines.pop(0)
+ lineno += 1
+ # parse pshell section for key/value pairs
+ resolver = DottedNameResolver(None)
+ self.loaded_objects = {}
+ self.object_help = {}
+ for line in lines:
+ lineno += 1
+ line = line.strip()
+ if not line or line.startswith('#'):
+ continue
+ if self._section_re.search(line):
+ break
+ if '=' not in line:
+ raise BadCommand('Missing = in %s at %s: %r'
+ % (filename, lineno, line))
+ name, value = line.split('=', 1)
+ name = name.strip()
+ value = value.strip() % vars
+ self.loaded_objects[name] = resolver.maybe_resolve(value)
+ self.object_help[name] = value
+
def command(self, IPShell=_marker):
# IPShell passed to command method is for testing purposes
if IPShell is _marker: # pragma: no cover
@@ -86,15 +128,58 @@ class PShellCommand(PCommand):
from IPython.Shell import IPShell
except ImportError:
IPShell = None
- cprt =('Type "help" for more information. "root" is the Pyramid app '
- 'root object, "registry" is the Pyramid registry object.')
+ cprt =('Type "help" for more information.')
banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt)
app_spec = self.args[0]
config_file = app_spec.split('#', 1)[0]
self.logging_file_config(config_file)
app = self.get_app(app_spec, loadapp=self.loadapp[0])
- root, closer = self.get_root(app)
- shell_globals = {'root':root, 'registry':app.registry}
+
+ # load default globals
+ shell_globals = {
+ 'app': app,
+ }
+ default_variables = {'app': 'The WSGI Application'}
+ if hasattr(app, 'registry'):
+ root, closer = self.get_root(app)
+ shell_globals.update({'root':root, 'registry':app.registry})
+ default_variables.update({
+ 'root': 'The root of the default resource tree.',
+ 'registry': 'The Pyramid registry object.',
+ 'settings': 'The Pyramid settings object.',
+ })
+ warning = ''
+ else:
+ # warn the user that this isn't actually the Pyramid app
+ warning = """\n
+WARNING: You have loaded a generic WSGI application, therefore the
+"root" and "registry" are not available. To correct this, run "pshell"
+again and specify the INI section containing your Pyramid application."""
+ closer = lambda: None
+
+ # load the pshell section of the ini file
+ self.pshell_file_config(config_file)
+ shell_globals.update(self.loaded_objects)
+
+ # eliminate duplicates from default_variables
+ for k in self.loaded_objects:
+ if k in default_variables:
+ del default_variables[k]
+
+ # append the loaded variables
+ if default_variables:
+ banner += '\n\nDefault Variables:'
+ for var, txt in default_variables.iteritems():
+ banner += '\n %-12s %s' % (var, txt)
+
+ if self.object_help:
+ banner += '\n\nCustom Variables:'
+ for var in sorted(self.object_help.keys()):
+ banner += '\n %-12s %s' % (var, self.object_help[var])
+
+ # append the warning
+ banner += warning
+ banner += '\n'
if (IPShell is None) or self.options.disable_ipython:
try: