Improve the documentation
--HG-- extra : rebase_source : 24b7ddcbfb6fb739787292db49148d3234d6f67a
This commit is contained in:
parent
f9c262758e
commit
6b8349696d
@ -9,11 +9,7 @@ Public API
|
||||
|
||||
.. module:: wsme
|
||||
|
||||
.. autoclass:: WSRoot
|
||||
:members:
|
||||
|
||||
.. autoclass:: expose
|
||||
.. autoclass:: validate
|
||||
.. autoclass:: signature([return_type, [arg0_type, [arg1_type, ... ] ] ], body=None, status=None)
|
||||
|
||||
.. autoclass:: wsproperty
|
||||
.. autoclass:: wsattr
|
||||
@ -22,6 +18,9 @@ Public API
|
||||
|
||||
Default value of the complex type attributes.
|
||||
|
||||
.. autoclass:: WSRoot
|
||||
:members:
|
||||
|
||||
Internals
|
||||
---------
|
||||
|
||||
|
@ -7,7 +7,9 @@ next
|
||||
* Add a special type 'HostRequest' that allow a function to ask for the host
|
||||
framework request object in its arguments.
|
||||
|
||||
* New Flask adapter: wsmeext.flask
|
||||
* New adapter: wsmeext.flask, for the Flask_ framework.
|
||||
|
||||
.. _Flask: http://flask.pocoo.org/
|
||||
|
||||
* Fix: the cornice adapter was not usable.
|
||||
|
||||
|
182
doc/functions.rst
Normal file
182
doc/functions.rst
Normal file
@ -0,0 +1,182 @@
|
||||
Functions
|
||||
=========
|
||||
|
||||
WSME is based on the idea that most of the time the input and output of web
|
||||
services are actually stricly typed. It uses this fact to ease the
|
||||
implementation of the actual functions by handling those input/output.
|
||||
It also uses these informations to propose alternate protocols on top of a
|
||||
proper REST api.
|
||||
|
||||
This chapter explains in details how to 'sign' a function with WSME.
|
||||
|
||||
The decorators
|
||||
--------------
|
||||
|
||||
Depending on the framework you are using, you will have to use either a
|
||||
@signature decorator, either a @wsexpose decorator.
|
||||
|
||||
@signature
|
||||
~~~~~~~~~~
|
||||
|
||||
The base @\ :class:`wsme.signature` decorator defines the return and argument types
|
||||
of the function, and if needed a few more options.
|
||||
|
||||
The Flask and Cornice adapters both propose a specific version of it, which
|
||||
also wrap the function so that it becomes suitable for the host framework.
|
||||
|
||||
In any case, the use of @signature has the same meaning: tell WSME what is the
|
||||
signature of the function.
|
||||
|
||||
@wsexpose
|
||||
~~~~~~~~~
|
||||
|
||||
The native Rest implementation, and the TG and Pecan adapters add a @wsexpose
|
||||
decorator.
|
||||
|
||||
It does what @signature does, *and* expose the function in the routing system
|
||||
of the host framework.
|
||||
|
||||
This decorator is generally used in object-dispatch routing context.
|
||||
|
||||
.. note::
|
||||
|
||||
Since both decorators plays the same role function-wise, the rest of this
|
||||
document will alway use @signature.
|
||||
|
||||
Signing a function
|
||||
------------------
|
||||
|
||||
Signing a function is just a matter of decorating it with @signature:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@signature(int, int, int)
|
||||
def multiply(a, b):
|
||||
return a * b
|
||||
|
||||
In this trivial example, we tell WSME that the 'multiply' function returns an
|
||||
integer, and takes two integer parameters.
|
||||
|
||||
WSME will match the argument types by order, and know the exact type of each
|
||||
named argument. This is important since most of the web service protocols don't
|
||||
provide strict argument ordering but only named parameters.
|
||||
|
||||
Optional arguments
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Defining an argument as optional is done by providing a default value:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@signature(int, int, int):
|
||||
def increment(value, delta=1):
|
||||
return value + delta
|
||||
|
||||
In this example, the caller may omit the 'delta' argument, and no
|
||||
'MissingArgument' error will be raised.
|
||||
|
||||
Additionally this argument will be documented as optional by the sphinx
|
||||
extension.
|
||||
|
||||
Body argument
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
When defining a Rest CRUD api, we generally have a URL on which we POST datas.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@signature(Author, Author)
|
||||
def update_author(data):
|
||||
# ...
|
||||
return data
|
||||
|
||||
Such a function will take at least one parameter 'data' that is a structured
|
||||
type. With the default way of handling parameters, the body of the request
|
||||
would be like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
"data":
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Pierre-Joseph"
|
||||
}
|
||||
}
|
||||
|
||||
If you think (and you should) that it has one extra nest level, the 'body'
|
||||
argument is here for you::
|
||||
|
||||
@signature(Author, body=Author)
|
||||
def update_author(data):
|
||||
# ...
|
||||
return data
|
||||
|
||||
With this syntax, we can now post a simpler body:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Pierre-Joseph"
|
||||
}
|
||||
|
||||
Note that it does not prevent from having multiple parameters, it just requires
|
||||
the body argument to be the last:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@signature(Author, bool, body=Author)
|
||||
def update_author(force_update=False, data=None):
|
||||
# ...
|
||||
return data
|
||||
|
||||
In this case, the other arguments can be passed in the URL, in addition to the
|
||||
body parameter. For example, a POST on ``/author/SOMEID?force_update=true``.
|
||||
|
||||
Status code
|
||||
~~~~~~~~~~~
|
||||
|
||||
The default status code returned by WSME are 200, 400 (if the client send wrong
|
||||
inputs) and 500 (for server-side errors).
|
||||
|
||||
Since a proper Rest API should use different return codes (201, etc), one can
|
||||
use the 'status=' option of @signature to do so.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@signature(Author, body=Author, status=201)
|
||||
def create_author(data):
|
||||
# ...
|
||||
return data
|
||||
|
||||
Of course this code will only be used if no error occur.
|
||||
|
||||
In case the function needs to change the status code on a per-request base, it
|
||||
can return a :class:`wsme.Response` object, that allow to override the status
|
||||
code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@signature(Author, body=Author, status=202)
|
||||
def update_author(data):
|
||||
# ...
|
||||
response = Response(data)
|
||||
if transaction_finished_and_successful:
|
||||
response.status_code = 200
|
||||
return response
|
||||
|
||||
Extra arguments
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The default behavior of WSME is to reject requests that gives extra/unknown
|
||||
arguments. In some (rare) cases, it can be unwanted.
|
||||
|
||||
Adding 'ignore_extra_args=True' to @signature changes this behavior.
|
||||
|
||||
.. note::
|
||||
|
||||
If using this option seems to solution to your problem, please think twice
|
||||
before using it !
|
@ -10,6 +10,7 @@ Contents
|
||||
gettingstarted
|
||||
api
|
||||
types
|
||||
functions
|
||||
protocols
|
||||
integrate
|
||||
document
|
||||
|
@ -24,11 +24,13 @@ This decorator can have two different names depending on the adapter.
|
||||
|
||||
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`.
|
||||
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.
|
||||
``/ws``. This subpath will then handle the additional protocols. In a future
|
||||
version, a wsgi middleware will probably play this role.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -115,7 +117,8 @@ Example
|
||||
Flask
|
||||
-----
|
||||
|
||||
*"Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions. And before you ask: It's BSD licensed! "*
|
||||
*"Flask is a microframework for Python based on Werkzeug, Jinja 2 and good
|
||||
intentions. And before you ask: It's BSD licensed! "*
|
||||
|
||||
|
||||
.. warning::
|
||||
|
@ -8,6 +8,11 @@ last chapter (:ref:`protocols-the-example`).
|
||||
REST
|
||||
----
|
||||
|
||||
.. note::
|
||||
|
||||
This chapter applies also for the different adapters, not only the native
|
||||
REST implementation.
|
||||
|
||||
The two REST protocols share common characterics.
|
||||
|
||||
Each function corresponds to distinct webpath that starts with the
|
||||
|
17
wsme/api.py
17
wsme/api.py
@ -136,6 +136,23 @@ class FunctionDefinition(object):
|
||||
|
||||
|
||||
class signature(object):
|
||||
"""
|
||||
Decorator that specify the argument types of an exposed function.
|
||||
|
||||
:param return_type: Type of the value returned by the function
|
||||
:param argN: Type of the Nth argument
|
||||
:param body: If the function takes a final argument that is supposed to be
|
||||
the request body by itself, its type.
|
||||
:param status: HTTP return status code of the function.
|
||||
:param ignore_extra_args: Allow extra/unknow arguments (default to False)
|
||||
|
||||
Most of the time this decorator is not supposed to be used directly,
|
||||
unless you are not using WSME on top of another framework.
|
||||
|
||||
If an adapter is used, it will provide either a specialised version of this
|
||||
decororator, either a new decorator named @wsexpose that takes the same
|
||||
parameters (it will in addition expose the function, hence its name).
|
||||
"""
|
||||
def __init__(self, *types, **options):
|
||||
self.return_type = types[0] if types else None
|
||||
self.arg_types = []
|
||||
|
Loading…
x
Reference in New Issue
Block a user