tesorotools-python 0.0.36__tar.gz → 0.0.37__tar.gz

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.
Files changed (76) hide show
  1. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/PKG-INFO +1 -1
  2. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/pyproject.toml +1 -1
  3. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/__init__.py +27 -2
  4. tesorotools_python-0.0.37/src/tesorotools/_build_context.py +49 -0
  5. tesorotools_python-0.0.37/src/tesorotools/_registry.py +238 -0
  6. tesorotools_python-0.0.37/src/tesorotools/artists/__init__.py +47 -0
  7. tesorotools_python-0.0.37/src/tesorotools/artists/_common.py +493 -0
  8. tesorotools_python-0.0.37/src/tesorotools/artists/barh_plot.py +372 -0
  9. tesorotools_python-0.0.37/src/tesorotools/artists/line_plot.py +289 -0
  10. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/artists/stacked.py +94 -21
  11. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/artists/type_curve.py +48 -12
  12. tesorotools_python-0.0.37/src/tesorotools/database/push.py +28 -0
  13. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/providers/__init__.py +7 -2
  14. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/providers/base.py +42 -0
  15. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/table.py +4 -5
  16. tesorotools_python-0.0.36/src/tesorotools/_registry.py +0 -117
  17. tesorotools_python-0.0.36/src/tesorotools/artists/__init__.py +0 -25
  18. tesorotools_python-0.0.36/src/tesorotools/artists/barh.md +0 -109
  19. tesorotools_python-0.0.36/src/tesorotools/artists/barh_plot.py +0 -510
  20. tesorotools_python-0.0.36/src/tesorotools/artists/line_plot.py +0 -621
  21. tesorotools_python-0.0.36/src/tesorotools/artists/table.py +0 -255
  22. tesorotools_python-0.0.36/src/tesorotools/convert.py +0 -123
  23. tesorotools_python-0.0.36/src/tesorotools/database/push.py +0 -58
  24. tesorotools_python-0.0.36/src/tesorotools/main.py +0 -37
  25. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/.gitignore +0 -0
  26. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/README.md +0 -0
  27. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
  28. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
  29. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
  30. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
  31. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
  32. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
  33. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
  34. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
  35. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/fonts/README.md +0 -0
  36. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/plots.yaml +0 -0
  37. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/assets/tesoro.mplstyle +0 -0
  38. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/data_sources/__init__.py +0 -0
  39. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/data_sources/debug.py +0 -0
  40. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/database/__init__.py +0 -0
  41. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/database/local.py +0 -0
  42. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/database/shared.py +0 -0
  43. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/dependencies/__init__.py +0 -0
  44. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/dependencies/node.py +0 -0
  45. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/dependencies/resolution.py +0 -0
  46. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/driver.py +0 -0
  47. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/manifest.py +0 -0
  48. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/offsets/__init__.py +0 -0
  49. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/offsets/offsets.py +0 -0
  50. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/offsets/outliers.py +0 -0
  51. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/pipeline/__init__.py +0 -0
  52. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/pipeline/diagnose.py +0 -0
  53. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/pipeline/engine.py +0 -0
  54. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/pipeline/rules.py +0 -0
  55. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/providers/bde.py +0 -0
  56. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/providers/ecb.py +0 -0
  57. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/py.typed +0 -0
  58. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/__init__.py +0 -0
  59. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/__init__.py +0 -0
  60. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/content.py +0 -0
  61. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/images.py +0 -0
  62. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/section.py +0 -0
  63. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/subtitle.py +0 -0
  64. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/text.py +0 -0
  65. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/content/title.py +0 -0
  66. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/render/report.py +0 -0
  67. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/testing/__init__.py +0 -0
  68. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/testing/compare.py +0 -0
  69. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/__init__.py +0 -0
  70. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/config.py +0 -0
  71. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/format.py +0 -0
  72. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/globals.py +0 -0
  73. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/matplotlib.py +0 -0
  74. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/series.py +0 -0
  75. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/shortcuts.py +0 -0
  76. {tesorotools_python-0.0.36 → tesorotools_python-0.0.37}/src/tesorotools/utils/template.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tesorotools-python
3
- Version: 0.0.36
3
+ Version: 0.0.37
4
4
  Requires-Python: >=3.13
5
5
  Requires-Dist: babel>=2.17
