Minor documentation edits
Change-Id: I0f8049241ffd870a4dac405fa0ca53fb122f2181
This commit is contained in:
parent
2c29787386
commit
4441ca74a9
10
README.rst
10
README.rst
@ -4,19 +4,19 @@ Web Services Made Easy
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Web Service Made Easy (WSME) simplify the writing of REST web services
|
||||
by providing simple yet powerful typing which removes the need to directly
|
||||
Web Services Made Easy (WSME) simplifies the writing of REST web services
|
||||
by providing simple yet powerful typing, removing the need to directly
|
||||
manipulate the request and the response objects.
|
||||
|
||||
WSME can work standalone or on top of your favorite python web
|
||||
WSME can work standalone or on top of your favorite Python web
|
||||
(micro)framework, so you can use both your preferred way of routing your REST
|
||||
requests and most of the features of WSME that rely on the typing system like:
|
||||
|
||||
- Alternate protocols, including ones supporting batch-calls
|
||||
- Alternate protocols, including those supporting batch-calls
|
||||
- Easy documentation through a Sphinx_ extension
|
||||
|
||||
WSME is originally a rewrite of TGWebServices
|
||||
with focus on extensibility, framework-independance and better type handling.
|
||||
with a focus on extensibility, framework-independance and better type handling.
|
||||
|
||||
How Easy ?
|
||||
~~~~~~~~~~
|
||||
|
@ -10,7 +10,7 @@ Install the extension
|
||||
|
||||
Here we consider that you already quick-started a sphinx project.
|
||||
|
||||
#. In your ``conf.py`` file, add ``'ext'`` to you extensions,
|
||||
#. In your ``conf.py`` file, add ``'ext'`` to your extensions,
|
||||
and optionally set the enabled protocols.
|
||||
|
||||
.. code-block:: python
|
||||
@ -34,7 +34,7 @@ Config values
|
||||
.. confval:: wsme_protocols
|
||||
|
||||
A list of strings that are WSME protocol names. If provided by an
|
||||
additionnal package (for example WSME-Soap or WSME-ExtDirect), it must
|
||||
additional package (for example WSME-Soap or WSME-ExtDirect), that package must
|
||||
be installed.
|
||||
|
||||
The types and services generated documentation will include code samples
|
||||
@ -57,10 +57,10 @@ Directives
|
||||
|
||||
.. rst:directive:: .. root:: <WSRoot full path>
|
||||
|
||||
Allow to define the service root controller in one documentation source file.
|
||||
Define the service root controller for this documentation source file.
|
||||
To set it globally, see :confval:`wsme_root`.
|
||||
|
||||
A ``webpath`` option allow to override :confval:`wsme_webpath`.
|
||||
A ``webpath`` option allows override of :confval:`wsme_webpath`.
|
||||
|
||||
Example:
|
||||
|
||||
@ -80,7 +80,7 @@ Directives
|
||||
.. rst:directive:: .. attribute:: aname
|
||||
|
||||
Equivalent to the :rst:dir:`py:attribute` directive to document a complex type
|
||||
attribute. It takes an additionnal ``:type:`` field.
|
||||
attribute. It takes an additional ``:type:`` field.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
@ -151,7 +151,7 @@ Python source
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
.. literalinclude:: ../wsmeext/sphinxext.py
|
||||
:lines: 42-67
|
||||
:lines: 69-96
|
||||
:language: python
|
||||
|
||||
Documentation source
|
||||
@ -161,6 +161,10 @@ Documentation source
|
||||
|
||||
.. default-domain:: wsmeext
|
||||
|
||||
.. type:: int
|
||||
|
||||
An integer
|
||||
|
||||
.. autotype:: wsmeext.sphinxext.SampleType
|
||||
:members:
|
||||
|
||||
|
@ -2,18 +2,17 @@ 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
|
||||
services are actually strictly typed. It uses this idea 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.
|
||||
It also proposes alternate protocols on top of a proper REST api.
|
||||
|
||||
This chapter explains in details how to 'sign' a function with WSME.
|
||||
This chapter explains in detail 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.
|
||||
@\ :class:`wsme.signature` decorator or a @\ :class:`wsme.wsexpose` decorator.
|
||||
|
||||
@signature
|
||||
~~~~~~~~~~
|
||||
@ -24,23 +23,23 @@ 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
|
||||
In any case, the use of @\ :class:`wsme.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
|
||||
The native Rest implementation, and the TG and Pecan adapters add a @\ :class:`wsme.wsexpose`
|
||||
decorator.
|
||||
|
||||
It does what @signature does, *and* expose the function in the routing system
|
||||
It does what @\ :class:`wsme.signature` does, *and* exposes the function in the routing system
|
||||
of the host framework.
|
||||
|
||||
This decorator is generally used in object-dispatch routing context.
|
||||
This decorator is generally used in an object-dispatch routing context.
|
||||
|
||||
.. note::
|
||||
|
||||
Since both decorators plays the same role function-wise, the rest of this
|
||||
Since both decorators play the same role, the rest of this
|
||||
document will alway use @signature.
|
||||
|
||||
Signing a function
|
||||
@ -57,7 +56,7 @@ Signing a function is just a matter of decorating it with @signature:
|
||||
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
|
||||
WSME will match the argument types by order to determine 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.
|
||||
|
||||
@ -75,13 +74,13 @@ Defining an argument as optional is done by providing a default value:
|
||||
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
|
||||
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.
|
||||
When defining a Rest CRUD API, we generally have a URL to which we POST data.
|
||||
|
||||
For example:
|
||||
|
||||
@ -92,9 +91,9 @@ For example:
|
||||
# ...
|
||||
return data
|
||||
|
||||
Such a function will take at least one parameter 'data' that is a structured
|
||||
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:
|
||||
would look like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
@ -106,7 +105,7 @@ would be like this:
|
||||
}
|
||||
}
|
||||
|
||||
If you think (and you should) that it has one extra nest level, the 'body'
|
||||
If you think (and you should) that it has one extra level of nesting, the 'body'
|
||||
argument is here for you::
|
||||
|
||||
@signature(Author, body=Author)
|
||||
@ -123,7 +122,7 @@ With this syntax, we can now post a simpler body:
|
||||
"name": "Pierre-Joseph"
|
||||
}
|
||||
|
||||
Note that it does not prevent from having multiple parameters, it just requires
|
||||
Note that this does not prevent the function from having multiple parameters; it just requires
|
||||
the body argument to be the last:
|
||||
|
||||
.. code-block:: python
|
||||
@ -139,7 +138,7 @@ 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
|
||||
The default status codes returned by WSME are 200, 400 (if the client sends invalid
|
||||
inputs) and 500 (for server-side errors).
|
||||
|
||||
Since a proper Rest API should use different return codes (201, etc), one can
|
||||
@ -152,10 +151,10 @@ use the 'status=' option of @signature to do so.
|
||||
# ...
|
||||
return data
|
||||
|
||||
Of course this code will only be used if no error occur.
|
||||
Of course this code will only be used if no error occurs.
|
||||
|
||||
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
|
||||
In case the function needs to change the status code on a per-request basis, it
|
||||
can return a :class:`wsme.Response` object, allowing it to override the status
|
||||
code:
|
||||
|
||||
.. code-block:: python
|
||||
@ -171,15 +170,15 @@ code:
|
||||
Extra arguments
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The default behavior of WSME is to reject requests that gives extra/unknown
|
||||
arguments. In some (rare) cases, it can be unwanted.
|
||||
The default behavior of WSME is to reject requests that give extra/unknown
|
||||
arguments. In some (rare) cases, this is undesirable.
|
||||
|
||||
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 !
|
||||
If using this option seems to solve your problem, please think twice
|
||||
before using it!
|
||||
|
||||
Accessing the request
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -6,7 +6,7 @@ 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.
|
||||
in addition to the framework's own way of declaring exposed functions.
|
||||
|
||||
This decorator can have two different names depending on the adapter.
|
||||
|
||||
@ -19,18 +19,18 @@ This decorator can have two different names depending on the adapter.
|
||||
:ref:`adapter-tg1`.
|
||||
|
||||
``@signature``
|
||||
This decorator only set the function signature and returns a function
|
||||
This decorator only sets 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
|
||||
Generally this decorator is provided for frameworks that expect functions
|
||||
taking a request object as a single parameter and returning a response
|
||||
object. This is the case of :ref:`adapter-cornice` and
|
||||
object. This is the case for :ref:`adapter-cornice` and
|
||||
:ref:`adapter-flask`.
|
||||
|
||||
Additionnaly, if you want to enable additionnal protocols, you will need to
|
||||
If you want to enable additional 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.
|
||||
version, a WSGI middleware will probably play this role.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -39,13 +39,13 @@ version, a wsgi middleware will probably play this role.
|
||||
WSGI Application
|
||||
----------------
|
||||
|
||||
The :func:`wsme.WSRoot.wsgiapp` function of WSRoot returns a wsgi
|
||||
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
|
||||
The following example assumes the REST protocol will be entirely handled by
|
||||
WSME, which is the case if you write a WSME standalone application.
|
||||
|
||||
.. code-block:: python
|
||||
@ -164,9 +164,9 @@ Pecan
|
||||
|
||||
.. warning::
|
||||
|
||||
A pecan application is not able to mount another wsgi application on a
|
||||
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
|
||||
until WSME provides a middleware that can do the same as a mounted
|
||||
WSRoot.
|
||||
|
||||
:mod:`wsmeext.pecan` -- Pecan adapter
|
||||
|
@ -10,8 +10,8 @@ REST
|
||||
|
||||
.. note::
|
||||
|
||||
This chapter applies also for the different adapters, not only the native
|
||||
REST implementation.
|
||||
This chapter applies for all adapters, not just the native REST
|
||||
implementation.
|
||||
|
||||
The two REST protocols share common characterics.
|
||||
|
||||
@ -19,8 +19,7 @@ Each function corresponds to distinct webpath that starts with the
|
||||
root webpath, followed by the controllers names if any, and finally
|
||||
the function name.
|
||||
|
||||
For example, the functions exposed functions will be mapped to the
|
||||
following paths :
|
||||
The example's exposed functions will be mapped to the following paths:
|
||||
|
||||
- ``/ws/persons/create``
|
||||
- ``/ws/persons/get``
|
||||
@ -31,10 +30,10 @@ following paths :
|
||||
In addition to this trivial function mapping, a `method` option can
|
||||
be given to the `expose` decorator. In such a case, the function
|
||||
name can be omitted by the caller, and the dispatch will look at the
|
||||
http method used in the request to select the correct function.
|
||||
HTTP method used in the request to select the correct function.
|
||||
|
||||
The function parameters can be transmitted in two ways (is using
|
||||
the http method to select the function, one way or the other
|
||||
The function parameters can be transmitted in two ways (if using
|
||||
the HTTP method to select the function, one way or the other
|
||||
may be usable) :
|
||||
|
||||
#. As a GET query string or POST form parameters.
|
||||
@ -49,7 +48,7 @@ may be usable) :
|
||||
|
||||
#. In a Json or XML encoded POST body (see below)
|
||||
|
||||
The result will be return Json or XML encoded (see below).
|
||||
The result will be returned Json or XML encoded (see below).
|
||||
|
||||
In case of error, a 400 or 500 status code is returned, and the
|
||||
response body contains details about the error (see below).
|
||||
@ -63,8 +62,8 @@ Implements a REST+Json protocol.
|
||||
|
||||
This protocol is selected if:
|
||||
|
||||
- The request content-type is either text/javascript or application/json
|
||||
- The request 'Accept' header contains 'text/javascript' or 'application.json'
|
||||
- The request content-type is either 'text/javascript' or 'application/json'
|
||||
- The request 'Accept' header contains 'text/javascript' or 'application/json'
|
||||
- A trailing '.json' is added to the path
|
||||
- A 'wsmeproto=restjson' is added in the query string
|
||||
|
||||
@ -108,11 +107,11 @@ Types
|
||||
Return
|
||||
~~~~~~
|
||||
|
||||
The json encoded result when the response code is 200, OR a json object
|
||||
The Json encoded result when the response code is 200, or a Json object
|
||||
with error properties ('faulcode', 'faultstring' and 'debuginfo' if
|
||||
available).
|
||||
available) on error.
|
||||
|
||||
For example, the /ws/person/get result looks like:
|
||||
For example, the '/ws/person/get' result looks like:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
@ -143,7 +142,7 @@ REST+XML
|
||||
|
||||
This protocol is selected if
|
||||
|
||||
- The request content-type is text/xml
|
||||
- The request content-type is 'text/xml'
|
||||
- The request 'Accept' header contains 'text/xml'
|
||||
- A trailing '.xml' is added to the path
|
||||
- A 'wsmeproto=restxml' is added in the query string
|
||||
@ -245,7 +244,7 @@ Implements the SOAP protocol.
|
||||
A wsdl definition of the webservice is available at the 'api.wsdl' subpath.
|
||||
(``/ws/api.wsdl`` in our example).
|
||||
|
||||
The protocol is selected if the request match one of the following condition:
|
||||
The protocol is selected if the request matches one of the following condition:
|
||||
|
||||
- The Content-Type is 'application/soap+xml'
|
||||
- A header 'Soapaction' is present
|
||||
|
@ -1,13 +1,13 @@
|
||||
Types
|
||||
=====
|
||||
|
||||
3 kinds of data types can be used as input or output by WSME.
|
||||
Three kinds of data types can be used as input or output by WSME.
|
||||
|
||||
Native types
|
||||
------------
|
||||
|
||||
The native types are a fixed set of standard python types that
|
||||
the different protocols will map to theirs own basic types.
|
||||
The native types are a fixed set of standard Python types that
|
||||
different protocols map to their own basic types.
|
||||
|
||||
The native types are :
|
||||
|
||||
@ -59,7 +59,7 @@ The native types are :
|
||||
def getlist(self):
|
||||
return ['a', 'b', 'c']
|
||||
|
||||
- Dictionaries -- Statically typed mapping are allowed. When exposing
|
||||
- Dictionaries -- Statically typed mappings are allowed. When exposing
|
||||
a dictionary datatype, you can specify the key and value types,
|
||||
with a restriction on the key value that must be a 'pod' type.
|
||||
Example::
|
||||
@ -67,16 +67,16 @@ The native types are :
|
||||
class SomeType(object):
|
||||
amap = {str: SomeOthertype}
|
||||
|
||||
There are other types that are supported out of the box, see
|
||||
the :ref:`pre-defined-user-types`.
|
||||
There are other types that are supported out of the box. See the
|
||||
:ref:`pre-defined-user-types`.
|
||||
|
||||
User types
|
||||
----------
|
||||
|
||||
User types allow to define new almost-native types.
|
||||
User types allow you to define new, almost-native types.
|
||||
|
||||
The idea is that you may have python data that should be transported as native
|
||||
types by the different protocols, but needs conversion to/from this basetypes,
|
||||
The idea is that you may have Python data that should be transported as base
|
||||
types by the different protocols, but needs conversion to/from these base types,
|
||||
or needs to validate data integrity.
|
||||
|
||||
To define a user type, you just have to inherit from
|
||||
@ -101,7 +101,7 @@ WSME provides some pre-defined user types:
|
||||
pre-defined list of values.
|
||||
|
||||
These types are good examples of how to define user types. Have
|
||||
a look at their source code !
|
||||
a look at their source code!
|
||||
|
||||
Here is a little example that combines :class:`binary <wsme.types.binary>`
|
||||
and :class:`Enum <wsme.types.Enum>`::
|
||||
@ -116,7 +116,7 @@ and :class:`Enum <wsme.types.Enum>`::
|
||||
.. data:: wsme.types.binary
|
||||
|
||||
The :class:`wsme.types.BinaryType` instance to use when you need to
|
||||
transfert base64 encoded data.
|
||||
transfer base64 encoded data.
|
||||
|
||||
.. autoclass:: wsme.types.BinaryType
|
||||
|
||||
@ -126,24 +126,24 @@ and :class:`Enum <wsme.types.Enum>`::
|
||||
Complex types
|
||||
-------------
|
||||
|
||||
Complex types are structured types. They are defined as simple python classes
|
||||
Complex types are structured types. They are defined as simple Python classes
|
||||
and will be mapped to adequate structured types in the various protocols.
|
||||
|
||||
A base class for structured types is proposed, :class:`wsme.types.Base`,
|
||||
but is not mandatory. The only thing it add is a default constructor.
|
||||
A base class for structured types is provided, :class:`wsme.types.Base`,
|
||||
but is not mandatory. The only thing it adds is a default constructor.
|
||||
|
||||
The attributes that are set at the class level will be used by WSME to discover
|
||||
the structure. These attributes can be:
|
||||
|
||||
- A datatype -- Any native, user or complex type.
|
||||
- A :class:`wsattr <wsme.wsattr>` -- Allow to add more information about
|
||||
- A :class:`wsattr <wsme.wsattr>` -- This allows you to add more information about
|
||||
the attribute, for example if it is mandatory.
|
||||
- A :class:`wsproperty <wsme.wsproperty>` -- Special typed property. Works
|
||||
like standard properties with additional properties like
|
||||
- A :class:`wsproperty <wsme.wsproperty>` -- A special typed property. Works
|
||||
like standard ``property`` with additional properties like
|
||||
:class:`wsattr <wsme.wsattr>`.
|
||||
|
||||
Attributes having a leading '_' in there name will be ignored, as well as the
|
||||
ones that are none of the above list. It means the type can have functions,
|
||||
Attributes having a leading '_' in their name will be ignored, as well as the
|
||||
attributes that are not in the above list. This means the type can have methods,
|
||||
they will not get in the way.
|
||||
|
||||
Example
|
||||
@ -177,10 +177,10 @@ A few things you should know about complex types:
|
||||
(and thus inspected) as soon a they are used in expose or validate,
|
||||
even if they are nested in another complex type.
|
||||
|
||||
If for some reasons you need to control when type is inspected, you
|
||||
If for some reason you need to control when type is inspected, you
|
||||
can use :func:`wsme.types.register_type`.
|
||||
|
||||
- The datatype attributes will be replaced
|
||||
- The datatype attributes will be replaced.
|
||||
|
||||
When using the 'short' way of defining attributes, ie setting a
|
||||
simple data type, they will be replaced by a wsattr instance.
|
||||
@ -207,7 +207,7 @@ A few things you should know about complex types:
|
||||
assert Person.name.key == "name"
|
||||
assert Person.name.mandatory is False
|
||||
|
||||
- The default value of instances attributes is
|
||||
- The default value of instance attributes is
|
||||
:data:`Unset <wsme.Unset>`.
|
||||
|
||||
::
|
||||
@ -218,13 +218,13 @@ A few things you should know about complex types:
|
||||
p = Person()
|
||||
assert p.name is Unset
|
||||
|
||||
This allow the protocol to make a clear distinction between null values
|
||||
This allows the protocol to make a clear distinction between null values
|
||||
that will be transmitted, and unset values that will not be transmitted.
|
||||
|
||||
For input values, it allows the code to know if the values were, or not,
|
||||
For input values, it allows the code to know if the values were, or were not,
|
||||
sent by the caller.
|
||||
|
||||
- When 2 complex types refers to each other, their names can be
|
||||
- When 2 complex types refer to each other, their names can be
|
||||
used as datatypes to avoid adding attributes afterwards:
|
||||
|
||||
::
|
||||
|
Loading…
Reference in New Issue
Block a user