Add basic documentation about glare framework
Change-Id: I92daa0b1293881cc0474e0b13cb0b99049281f8e Co-Authored-By: Idan Narotzki <idan.narotzki@nokia.com>
This commit is contained in:
parent
817d3f9735
commit
0c92788318
@ -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. Let’s 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::
|
||||
|
||||
It’s 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 method’s 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*. Let’s 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(),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user