|
21 | 21 | ## granted to it by virtue of its status as an Intergovernmental Organization |
22 | 22 | ## or submit itself to any jurisdiction. |
23 | 23 |
|
24 | | -""" |
25 | | -Flask extension |
26 | | -=============== |
| 24 | +"""Flask extension. |
27 | 25 |
|
28 | 26 | Flask-Registry is initialized like this: |
29 | 27 |
|
30 | | ->>> from flask import Flask |
31 | | ->>> from flask_registry import Registry, ListRegistry |
32 | | ->>> app = Flask('myapp') |
33 | | ->>> r = Registry(app=app) |
34 | | -
|
35 | | -A simple usage example of ``ListRegistry`` looks like this: |
36 | | -
|
37 | | ->>> app.extensions['registry']['my.namespace'] = ListRegistry() |
38 | | ->>> len(app.extensions['registry']) |
39 | | -1 |
40 | | ->>> app.extensions['registry']['my.namespace'].register("something") |
41 | | ->>> app.extensions['registry']['my.namespace'].register("something else") |
42 | | ->>> len(app.extensions['registry']['my.namespace']) |
43 | | -2 |
44 | | ->>> for obj in app.extensions['registry']['my.namespace']: |
45 | | -... print(obj) |
46 | | -something |
47 | | -something else |
48 | | -""" |
49 | | - |
50 | | -from __future__ import absolute_import |
51 | | - |
52 | | -from werkzeug.local import LocalProxy |
53 | | -from flask import current_app |
54 | | - |
55 | | - |
56 | | -class RegistryError(Exception): |
57 | | - """ |
58 | | - Exception class raised for user errors (e.g. creating two registries in |
59 | | - the same namespace) |
60 | | - """ |
61 | | - pass |
62 | | - |
63 | | - |
64 | | -class Registry(object): |
65 | | - """ |
66 | | - Flask extension |
67 | | -
|
68 | | - Initialization of the extension: |
| 28 | +.. code-block:: pycon |
69 | 29 |
|
70 | 30 | >>> from flask import Flask |
71 | 31 | >>> from flask_registry import Registry, ListRegistry |
72 | 32 | >>> app = Flask('myapp') |
73 | 33 | >>> r = Registry(app=app) |
74 | 34 |
|
75 | | - or alternatively using the factory pattern: |
76 | | -
|
77 | | - >>> app = Flask('myapp') |
78 | | - >>> r = Registry() |
79 | | - >>> r.init_app(app) |
80 | | - """ |
81 | | - def __init__(self, app=None): |
82 | | - self._registry = dict() |
83 | | - self.app = app |
84 | | - if app is not None: |
85 | | - self.init_app(app) |
86 | | - |
87 | | - def init_app(self, app): |
88 | | - """ |
89 | | - Initialize a Flask application. |
90 | | -
|
91 | | - Only one Registry per application is allowed. |
92 | | - """ |
93 | | - # Follow the Flask guidelines on usage of app.extensions |
94 | | - if not hasattr(app, 'extensions'): |
95 | | - app.extensions = {} |
96 | | - if 'registry' in app.extensions: |
97 | | - raise RegistryError("Flask application already initialized") |
98 | | - app.extensions['registry'] = self |
99 | | - |
100 | | - def __iter__(self): |
101 | | - """ |
102 | | - Get iterator over registries. |
103 | | - """ |
104 | | - return self._registry.__iter__() |
105 | | - |
106 | | - def __len__(self): |
107 | | - """ |
108 | | - Get number of registries. |
109 | | - """ |
110 | | - return self._registry.__len__() |
111 | | - |
112 | | - def __contains__(self, item): |
113 | | - """ |
114 | | - Check if namespace exists in Flask application registry. |
115 | | -
|
116 | | - :param item: Namespace |
117 | | - """ |
118 | | - return self._registry.__contains__(item) |
119 | | - |
120 | | - def __getitem__(self, key): |
121 | | - """ |
122 | | - Get a registry with a given namespace. |
123 | | -
|
124 | | - :param key: Namespace |
125 | | - """ |
126 | | - return self._registry[key] |
127 | | - |
128 | | - def __delitem__(self, key): |
129 | | - """ |
130 | | - Remove a registry |
131 | | -
|
132 | | - :param key: Namespace |
133 | | - """ |
134 | | - obj = self._registry[key] |
135 | | - del self._registry[key] |
136 | | - obj.namespace = None |
137 | | - |
138 | | - def __setitem__(self, key, value): |
139 | | - """ |
140 | | - Register a registry in the Flask application registry. |
141 | | -
|
142 | | - :param key: Namespace |
143 | | - :param value: Instance of RegistryBase or subclass |
144 | | - """ |
145 | | - if key in self._registry: |
146 | | - raise RegistryError("Namespace %s already taken." % key) |
147 | | - self._registry[key] = value |
148 | | - self._registry[key].namespace = key |
149 | | - |
150 | | - def items(self): |
151 | | - """ Get list of (namespace, registry)-pairs. """ |
152 | | - return self._registry.items() |
153 | | - |
154 | | - |
155 | | -# pylint: disable=R0921 |
156 | | -class RegistryBase(object): |
157 | | - """ |
158 | | - Abstract base class for all registries. |
159 | | -
|
160 | | - Each subclass must implement the ``register()`` method. |
161 | | - Each subclass may implement the ``unregister()`` method. |
162 | | -
|
163 | | - Once a registry is registered in the Flask application, the namespace |
164 | | - under which it is available is injected into it self. |
165 | | -
|
166 | | - Please see ``flask_registry.registries.core`` for simple examples of |
167 | | - subclasses. |
168 | | - """ |
169 | | - _namespace = None |
170 | | - |
171 | | - @property |
172 | | - def namespace(self): |
173 | | - """ |
174 | | - Namespace. Used only by the Flask extension to inject the namespace |
175 | | - under which this instance is registered in the Flask application. |
176 | | - Defaults to ``None`` if not registered in a Flask application. |
177 | | - """ |
178 | | - return self._namespace |
179 | | - |
180 | | - @namespace.setter |
181 | | - def namespace(self, value): |
182 | | - """ Setter for namespace property. """ |
183 | | - if self._namespace and value is not None: |
184 | | - raise RegistryError("Namespace cannot be changed.") |
185 | | - self._namespace = value |
186 | | - |
187 | | - def register(self, *args, **kwargs): |
188 | | - """ |
189 | | - Abstract method which MUST be overwritten by subclasses. A subclass |
190 | | - does not need to take the same number of arguments as the abstract |
191 | | - base class. |
192 | | - """ |
193 | | - raise NotImplementedError() |
194 | | - |
195 | | - def unregister(self, *args, **kwargs): |
196 | | - """ |
197 | | - Abstract method which MAY be overwritten by subclasses. A subclass |
198 | | - does not need to take the same number of arguments as the abstract |
199 | | - base class. |
200 | | - """ |
201 | | - raise NotImplementedError() |
202 | | - |
203 | | - |
204 | | -class RegistryProxy(LocalProxy): |
205 | | - """ |
206 | | - Lazy proxy object to a registry in the ``current_app`` |
207 | | -
|
208 | | - Allows you to define a registry in your local module without needing to |
209 | | - initialize it first. Once accessed the first time, the registry will be |
210 | | - initialized in the current_app, thus you must be working in either |
211 | | - the Flask application context or request context. |
212 | | -
|
213 | | - >>> from flask import Flask |
214 | | - >>> app = Flask('myapp') |
215 | | - >>> from flask_registry import Registry, RegistryProxy, RegistryBase |
216 | | - >>> r = Registry(app=app) |
217 | | - >>> proxy = RegistryProxy('myns', RegistryBase) |
218 | | - >>> 'myns' in app.extensions['registry'] |
219 | | - False |
220 | | - >>> with app.app_context(): |
221 | | - ... print(proxy.namespace) |
222 | | - ... |
223 | | - myns |
224 | | - >>> 'myns' in app.extensions['registry'] |
225 | | - True |
226 | | -
|
227 | | - :param namespace: Namespace for registry |
228 | | - :param registry_class: The registry class - i.e. a sublcass of |
229 | | - ``RegistryBase``. |
230 | | - :param args: Arguments passed to ``registry_class`` on initialization. |
231 | | - :param kwargs: Keyword arguments passed to ``registry_class`` on |
232 | | - initialization. |
233 | | - """ |
| 35 | +A simple usage example of ``ListRegistry`` looks like this: |
234 | 36 |
|
235 | | - # pylint: disable=W0142, C0111, E1002 |
236 | | - def __init__(self, namespace, registry_class, *args, **kwargs): |
237 | | - def _lookup(): |
238 | | - if not 'registry' in getattr(current_app, 'extensions', {}): |
239 | | - raise RegistryError('Registry is not initialized.') |
240 | | - if namespace not in current_app.extensions['registry']: |
241 | | - # pylint: disable=W0142 |
242 | | - current_app.extensions['registry'][namespace] = \ |
243 | | - registry_class( |
244 | | - *args, **kwargs |
245 | | - ) |
246 | | - return current_app.extensions['registry'][namespace] |
247 | | - super(RegistryProxy, self).__init__(_lookup) |
| 37 | +.. code-block:: pycon |
| 38 | +
|
| 39 | + >>> app.extensions['registry']['my.namespace'] = ListRegistry() |
| 40 | + >>> len(app.extensions['registry']) |
| 41 | + 1 |
| 42 | + >>> app.extensions['registry']['my.namespace'].register("something") |
| 43 | + >>> app.extensions['registry']['my.namespace'].register("something else") |
| 44 | + >>> len(app.extensions['registry']['my.namespace']) |
| 45 | + 2 |
| 46 | + >>> for obj in app.extensions['registry']['my.namespace']: |
| 47 | + ... print(obj) |
| 48 | + something |
| 49 | + something else |
| 50 | +""" |
248 | 51 |
|
| 52 | +from .base import Registry, RegistryError, RegistryProxy, RegistryBase |
| 53 | +from .registries.core import (ListRegistry, DictRegistry, |
| 54 | + ImportPathRegistry, ModuleRegistry, |
| 55 | + SingletonRegistry) |
| 56 | +from .registries.modulediscovery import (ModuleDiscoveryRegistry, |
| 57 | + ModuleAutoDiscoveryRegistry) |
| 58 | +from .registries.pkgresources import (EntryPointRegistry, |
| 59 | + PkgResourcesDirDiscoveryRegistry) |
| 60 | +from .registries.appdiscovery import (PackageRegistry, |
| 61 | + ExtensionRegistry, |
| 62 | + ConfigurationRegistry, |
| 63 | + BlueprintAutoDiscoveryRegistry) |
249 | 64 |
|
250 | | -# Version information |
251 | 65 | from .version import __version__ |
252 | 66 |
|
253 | | -# |
254 | | -# API of registries |
255 | | -# |
256 | | -from .registries.core import ListRegistry, DictRegistry, \ |
257 | | - ImportPathRegistry, ModuleRegistry, SingletonRegistry |
258 | | -from .registries.modulediscovery import \ |
259 | | - ModuleDiscoveryRegistry, ModuleAutoDiscoveryRegistry |
260 | | -from .registries.pkgresources import EntryPointRegistry, \ |
261 | | - PkgResourcesDirDiscoveryRegistry |
262 | | -from .registries.appdiscovery import PackageRegistry, \ |
263 | | - ExtensionRegistry, ConfigurationRegistry, BlueprintAutoDiscoveryRegistry |
264 | | - |
265 | | -__all__ = [ |
| 67 | +__all__ = ( |
266 | 68 | 'Registry', 'RegistryError', 'RegistryProxy', 'RegistryBase', |
267 | 69 | 'ListRegistry', 'DictRegistry', 'ImportPathRegistry', 'ModuleRegistry', |
268 | 70 | 'ModuleDiscoveryRegistry', 'ModuleAutoDiscoveryRegistry', |
269 | 71 | 'EntryPointRegistry', 'PkgResourcesDirDiscoveryRegistry', |
270 | 72 | 'PackageRegistry', 'ExtensionRegistry', 'ConfigurationRegistry', |
271 | 73 | 'BlueprintAutoDiscoveryRegistry', 'SingletonRegistry', '__version__' |
272 | | -] |
| 74 | +) |
0 commit comments