Add documentation - part 3
Document REST v2 with autodocs Change-Id: Ib43d2237ebb0f8ef9f8d18e70182d7cc5f2f0828
This commit is contained in:
parent
2f6f95b19b
commit
b8390eb84d
24
doc/README.md
Normal file
24
doc/README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Sphinx DOC hints
|
||||||
|
|
||||||
|
## Migrating from Openstack Wiki
|
||||||
|
|
||||||
|
* Install pandoc
|
||||||
|
* Copy wiki code into a file, e.g. `source.mw`
|
||||||
|
* Convert to .rst
|
||||||
|
|
||||||
|
pandoc --from=mediawiki --to=rst --output=doc/source/dsl/dsl_v1.rst doc/source/dsl/source.mw
|
||||||
|
|
||||||
|
* To make code samples fancy:
|
||||||
|
|
||||||
|
TODO: figure how to make YAML samples look nicer with `code::` directive
|
||||||
|
|
||||||
|
## Using autodoc with sphinxcontrib.pecanwsme.rest and wsmeext.sphinxext plugins
|
||||||
|
|
||||||
|
TODO: why REST URL is not generated with parameters?
|
||||||
|
|
||||||
|
## Running sphinx-audobuild
|
||||||
|
|
||||||
|
[auto-loader](https://pypi.python.org/pypi/sphinx-autobuild/0.2.3) - rules for convenient development https://pypi.python.org/pypi/sphinx-autobuild/0.2.3. install, and run:
|
||||||
|
|
||||||
|
sphinx-autobuild doc/source doc/build
|
||||||
|
|
@ -28,7 +28,7 @@ extensions = [
|
|||||||
'wsmeext.sphinxext',
|
'wsmeext.sphinxext',
|
||||||
]
|
]
|
||||||
|
|
||||||
wsme_protocols = ['restjson', 'restxml']
|
wsme_protocols = ['restjson']
|
||||||
|
|
||||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||||
# text edit cycles.
|
# text edit cycles.
|
||||||
|
@ -1,3 +1,102 @@
|
|||||||
V2 API
|
V2 API
|
||||||
======
|
======
|
||||||
|
|
||||||
|
.. warning:: (2014-10-5): API described in this document might slightly change within a short period of time (2-3 weeks) and should be now considered experimental. Mistral team is now actively working on stabilization.
|
||||||
|
|
||||||
|
This API describes the ways of interacting with Mistral service via HTTP protocol using Representational State Transfer concept (ReST).
|
||||||
|
|
||||||
|
|
||||||
|
Basics
|
||||||
|
-------
|
||||||
|
|
||||||
|
|
||||||
|
Media Types
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Currently this API relies on JSON to represent states of REST resources.
|
||||||
|
|
||||||
|
Error States
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The common HTTP Response Status Codes (https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md) are used.
|
||||||
|
|
||||||
|
Application Root [/]
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Application Root provides links to all possible API methods for Mistral. URLs for other resources described below are relative to Application Root.
|
||||||
|
|
||||||
|
API v2 Root [/v2/]
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
All API v2 urls are relative to API v2 root.
|
||||||
|
|
||||||
|
Workbooks
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.workbook.Workbook
|
||||||
|
:members:
|
||||||
|
|
||||||
|
`name` is immutable. tags is a list of values associated with a workbook that a user can use to group workbooks by some criteria (deployment workbooks, Big Data processing workbooks etc.). Note that name and tags get inferred from workbook definition when Mistral service receives a POST request. So they can't be changed in another way.
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.workbook.Workbooks
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. rest-controller:: mistral.api.controllers.v2.workbook:WorkbooksController
|
||||||
|
:webprefix: /v2/workbooks
|
||||||
|
|
||||||
|
|
||||||
|
Workflows
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.workflow.Workflow
|
||||||
|
:members:
|
||||||
|
|
||||||
|
`name` is immutable. tags is a list of values associated with a workflow that a user can use to group workflows by some criteria. Note that name and tags get inferred from workflow definition when Mistral service receives a POST request. So they can't be changed in another way.
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.workflow.Workflows
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. rest-controller:: mistral.api.controllers.v2.workflow:WorkflowsController
|
||||||
|
:webprefix: /v2/workflows
|
||||||
|
|
||||||
|
Actions
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.action.Action
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.action.Actions
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. rest-controller:: mistral.api.controllers.v2.action:ActionsController
|
||||||
|
:webprefix: /v2/actions
|
||||||
|
|
||||||
|
|
||||||
|
Executions
|
||||||
|
------------
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.execution.Execution
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.execution.Executions
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. rest-controller:: mistral.api.controllers.v2.execution:ExecutionsController
|
||||||
|
:webprefix: /v2/executions
|
||||||
|
|
||||||
|
|
||||||
|
Tasks
|
||||||
|
------------
|
||||||
|
|
||||||
|
When a workflow starts Mistral creates an execution. It in turn consists of a set of tasks. So Task is an instance of a task described in a Workflow that belongs to a particular execution.
|
||||||
|
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.task.Task
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autotype:: mistral.api.controllers.v2.task.Tasks
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. rest-controller:: mistral.api.controllers.v2.task:TasksController
|
||||||
|
:webprefix: /v2/tasks
|
||||||
|
|
||||||
|
.. rest-controller:: mistral.api.controllers.v2.task:ExecutionTasksController
|
||||||
|
:webprefix: /v2/executions
|
@ -30,7 +30,13 @@ SCOPE_TYPES = wtypes.Enum(str, 'private', 'public')
|
|||||||
|
|
||||||
|
|
||||||
class Action(resource.Resource):
|
class Action(resource.Resource):
|
||||||
"""Action resource."""
|
"""Action resource.
|
||||||
|
|
||||||
|
NOTE: *name* is immutable. Note that name and description get inferred
|
||||||
|
from action definition when Mistral service receives a POST request.
|
||||||
|
So they can't be changed in another way.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
id = wtypes.text
|
id = wtypes.text
|
||||||
name = wtypes.text
|
name = wtypes.text
|
||||||
@ -49,7 +55,7 @@ class Action(resource.Resource):
|
|||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
||||||
name='flow',
|
name='flow',
|
||||||
definition='---',
|
definition='HERE GOES ACTION DEFINITION IN MISTRAL DSL v2',
|
||||||
tags=['large', 'expensive'],
|
tags=['large', 'expensive'],
|
||||||
scope='private',
|
scope='private',
|
||||||
created_at='1970-01-01T00:00:00.000000',
|
created_at='1970-01-01T00:00:00.000000',
|
||||||
|
@ -34,18 +34,28 @@ class Execution(resource.Resource):
|
|||||||
"""Execution resource."""
|
"""Execution resource."""
|
||||||
|
|
||||||
id = wtypes.text
|
id = wtypes.text
|
||||||
|
"id is immutable and auto assigned."
|
||||||
|
|
||||||
workflow_name = wtypes.text
|
workflow_name = wtypes.text
|
||||||
|
"reference to workflow definition"
|
||||||
|
|
||||||
params = wtypes.text
|
params = wtypes.text
|
||||||
|
"params define workflow type specific parameters. For example, reverse \
|
||||||
|
workflow takes one parameter 'task_name' that defines a target task."
|
||||||
|
|
||||||
state = wtypes.text
|
state = wtypes.text
|
||||||
# Context is a JSON object but since WSME doesn't support arbitrary
|
"state can be one of: RUNNING, SUCCESS, ERROR, PAUSED"
|
||||||
# dictionaries we have to use text type convert to json and back manually.
|
|
||||||
input = wtypes.text
|
input = wtypes.text
|
||||||
|
"input is a JSON structure containing workflow input values."
|
||||||
output = wtypes.text
|
output = wtypes.text
|
||||||
|
"output is a workflow output."
|
||||||
|
|
||||||
created_at = wtypes.text
|
created_at = wtypes.text
|
||||||
updated_at = wtypes.text
|
updated_at = wtypes.text
|
||||||
|
|
||||||
|
# Context is a JSON object but since WSME doesn't support arbitrary
|
||||||
|
# dictionaries we have to use text type convert to json and back manually.
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
d = super(Execution, self).to_dict()
|
d = super(Execution, self).to_dict()
|
||||||
|
|
||||||
@ -110,10 +120,15 @@ class ExecutionsController(rest.RestController):
|
|||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(Execution, wtypes.text, body=Execution)
|
@wsme_pecan.wsexpose(Execution, wtypes.text, body=Execution)
|
||||||
def put(self, id, execution):
|
def put(self, id, execution):
|
||||||
"""Update the specified Execution."""
|
"""Update the specified Execution.
|
||||||
|
|
||||||
|
:param id: execution ID.
|
||||||
|
:param execution: Execution objects
|
||||||
|
"""
|
||||||
LOG.debug("Update execution [id=%s, execution=%s]" %
|
LOG.debug("Update execution [id=%s, execution=%s]" %
|
||||||
(id, execution))
|
(id, execution))
|
||||||
|
|
||||||
|
# TODO(dzimine): Why update execution? We must only pause and resume.
|
||||||
db_model = db_api.update_execution(id, execution.to_dict())
|
db_model = db_api.update_execution(id, execution.to_dict())
|
||||||
|
|
||||||
return Execution.from_dict(db_model.to_dict())
|
return Execution.from_dict(db_model.to_dict())
|
||||||
@ -121,7 +136,10 @@ class ExecutionsController(rest.RestController):
|
|||||||
@rest_utils.wrap_wsme_controller_exception
|
@rest_utils.wrap_wsme_controller_exception
|
||||||
@wsme_pecan.wsexpose(Execution, body=Execution, status_code=201)
|
@wsme_pecan.wsexpose(Execution, body=Execution, status_code=201)
|
||||||
def post(self, execution):
|
def post(self, execution):
|
||||||
"""Create a new Execution."""
|
"""Create a new Execution.
|
||||||
|
|
||||||
|
:param execution: Execution object with input content.
|
||||||
|
"""
|
||||||
LOG.debug("Create execution [execution=%s]" % execution)
|
LOG.debug("Create execution [execution=%s]" % execution)
|
||||||
|
|
||||||
engine = rpc.get_engine_client()
|
engine = rpc.get_engine_client()
|
||||||
|
@ -45,8 +45,10 @@ class Task(resource.Resource):
|
|||||||
execution_id = wtypes.text
|
execution_id = wtypes.text
|
||||||
|
|
||||||
state = wtypes.text
|
state = wtypes.text
|
||||||
result = wtypes.text
|
"state can take one of the following values: \
|
||||||
|
IDLE, RUNNING, SUCCESS, ERROR, DELAYED"
|
||||||
|
|
||||||
|
result = wtypes.text
|
||||||
input = wtypes.text
|
input = wtypes.text
|
||||||
output = wtypes.text
|
output = wtypes.text
|
||||||
|
|
||||||
|
@ -35,8 +35,10 @@ class Workbook(resource.Resource):
|
|||||||
name = wtypes.text
|
name = wtypes.text
|
||||||
|
|
||||||
definition = wtypes.text
|
definition = wtypes.text
|
||||||
|
"workbook definition in Mistral v2 DSL"
|
||||||
tags = [wtypes.text]
|
tags = [wtypes.text]
|
||||||
scope = SCOPE_TYPES
|
scope = SCOPE_TYPES
|
||||||
|
"'private' or 'public'"
|
||||||
|
|
||||||
created_at = wtypes.text
|
created_at = wtypes.text
|
||||||
updated_at = wtypes.text
|
updated_at = wtypes.text
|
||||||
@ -45,7 +47,8 @@ class Workbook(resource.Resource):
|
|||||||
def sample(cls):
|
def sample(cls):
|
||||||
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
||||||
name='book',
|
name='book',
|
||||||
definition='---',
|
definition='HERE GOES'
|
||||||
|
'WORKBOOK DEFINITION IN MISTRAL DSL v2',
|
||||||
tags=['large', 'expensive'],
|
tags=['large', 'expensive'],
|
||||||
scope='private',
|
scope='private',
|
||||||
created_at='1970-01-01T00:00:00.000000',
|
created_at='1970-01-01T00:00:00.000000',
|
||||||
|
@ -36,8 +36,10 @@ class Workflow(resource.Resource):
|
|||||||
input = wtypes.text
|
input = wtypes.text
|
||||||
|
|
||||||
definition = wtypes.text
|
definition = wtypes.text
|
||||||
|
"Workflow definition in Mistral v2 DSL"
|
||||||
tags = [wtypes.text]
|
tags = [wtypes.text]
|
||||||
scope = SCOPE_TYPES
|
scope = SCOPE_TYPES
|
||||||
|
"'private' or 'public'"
|
||||||
|
|
||||||
created_at = wtypes.text
|
created_at = wtypes.text
|
||||||
updated_at = wtypes.text
|
updated_at = wtypes.text
|
||||||
@ -47,7 +49,8 @@ class Workflow(resource.Resource):
|
|||||||
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
||||||
name='flow',
|
name='flow',
|
||||||
input='param1, param2',
|
input='param1, param2',
|
||||||
definition='---',
|
definition='HERE GOES'
|
||||||
|
'WORKFLOW DEFINITION IN MISTRAL DSL v2',
|
||||||
tags=['large', 'expensive'],
|
tags=['large', 'expensive'],
|
||||||
scope='private',
|
scope='private',
|
||||||
created_at='1970-01-01T00:00:00.000000',
|
created_at='1970-01-01T00:00:00.000000',
|
||||||
|
Loading…
Reference in New Issue
Block a user