Merged cdevienne/wsme into default
This commit is contained in:
commit
3d69ac33d8
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user