Openstack:16, openstack-Development Foundation Stevedore Learning _openstack

Source: Internet
Author: User

The following content is from: http://blog.csdn.net/gqtcgq/article/details/49620279


Stevedore is an open source module for implementing dynamic load code. It is a public module that is used to load plug-ins in OpenStack. Can be installed independently of OpenStack: https://pypi.Python.org/pypi/stevedore/

Stevedore uses Setuptools's entry points to define and load Plug-ins. Entry point refers to objects defined in a module, such as classes, functions, instances, and so on, as long as an object can be created when the import module is made.

First: The name and namespace of the plugin

Generally speaking, the name of the entry point is public, visible to the user, and often appears in the configuration file. The namespace, also known as the entry point group name, is an implementation detail that is typically geared toward developers rather than end users. You can use the Python package name as the entry point namespace to ensure uniqueness, but this is not necessary.

The main feature of entry points is that it can be registered independently, that is, the development and installation of Plug-ins can be completely independent of the use of the application, as long as developers and users agree on the namespace and API.

Namespaces are used to search entry points. The name of the entry points must be unique in a given release package, but it may not be unique in a single namespace. That is, entry point with the same name is not allowed within the same publication package, but if it is a two separate release package, you can register the plug-in using exactly the same EntryPoint group name and entry point name.

Second: How to use Plug-ins

In stevedore, there are three ways to use Plug-ins: Drivers, Hooks, Extensions

1:drivers

A name corresponds to a entry point. Navigate to a separate plug-in based on the namespace and name of the plug-in when used:

2:hooks, a name corresponds to multiple entry point. Allows plug-ins in the same namespace to have the same name, loading multiple plug-ins corresponding to the name, given the namespace and name.

3:extensions, multiple names, multiple entry point. Given a namespace, all plug-ins in the namespace are loaded and, of course, plug-ins in the same namespace are allowed to have the same name.

Three: Define and register Plug-ins

After a great deal of experimentation and summary lessons, the easiest way to define an API is to follow the steps below:

A: Using the ABC module, create an abstract base class to define the behavior of the plug-in API, although developers do not need to inherit a base class, but this way has its own advantages;

B: Create plug-ins by inheriting base classes and implementing the necessary methods

C: Define a namespace for each API. You can combine the name of the application or library, and the name of the API, which is easy to understand, such as "cliff.formatters" or "Ceilometer.pollsters.compute".

The plug-in created in this section of the example is used to format the output of the data, each of which takes a dictionary as input, and then produces the string to be output according to certain rules. The format class can have a parameter with a maximum output width.

1: First define a base class, where the API needs to be implemented by Plug-ins

[python]  View plain  copy # example/pluginbase.py      import abc    import six       @six. Add_metaclass (ABC. Abcmeta)    class formatterbase (object):        "" Base class  for example plugin used in the tutorial. "" "           def __init__ (self, max_width=60):            self.max_width = max_width           @abc .abstractmethod       def format (self, data):             "" "format the data and return  unicode text.            :p aram data: a  Dictionary with string keys and simple types as                        values.          :type data:  dict (str:?)           :returns: Iterable producing the  formatted text.           ""   

2: Define plugin 1

Start defining specific plug-in classes that need to implement the Format method. Here is a simple plugin that produces output that is on one line.

[python]  View plain  copy # example/simple.py      import pluginbase & nbsp    class simple (pluginbase. formatterbase):        "" "a very basic formatter.        ""           def format (self, data):            "" "Format the data and return unicode  text.            :p aram data: a  dictionary with string keys and simple types as                         values.          :type data: dict (str:?)            ""            for name, value in sorted (Data.items ()):                line =  ' {Name} = {value} \ n '. Format (                    name=name,                    value=value,                )                yield  line  

3: Register the plugin 1

In this case, using "Stevedoretest.formatter" as the entry points namespace, the entry points group name, the source tree is as follows:

[Plain] View plain copy setup.py example/__init__.py pluginbase.py simple.py

The setup.py content of the release package is as follows:

