uwsgiconf 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uwsgiconf/__init__.py +1 -0
- uwsgiconf/base.py +298 -0
- uwsgiconf/cli.py +105 -0
- uwsgiconf/config.py +844 -0
- uwsgiconf/contrib/django/__init__.py +5 -0
- uwsgiconf/contrib/django/uwsgify/__init__.py +1 -0
- uwsgiconf/contrib/django/uwsgify/admin/__init__.py +12 -0
- uwsgiconf/contrib/django/uwsgify/admin/base.py +54 -0
- uwsgiconf/contrib/django/uwsgify/admin/models.py +38 -0
- uwsgiconf/contrib/django/uwsgify/admin/realms.py +236 -0
- uwsgiconf/contrib/django/uwsgify/admin/task.py +35 -0
- uwsgiconf/contrib/django/uwsgify/apps.py +25 -0
- uwsgiconf/contrib/django/uwsgify/cache.py +63 -0
- uwsgiconf/contrib/django/uwsgify/locale/ru/LC_MESSAGES/django.mo +0 -0
- uwsgiconf/contrib/django/uwsgify/locale/ru/LC_MESSAGES/django.po +259 -0
- uwsgiconf/contrib/django/uwsgify/management/__init__.py +1 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/__init__.py +1 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/_base.py +34 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/uwsgi_log.py +22 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/uwsgi_reload.py +30 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/uwsgi_run.py +41 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/uwsgi_stats.py +9 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/uwsgi_stop.py +18 -0
- uwsgiconf/contrib/django/uwsgify/management/commands/uwsgi_sysinit.py +51 -0
- uwsgiconf/contrib/django/uwsgify/migrations/0001_initial.py +34 -0
- uwsgiconf/contrib/django/uwsgify/migrations/__init__.py +0 -0
- uwsgiconf/contrib/django/uwsgify/models.py +12 -0
- uwsgiconf/contrib/django/uwsgify/settings.py +18 -0
- uwsgiconf/contrib/django/uwsgify/static/uwsgify/403.html +28 -0
- uwsgiconf/contrib/django/uwsgify/static/uwsgify/404.html +29 -0
- uwsgiconf/contrib/django/uwsgify/static/uwsgify/500.html +29 -0
- uwsgiconf/contrib/django/uwsgify/static/uwsgify/503.html +30 -0
- uwsgiconf/contrib/django/uwsgify/taskutils/__init__.py +0 -0
- uwsgiconf/contrib/django/uwsgify/taskutils/backends.py +126 -0
- uwsgiconf/contrib/django/uwsgify/taskutils/context.py +22 -0
- uwsgiconf/contrib/django/uwsgify/taskutils/decorators.py +72 -0
- uwsgiconf/contrib/django/uwsgify/taskutils/models.py +111 -0
- uwsgiconf/contrib/django/uwsgify/templates/admin/uwsgify/onepage.html +46 -0
- uwsgiconf/contrib/django/uwsgify/toolbox.py +306 -0
- uwsgiconf/contrib/django/uwsgify/utils.py +3 -0
- uwsgiconf/contrib/django/uwsgify/uwsgiinit.py +48 -0
- uwsgiconf/emulator/__init__.py +0 -0
- uwsgiconf/emulator/caching.py +53 -0
- uwsgiconf/emulator/mules.py +10 -0
- uwsgiconf/emulator/rpc.py +16 -0
- uwsgiconf/emulator/scheduling.py +13 -0
- uwsgiconf/emulator/signals.py +30 -0
- uwsgiconf/exceptions.py +11 -0
- uwsgiconf/formatters.py +142 -0
- uwsgiconf/maintenance.py +12 -0
- uwsgiconf/options/__init__.py +38 -0
- uwsgiconf/options/alarm_types.py +90 -0
- uwsgiconf/options/alarms.py +152 -0
- uwsgiconf/options/applications.py +94 -0
- uwsgiconf/options/caching.py +219 -0
- uwsgiconf/options/empire.py +211 -0
- uwsgiconf/options/locks.py +73 -0
- uwsgiconf/options/logging.py +560 -0
- uwsgiconf/options/logging_encoders.py +106 -0
- uwsgiconf/options/logging_loggers.py +233 -0
- uwsgiconf/options/main_process.py +464 -0
- uwsgiconf/options/main_process_actions.py +224 -0
- uwsgiconf/options/master_process.py +362 -0
- uwsgiconf/options/monitoring.py +258 -0
- uwsgiconf/options/monitoring_collectors.py +138 -0
- uwsgiconf/options/monitoring_metric_types.py +123 -0
- uwsgiconf/options/monitoring_pushers.py +225 -0
- uwsgiconf/options/networking.py +383 -0
- uwsgiconf/options/networking_sockets.py +350 -0
- uwsgiconf/options/python.py +237 -0
- uwsgiconf/options/queue.py +39 -0
- uwsgiconf/options/routing.py +419 -0
- uwsgiconf/options/routing_actions.py +669 -0
- uwsgiconf/options/routing_modifiers.py +431 -0
- uwsgiconf/options/routing_routers.py +1061 -0
- uwsgiconf/options/routing_subjects.py +167 -0
- uwsgiconf/options/routing_vars.py +145 -0
- uwsgiconf/options/spooler.py +111 -0
- uwsgiconf/options/statics.py +196 -0
- uwsgiconf/options/subscriptions.py +216 -0
- uwsgiconf/options/subscriptions_algos.py +39 -0
- uwsgiconf/options/workers.py +463 -0
- uwsgiconf/options/workers_cheapening.py +250 -0
- uwsgiconf/presets/__init__.py +0 -0
- uwsgiconf/presets/empire.py +86 -0
- uwsgiconf/presets/nice.py +401 -0
- uwsgiconf/runtime/__init__.py +0 -0
- uwsgiconf/runtime/alarms.py +3 -0
- uwsgiconf/runtime/asynced.py +13 -0
- uwsgiconf/runtime/caching.py +173 -0
- uwsgiconf/runtime/control.py +65 -0
- uwsgiconf/runtime/locking.py +87 -0
- uwsgiconf/runtime/logging.py +20 -0
- uwsgiconf/runtime/monitoring.py +107 -0
- uwsgiconf/runtime/mules.py +243 -0
- uwsgiconf/runtime/platform.py +159 -0
- uwsgiconf/runtime/request.py +51 -0
- uwsgiconf/runtime/rpc.py +73 -0
- uwsgiconf/runtime/scheduling.py +261 -0
- uwsgiconf/runtime/signals.py +201 -0
- uwsgiconf/runtime/spooler.py +426 -0
- uwsgiconf/runtime/websockets.py +32 -0
- uwsgiconf/settings.py +29 -0
- uwsgiconf/sysinit.py +149 -0
- uwsgiconf/typehints.py +8 -0
- uwsgiconf/utils.py +544 -0
- uwsgiconf/uwsgi.py +26 -0
- uwsgiconf/uwsgi_stub.py +1272 -0
- uwsgiconf-2.0.0.dist-info/METADATA +159 -0
- uwsgiconf-2.0.0.dist-info/RECORD +113 -0
- uwsgiconf-2.0.0.dist-info/WHEEL +4 -0
- uwsgiconf-2.0.0.dist-info/entry_points.txt +2 -0
- uwsgiconf-2.0.0.dist-info/licenses/LICENSE +28 -0
uwsgiconf/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = '2.0.0'
|
uwsgiconf/base.py
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Union
|
|
3
|
+
|
|
4
|
+
from .utils import listify
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from .config import Section
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Options:
|
|
11
|
+
"""Options descriptor. Allows option."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, opt_type: type['OptionsGroup']):
|
|
14
|
+
"""
|
|
15
|
+
:param opt_type:
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
self.opt_type = opt_type
|
|
19
|
+
|
|
20
|
+
def __get__(self, section: 'Section', section_cls: type['Section']) -> Union['OptionsGroup', type['OptionsGroup']]:
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
:param section:
|
|
24
|
+
:param section_cls:
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
key = self.opt_type.__name__
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
options_obj = section._options_objects.get(key)
|
|
31
|
+
|
|
32
|
+
except AttributeError:
|
|
33
|
+
# Allow easy access to option group static params:
|
|
34
|
+
# Section.networking.socket_types.DEFAULT
|
|
35
|
+
return self.opt_type
|
|
36
|
+
|
|
37
|
+
if not options_obj:
|
|
38
|
+
options_obj = self.opt_type(_section=section)
|
|
39
|
+
|
|
40
|
+
section._options_objects[key] = options_obj
|
|
41
|
+
|
|
42
|
+
return options_obj
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class OptionKey:
|
|
46
|
+
|
|
47
|
+
__slots__ = ['key']
|
|
48
|
+
|
|
49
|
+
def __init__(self, key: str):
|
|
50
|
+
self.key = key
|
|
51
|
+
|
|
52
|
+
def swap(self, new_key: Any):
|
|
53
|
+
|
|
54
|
+
if new_key:
|
|
55
|
+
self.key = f'{new_key}'
|
|
56
|
+
|
|
57
|
+
def __str__(self):
|
|
58
|
+
return self.key
|
|
59
|
+
|
|
60
|
+
def __eq__(self, obj):
|
|
61
|
+
return self.key == obj
|
|
62
|
+
|
|
63
|
+
def __hash__(self):
|
|
64
|
+
return hash(self.key)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class OptionsGroup:
|
|
68
|
+
"""Introduces group of options.
|
|
69
|
+
|
|
70
|
+
Basic group parameters may be passed to initializer
|
|
71
|
+
or `set_basic_params` method.
|
|
72
|
+
|
|
73
|
+
Usually methods setting parameters are named `set_***_params`.
|
|
74
|
+
|
|
75
|
+
Methods ending with `_params` return section object and may be chained.
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
_section: 'Section' = None
|
|
79
|
+
"""Section this option group belongs to."""
|
|
80
|
+
|
|
81
|
+
plugin: bool | str = False
|
|
82
|
+
"""Indication this option group belongs to a plugin."""
|
|
83
|
+
|
|
84
|
+
name: str = ''
|
|
85
|
+
"""Name to represent the group."""
|
|
86
|
+
|
|
87
|
+
def __init__(self, *args, **kwargs):
|
|
88
|
+
if self._section is None:
|
|
89
|
+
self._section = kwargs.pop('_section', None)
|
|
90
|
+
|
|
91
|
+
self.set_basic_params(*args, **kwargs)
|
|
92
|
+
|
|
93
|
+
def _get_name(self, *args, **kwargs) -> str:
|
|
94
|
+
return self.name
|
|
95
|
+
|
|
96
|
+
def __str__(self):
|
|
97
|
+
return self._get_name()
|
|
98
|
+
|
|
99
|
+
def __call__(self, *args, **kwargs) -> 'Section':
|
|
100
|
+
"""The call is translated into ``set_basic_params``` call.
|
|
101
|
+
|
|
102
|
+
This approach is much more convenient yet IDE most probably won't
|
|
103
|
+
give you a hint on what arguments are accepted.
|
|
104
|
+
|
|
105
|
+
:param args:
|
|
106
|
+
:param kwargs:
|
|
107
|
+
|
|
108
|
+
"""
|
|
109
|
+
return self.set_basic_params(*args, **kwargs)
|
|
110
|
+
|
|
111
|
+
def __eq__(self, obj):
|
|
112
|
+
return f'{self}' == obj
|
|
113
|
+
|
|
114
|
+
def __hash__(self):
|
|
115
|
+
return hash(f'{self}')
|
|
116
|
+
|
|
117
|
+
def set_basic_params(self, *args, **kwargs) -> 'Section':
|
|
118
|
+
return self._section
|
|
119
|
+
|
|
120
|
+
def _set(
|
|
121
|
+
self,
|
|
122
|
+
key: str,
|
|
123
|
+
value: Any,
|
|
124
|
+
*,
|
|
125
|
+
condition: bool | str | None = True,
|
|
126
|
+
cast: Callable | None = None,
|
|
127
|
+
multi: bool = False,
|
|
128
|
+
plugin: str | None = None,
|
|
129
|
+
priority: int | None = None
|
|
130
|
+
):
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
:param key: Option name
|
|
134
|
+
|
|
135
|
+
:param value: Option value. Can be a lis if ``multi``.
|
|
136
|
+
|
|
137
|
+
:param condition: Condition to test whether this option should be added to section.
|
|
138
|
+
* True - test value is not None.
|
|
139
|
+
|
|
140
|
+
:param cast: Value type caster.
|
|
141
|
+
* bool - treat value as a flag
|
|
142
|
+
|
|
143
|
+
:param multi: Indicate that many options can use the same name.
|
|
144
|
+
|
|
145
|
+
:param plugin: Plugin this option exposed by. Activated automatically.
|
|
146
|
+
|
|
147
|
+
:param priority: Option priority indicator. Options with lower numbers will come first.
|
|
148
|
+
|
|
149
|
+
"""
|
|
150
|
+
key = OptionKey(key)
|
|
151
|
+
|
|
152
|
+
def set_plugin(plugin):
|
|
153
|
+
self._section.set_plugins_params(plugins=plugin)
|
|
154
|
+
|
|
155
|
+
def handle_priority(value, *, use_list=False):
|
|
156
|
+
|
|
157
|
+
if priority is not None:
|
|
158
|
+
# Restructure options.
|
|
159
|
+
opts_copy = opts.copy()
|
|
160
|
+
opts.clear()
|
|
161
|
+
|
|
162
|
+
existing_value = opts_copy.pop(key, [])
|
|
163
|
+
|
|
164
|
+
if use_list:
|
|
165
|
+
existing_value.extend(value)
|
|
166
|
+
value = existing_value
|
|
167
|
+
|
|
168
|
+
for pos, (item_key, item_val) in enumerate(opts_copy.items()):
|
|
169
|
+
|
|
170
|
+
if priority == pos:
|
|
171
|
+
opts[key] = value
|
|
172
|
+
|
|
173
|
+
opts[item_key] = item_val
|
|
174
|
+
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
def handle_plugin_required(val):
|
|
178
|
+
|
|
179
|
+
if isinstance(val, ParametrizedValue):
|
|
180
|
+
key.swap(val.opt_key or key) # todo
|
|
181
|
+
|
|
182
|
+
if val.plugin:
|
|
183
|
+
# Automatic plugin activation.
|
|
184
|
+
set_plugin(val.plugin)
|
|
185
|
+
|
|
186
|
+
if val._opts:
|
|
187
|
+
opts.update(val._opts)
|
|
188
|
+
|
|
189
|
+
if condition is True:
|
|
190
|
+
condition = value is not None
|
|
191
|
+
|
|
192
|
+
if condition is None or condition:
|
|
193
|
+
|
|
194
|
+
opts = self._section._opts
|
|
195
|
+
|
|
196
|
+
if cast is bool:
|
|
197
|
+
if value:
|
|
198
|
+
value = 'true'
|
|
199
|
+
|
|
200
|
+
else:
|
|
201
|
+
try:
|
|
202
|
+
del opts[key]
|
|
203
|
+
except KeyError:
|
|
204
|
+
pass
|
|
205
|
+
|
|
206
|
+
return
|
|
207
|
+
|
|
208
|
+
if self.plugin is True:
|
|
209
|
+
# Automatic plugin activation when option from it is used.
|
|
210
|
+
set_plugin(self)
|
|
211
|
+
|
|
212
|
+
if plugin:
|
|
213
|
+
set_plugin(plugin)
|
|
214
|
+
|
|
215
|
+
if isinstance(value, tuple): # Tuple - expect ParametrizedValue.
|
|
216
|
+
list(map(handle_plugin_required, value))
|
|
217
|
+
value = ' '.join(map(str, value))
|
|
218
|
+
|
|
219
|
+
if multi:
|
|
220
|
+
values = []
|
|
221
|
+
|
|
222
|
+
# First activate plugin if required.
|
|
223
|
+
for value_ in listify(value):
|
|
224
|
+
handle_plugin_required(value_)
|
|
225
|
+
values.append(value_)
|
|
226
|
+
|
|
227
|
+
# Second: list in new option.
|
|
228
|
+
if not handle_priority(values, use_list=True):
|
|
229
|
+
opts.setdefault(key, []).extend(values)
|
|
230
|
+
|
|
231
|
+
else:
|
|
232
|
+
handle_plugin_required(value)
|
|
233
|
+
|
|
234
|
+
if not handle_priority(value):
|
|
235
|
+
opts[key] = value
|
|
236
|
+
|
|
237
|
+
def _make_section_like(self):
|
|
238
|
+
self._section = type('SectionLike', (object,), {'_opts': {}})
|
|
239
|
+
|
|
240
|
+
def _contribute_to_opts(self, target):
|
|
241
|
+
target_section = target._section
|
|
242
|
+
target_section._opts.update(self._section._opts)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class ParametrizedValue(OptionsGroup):
|
|
246
|
+
"""Represents parametrized option value."""
|
|
247
|
+
|
|
248
|
+
alias: str = ''
|
|
249
|
+
"""Alias to address this value."""
|
|
250
|
+
|
|
251
|
+
args_joiner: str = ' '
|
|
252
|
+
"""Symbol to join arguments with."""
|
|
253
|
+
|
|
254
|
+
name_separator: str = ':'
|
|
255
|
+
"""Separator to add after name portion."""
|
|
256
|
+
|
|
257
|
+
name_separator_strip: bool = False
|
|
258
|
+
"""Strip leading and trailing name separator from the result."""
|
|
259
|
+
|
|
260
|
+
opt_key: str | None = None
|
|
261
|
+
"""Allows swapping default option key with custom value."""
|
|
262
|
+
|
|
263
|
+
def __init__(self, *args):
|
|
264
|
+
self.args = list(args)
|
|
265
|
+
self._opts = {}
|
|
266
|
+
super().__init__(_section=self)
|
|
267
|
+
|
|
268
|
+
def __str__(self):
|
|
269
|
+
args = [f'{arg}' for arg in self.args if arg is not None]
|
|
270
|
+
|
|
271
|
+
result = ''
|
|
272
|
+
|
|
273
|
+
if self.opt_key is None:
|
|
274
|
+
result += self._get_name() + self.name_separator
|
|
275
|
+
|
|
276
|
+
result += self.args_joiner.join(args)
|
|
277
|
+
|
|
278
|
+
if self.alias:
|
|
279
|
+
result = f'{self.alias} {result}'
|
|
280
|
+
|
|
281
|
+
result = result.strip()
|
|
282
|
+
|
|
283
|
+
if self.name_separator_strip:
|
|
284
|
+
result = result.strip(self.name_separator)
|
|
285
|
+
|
|
286
|
+
return result
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class TemplatedValue(ParametrizedValue):
|
|
290
|
+
|
|
291
|
+
tpl: str = '%s'
|
|
292
|
+
|
|
293
|
+
def __init__(self, name: str):
|
|
294
|
+
self._name = name
|
|
295
|
+
super().__init__()
|
|
296
|
+
|
|
297
|
+
def __str__(self):
|
|
298
|
+
return self.tpl % self._name
|
uwsgiconf/cli.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from uwsgiconf import VERSION
|
|
7
|
+
from uwsgiconf.exceptions import ConfigurationError
|
|
8
|
+
from uwsgiconf.sysinit import TYPE_SYSTEMD, TYPES, get_config
|
|
9
|
+
from uwsgiconf.utils import ConfModule, UwsgiRunner
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@contextmanager
|
|
13
|
+
def errorprint():
|
|
14
|
+
"""Print out descriptions from ConfigurationError."""
|
|
15
|
+
try:
|
|
16
|
+
yield
|
|
17
|
+
|
|
18
|
+
except ConfigurationError as e:
|
|
19
|
+
click.secho(f'{e}', err=True, fg='red')
|
|
20
|
+
sys.exit(1)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@click.group()
|
|
24
|
+
@click.version_option(version='.'.join(map(str, VERSION)))
|
|
25
|
+
def base():
|
|
26
|
+
"""uwsgiconf command line utility.
|
|
27
|
+
|
|
28
|
+
Tools to facilitate uWSGI configuration.
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
arg_conf = click.argument(
|
|
33
|
+
'conf', type=click.Path(exists=True, dir_okay=False), default=ConfModule.default_name)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@base.command()
|
|
37
|
+
@arg_conf
|
|
38
|
+
@click.option('--only', help='Configuration alias from module to run uWSGI with.')
|
|
39
|
+
def run(conf, only):
|
|
40
|
+
"""Runs uWSGI passing to it using the default or another `uwsgiconf` configuration module.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
with errorprint():
|
|
44
|
+
config = ConfModule(conf)
|
|
45
|
+
spawned = config.spawn_uwsgi(only=only)
|
|
46
|
+
|
|
47
|
+
for alias, pid in spawned:
|
|
48
|
+
click.secho(f"Spawned uWSGI for configuration aliased '{alias}'. PID {pid}", fg='green')
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@base.command()
|
|
52
|
+
@arg_conf
|
|
53
|
+
def compile(conf):
|
|
54
|
+
"""Compiles classic uWSGI configuration file using the default
|
|
55
|
+
or given `uwsgiconf` configuration module.
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
with errorprint():
|
|
59
|
+
config = ConfModule(conf)
|
|
60
|
+
for conf in config.configurations:
|
|
61
|
+
conf.format(do_print=True)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@base.command()
|
|
65
|
+
@click.argument('systype', type=click.Choice(TYPES), default=TYPE_SYSTEMD)
|
|
66
|
+
@arg_conf
|
|
67
|
+
@click.option('--project', help='Project name to use as service name.')
|
|
68
|
+
def sysinit(systype, conf, project):
|
|
69
|
+
"""Outputs configuration for system initialization subsystem."""
|
|
70
|
+
|
|
71
|
+
click.secho(get_config(
|
|
72
|
+
systype,
|
|
73
|
+
conf=ConfModule(conf).configurations[0],
|
|
74
|
+
conf_path=conf,
|
|
75
|
+
project_name=project,
|
|
76
|
+
))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@base.command()
|
|
80
|
+
def probe_plugins():
|
|
81
|
+
"""Runs uWSGI to determine what plugins are available and prints them out.
|
|
82
|
+
|
|
83
|
+
Generic plugins come first then after blank line follow request plugins.
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
plugins = UwsgiRunner().get_plugins()
|
|
87
|
+
|
|
88
|
+
for plugin in sorted(plugins.generic):
|
|
89
|
+
click.secho(plugin)
|
|
90
|
+
|
|
91
|
+
click.secho('')
|
|
92
|
+
|
|
93
|
+
for plugin in sorted(plugins.request):
|
|
94
|
+
click.secho(plugin)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def main():
|
|
98
|
+
"""
|
|
99
|
+
CLI entry point
|
|
100
|
+
"""
|
|
101
|
+
base(obj={})
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == '__main__':
|
|
105
|
+
main()
|