Merged cdevienne/wsme into default

This commit is contained in:
Endre Karlson 2013-03-28 13:08:03 +01:00
commit 3d69ac33d8
5 changed files with 75 additions and 7 deletions

View File

@ -62,7 +62,7 @@ Main features
- Extensible : easy to add more protocols or more base types.
- Framework independance : adapters are provided to easily integrate
your API in any web framework, for example a wsgi container,
Pecan_, TurboGears_, cornice_...
Pecan_, TurboGears_, Flask_, cornice_...
- Very few runtime dependencies: webob, simplegeneric. Optionnaly lxml and
simplejson if you need better performances.
- Integration in `Sphinx`_ for making clean documentation with
@ -70,6 +70,7 @@ Main features
.. _Pecan: http://pecanpy.org/
.. _TurboGears: http://www.turbogears.org/
.. _Flask: http://flask.pocoo.org/
.. _cornice: http://pypi.python.org/pypi/cornice
Install

View File

@ -4,6 +4,8 @@ Changes
next
----
* New Flask adapter: wsmeext.flask
* Fix: Submodules of wsmeext were missing in the packages.
* Fix: The demo app was still depending on the WSME-Soap package (which has

View File

@ -110,6 +110,44 @@ Example
print("Got a message: %s" % info.message)
.. _adapter-flask:
Flask
-----
*"Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions. And before you ask: It's BSD licensed! "*
.. warning::
Flask support is limited to function signature handling. It does not
support additional protocols. This is a temporary limitation, if you have
needs on that matter please tell us at python-wsme@googlegroups.com.
:mod:`wsmeext.flask` -- Flask adapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. module:: wsmeext.flask
.. function:: signature(return_type, \*arg_types, \*\*options)
See @\ :func:`signature` for parameters documentation.
Can be used on a function before routing it with flask.
Example
~~~~~~~
.. code-block:: python
from wsmeext.flask import signature
@app.route('/multiply')
@signature(int, int, int)
def multiply(a, b):
return a * b
.. _adapter-pecan:
Pecan

View File

@ -9,6 +9,11 @@ class Model(Base):
name = text
class Criterion(Base):
op = text
attr = text
value = text
test_app = Flask(__name__)
@ -25,9 +30,13 @@ def divide_by_zero():
@test_app.route('/models')
@signature([Model])
def list_models():
return [Model(name='first')]
@signature([Model], [Criterion])
def list_models(q=None):
if q:
name = q[0].value
else:
name = 'first'
return [Model(name=name)]
@test_app.route('/models/<name>')
@ -63,6 +72,14 @@ class FlaskrTestCase(unittest.TestCase):
resp = self.app.get('/models')
assert resp.status_code == 200
def test_array_parameter(self):
resp = self.app.get('/models?q.op=%3D&q.attr=name&q.value=second')
assert resp.status_code == 200
print resp.data
self.assertEquals(
resp.data, '[{"name": "second"}]'
)
def test_post_model(self):
resp = self.app.post('/models', data={"body.name": "test"})
assert resp.status_code == 200

View File

@ -81,11 +81,19 @@ def from_params(datatype, params, path, hit_paths):
@from_params.when_type(ArrayType)
def array_from_params(datatype, params, path, hit_paths):
if hasattr(params, 'getall'):
# webob multidict
def getall(params, path):
return params.getall(path)
elif hasattr(params, 'getlist'):
# werkzeug multidict
def getall(params, path): # noqa
return params.getlist(path)
if path in params:
hit_paths.add(path)
return [
from_param(datatype.item_type, value)
for value in params.getall(path)]
for value in getall(params, path)]
if iscomplex(datatype.item_type):
attributes = set()
@ -99,7 +107,7 @@ def array_from_params(datatype, params, path, hit_paths):
for attrdef in list_attributes(datatype.item_type):
attrpath = '%s.%s' % (path, attrdef.key)
hit_paths.add(attrpath)
attrvalues = params.getall(attrpath)
attrvalues = getall(params, attrpath)
if len(value) < len(attrvalues):
value[-1:] = [
datatype.item_type()
@ -158,7 +166,9 @@ def args_from_args(funcdef, args, kwargs):
newargs.append(from_param(argdef.datatype, arg))
newkwargs = {}
for argname, value in kwargs.items():
newkwargs[argname] = from_param(funcdef.get_arg(argname).datatype, value)
newkwargs[argname] = from_param(
funcdef.get_arg(argname).datatype, value
)
return newargs, newkwargs