[Python] View plain Copy from Setuptools Import setup, find_packages Setup (name= ' stevedoretest1 ', vers               Ion= ' 1.0 ', Packages=find_packages (), entry_points={' Stevedoretest.formatter ': [ ' Simple = Example.simple:Simple ', ' plain = Example.simple:Simple ',],},

Each entry point is registered in the form of "name = Module:importable", which is the name of the plug-in, and module is the Python module, and importable is the object that can be referenced in the module.

Two plugins are registered here, simple and plain, the Python objects referenced by the two plug-ins are the same, all example.simple:Simple classes, so plain is simply an alias.

After you have defined the setup.py, run the python setup.py install to install the publishing package. After the installation was successful, a file entry_points.txt exists in the egg directory of the publication, which reads as follows:

[Plain] View plain copy [Stevedoretest.formatter] plain = example.simple:Simple simple = Example.simple:Simple

At run time, Pkg_resources looks for plug-ins in the entry_points.txt of all installed packages, so do not edit the file manually.

4: Define plugin 2

One of the benefits of creating Plug-ins with entry points is that you can develop different plug-ins for a single application. You can therefore define a second plug-in in another release package:

[python]  View plain  copy #example2/fields.py   import textwrap      from example import pluginbase         class fieldlist ( Pluginbase. formatterbase):        "" "Format values as a restructuredtext  field list.        For example::           : name1 : value        : name2 :  value        : name3 : a long value            will be wrapped with             a hanging indent       "" "          def format (self, data):            "" "Format the data and return unicode text.             :p Aram data: a dictionary with  string keys and simple types as                        values.           :type data: dict (str:?)            ""             for name, value in sorted (Data.items ()):                full_text =  ':  {name} : {value} '. Format (                    name=name,                   value=value,                )                 wrapped_text = textwrap.fill (                    full_text,                    initial_indent= ',                     Subsequent_indent= '      ',                    width=self.max_width,                )                 yield wrapped_text +  ' \ n '   

5: Register the plugin 2

Plug-in 2 of the source tree is as follows:

[Plain] View plain copy setup.py example2/__init__.py fields.py

In setup.py, you also use "Stevedoretest.formatter" as the entry points group name, and the setup.py content of the publication package is as follows:

[Python] View plain Copy from Setuptools Import setup, find_packages Setup (name= ' stevedoretest2 ', vers               Ion= ' 1.0 ', Packages=find_packages (), entry_points={' Stevedoretest.formatter ': [ ' fields = Example2.fields:FieldList '],},

The plugin fields is registered here, and it refers to the Example2.fields:FieldList class. After you have defined the setup.py, run the python setup.py install to install the publishing package. The contents of the Entry_points.txt file in the publication are as follows:

[Plain] View plain copy [stevedoretest.formatter] fields = Example2.fields:FieldList

Four: Loading Plug-ins

1:drivers loading

The most common way to use plug-ins is to use them as separate drivers, where there can be multiple plug-ins, but only one of them is loaded and invoked, in which case the Stevedore DriverManager class can be used. Here is an example of using this class:

[python]  View Plain  copy from __future__ import print_function      import argparse      from stevedore import driver          if __name__ ==  ' __main__ ':       parser =  argparse. Argumentparser ()        parser.add_argument (             ' format ',           nargs= '? ',            default= ' simple ',            help= ' The output format ',       )        parser.add_argument (            "-- Width ',           default=60,           type=int,           help = ' Maximum output width for text ',       )         parsed_args = parser.parse_args ()            data = {            ' A ':  ' a ',             ' B ':  ' B ',             ' Long ':  ' word  '  * 80,       }          mgr = driver. DriverManager (           namespace= ' Stevedoretest.formatter ',            name=parsed_args.format,            invoke_on_load=true, &nbsP         invoke_args= (Parsed_args.width,),        )        for chunk in mgr.driver.format (data):            print (chunk, end= ')   

The parser is mainly used to parse command-line arguments, the script accepts three parameters, one is format, which is the name of the plug-in to use, which is simple by default, and the other parameter is--width, the parameter that the plug-in method may use, which defaults to 60, The script can also print help information through the--HELP parameter:

[Python] View plain copy # python load_as_driver.py--help usage:load_as_driver.py [-h] [--width width] [format] Positional arguments:format the output format optional arguments:-H,--help show this help mes Sage and exit--width width maximum output width for text

In the script, driver. DriverManager the plug-in namespace and plug-in name to find Plug-ins, that is, entry points group name and entry points itself. That is, you want to uniquely locate a plugin by name of the group name and entry point itself, but because the same entry points group can have entry point of the same name, for DriverManager, if you pass entry Points group name and entry points the name of their own found a number of registered Plug-ins, it will be an error. For example, if there are multiple publishing modules in "Stevedoretest.formatter" that register the entry point named "Simiple," the script will be executed with an error:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.