Skip to content

Commit 1f28346

Browse files
authored
Merge pull request #12 from InfrastructureAsCode-ch/develop
Update dependencies Bump version
2 parents 463a869 + b166168 commit 1f28346

8 files changed

Lines changed: 253 additions & 221 deletions

File tree

.github/workflows/main.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@ jobs:
6767

6868
- name: Install Dependencies
6969
run: poetry install --no-interaction --no-root
70+
71+
- name: Poetry show
72+
run: poetry show
73+
74+
- name: Poetry env info
75+
run: poetry env info
7076

7177
- name: Force using UTF-8 encoding for windows tests
72-
run: make pytest
78+
run: poetry run python -m pytest -vs
7379
if: ${{ matrix.platform == 'windows-latest' }}
7480
env:
7581
PYTHONIOENCODING: utf-8

demo.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ def greet_and_count(task: Task, number: int) -> Result:
6666

6767
print_result(results)
6868
print_result(results, vars=["diff", "result", "name", "exception", "severity_level"])
69+
print_result(
70+
results,
71+
vars=["diff", "result", "name", "exception", "severity_level"],
72+
line_breaks=True,
73+
)
6974
print_failed_hosts(results)
7075

7176
print_inventory(nr)

nornir_rich/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.1.5" # From Makefile
1+
__version__ = "0.1.6" # From Makefile

nornir_rich/functions.py

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
import threading
3-
from typing import Any, List, Union, Dict
4-
from rich.console import RenderableType
3+
from typing import Any, List, Union, Dict, Tuple, Optional
4+
from rich.console import RenderableType, ConsoleRenderable
55

66
from nornir.core import Nornir
77
from nornir.core.inventory import Inventory
@@ -10,10 +10,11 @@
1010
from rich import print
1111
from rich.columns import Columns
1212
from rich.panel import Panel
13-
from rich.scope import render_scope
1413
from rich.padding import PaddingDimensions
1514
from rich.pretty import Pretty
1615
from rich.protocol import is_renderable, rich_cast
16+
from rich.table import Table
17+
from rich.text import Text
1718

1819

