More documentation for the next release
This commit is contained in:
12
doc/api.rst
12
doc/api.rst
@@ -28,15 +28,15 @@ Internals
|
||||
.. automodule:: wsme.types
|
||||
:members: register_type
|
||||
|
||||
:mod:`wsme.controller` -- Controller
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
:mod:`wsme.api` -- API related api
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. automodule:: wsme.controller
|
||||
.. automodule:: wsme.api
|
||||
:members: scan_api, FunctionArgument, FunctionDefinition
|
||||
|
||||
:mod:`wsme.rest` -- REST protocol commons
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
:mod:`wsme.protocols.rest` -- REST protocol commons
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. automodule:: wsme.rest
|
||||
.. automodule:: wsme.protocols.rest
|
||||
:members:
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@ Changes
|
||||
* Fix: If a complex type was only used as an input type, it was
|
||||
not registered.
|
||||
|
||||
* Add support for user types.
|
||||
|
||||
* Add an Enum type (which is a user type).
|
||||
|
||||
* The 'binary' type is now a user type.
|
||||
|
||||
* Complex types:
|
||||
|
||||
- Fix inspection of complex types with inheritance.
|
||||
|
||||
@@ -9,6 +9,7 @@ Contents
|
||||
|
||||
gettingstarted
|
||||
api
|
||||
types
|
||||
protocols
|
||||
integrate
|
||||
|
||||
|
||||
184
doc/types.rst
Normal file
184
doc/types.rst
Normal file
@@ -0,0 +1,184 @@
|
||||
Types
|
||||
=====
|
||||
|
||||
3 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 :
|
||||
|
||||
- :class:`str`
|
||||
- :class:`unicode`
|
||||
- :class:`int`
|
||||
- :class:`float`
|
||||
- :class:`bool`
|
||||
- :class:`decimal.Decimal`
|
||||
- :class:`datetime.date`
|
||||
- :class:`datetime.datetime`
|
||||
- :class:`datetime.time`
|
||||
|
||||
- Arrays -- This is a special case. When stating a list
|
||||
datatype, always state its content type as the unique element
|
||||
of a list. Example::
|
||||
|
||||
class SomeWebService(object):
|
||||
@expose([str])
|
||||
def getlist(self):
|
||||
return ['a', 'b', 'c']
|
||||
|
||||
There are other types that are supported out of the boxe, see
|
||||
the :ref:`pre-defined-user-types`.
|
||||
|
||||
User types
|
||||
----------
|
||||
|
||||
User types allow 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,
|
||||
or needs to validate data integrity.
|
||||
|
||||
To define a user type, you just have to inherit from
|
||||
:class:`wsme.types.UserType` and instanciate your new class. This instance
|
||||
will be your new type and can be used as @:class:`wsme.expose` or
|
||||
@:class:`wsme.validate` parameters.
|
||||
|
||||
Note that protocols can choose to specifically handle a user type or
|
||||
a base class of user types. This is case with the two pre-defined
|
||||
user types, :class:`wsme.types.Enum` and :data:`wsme.types.binary`.
|
||||
|
||||
.. _pre-defined-user-types:
|
||||
|
||||
Pre-defined user types
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
WSME provides some pre-defined user types:
|
||||
|
||||
- :class:`binary <wsme.types.binary>` -- for transporting binary data as
|
||||
base64 strings.
|
||||
- :class:`Enum <wsme.types.Enum>` -- enforce that the values belongs to a
|
||||
pre-defined list of values.
|
||||
|
||||
These types are good examples of how to define user types. Have
|
||||
a look at their source code !
|
||||
|
||||
Here is a little example that combines :class:`binary <wsme.types.binary>`
|
||||
and :class:`Enum <wsme.types.Enum>`::
|
||||
|
||||
ImageKind = Enum(str, 'jpeg', 'gif')
|
||||
|
||||
class Image(object):
|
||||
name = unicode
|
||||
kind = ImageKind
|
||||
data = binary
|
||||
|
||||
.. data:: wsme.types.binary
|
||||
|
||||
The :class:`wsme.types.BinaryType` instance to use when you need to
|
||||
transfert base64 encoded data.
|
||||
|
||||
.. autoclass:: wsme.types.BinaryType
|
||||
|
||||
.. autoclass:: wsme.types.Enum
|
||||
|
||||
|
||||
Complex types
|
||||
-------------
|
||||
|
||||
Complex types are structured types. They are defined as simple python classes
|
||||
and will be mapped to adequate structured types in the various protocols.
|
||||
|
||||
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
|
||||
the attribute, for example if it is mandatory.
|
||||
- A :class:`wsproperty <wsme.wsproperty>` -- Special typed property. Works
|
||||
like standard properties 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,
|
||||
they will not get in the way.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
Gender = Enum(str, 'male', 'female')
|
||||
Title = Enum(str, 'M', 'Mrs')
|
||||
|
||||
class Person(object):
|
||||
lastname = wsattr(unicode, mandatory=True)
|
||||
firstname = wsattr(unicode, mandatory=True)
|
||||
|
||||
age = int
|
||||
gender = Gender
|
||||
title = Title
|
||||
|
||||
hobbies = [unicode]
|
||||
|
||||
Rules
|
||||
~~~~~
|
||||
|
||||
A few things you should know about complex types:
|
||||
|
||||
- The class must have a default constructor --
|
||||
Since instances of the type will be created by the protocols when
|
||||
used as input types, they must be instanciable without any argument.
|
||||
|
||||
- Complex types are registered automatically
|
||||
(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
|
||||
can use :func:`wsme.types.register_type`.
|
||||
|
||||
- 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.
|
||||
|
||||
So, when you write::
|
||||
|
||||
class Person(object):
|
||||
name = unicode
|
||||
|
||||
After type registration the class will actually be equivalent to::
|
||||
|
||||
class Person(object):
|
||||
name = wsattr(unicode)
|
||||
|
||||
You can still access the datatype by accessing the attribute on the
|
||||
class, along with the other wsattr properties::
|
||||
|
||||
class Person(object):
|
||||
name = unicode
|
||||
|
||||
register_type(Person)
|
||||
|
||||
assert Person.name.datatype is unicode
|
||||
assert Person.name.key == "name"
|
||||
assert Person.name.mandatory is False
|
||||
|
||||
- The default value of instances attributes is :data:`Unset <wsme.types.Unset>`.
|
||||
|
||||
::
|
||||
|
||||
class Person(object):
|
||||
name = wsattr(unicode)
|
||||
|
||||
p = Person()
|
||||
assert p.name is Unset
|
||||
|
||||
This allow 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,
|
||||
sent by the caller.
|
||||
Reference in New Issue
Block a user