File: integrate.rst

package info (click to toggle)
python-wsme 0.6-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 956 kB
  • ctags: 1,831
  • sloc: python: 8,452; makefile: 138
file content (327 lines) | stat: -rw-r--r-- 8,671 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
Integrating with a Framework
============================

General considerations
----------------------

Using WSME within another framework providing its own REST capabilities is
generally done by using a specific decorator to declare the function signature,
in addition to the framework own way of declaring exposed functions.

This decorator can have two different names depending on the adapter.

``@wsexpose``
    This decorator will declare the function signature *and*
    take care of calling the adequate decorators of the framework.

    Generally this decorator is provided for frameworks that use
    object-dispatch controllers, such as :ref:`adapter-pecan` and
    :ref:`adapter-tg1`. 

``@signature``
    This decorator only set the function signature and returns a function
    that can be used by the host framework as a REST request target.

    Generally this decorator is provided for frameworks that expects functions
    taking a request object as a single parameter and returning a response
    object. This is the case of :ref:`adapter-cornice` and
    :ref:`adapter-flask`.

Additionnaly, if you want to enable additionnal protocols, you will need to
mount a :class:`WSRoot` instance somewhere in the application, generally
``/ws``. This subpath will then handle the additional protocols. In a future
version, a wsgi middleware will probably play this role.

.. note::

    Not all the adapters are at the same level of maturity.

WSGI Application
----------------

The :func:`wsme.WSRoot.wsgiapp` function of WSRoot returns a wsgi
application.

Example
~~~~~~~

The following example assume the REST protocol will be entirely handled by
WSME, which is the case if you write a WSME standalone application.

.. code-block:: python

    from wsme import WSRoot, expose


    class MyRoot(WSRoot):
        @expose(unicode)
        def helloworld(self):
            return u"Hello World !"

    root = MyRoot(protocols=['restjson'])
    application = root.wsgiapp()


.. _adapter-cornice:

Cornice
-------

.. _cornice: http://cornice.readthedocs.org/en/latest/

    *"* Cornice_ *provides helpers to build & document REST-ish Web Services with
    Pyramid, with decent default behaviors. It takes care of following the HTTP
    specification in an automated way where possible."*


:mod:`wsmeext.cornice` -- Cornice adapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. module:: wsmeext.cornice

.. function:: signature
    
    Declare the parameters of a function and returns a function suitable for
    cornice (ie that takes a request and returns a response).

Example
~~~~~~~

.. code-block:: python

    from cornice import Service
    from wsmeext.cornice import signature
    import wsme.types

    hello = Service(name='hello', path='/', description="Simplest app")

    class Info(wsme.types.Base):
        message = wsme.types.text


    @hello.get()
    @signature(Info)
    def get_info():
        """Returns Hello in JSON or XML."""
        return Info(message='Hello World')


    @hello.post()
    @signature(None, Info)
    def set_info(info):
        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
-----

    *"*\ Pecan_ *was created to fill a void in the Python web-framework world –
    a very lightweight framework that provides object-dispatch style routing.
    Pecan does not aim to be a "full stack" framework, and therefore includes
    no out of the box support for things like sessions or databases. Pecan
    instead focuses on HTTP itself."*

.. warning::

    A pecan application is not able to mount another wsgi application on a
    subpath. For that reason, additional protocols are not supported for now,
    ie until wsme provides a middleware that can do the same as a mounted
    WSRoot.

:mod:`wsmeext.pecan` -- Pecan adapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. module:: wsmeext.pecan

.. function:: wsexpose(return_type, \*arg_types, \*\*options)

    See @\ :func:`signature` for parameters documentation.

    Can be used on any function of a pecan
    `RestController <http://pecan.readthedocs.org/en/latest/rest.html>`_
    instead of the expose decorator from Pecan.

Configuration
~~~~~~~~~~~~~

WSME can be configured through the application configation, by adding a 'wsme'
configuration entry in ``config.py``:

.. code-block:: python

    wsme = {
        'debug': True
    }

Valid configuration variables are :

-   ``'debug'``: Whether or not to include exception tracebacks in the returned
    server-side errors.

Example
~~~~~~~

The `example <http://pecan.readthedocs.org/en/latest/rest.html#nesting-restcontroller>`_ from the Pecan documentation becomes:

.. code-block:: python

    from wsmeext.pecan import wsexpose
        
    class BooksController(RestController):
        @wsexpose(Book, int, int)
        def get(self, author_id, id):
            # ..

        @wsexpose(Book, int, int, body=Book)
        def put(self, author_id, id, book):
            # ..

    class AuthorsController(RestController):
            books = BooksController()

.. _Pecan: http://pecanpy.org/

.. _adapter-tg1:

Turbogears 1.x
--------------

The TG adapters have an api very similar to TGWebServices. Migrating from it
should be straightforward (a little howto migrate would not hurt though, and it
will be written as soon as possible).

:mod:`wsmeext.tg11` -- TG 1.1 adapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. module:: wsmeext.tg11

.. function:: wsexpose(return_type, \*arg_types, \*\*options)

    See @\ :func:`signature` for parameters documentation.

    Can be used on any function of a controller
    instead of the expose decorator from TG.

.. function:: wsvalidate(\*arg_types)

    Set the argument types of an exposed function. This decorator is provided
    so that WSME is an almost drop-in replacement for TGWebServices. If
    starting from scratch you can use \ :func:`wsexpose` only

.. function:: adapt(wsroot)

    Returns a TG1 controller instance that publish a :class:`wsme.WSRoot`.
    It can then be mounted on a TG1 controller.

    Because the adapt function modifies the cherrypy filters of the controller
    the 'webpath' of the WSRoot instance must be consistent with the path it
    will be mounted on.

:mod:`wsmeext.tg15` -- TG 1.5 adapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. module:: wsmeext.tg15

This adapter has the exact same api as :mod:`wsmeext.tg11`.

Example
~~~~~~~

In a freshly quickstarted tg1 application (let's say, wsmedemo), you can add
REST-ish functions anywhere in your controller tree. Here directly on the root,
in controllers.py:

.. code-block:: python

    # ...

    # For tg 1.5, import from wsmeext.tg15 instead :
    from wsmeext.tg11 import wsexpose, WSRoot

    class Root(controllers.RootController):
        # Having a WSRoot on /ws is only required to enable additional
        # protocols. For REST-only services, it can be ignored.
        ws = adapt(
            WSRoot(webpath='/ws', protocols=['soap'])
        )

        @wsexpose(int, int, int)
        def multiply(self, a, b):
            return a * b

.. _TurboGears: http://www.turbogears.org/

Other frameworks
----------------

Bottle
~~~~~~

No adapter is provided yet but it should not be hard to write one, by taking
example on the cornice adapter.

This example only show how to mount a WSRoot inside a bottle application.

.. code-block:: python

    import bottle
    import wsme

    class MyRoot(wsme.WSRoot):
        @wsme.expose(unicode)
        def helloworld(self):
            return u"Hello World !"

    root = MyRoot(webpath='/ws', protocols=['restjson'])

    bottle.mount('/ws', root.wsgiapp())
    bottle.run()

Pyramid
~~~~~~~

The recommended way of using WSME inside Pyramid is to use
:ref:`adapter-cornice`.