mtcli 3.7.0.dev4__py3-none-any.whl → 3.7.0.dev6__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.
- mtcli/plugin_loader.py +80 -55
- {mtcli-3.7.0.dev4.dist-info → mtcli-3.7.0.dev6.dist-info}/METADATA +1 -1
- {mtcli-3.7.0.dev4.dist-info → mtcli-3.7.0.dev6.dist-info}/RECORD +6 -6
- {mtcli-3.7.0.dev4.dist-info → mtcli-3.7.0.dev6.dist-info}/WHEEL +0 -0
- {mtcli-3.7.0.dev4.dist-info → mtcli-3.7.0.dev6.dist-info}/entry_points.txt +0 -0
- {mtcli-3.7.0.dev4.dist-info → mtcli-3.7.0.dev6.dist-info}/licenses/LICENSE +0 -0
mtcli/plugin_loader.py
CHANGED
|
@@ -1,98 +1,123 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Sistema de carregamento de plugins do mtcli.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Descobre e registra plugins instalados via entry points.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
2. Plugins externos registrados via entry points `mtcli.plugins`
|
|
6
|
+
Plugins devem declarar:
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
[project.entry-points."mtcli.plugins"]
|
|
9
|
+
nome = "pacote.plugin:register"
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
O plugin pode fornecer:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
1. register(cli)
|
|
14
|
+
2. um objeto click.Command
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
|
-
import
|
|
17
|
-
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Iterable, List
|
|
18
20
|
|
|
19
21
|
import click
|
|
20
22
|
|
|
21
23
|
try:
|
|
22
|
-
from importlib.metadata import entry_points
|
|
23
|
-
except ImportError: #
|
|
24
|
-
from importlib_metadata import entry_points
|
|
24
|
+
from importlib.metadata import EntryPoint, entry_points
|
|
25
|
+
except ImportError: # pragma: no cover
|
|
26
|
+
from importlib_metadata import EntryPoint, entry_points
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
from mtcli.logger import setup_logger
|
|
27
29
|
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
"""
|
|
31
|
-
Carrega plugins internos do pacote `mtcli.plugins`.
|
|
31
|
+
logger = setup_logger(__name__)
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
PLUGIN_GROUP = "mtcli.plugins"
|
|
34
34
|
|
|
35
|
-
register(cli)
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
cli: grupo principal do Click.
|
|
36
|
+
def discover_plugins() -> Iterable[EntryPoint]:
|
|
39
37
|
"""
|
|
38
|
+
Descobre plugins registrados via entry points.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
Iterable[EntryPoint]
|
|
43
|
+
Entry points encontrados.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
eps = entry_points()
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
if hasattr(eps, "select"):
|
|
50
|
+
plugins = eps.select(group=PLUGIN_GROUP)
|
|
51
|
+
else:
|
|
52
|
+
plugins = eps.get(PLUGIN_GROUP, [])
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
logger.debug("Plugins descobertos: %s", [ep.name for ep in plugins])
|
|
44
55
|
|
|
45
|
-
|
|
56
|
+
return plugins
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
except Exception as exc:
|
|
59
|
+
logger.exception("Erro ao descobrir plugins: %s", exc)
|
|
60
|
+
return []
|
|
49
61
|
|
|
50
62
|
|
|
51
|
-
def
|
|
63
|
+
def register_plugin(cli: click.Group, ep: EntryPoint) -> None:
|
|
64
|
+
"""
|
|
65
|
+
Carrega e registra um plugin individual.
|
|
52
66
|
"""
|
|
53
|
-
Carrega plugins externos instalados via entry points.
|
|
54
67
|
|
|
55
|
-
|
|
68
|
+
logger.debug("Carregando plugin: %s -> %s", ep.name, ep.value)
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
nome = "pacote.plugin:register"
|
|
70
|
+
plugin = ep.load()
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
cli: grupo principal do Click.
|
|
62
|
-
"""
|
|
72
|
+
if callable(plugin) and not isinstance(plugin, click.Command):
|
|
63
73
|
|
|
64
|
-
|
|
74
|
+
plugin(cli)
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
eps.select(group="mtcli.plugins")
|
|
68
|
-
if hasattr(eps, "select")
|
|
69
|
-
else eps.get("mtcli.plugins", [])
|
|
70
|
-
)
|
|
76
|
+
logger.info("Plugin registrado via register(): %s", ep.name)
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
elif isinstance(plugin, click.Command):
|
|
73
79
|
|
|
74
|
-
|
|
80
|
+
cli.add_command(plugin)
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
plugin(cli)
|
|
82
|
+
logger.info("Plugin registrado como comando: %s", ep.name)
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
cli.add_command(plugin)
|
|
84
|
+
else:
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
raise TypeError(
|
|
87
|
+
f"Plugin '{ep.name}' inválido: "
|
|
88
|
+
"não é click.Command nem função register(cli)"
|
|
89
|
+
)
|
|
86
90
|
|
|
87
91
|
|
|
88
|
-
def load_plugins(cli: click.Group) ->
|
|
92
|
+
def load_plugins(cli: click.Group) -> List[str]:
|
|
89
93
|
"""
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
Args:
|
|
93
|
-
cli: grupo principal do Click.
|
|
94
|
+
Descobre e carrega todos os plugins instalados.
|
|
94
95
|
"""
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
loaded: List[str] = []
|
|
98
|
+
seen = set()
|
|
99
|
+
|
|
100
|
+
for ep in discover_plugins():
|
|
101
|
+
|
|
102
|
+
if ep.name in seen:
|
|
103
|
+
logger.warning("Plugin duplicado ignorado: %s", ep.name)
|
|
104
|
+
continue
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
|
|
108
|
+
register_plugin(cli, ep)
|
|
109
|
+
|
|
110
|
+
seen.add(ep.name)
|
|
111
|
+
loaded.append(ep.name)
|
|
112
|
+
|
|
113
|
+
except Exception as exc:
|
|
114
|
+
|
|
115
|
+
logger.exception(
|
|
116
|
+
"Falha ao carregar plugin '%s': %s",
|
|
117
|
+
ep.name,
|
|
118
|
+
exc,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
logger.info("Total de plugins carregados: %d", len(loaded))
|
|
98
122
|
|
|
123
|
+
return loaded
|
|
@@ -28,7 +28,7 @@ mtcli/models/signals_model.py,sha256=XhyCErgyuHF0o85vnjIVJlgsCF7XFsWQltSbLZ3Aals
|
|
|
28
28
|
mtcli/models/unconsecutive_bar_model.py,sha256=AiClcoyYnk3K6D1YkC0E2PRUhbGwsjdSnh1vIHZsIe8,2079
|
|
29
29
|
mtcli/mt5_context.py,sha256=oLevCe4nYeZ6VtGoaO-j7U4xzACE09wGmX38P0oRg5A,2147
|
|
30
30
|
mtcli/plugin.py,sha256=Wabbr22BVi32D-XNM7XS45bRdgKob7EKO6TuWtq9_ZM,414
|
|
31
|
-
mtcli/plugin_loader.py,sha256=
|
|
31
|
+
mtcli/plugin_loader.py,sha256=5709Az6SEYLdyDEblzfeLWH_R7HXpZpW6pY6fgJ9btM,2746
|
|
32
32
|
mtcli/plugin_manager.py,sha256=JTK6rmhjLa9MdyUiGgufAAnaaBhUI1Bm4g4t6p18WdU,555
|
|
33
33
|
mtcli/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
mtcli/plugins/exemplo.py-dist,sha256=q8H_sBpI-IZej9RvkCl2o_br9q2z_WXXn_qA1MRRbBo,538
|
|
@@ -65,8 +65,8 @@ mtcli/views/ranges_view.py,sha256=5gA2bAJuco-Xj964nsjs87tZ-079O7xKvaeif1UJ-PQ,12
|
|
|
65
65
|
mtcli/views/rates_view.py,sha256=Jkdbg-Q_OVJuID-Q9HFUVICCF1jE82d-qfZWNm1JJ_4,1214
|
|
66
66
|
mtcli/views/vars_view.py,sha256=Vpcej41qnZSvvSyvXYyW8W7CEFdqTxBd8NczV84XPJY,1635
|
|
67
67
|
mtcli/views/volumes_view.py,sha256=d_6YxM0vA1revwoPwnwUjV19KcqnddVgdpBHTt5Vqms,1575
|
|
68
|
-
mtcli-3.7.0.
|
|
69
|
-
mtcli-3.7.0.
|
|
70
|
-
mtcli-3.7.0.
|
|
71
|
-
mtcli-3.7.0.
|
|
72
|
-
mtcli-3.7.0.
|
|
68
|
+
mtcli-3.7.0.dev6.dist-info/entry_points.txt,sha256=sFL07BcOh-MKaij-M26bNlRbmlw9Xx0CTYTPtHegfI8,99
|
|
69
|
+
mtcli-3.7.0.dev6.dist-info/licenses/LICENSE,sha256=Z-2ANeRgM9IjXnHeg9mA2gillM6eTQj8sIExAGNe2-8,1092
|
|
70
|
+
mtcli-3.7.0.dev6.dist-info/METADATA,sha256=Qtl2W-YL3ZpTx5-O7K7oNrpAXANkfgqiBVHgj1xijMk,3650
|
|
71
|
+
mtcli-3.7.0.dev6.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
72
|
+
mtcli-3.7.0.dev6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|