A few minor tweaks:
* Only require simplejson if we need to. * Improve upon parameter validation. * Add a redirect utility function. * Remove some print statements.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from paste.urlparser import StaticURLParser
|
||||
from paste.cascade import Cascade
|
||||
|
||||
from pecan import Pecan, request, response, override_template
|
||||
from pecan import Pecan, request, response, override_template, redirect
|
||||
from decorators import expose
|
||||
|
||||
__all__ = [
|
||||
|
@@ -1,10 +1,18 @@
|
||||
from inspect import getargspec
|
||||
|
||||
def expose(template=None, content_type='text/html'):
|
||||
if template == 'json': content_type = 'application/json'
|
||||
def decorate(f):
|
||||
# flag the method as exposed
|
||||
f.exposed = True
|
||||
|
||||
# set a "pecan" attribute, where we will store details
|
||||
if not hasattr(f, 'pecan'): f.pecan = {}
|
||||
f.pecan['content_type'] = content_type
|
||||
f.pecan.setdefault('template', []).append(template)
|
||||
f.pecan.setdefault('content_types', {})[content_type] = template
|
||||
|
||||
# store the arguments for this controller method
|
||||
f.pecan['argspec'] = getargspec(f)
|
||||
return f
|
||||
return decorate
|
@@ -28,6 +28,10 @@ def override_template(template):
|
||||
request.override_template = template
|
||||
|
||||
|
||||
def redirect(location):
|
||||
raise exc.HTTPFound(location=location)
|
||||
|
||||
|
||||
class Pecan(object):
|
||||
def __init__(self, root,
|
||||
renderers = renderers,
|
||||
@@ -70,6 +74,13 @@ class Pecan(object):
|
||||
for hook in state.hooks:
|
||||
getattr(hook, hook_type)(*args)
|
||||
|
||||
def get_validated_params(self, all_params, argspec):
|
||||
valid_params = dict()
|
||||
for param_name, param_value in all_params.iteritems():
|
||||
if param_name in argspec.args:
|
||||
valid_params[param_name] = param_value
|
||||
return valid_params
|
||||
|
||||
def handle_request(self):
|
||||
# lookup the controller, respecting content-type as requested
|
||||
# by the file extension on the URI
|
||||
@@ -94,8 +105,12 @@ class Pecan(object):
|
||||
self.handle_hooks('before', state)
|
||||
|
||||
# get the result from the controller, properly handling wrap hooks
|
||||
result = controller(**dict(state.request.str_params))
|
||||
|
||||
params = self.get_validated_params(
|
||||
dict(state.request.str_params),
|
||||
controller.pecan['argspec']
|
||||
)
|
||||
result = controller(**params)
|
||||
|
||||
# pull the template out based upon content type and handle overrides
|
||||
template = controller.pecan.get('content_types', {}).get(content_type)
|
||||
template = getattr(request, 'override_template', template)
|
||||
|
@@ -35,10 +35,6 @@ class JsonRenderer(object):
|
||||
def render(self, template_path, namespace):
|
||||
from jsonify import encode
|
||||
result = encode(namespace)
|
||||
print '*' * 80
|
||||
print result
|
||||
print type(result)
|
||||
print '*' * 80
|
||||
return result
|
||||
|
||||
|
||||
|
41
setup.py
41
setup.py
@@ -17,10 +17,34 @@ class PyTest(Command):
|
||||
py.cmdline.pytest(py.std.sys.argv[2:])
|
||||
|
||||
|
||||
#
|
||||
# determine requirements
|
||||
#
|
||||
requirements = [
|
||||
"WebOb >= 0.9.8",
|
||||
"simplegeneric >= 0.7",
|
||||
"Genshi >= 0.6",
|
||||
"Kajiki >= 0.2.2",
|
||||
"Mako >= 0.3",
|
||||
"py >= 1.3.4",
|
||||
"WebTest >= 1.2.2",
|
||||
"Paste >= 1.7.5.1",
|
||||
"PasteScript >= 1.7.3"
|
||||
]
|
||||
|
||||
try:
|
||||
import json
|
||||
except:
|
||||
requirements.append("simplejson >= 2.1.1")
|
||||
|
||||
|
||||
#
|
||||
# call setup
|
||||
#
|
||||
setup(
|
||||
name = 'pecan',
|
||||
version = version,
|
||||
description = "A WSGI object-dispatching web framework, in the spirit of TurboGears, only much much smaller, with many fewer dependancies.",
|
||||
description = "A WSGI object-dispatching web framework, in the spirit of TurboGears, only much much smaller, with many fewer dependencies.",
|
||||
long_description = None,
|
||||
classifiers = [],
|
||||
keywords = '',
|
||||
@@ -32,19 +56,8 @@ setup(
|
||||
include_package_data = True,
|
||||
zip_safe = True,
|
||||
cmdclass = {'test': PyTest},
|
||||
install_requires=[
|
||||
"WebOb >= 0.9.8",
|
||||
"simplegeneric >= 0.7",
|
||||
"Genshi >= 0.6",
|
||||
"Kajiki >= 0.2.2",
|
||||
"Mako >= 0.3",
|
||||
"py >= 1.3.4",
|
||||
"WebTest >= 1.2.2",
|
||||
"Paste >= 1.7.5.1",
|
||||
"simplejson >= 2.1.1",
|
||||
"PasteScript >= 1.7.3"
|
||||
],
|
||||
entry_points = """
|
||||
install_requires = requirements,
|
||||
entry_points = """
|
||||
[paste.paster_create_template]
|
||||
pecan-base = templates:NewProjectTemplate
|
||||
""",
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from pecan import Pecan, expose, request, response
|
||||
from pecan import Pecan, expose, request, response, redirect
|
||||
from webtest import TestApp
|
||||
|
||||
class TestBase(object):
|
||||
@@ -160,4 +160,36 @@ class TestEngines(object):
|
||||
r = app.get('/')
|
||||
assert r.status_int == 200
|
||||
result = dict(loads(r.body))
|
||||
assert result == expected_result
|
||||
assert result == expected_result
|
||||
|
||||
def test_controller_parameters(self):
|
||||
class RootController(object):
|
||||
@expose('json')
|
||||
def index(self, argument=None):
|
||||
assert argument == 'value'
|
||||
|
||||
# arguments should get passed appropriately
|
||||
app = TestApp(Pecan(RootController()))
|
||||
r = app.get('/?argument=value')
|
||||
assert r.status_int == 200
|
||||
|
||||
# extra arguments get stripped off
|
||||
r = app.get('/?argument=value&extra=not')
|
||||
assert r.status_int == 200
|
||||
|
||||
def test_redirect(self):
|
||||
class RootController(object):
|
||||
@expose()
|
||||
def index(self):
|
||||
redirect('/testing')
|
||||
|
||||
@expose()
|
||||
def testing(self):
|
||||
return 'it worked!'
|
||||
|
||||
app = TestApp(Pecan(RootController()))
|
||||
r = app.get('/')
|
||||
assert r.status_int == 302
|
||||
r = r.follow()
|
||||
assert r.status_int == 200
|
||||
assert r.body == 'it worked!'
|
Reference in New Issue
Block a user