Merge "Add basic documentation about glare framework"

This commit is contained in:
Jenkins 2017-06-20 12:44:36 +00:00 committed by Gerrit Code Review
commit 768360d064
1 changed files with 174 additions and 2 deletions

View File

@ -1,2 +1,174 @@
How to write an Artifact Type
=============================
How to create new Artifact Type
===============================
Basics
------
Each artifact type must realize **Glare Artifact Type Interface** (GATI)
and be inherited from ``glare.objects.base.BaseArtifact`` class.
GATI obliges to specify only one class method ``get_type_name``
that returns a string with unique artifact type name. Other methods
and fields are optional.
.. note::
Conventionally it is recommended to give names in the plural, in
lowercase, with words separated by underscores.
Example of code for minimal artifact type:
.. code-block:: python
from glare.objects import base
class HelloWorld(base.BaseArtifact):
@classmethod
def get_type_name(cls):
return "hello_worlds"
Custom artifact fields
----------------------
Users can add type specific fields to their artifact type to extend
its logic and functionality. Follow the requirements of
oslo.versionedobjects library all new fields must be placed in class
dictionary attribute called ``fields``:
.. code-block:: python
from glare.objects import base
class HelloWorld(base.BaseArtifact):
...
fields = {...}
There is a large number of possible field options. Lets look at the
most popular ones.
Fields of primitive types
^^^^^^^^^^^^^^^^^^^^^^^^^
Users are allowed to create additional fields of 5 primitive types:
* IntegerField
* FloatField
* FlexibleBooleanField
* StringField
* Link
First four are taken from oslo.versionedobjects directly, Link is a
glare-specific field which stores links in specific format to other
artifacts in the system.
.. note::
Its recommended to use FlexibleBoolean field instead of just
Boolean, because it has more sophisticated coercing. For instance,
it accepts string parameters like “true”, “yes”, “1” and so on,
and successfully coerces it to boolean value True.
Users can create their own fields with method ``init`` from Attribute class.
This methods first parameter must be an appropriate field class, other
parameters are optional and will be discussed later. In next example we
will create 5 new custom fields, one for each primitive type:
.. code-block:: python
from oslo_versionedobjects import fields
from glare.objects import base
from glare.objects.meta import wrappers
from glare.objects.meta import fields as glare_fields
Field = wrappers.Field.init
class HelloWorld(base.BaseArtifact):
@classmethod
def get_type_name(cls):
return "hello_worlds"
fields = {
'my_int': Field(fields.IntegerField),
'my_float': Field(fields.FloatField),
'my_bool': Field(fields.FlexibleBooleanField),
'my_string': Field(fields.StringField),
'my_link': Field(glare_fields.Link)
}
Compound types
^^^^^^^^^^^^^^
There are two collections, that may contain fields of primitive types:
*List* and *Dict*. Fields of compound types are created with method ``init``
of classes ListAttribute and DictAttribute respectively.
Unlike Attribute class ``init``, this method takes field type class as
a first parameter, but not just field class. So, *IntegerField* must be changed
to *Integer*, *FloatField* to *Float*, and so on. Finally for collection of
links user should use *LinkType*. Lets add several new compound fields to
*HelloWorld* class.
.. code-block:: python
from oslo_versionedobjects import fields
from glare.objects import base
from glare.objects.meta import wrappers
from glare.objects.meta import fields as glare_fields
Field = wrappers.Field.init
Dict = wrappers.DictField.init
List = wrappers.ListField.init
class HelloWorld(base.BaseArtifact):
@classmethod
def get_type_name(cls):
return "hello_worlds"
fields = {
...
'my_list_of_str': List(fields.String),
'my_dict_of_int': Dict(fields.Integer),
'my_list_of_float': List(fields.Float),
'my_dict_of_bools': Dict(fields.FlexibleBoolean),
'my_list_of_links': List(glare_fields.LinkType)
}
Other parameters, like collection max size, possible item values,
and so on, also can be specified with additional parameters to ``init``
method. They will be discussed later.
Blob and Folder types
^^^^^^^^^^^^^^^^^^^^^
The most interesting fields in glare framework are *Blob* and
*Folder* (or *BlobDict*). These fields allow users to work binary data,
which is stored in a standalone cloud storage, like Swift or Ceph.
The difference between Blob and Folder is that Blob sets unique endpoint
and may contain only one binary object, on the other hand Folder may
contain lots of binaries with names specified by user.
Example of Blob and Folder fields:
.. code-block:: python
from oslo_versionedobjects import fields
from glare.objects import base
from glare.objects.meta import wrappers
from glare.objects.meta import fields as glare_fields
Field = wrappers.Field.init
Dict = wrappers.DictField.init
List = wrappers.ListField.init
Blob = wrappers.BlobField.init
Folder = wrappers.FolderField.init
class HelloWorld(base.BaseArtifact):
@classmethod
def get_type_name(cls):
return "hello_worlds"
fields = {
...
'my_blob': Blob(),
'my_folder': Folder(),
}