Codebase list python-lml / d475893 docs / source / api_tutorial.rst
d475893

Tree @d475893 (Download .tar.gz)

api_tutorial.rst @d475893view markup · raw · history · blame

Robot Chef version 2: Use lml to write a shared library

In previous chapter, lml was used to split all in one Robot Chef into one core package and several plugins module and packages. In this chapter, we are going to go one step further to split the core package into two so as to showcase how to use lml to write a shared api library.

_static/images/robotchef_api_crd.svg

Demo

Please checkout the following examples:

$ virtualenv --no-site-packages robotchefv2
$ source robotchefv2/bin/activate
$ git clone https://github.com/python-lml/robotchef_v2
$ cd robotchef_v2
$ python setup.py install
$ cd ..
$ git clone https://github.com/python-lml/robotchef_api
$ cd robotchef_api
$ python setup.py install

And then you can type in and test the second version of Robot Chef:

$ robotchef_v2 "Portable Battery"
I can cook Portable Battery for robots
$ robotchef_v2 "Jacket Potato"
I do not know how to cook Jacket Potato

In order to add "Jacket Potato" in the know-how, you would need to install robotchef_britishcuisine in this folder:

$ git clone https://github.com/python-lml/robotchef_britishcuisine_v2
$ cd robotchef_britishcuisine_v2
$ python setup.py install
$ robotchef_v2 "Jacket Potato"
I can bake Jacket Potato

Robot Chef v2 code

Let us look at main code robotchef_v2:

System Message: INFO/1 (<string>, line 47)

No directive entry for "literalinclude" in module "docutils.parsers.rst.languages.en". Trying "literalinclude" as canonical directive name.

System Message: ERROR/3 (<string>, line 47)

Unknown directive type "literalinclude".

.. literalinclude:: ../../examples/v2/robotchef_v2/robotchef_v2/main.py
  :diff: ../../examples/robotchef/robotchef/main.py


The code highlighted in red are removed from main.py and are placed into robotchef_api package. And robotchef_v2 becomes the consumer of the robotchef api.

And plugin.py and robot_cuisine has been moved to robotchef_api package.

Robot Chef API

Now let us look at robotchef_api. In the following directory listing, the plugin.py And robot_cuisine is exactly the same as the :ref:`plugin.py <plugin>` and :ref:`robot_cuisine <builtin_plugin>` in robotchef:

System Message: INFO/1 (<string>, line 60)

No role entry for "ref" in module "docutils.parsers.rst.languages.en". Trying "ref" as canonical role name.

System Message: ERROR/3 (<string>, line 60); backlink

Unknown interpreted text role "ref".

System Message: INFO/1 (<string>, line 60)

No role entry for "ref" in module "docutils.parsers.rst.languages.en". Trying "ref" as canonical role name.

System Message: ERROR/3 (<string>, line 60); backlink

Unknown interpreted text role "ref".
__init__.py    plugin.py       robot_cuisine

Notably, the plugin loader is put in the __init__.py:

System Message: INFO/1 (<string>, line 68)

No directive entry for "literalinclude" in module "docutils.parsers.rst.languages.en". Trying "literalinclude" as canonical directive name.

System Message: ERROR/3 (<string>, line 68)

Unknown directive type "literalinclude".

.. literalinclude:: ../../examples/v2/robotchef_api/robotchef_api/__init__.py
  :language: python

scan_plugins_regex here loads all modules that start with "robotchef_" and as well as the module robotchef_api.robot_cuisine in the white_list.

This is how you will write the main component as a library.

Built-in plugin and Standalone plugin

You may have noticed that a copy of robotchef_britishcuisine is placed in v2 directory. Why not using the same one above v2 directory? although they are almost identical, there is a minor difference. robotchef_britishcuisine in v2 directory depends on robotchef_api but the other British cuisine package depends on robotchef. Hence, if you look at the fry.py in v2 directory, you will notice a slight difference:

System Message: INFO/1 (<string>, line 85)

No directive entry for "literalinclude" in module "docutils.parsers.rst.languages.en". Trying "literalinclude" as canonical directive name.

System Message: ERROR/3 (<string>, line 85)

Unknown directive type "literalinclude".

.. literalinclude:: ../../examples/v2/robotchef_britishcuisine/robotchef_britishcuisine/fry.py
  :diff: ../../examples/robotchef_britishcuisine/robotchef_britishcuisine/fry.py

Docutils System Messages

System Message: ERROR/3 (<string>, line 71); backlink

Unknown target name: "robotchef".