Browse Source

Documentation on the lodel.plugin.datasource_plugin et lodel.plugin.exceptions modules

Roland Haroutiounian 7 years ago
parent
commit
72316b0f0a
2 changed files with 108 additions and 98 deletions
  1. 105
    98
      lodel/plugin/datasource_plugin.py
  2. 3
    0
      lodel/plugin/exceptions.py

+ 105
- 98
lodel/plugin/datasource_plugin.py View File

@@ -1,3 +1,8 @@
1
+## @package lodel.plugin.datasource_plugin Datasource plugins management module
2
+#
3
+# It contains the base classes for all the datasource plugins that could be added to Lodel
4
+
5
+
1 6
 from lodel.context import LodelContext
2 7
 LodelContext.expose_modules(globals(), {
3 8
     'lodel.plugin.plugins': ['Plugin'],
@@ -7,58 +12,61 @@ LodelContext.expose_modules(globals(), {
7 12
     'lodel.exceptions': ['LodelException', 'LodelExceptions',
8 13
         'LodelFatalError', 'DataNoneValid', 'FieldValidationError']})
9 14
 
15
+## @brief The plugin type that is used in the global settings of Lodel
10 16
 _glob_typename = 'datasource'
11 17
 
12 18
 
13
-##@brief Datasource class in plugins HAVE TO inherit from this abstract class
19
+## @brief Main abstract class from which the plugins' datasource classes must inherit.
14 20
 class AbstractDatasource(object):
15 21
     
16
-    ##@brief Trigger LodelFatalError when abtract method called
22
+    ## @brief Trigger LodelFatalError when abtract method called
23
+    # @throw LodelFatalError if there is an attempt to instanciate an object from this class
17 24
     @staticmethod
18 25
     def _abs_err():
19 26
         raise LodelFatalError("This method is abstract and HAVE TO be \
20 27
 reimplemented by plugin datasource child class")
21 28
     
22
-    ##@brief The constructor
29
+    ##
30
+    # @param *conn_args
31
+    # @param **conn_kwargs
23 32
     def __init__(self, *conn_args, **conn_kwargs):
24 33
         self._abs_err()
25 34
 
26
-    ##@brief Provide a new uniq numeric ID
27
-    #@param emcomp LeObject subclass (not instance) : To know on wich things we
28
-    #have to be uniq
29
-    #@return an integer
35
+    ## @brief Provides a new uniq numeric ID
36
+    # @param emcomp LeObject subclass (not instance) : defines against which objects type the id should be unique
37
+    # @return int
30 38
     def new_numeric_id(self, emcomp):
31 39
         self._abs_err()
32 40
 
33
-    ##@brief returns a selection of documents from the datasource
34
-    #@param target Emclass
35
-    #@param field_list list
36
-    #@param filters list : List of filters
37
-    #@param rel_filters list : List of relational filters
38
-    #@param order list : List of column to order. ex: order = [('title', 'ASC'),]
39
-    #@param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),]
40
-    #@param limit int : Number of records to be returned
41
-    #@param offset int: used with limit to choose the start record
42
-    #@param instanciate bool : If true, the records are returned as instances, else they are returned as dict
43
-    #@return list
41
+    ## @brief Returns a selection of documents from the datasource
42
+    # @param target Emclass : class of the documents
43
+    # @param field_list list : fields to get from the datasource
44
+    # @param filters list : List of filters
45
+    # @param rel_filters list : List of relational filters (default value : None)
46
+    # @param order list : List of column to order. ex: order = [('title', 'ASC'),] (default value : None)
47
+    # @param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),] (default value : None)
48
+    # @param limit int : Number of records to be returned (default value None)
49
+    # @param offset int: used with limit to choose the start record (default value : 0)
50
+    # @param instanciate bool : If true, the records are returned as instances, else they are returned as dict (default value : True)
51
+    # @return list
44 52
     def select(self, target, field_list, filters, rel_filters=None, order=None, group=None, limit=None, offset=0,
45 53
                instanciate=True):
46 54
         self._abs_err()
47 55
 
48
-    ##@brief Deletes records according to given filters
49
-    #@param target Emclass : class of the record to delete
50
-    #@param filters list : List of filters
51
-    #@param relational_filters list : List of relational filters
52
-    #@return int : number of deleted records
56
+    ## @brief Deletes records according to given filters
57
+    # @param target Emclass : class of the record to delete
58
+    # @param filters list : List of filters
59
+    # @param relational_filters list : List of relational filters
60
+    # @return int : number of deleted records
53 61
     def delete(self, target, filters, relational_filters):
54 62
         self._abs_err()
55 63
 
56 64
     ## @brief updates records according to given filters
57
-    #@param target Emclass : class of the object to insert
58
-    #@param filters list : List of filters
59
-    #@param relational_filters list : List of relational filters
60
-    #@param upd_datas dict : datas to update (new values)
61
-    #@return int : Number of updated records
65
+    # @param target Emclass : class of the object to insert
66
+    # @param filters list : List of filters
67
+    # @param relational_filters list : List of relational filters
68
+    # @param upd_datas dict : datas to update (new values)
69
+    # @return int : Number of updated records
62 70
     def update(self, target, filters, relational_filters, upd_datas):
63 71
         self._abs_err()
64 72
 
@@ -77,22 +85,21 @@ reimplemented by plugin datasource child class")
77 85
         self._abs_err()
78 86
 
79 87
 
80
-##@brief Designed to handles datasources plugins
88
+## @brief Represents a Datasource plugin
81 89
 #
82
-#A datasource provide data access to LeAPI typically a connector on a DB
83
-#or an API
90
+# It will provide an access to a data collection to LeAPI (i.e. database connector, API ...).
84 91
 #
85
-#Provide methods to initialize datasource attribute in LeAPI LeObject child
86
-#classes (see @ref leapi.leobject.LeObject._init_datasources() )
92
+# It provides the methods needed to initialize the datasource attribute in LeAPI LeObject child
93
+# classes (see @ref leapi.leobject.LeObject._init_datasources() )
87 94
 #
88
-#@note For the moment implementation is done with a retro-compatibilities
89
-#priority and not with a convenience priority.
90
-#@todo Refactor and rewrite lodel2 datasource handling
91
-#@todo Write abstract classes for Datasource and MigrationHandler !!!
95
+# @note For the moment implementation is done with a retro-compatibilities priority and not with a convenience priority.
96
+# @todo Refactor and rewrite lodel2 datasource handling
97
+# @todo Write abstract classes for Datasource and MigrationHandler !!!
92 98
 class DatasourcePlugin(Plugin):
93 99
     
94 100
     _type_conf_name = _glob_typename
95
-    ##@brief Stores confspecs indicating where DatasourcePlugin list is stored
101
+  
102
+    ## @brief Stores confspecs indicating where DatasourcePlugin list is stored
96 103
     _plist_confspecs = {
97 104
         'section': 'lodel2',
98 105
         'key': 'datasource_connectors',
@@ -104,15 +111,17 @@ class DatasourcePlugin(Plugin):
104 111
                 'none_is_valid': False})
105 112
         }
106 113
  
107
-    ##@brief Construct a DatasourcePlugin 
108
-    #@param name str : plugin name
109
-    #@see plugins.Plugin
114
+    ##
115
+    # @param name str : plugin's name
116
+    # @see plugins.Plugin
110 117
     def __init__(self, name):
111 118
         super().__init__(name)
112 119
         self.__datasource_cls = None
113 120
     
114
-    ##@brief Accessor to the datasource class
115
-    #@return A python datasource class
121
+    ## @brief Returns an accessor to the datasource class
122
+    # @return A python datasource class
123
+    # @throw DatasourcePluginError if the plugin's datasource class is not a child of 
124
+    # @ref lodel.plugin.datasource_plugin.AbstractDatasource
116 125
     def datasource_cls(self):
117 126
         if self.__datasource_cls is None:
118 127
             self.__datasource_cls = self.loader_module().Datasource
@@ -122,17 +131,15 @@ class DatasourcePlugin(Plugin):
122 131
 lodel.plugin.datasource_plugin.AbstractDatasource" % (self.name))
123 132
         return self.__datasource_cls
124 133
     
125
-    ##@brief Accessor to migration handler class
126
-    #@return A python migration handler class
134
+    ## @brief Returns an accessor to migration handler class
135
+    # @return A python migration handler class
127 136
     def migration_handler_cls(self):
128 137
         return self.loader_module().migration_handler_class()
129 138
 
130
-    ##@brief Return an initialized Datasource instance
131
-    #@param ds_name str : The name of the datasource to instanciate
132
-    #@param ro bool
133
-    #@return A properly initialized Datasource instance
134
-    #@throw SettingsError if an error occurs in settings
135
-    #@throw DatasourcePluginError for various errors
139
+    ## @brief Returns an initialized Datasource instance
140
+    # @param ds_name str : The name of the datasource to instanciate
141
+    # @param ro bool : indicates if it will be in read only mode, else it will be in write only mode
142
+    # @return A properly initialized Datasource instance
136 143
     @classmethod
137 144
     def init_datasource(cls, ds_name, ro):
138 145
         plugin_name, ds_identifier = cls.plugin_name(ds_name, ro)
@@ -140,9 +147,10 @@ lodel.plugin.datasource_plugin.AbstractDatasource" % (self.name))
140 147
         ds_cls = cls.get_datasource(plugin_name)
141 148
         return ds_cls(**ds_conf)
142 149
     
143
-    ##@brief Return an initialized MigrationHandler instance
144
-    #@param ds_name str : The datasource name
145
-    #@return A properly initialized MigrationHandler instance
150
+    ## @brief Returns an initialized MigrationHandler instance
151
+    # @param ds_name str : The datasource name
152
+    # @return A properly initialized MigrationHandler instance
153
+    # @throw PluginError if a read only datasource instance was given to the migration handler. 
146 154
     @classmethod
147 155
     def init_migration_handler(cls, ds_name):
148 156
         plugin_name, ds_identifier = cls.plugin_name(ds_name, False)
@@ -156,13 +164,12 @@ migration handler !!!")
156 164
         return mh_cls(**ds_conf)
157 165
 
158 166
 
159
-    ##@brief Given a datasource name returns a DatasourcePlugin name
160
-    #@param ds_name str : datasource name
161
-    #@param ro bool : if true consider the datasource as readonly
162
-    #@return a DatasourcePlugin name
163
-    #@throw PluginError if datasource name not found
164
-    #@throw DatasourcePermError if datasource is read_only but ro flag arg is
165
-    #false
167
+    ## @brief Given a datasource name returns a DatasourcePlugin name
168
+    # @param ds_name str : datasource name
169
+    # @param ro bool : if true consider the datasource as readonly
170
+    # @return a DatasourcePlugin name
171
+    # @throw DatasourcePluginError if the given datasource is unknown or not configured, or if there is a conflict in its "read-only" property (between the instance and the settings).
172
+    # @throw SettingsError if there are misconfigured datasource settings.
166 173
     @staticmethod
167 174
     def plugin_name(ds_name, ro):
168 175
         LodelContext.expose_modules(globals(), {
@@ -195,11 +202,11 @@ True found in settings for datasource '%s'" % ds_name)
195 202
 DS_PLUGIN_NAME.DS_INSTANCE_NAME. But got %s" % ds_identifier)
196 203
         return res
197 204
 
198
-    ##@brief Try to fetch a datasource configuration
199
-    #@param ds_identifier str : datasource name
200
-    #@param ds_plugin_name : datasource plugin name
201
-    #@return a dict containing datasource initialisation options
202
-    #@throw NameError if a datasource plugin or instance cannot be found
205
+    ## @brief Returns a datasource's configuration
206
+    # @param ds_identifier str : datasource name
207
+    # @param ds_plugin_name : datasource plugin name
208
+    # @return a dict containing datasource initialisation options
209
+    # @throw DatasourcePluginError if a datasource plugin or instance cannot be found
203 210
     @staticmethod
204 211
     def _get_ds_connection_conf(ds_identifier,ds_plugin_name):
205 212
         LodelContext.expose_modules(globals(), {
@@ -216,56 +223,55 @@ DS_PLUGIN_NAME.DS_INSTANCE_NAME. But got %s" % ds_identifier)
216 223
         ds_conf = getattr(ds_conf, ds_identifier)
217 224
         return {k: getattr(ds_conf,k) for k in ds_conf._fields }
218 225
 
219
-    ##@brief DatasourcePlugin instance accessor
220
-    #@param ds_name str : plugin name
221
-    #@return a DatasourcePlugin instance
222
-    #@throw PluginError if no plugin named ds_name found
223
-    #@throw PluginTypeError if ds_name ref to a plugin that is not a 
224
-    #DatasourcePlugin
226
+    ## @brief Returns a DatasourcePlugin instance from a plugin's name
227
+    # @param ds_name str : plugin name
228
+    # @return DatasourcePlugin
229
+    # @throw PluginError if no plugin named ds_name found (@see lodel.plugin.plugins.Plugin)
230
+    # @throw PluginTypeError if ds_name ref to a plugin that is not a DatasourcePlugin
225 231
     @classmethod
226 232
     def get(cls, ds_name):
227
-        pinstance = super().get(ds_name) #Will raise PluginError if bad name
233
+        pinstance = super().get(ds_name)  # Will raise PluginError if bad name
228 234
         if not isinstance(pinstance, DatasourcePlugin):
229 235
            raise PluginTypeErrror("A name of a DatasourcePlugin was excepted \
230 236
 but %s is a %s" % (ds_name, pinstance.__class__.__name__))
231 237
         return pinstance
232 238
 
233
-    ##@brief Return a datasource class given a datasource name
234
-    #@param ds_plugin_name str : datasource plugin name
235
-    #@throw PluginError if ds_name is not an existing plugin name
236
-    #@throw PluginTypeError if ds_name is not the name of a DatasourcePlugin
239
+    ## @brief Returns a datasource class given a datasource name
240
+    # @param ds_plugin_name str : datasource plugin name
241
+    # @return Datasource class
237 242
     @classmethod
238 243
     def get_datasource(cls, ds_plugin_name):
239 244
         return cls.get(ds_plugin_name).datasource_cls()
240 245
     
241
-    ##@brief Given a plugin name returns a migration handler class
242
-    #@param ds_plugin_name str : a datasource plugin name
246
+    ## @brief Returns a migration handler class, given a plugin name
247
+    # @param ds_plugin_name str : a datasource plugin name
248
+    # @return MigrationHandler class
243 249
     @classmethod
244 250
     def get_migration_handler(cls, ds_plugin_name):
245 251
         return cls.get(ds_plugin_name).migration_handler_cls()
246 252
 
247 253
 
248
-##@page lodel2_datasources Lodel2 datasources
254
+## @page lodel2_datasources Lodel2 datasources
249 255
 #
250
-#@par lodel2_datasources_intro Intro
256
+# @par lodel2_datasources_intro Introduction
251 257
 # A single lodel2 website can interact with multiple datasources. This page
252
-# aims to describe configuration & organisation of datasources in lodel2.
258
+# aims to describe configuration and organisation of datasources in lodel2.
253 259
 # Each object is attached to a datasource. This association is done in the
254
-# editorial model, the datasource is identified by a name.
260
+# editorial model, in which the datasource is identified by its name.
255 261
 #
256
-#@par Datasources declaration
257
-# To define a datasource you have to write something like this in confs file :
258
-#<pre>
259
-#[lodel2.datasources.DATASOURCE_NAME]
260
-#identifier = DATASOURCE_FAMILY.SOURCE_NAME
261
-#</pre>
262
-# See below for DATASOURCE_FAMILY & SOURCE_NAME
262
+# @par Datasources declaration
263
+# To define a datasource you have to write something like this in configuration file :
264
+# <pre>
265
+# [lodel2.datasources.DATASOURCE_NAME]
266
+# identifier = DATASOURCE_FAMILY.SOURCE_NAME
267
+# </pre>
268
+#  See below for DATASOURCE_FAMILY & SOURCE_NAME
263 269
 #
264
-#@par Datasources plugins
265
-# Each datasource family is a plugin ( 
266
-#@ref plugin_doc "More informations on plugins" ). For example mysql or a 
267
-#mongodb plugins. Here is the CONFSPEC variable templates for datasources 
268
-#plugin
270
+# @par Datasources plugins
271
+# Each datasource family is a plugin ( @ref plugin_doc "More informations on plugins" ). 
272
+# For example mysql or a mongodb plugins. \n
273
+#
274
+# Here is the CONFSPEC variable templates for datasources plugin
269 275
 #<pre>
270 276
 #CONFSPEC = {
271 277
 #                'lodel2.datasource.example.*' : {
@@ -275,7 +281,8 @@ but %s is a %s" % (ds_name, pinstance.__class__.__name__))
275 281
 #                }
276 282
 #}
277 283
 #</pre>
278
-#MySQL example
284
+# 
285
+#MySQL example \n
279 286
 #<pre>
280 287
 #CONFSPEC = {
281 288
 #                'lodel2.datasource.mysql.*' : {
@@ -291,8 +298,8 @@ but %s is a %s" % (ds_name, pinstance.__class__.__name__))
291 298
 #}
292 299
 #</pre>
293 300
 #
294
-#@par Configuration example
295
-#<pre>
301
+# @par Configuration example
302
+# <pre>
296 303
 # [lodel2.datasources.main]
297 304
 # identifier = mysql.Core
298 305
 # [lodel2.datasources.revues_write]

+ 3
- 0
lodel/plugin/exceptions.py View File

@@ -1,3 +1,6 @@
1
+## @package lodel.plugin.exceptions Plugin management specific exceptions
2
+
3
+
1 4
 class PluginError(Exception):
2 5
     pass
3 6
 

Loading…
Cancel
Save