Minor documentation edits

Change-Id: I0f8049241ffd870a4dac405fa0ca53fb122f2181
This commit is contained in:
Dustin J. Mitchell 2014-06-20 15:24:22 -04:00
parent 2c29787386
commit 4441ca74a9
6 changed files with 88 additions and 86 deletions

View File

@ -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 ?
~~~~~~~~~~

View File

@ -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:

View File

@ -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
~~~~~~~~~~~~~~~~~~~~~

View File

@ -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

View File

@ -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

View File

@ -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:
::