1920
LOCK = threading.Lock()
@@ -31,17 +32,19 @@ class RichHelper:
3132
vars: Which attributes you want to print
3233
severity_level: Print only errors with this severity level or higher
3334
failed: if ``True`` assume the task failed
35+
line_breaks: if ``True`` line breaks in strings will be printed
3436
"""
3537

3638
def __init__(
3739
self,
3840
columns_settings: Dict[str, Any] = dict(),
39-
padding: PaddingDimensions = None,
41+
padding: Optional[PaddingDimensions] = None,
4042
expand: bool = False,
4143
equal: bool = True,
42-
vars: List[str] = None,
44+
vars: Optional[List[str]] = None,
4345
severity_level: int = 0,
44-
failed: bool = None,
46+
failed: Optional[bool] = None,
47+
line_breaks: Optional[bool] = None,
4548
) -> None:
4649
self.columns_settings = columns_settings
4750
self.columns_settings["expand"] = expand
@@ -51,6 +54,7 @@ def __init__(
5154
self.vars = vars
5255
self.severity_level = severity_level
5356
self.failed = failed
57+
self.line_breaks = line_breaks
5458

5559
def print_aggregated_result(self, result: AggregatedResult) -> Panel:
5660
"""
@@ -110,7 +114,7 @@ def print_result(self, result: Result) -> Union[Panel, None]:
110114
return None
111115
if self.vars:
112116
return Panel(
113-
render_scope({x: getattr(result, x) for x in self.vars}),
117+
self._scope_talbe(scope={x: getattr(result, x) for x in self.vars}),
114118
title=result.name,
115119
style="red" if result.failed else "green",
116120
)
@@ -129,13 +133,15 @@ def print_result(self, result: Result) -> Union[Panel, None]:
129133
def print_scopes(self, scopes: Dict[str, Any]) -> Columns:
130134
if self.vars:
131135
columns = [
132-
render_scope(
136+
self._scope_talbe(
133137
{k: v for k, v in map.items() if k in self.vars}, title=name
134138
)
135139
for name, map in scopes.items()
136140
]
137141
else:
138-
columns = [render_scope(map, title=name) for name, map in scopes.items()]
142+
columns = [
143+
self._scope_talbe(map, title=name) for name, map in scopes.items()
144+
]
139145
return Columns(
140146
columns,
141147
**self.columns_settings,
@@ -161,16 +167,65 @@ def print_dispatch(
161167
return self.print_result(result)
162168
return Panel(f"Unable to find printer function for {result}")
163169

170+
def _scope_talbe(
171+
self,
172+
scope: "Dict[str, Any]",
173+
title: Optional[str] = None,
174+
) -> Panel:
175+
"""Render python variables in a given scope.
176+
177+
***This code is heavily inspired/copied by/from nornir.scope.render_scope***
178+
https://github.com/Textualize/rich/blob/master/rich/scope.py
179+
180+
Args:
181+
scope (Dict[str, Any]): A mapping containing variable names and values.
182+
183+
Returns:
184+
Panel: Panel containing the table with key value mapping
185+
"""
186+
items_table = Table.grid(padding=(0, 1), expand=False)
187+
items_table.add_column(justify="right")
188+
189+
def sort_items(item: Tuple[str, Any]) -> Tuple[bool, str]:
190+
"""Sort special variables first, then alphabetically."""
191+
key, _ = item
192+
return (not key.startswith("__"), key.lower())
193+
194+
items = sorted(scope.items(), key=sort_items)
195+
196+
for key, value in items:
197+
key_text = Text.assemble(
198+
(key, "scope.key.special" if key.startswith("__") else "scope.key"),
199+
(" =", "scope.equals"),
200+
)
201+
202+
if self.line_breaks and isinstance(value, str):
203+
value_text: ConsoleRenderable = Text(value.strip())
204+
else:
205+
value_text = Pretty(value)
206+
207+
items_table.add_row(
208+
key_text,
209+
value_text,
210+
)
211+
return Panel.fit(
212+
items_table,
213+
title=title,
214+
border_style="scope.border",
215+
padding=(0, 1),
216+
)
217+
164218

165219
def print_result(
166220
result: Union[Result, MultiResult, AggregatedResult],
167-
vars: List[str] = None,
221+
vars: Optional[List[str]] = None,
168222
failed: bool = False,
169223
severity_level: int = logging.INFO,
170224
columns_settings: Dict[str, Any] = dict(),
171-
padding: PaddingDimensions = None,
225+
padding: Optional[PaddingDimensions] = None,
172226
expand: bool = False,
173227
equal: bool = True,
228+
line_breaks: bool = False,
174229
) -> None:
175230
"""
176231
Prints an object of type `nornir.core.task.Result` || `nornir.core.task.MultiResult` || `nornir.core.task.AggregatedResult`
@@ -184,6 +239,7 @@ def print_result(
184239
padding: Optional padding around cells. Defaults to (0, 1).
185240
expand: Expand columns to full width. Defaults to False.
186241
equal: Equal sized columns. Defaults to False
242+
line_breaks: if ``True`` line breaks in strings will be printed
187243
"""
188244
LOCK.acquire()
189245
equal = False if expand else equal
@@ -195,6 +251,7 @@ def print_result(
195251
vars=vars,
196252
severity_level=severity_level,
197253
failed=failed,
254+
line_breaks=line_breaks,
198255
)
199256
try:
200257
if isinstance(result, AggregatedResult):
@@ -209,13 +266,14 @@ def print_result(
209266

210267
def print_failed_hosts(
211268
result: AggregatedResult,
212-
vars: List[str] = None,
269+
vars: Optional[List[str]] = None,
213270
failed: bool = False,
214271
severity_level: int = logging.INFO,
215272
columns_settings: Dict[str, Any] = dict(),
216-
padding: PaddingDimensions = None,
273+
padding: Optional[PaddingDimensions] = None,
217274
expand: bool = False,
218275
equal: bool = True,
276+
line_breaks: bool = False,
219277
) -> None:
220278
"""
221279
Prints results of all failed hosts from `nornir.core.task.AggregatedResult`
@@ -229,6 +287,7 @@ def print_failed_hosts(
229287
padding: Optional padding around cells. Defaults to (0, 1).
230288
expand: Expand columns to full width. Defaults to False.
231289
equal: Equal sized columns. Defaults to False
290+
line_breaks: if ``True`` line breaks in strings will be printed
232291
"""
233292
LOCK.acquire()
234293
equal = False if expand else equal
@@ -240,6 +299,7 @@ def print_failed_hosts(
240299
vars=vars,
241300
severity_level=severity_level,
242301
failed=failed,
302+
line_breaks=line_breaks,
243303
)
244304
try:
245305
for host, multi_result in result.failed_hosts.items():
@@ -250,11 +310,11 @@ def print_failed_hosts(
250310

251311
def print_inventory(
252312
inventory: Union[Inventory, Nornir],
253-
vars: List[str] = None,
313+
vars: Optional[List[str]] = None,
254314
failed: bool = False,
255315
severity_level: int = logging.INFO,
256316
columns_settings: Dict[str, Any] = dict(),
257-
padding: PaddingDimensions = None,
317+
padding: Optional[PaddingDimensions] = None,
258318
expand: bool = False,
259319
equal: bool = True,
260320
) -> None:

0 commit comments

Comments
 (0)