6
6
  Requires-Dist: matplotlib>=3.10
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "tesorotools-python"
3
3
  requires-python = ">=3.13"
4
- version = "0.0.36"
4
+ version = "0.0.37"
5
5
  dependencies = [
6
6
  # database and ORM
7
7
  "psycopg[binary]>=3.1",
@@ -12,7 +12,9 @@ requires ``[ecb]``) are exposed lazily through
12
12
  extras to be installed.
13
13
 
14
14
  Third parties extend the package via ``register_artist``,
15
- ``register_tag``, and ``register_provider``.
15
+ ``register_tag``, and ``register_provider`` (and their
16
+ plural variants). See ``docs/extending.md`` for the
17
+ recommended idioms.
16
18
  """
17
19
 
18
20
  from typing import TYPE_CHECKING, Any
@@ -21,13 +23,24 @@ if TYPE_CHECKING:
21
23
  from tesorotools.providers.bde import BdeProvider
22
24
  from tesorotools.providers.ecb import EcbProvider
23
25
 
26
+ from tesorotools._build_context import BuildContext
24
27
  from tesorotools._registry import (
25
28
  Artist,
29
+ YamlConstructor,
30
+ all_artists,
31
+ all_providers,
32
+ all_tags,
26
33
  get_artist,
27
34
  get_provider,
35
+ iter_artists,
36
+ iter_providers,
37
+ iter_tags,
28
38
  register_artist,
39
+ register_artists,
29
40
  register_provider,
41
+ register_providers,
30
42
  register_tag,
43
+ register_tags,
31
44
  )
32
45
  from tesorotools.artists import (
33
46
  Format,
@@ -38,7 +51,7 @@ from tesorotools.artists import (
38
51
  StackedBarPlot,
39
52
  TypeCurve,
40
53
  )
41
- from tesorotools.providers.base import DataProvider
54
+ from tesorotools.providers.base import DataProvider, DataProviderProtocol
42
55
  from tesorotools.render import (
43
56
  Content,
44
57
  Image,
@@ -77,8 +90,10 @@ _register_builtins()
77
90
  __all__ = [
78
91
  "Artist",
79
92
  "BdeProvider",
93
+ "BuildContext",
80
94
  "Content",
81
95
  "DataProvider",
96
+ "DataProviderProtocol",
82
97
  "EcbProvider",
83
98
  "Format",
84
99
  "HorizontalBarChart",
@@ -95,11 +110,21 @@ __all__ = [
95
110
  "Text",
96
111
  "Title",
97
112
  "TypeCurve",
113
+ "YamlConstructor",
114
+ "all_artists",
115
+ "all_providers",
116
+ "all_tags",
98
117
  "get_artist",
99
118
  "get_provider",
119
+ "iter_artists",
120
+ "iter_providers",
121
+ "iter_tags",
100
122
  "register_artist",
123
+ "register_artists",
101
124
  "register_provider",
125
+ "register_providers",
102
126
  "register_tag",
127
+ "register_tags",
103
128
  ]
104
129
 
105
130
 
@@ -0,0 +1,49 @@
1
+ """Shared context object for ``build_for`` provider/artist factories.
2
+
3
+ Consumer projects increasingly converge on a pattern where
4
+ each provider/artist class has a ``build_for(cls, ctx) ->
5
+ dict[str, ...]`` classmethod that decides whether to
6
+ instantiate itself based on the catalog and runtime context.
7
+
8
+ ``BuildContext`` is the minimal shape we expect callers to
9
+ share across that pattern. It deliberately stays small so
10
+ projects can subclass or compose freely:
11
+
12
+ .. code-block:: python
13
+
14
+ @dataclass(frozen=True)
15
+ class DiaryBuildContext(BuildContext):
16
+ lseg_fallback: Literal["mock", "raise"] = "mock"
17
+
18
+ The base fields capture the cross-project minimum:
19
+
20
+ * ``registry`` -- whatever catalog the orchestrator uses to
21
+ decide which series each provider must serve. Typed as
22
+ ``Any`` because each project's catalog has a different
23
+ shape.
24
+ * ``consumer`` -- a free-form string identifying the calling
25
+ workflow (e.g. ``"diary"``, ``"weekly"``). ``build_for``
26
+ implementations dispatch on this.
27
+ * ``mock`` / ``mock_seed`` -- toggle for deterministic
28
+ fixtures during tests and demos.
29
+ * ``historic_file`` -- optional path to a historical dump
30
+ used by some providers as a fallback.
31
+
32
+ See ``docs/extending.md`` for the recommended ``build_for``
33
+ classmethod shape.
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ from dataclasses import dataclass
39
+ from pathlib import Path
40
+ from typing import Any
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class BuildContext:
45
+ registry: Any
46
+ consumer: str
47
+ mock: bool = False
48
+ mock_seed: int | None = None
49
+ historic_file: Path | None = None
@@ -0,0 +1,238 @@
1
+ """Registries for artists, providers, and YAML tags.
2
+
3
+ Single source of truth for "name -> class" lookups used both
4
+ by the YAML loader (``TemplateLoader``) and by code that
5
+ dispatches by string name.
6
+
7
+ Singular registration entry points:
8
+
9
+ ``register_artist(name, cls, *, with_tag=True)``
10
+ Adds ``cls`` to the artist registry and, when
11
+ ``with_tag`` is true (the default), binds the YAML tag
12
+ ``!{name}`` to ``cls.from_yaml``. Pass
13
+ ``with_tag=False`` to register an artist that is
14
+ dispatched only programmatically (no YAML tag, no
15
+ ``from_yaml`` requirement).
16
+
17
+ ``register_tag(name, constructor)``
18
+ Registers a YAML tag ``!{name}`` only. Use for things
19
+ that exist as YAML constructors but are not artists or
20
+ providers (Format, Legend, Title, Subtitle, Section,
21
+ Image, Text, Table, Report).
22
+
23
+ ``register_provider(name, cls)``
24
+ Adds ``cls`` to the provider registry. Programmatic
25
+ only -- providers do not appear in YAML today.
26
+
27
+ Plural variants (``register_artists`` / ``register_tags`` /
28
+ ``register_providers``) accept a ``Mapping[str, type]`` and
29
+ iterate, saving boilerplate when a project registers several
30
+ items at once.
31
+
32
+ Look up registered classes via ``get_artist`` /
33
+ ``get_provider``; both raise ``KeyError`` listing the
34
+ available names. Iterate the live state via
35
+ ``iter_artists`` / ``iter_providers`` / ``iter_tags`` (and
36
+ the eager ``all_*`` snapshots) so callers do not need to
37
+ import the private dictionaries.
38
+ """
39
+
40
+ from __future__ import annotations
41
+
42
+ from collections.abc import Iterator, Mapping
43
+ from typing import Any, Callable, Literal, Protocol, Self, cast, overload
44
+
45
+ from yaml.nodes import MappingNode
46
+
47
+ from tesorotools.artists._common import Artist
48
+ from tesorotools.providers.base import DataProvider
49
+ from tesorotools.utils.template import TemplateLoader
50
+
51
+ # Re-export so ``from tesorotools._registry import Artist`` keeps working
52
+ # (and the runtime-checkable Protocol is the single source of truth in
53
+ # :mod:`tesorotools.artists._common`).
54
+ __all__ = ["Artist"]
55
+
56
+
57
+ class _YamlConstructable(Protocol):
58
+ """Loose Protocol for any class plugged in as a YAML tag.
59
+
60
+ ``register_tag`` and ``register_artist(with_tag=True)``
61
+ both end up calling ``cls.from_yaml`` on the registered
62
+ type; that is the only structural requirement. The
63
+ artist-grade Protocol (with ``plot()`` and ``out_path``)
64
+ lives in :mod:`tesorotools.artists._common`.
65
+ """
66
+
67
+ @classmethod
68
+ def from_yaml(cls, loader: Any, node: MappingNode) -> Self: ...
69
+
70
+
71
+ YamlConstructor = Callable[[Any, MappingNode], Any]
72
+
73
+
74
+ _ARTIST_REGISTRY: dict[str, type[Artist]] = {}
75
+ _PROVIDER_REGISTRY: dict[str, type[DataProvider]] = {}
76
+
77
+
78
+ # ----------------------------------------------------------------------
79
+ # Singular registration
80
+ # ----------------------------------------------------------------------
81
+
82
+
83
+ @overload
84
+ def register_artist(name: str, cls: type[Artist]) -> None: ...
85
+ @overload
86
+ def register_artist(
87
+ name: str, cls: type[Artist], *, with_tag: Literal[True]
88
+ ) -> None: ...
89
+ @overload
90
+ def register_artist(
91
+ name: str, cls: type, *, with_tag: Literal[False]
92
+ ) -> None: ...
93
+ def register_artist(name: str, cls: type, *, with_tag: bool = True) -> None:
94
+ """Register ``cls`` as the artist for ``name``.
95
+
96
+ Adds ``cls`` to the artist registry. When ``with_tag``
97
+ is true (the default), also binds the YAML tag
98
+ ``!{name}`` to ``cls.from_yaml``. Re-registering the
99
+ same name overrides both bindings.
100
+
101
+ Pass ``with_tag=False`` to skip the YAML side; in that
102
+ case ``cls`` is not required to expose ``from_yaml``.
103
+ """
104
+ _ARTIST_REGISTRY[name] = cast(type[Artist], cls)
105
+ if with_tag:
106
+ TemplateLoader.add_constructor(
107
+ f"!{name}",
108
+ cast(YamlConstructor, cast(type[Artist], cls).from_yaml),
109
+ )
110
+
111
+
112
+ def get_artist(name: str) -> type[Artist]:
113
+ try:
114
+ return _ARTIST_REGISTRY[name]
115
+ except KeyError:
116
+ available = sorted(_ARTIST_REGISTRY)
117
+ raise KeyError(
118
+ f"No artist registered as {name!r}. Available: {available}"
119
+ ) from None
120
+
121
+
122
+ def register_provider(name: str, cls: type[DataProvider]) -> None:
123
+ """Register ``cls`` as the provider for ``name``."""
124
+ _PROVIDER_REGISTRY[name] = cls
125
+
126
+
127
+ def get_provider(name: str) -> type[DataProvider]:
128
+ try:
129
+ return _PROVIDER_REGISTRY[name]
130
+ except KeyError:
131
+ available = sorted(_PROVIDER_REGISTRY)
132
+ raise KeyError(
133
+ f"No provider registered as {name!r}. Available: {available}"
134
+ ) from None
135
+
136
+
137
+ def register_tag(
138
+ name: str,
139
+ constructor: type[_YamlConstructable] | YamlConstructor,
140
+ ) -> None:
141
+ """Register a YAML tag ``!{name}``.
142
+
143
+ Accepts either a class with a ``from_yaml`` classmethod
144
+ or a bare callable matching the loader signature. Use
145
+ ``register_artist`` / ``register_provider`` instead when
146
+ the registered name should also be looked up by code
147
+ via ``get_artist`` / ``get_provider``.
148
+ """
149
+ if isinstance(constructor, type):
150
+ cls = cast(type[_YamlConstructable], constructor)
151
+ TemplateLoader.add_constructor(
152
+ f"!{name}", cast(YamlConstructor, cls.from_yaml)
153
+ )
154
+ else:
155
+ TemplateLoader.add_constructor(f"!{name}", constructor)
156
+
157
+
158
+ # ----------------------------------------------------------------------
159
+ # Plural registration helpers
160
+ # ----------------------------------------------------------------------
161
+
162
+
163
+ @overload
164
+ def register_artists(items: Mapping[str, type[Artist]]) -> None: ...
165
+ @overload
166
+ def register_artists(
167
+ items: Mapping[str, type[Artist]], *, with_tag: Literal[True]
168
+ ) -> None: ...
169
+ @overload
170
+ def register_artists(
171
+ items: Mapping[str, type], *, with_tag: Literal[False]
172
+ ) -> None: ...
173
+ def register_artists(
174
+ items: Mapping[str, type], *, with_tag: bool = True
175
+ ) -> None:
176
+ """Register every (name, cls) entry as an artist.
177
+
178
+ Equivalent to looping over ``items.items()`` and calling
179
+ :func:`register_artist`. ``with_tag`` is forwarded to
180
+ every call; pass ``with_tag=False`` to register classes
181
+ that do not expose ``from_yaml``.
182
+ """
183
+ for name, cls in items.items():
184
+ if with_tag:
185
+ register_artist(name, cast(type[Artist], cls))
186
+ else:
187
+ register_artist(name, cls, with_tag=False)
188
+
189
+
190
+ def register_providers(items: Mapping[str, type[DataProvider]]) -> None:
191
+ """Register every (name, cls) entry as a provider."""
192
+ for name, cls in items.items():
193
+ register_provider(name, cls)
194
+
195
+
196
+ def register_tags(
197
+ items: Mapping[str, type[Artist] | YamlConstructor],
198
+ ) -> None:
199
+ """Register every (name, constructor) entry as a YAML tag."""
200
+ for name, constructor in items.items():
201
+ register_tag(name, constructor)
202
+
203
+
204
+ # ----------------------------------------------------------------------
205
+ # Read-only views over the registries
206
+ # ----------------------------------------------------------------------
207
+
208
+
209
+ def iter_artists() -> Iterator[tuple[str, type[Artist]]]:
210
+ """Yield (name, cls) pairs for every registered artist."""
211
+ return iter(_ARTIST_REGISTRY.items())
212
+
213
+
214
+ def all_artists() -> dict[str, type[Artist]]:
215
+ """Return a snapshot dict of every registered artist."""
216
+ return dict(_ARTIST_REGISTRY)
217
+
218
+
219
+ def iter_providers() -> Iterator[tuple[str, type[DataProvider]]]:
220
+ """Yield (name, cls) pairs for every registered provider."""
221
+ return iter(_PROVIDER_REGISTRY.items())
222
+
223
+
224
+ def all_providers() -> dict[str, type[DataProvider]]:
225
+ """Return a snapshot dict of every registered provider."""
226
+ return dict(_PROVIDER_REGISTRY)
227
+
228
+
229
+ def iter_tags() -> Iterator[tuple[str, YamlConstructor]]:
230
+ """Yield (tag, constructor) pairs for every ``!`` YAML tag."""
231
+ for tag, ctor in TemplateLoader.yaml_constructors.items():
232
+ if isinstance(tag, str) and tag.startswith("!"):
233
+ yield tag, cast(YamlConstructor, ctor)
234
+
235
+
236
+ def all_tags() -> dict[str, YamlConstructor]:
237
+ """Return a snapshot dict of every registered ``!`` YAML tag."""
238
+ return dict(iter_tags())
@@ -0,0 +1,47 @@
1
+ """Image artists.
2
+
3
+ Five chart classes, one shared helpers module, one
4
+ matplotlib stylesheet side effect on import.
5
+
6
+ Each class follows the same shape:
7
+
8
+ * ``__init__(out_path, *, data | data_path, series, ...)``
9
+ -- kw-only configuration; ``out_path`` must be ``.png``.
10
+ Pass either ``data`` (DataFrame in memory) or
11
+ ``data_path`` (``.feather`` on disk), never both.
12
+ * ``from_yaml(loader, node)`` -- builds the same instance
13
+ from a ``!{name}`` YAML tag.
14
+ * ``plot()`` -- renders the chart and writes the PNG; some
15
+ classes also expose ``build()`` / ``save()`` for
16
+ fine-grained control.
17
+
18
+ Shared layout, annotation and styling helpers (plus the
19
+ ``Format`` and ``Legend`` config holders) live in
20
+ :mod:`tesorotools.artists._common`.
21
+
22
+ Document-element artists (Word tables, sections, titles)
23
+ live under :mod:`tesorotools.render`; this package is
24
+ strictly image output.
25
+ """
26
+
27
+ import matplotlib.style
28
+
29
+ from tesorotools.artists._common import Artist, Format, Legend
30
+ from tesorotools.artists.barh_plot import HorizontalBarChart
31
+ from tesorotools.artists.line_plot import LinePlot
32
+ from tesorotools.artists.stacked import StackedAreaPlot, StackedBarPlot
33
+ from tesorotools.artists.type_curve import TypeCurve
34
+ from tesorotools.utils.globals import STYLE_SHEET
35
+
36
+ matplotlib.style.use(STYLE_SHEET)
37
+
38
+ __all__ = [
39
+ "Artist",
40
+ "Format",
41
+ "HorizontalBarChart",
42
+ "Legend",
43
+ "LinePlot",
44
+ "StackedAreaPlot",
45
+ "StackedBarPlot",
46
+ "TypeCurve",
47
+ ]