textualize / rich Goto Github PK
View Code? Open in Web Editor NEWRich is a Python library for rich text and beautiful formatting in the terminal.
Home Page: https://rich.readthedocs.io/en/latest/
License: MIT License
Rich is a Python library for rich text and beautiful formatting in the terminal.
Home Page: https://rich.readthedocs.io/en/latest/
License: MIT License
rich.traceback
makes stacktrace nicer but it wraps everything in 80 characters.
For example, see a screenshot in your blog post -- https://www.willmcgugan.com/blog/tech/post/better-python-tracebacks-with-rich/.
Traceback (most recent call last):
╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ File │
│"/home/USERNAME/.miniconda3/envs/longer-paths-for-reasons/lib/python3.7/site-packages/numpy/core/f│
│line 1477, in squeeze │
(... omitted)
│
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
As it truncates the full stacktrace line at certain characters, it becomes inconvenient for users to see which file to look at. I suggest we should not wrap them inside a box.
First off, AWESOME project. I'll definitely be tinkering with this.
Question: will you be applying a license to the code? I'm not here to push any license, but I do think at least having a license is a good idea.
Good job on the project 👏 👏
Hey, great project! Really awesome!
Just read about it and couldn't wait to play with it. 😃
I was trying to make it work in the Github Actions' shell (the online one) to get pretty colored text, but it seems to not be colorized somehow. 😢
Trying to gather some info online lead me nowhere... Still clueless (the only - maybe - useful thing being https://github.community/t5/GitHub-Actions/ANSI-color-output-in-webview/td-p/46226).
Posting, as you may be already aware of the issue (although I couldn't find a closed or open one).
As to what's happening, and how to reproduce:
I'm using code like this one:
from rich.console import Console
print("python print")
console = Console()
console.log("console.log", [1, "str"], 'https://github.com/willmcgugan/rich/blob/9cba2027f4/tests/test_color_triplet.py', {"k": 'v', "date": '00:46:54'}, None, '2009-11-27T00:00:00.000100-06:39')
console.print("console.print", [1, "str"], 'https://github.com/willmcgugan/rich/blob/9cba2027f4/tests/test_color_triplet.py', {"k": 'v', "date": '00:46:54'}, None, '2009-11-27T00:00:00.000100-06:39')
And seeing this locally on my Windows box (via Cmder) - which is fine:
But then this is what shows in the Actions section on Github:
Of course I'm open to test on my end, whatever you think might be of help.
PS: I've made a little repo to help reproduce the issue (https://github.com/azrafe7/test_python_rich_on_gh_pages)
Please let me know if and how can I help.
...And thank you for your work.
I want to format parts of a string that are being built up dynamically, but it seems that the color portion of
Hello!
Found a issue in the behaviour of Progress Bar starting rich 0.8.11:
> python --version
Python 3.7.4
> pip list | grep rich
rich 0.8.11
> python -m rich.progress
0 0 0
Downloading... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:-- 0 0 0
0 0 0
Downloading... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:--
Processing... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:-- 0 0 0
0 0 0
Downloading... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:--
Processing... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:--
Cooking... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:-- 2.5 0 0
Downloading... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% 0:00:41
Processing... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% 0:01:08
Cooking... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% 0:00:23 5.0 0 0
Downloading... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% 0:00:41
Processing... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% 0:01:08
Cooking... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1% 0:00:23 7.5 0 0
[...]
No issue with the 0.8.8
> python --version
Python 3.7.4
> pip list | grep rich
rich 0.8.11
> python -m rich.progress
Downloading... ━━╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7% 0:00:39
Processing... ━╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4% 0:01:07
Cooking... ━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 13% 0:00:21
While generating row's I'd like to set slightly different colour for every odd row, to make it easier to visually stay in line.
I can do something like this to hack around it:
def row(self, table, *rows):
clr = "grey93" if self.row_number % 2 == 0 else "white"
rows = [self.color(clr, row) for row in rows]
table.add_row(*rows)
self.row_number += 1
(self.color just wraps the string with the colour)
The problem with this approach is that as I'm not really setting the row style, I remove any existing colours that the row items may have, and I'd only like to change the default colour.
def fetch_file(url, filename):
with open(filename, "ab") as file:
headers = create_header()
pos = file.tell()
if pos:
headers['Range'] = f'bytes={pos}-'
response = requests.get(url, headers=headers, stream=True)
total_size = int(response.headers.get('content-length'))
task_id = download_progress.add_task(description="Downloading", filename=filename, total=total_size, completed=pos)
for data in response.iter_content(chunk_size=1024):
file.write(data)
download_progress.advance(task_id=task_id, advance=len(data))
This code will not update the progress bar and it will only be renderd once.
Changing the last line todownload_progress.update(task_id=task_id, advance=len(data), refresh=True)
fixes it but makes the progress bar update to frequent.
This was done using Windows Terminal,
In [9]: with Progress() as progress:
...: a_task = progress.add_task("thing", total=41)
...: progress.start()
...: for cnt in range(41):
...: time.sleep(.1)
...: progress.update(a_task, 1)
...:
thing ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0% -:--:-- Exception in thread Thread-704:
Traceback (most recent call last):
File "/org/seg/tools/freeware/python/3.6.3/1/el-6-x86_64/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/home/bphunter/.cache/pypoetry/virtualenvs/icmerge-0gw-uTeS-py3.6/lib/python3.6/site-packages/rich/progress.py", line 289, in run
self.progress.refresh()
File "/home/bphunter/.cache/pypoetry/virtualenvs/icmerge-0gw-uTeS-py3.6/lib/python3.6/site-packages/rich/progress.py", line 501, in refresh
self._live_render.set_renderable(self._table)
File "/home/bphunter/.cache/pypoetry/virtualenvs/icmerge-0gw-uTeS-py3.6/lib/python3.6/site-packages/rich/progress.py", line 521, in _table
widget = column(task)
File "/home/bphunter/.cache/pypoetry/virtualenvs/icmerge-0gw-uTeS-py3.6/lib/python3.6/site-packages/rich/progress.py", line 107, in __call__
renderable = self.render(task)
File "/home/bphunter/.cache/pypoetry/virtualenvs/icmerge-0gw-uTeS-py3.6/lib/python3.6/site-packages/rich/progress.py", line 136, in render
remaining = task.time_remaining
File "/home/bphunter/.cache/pypoetry/virtualenvs/icmerge-0gw-uTeS-py3.6/lib/python3.6/site-packages/rich/progress.py", line 270, in time_remaining
estimate = ceil(self.remaining / speed)
ZeroDivisionError: float division by zero
In readme there is a row that is wrong in the add_column.
From:
table.add_columngit ("Production Budget", justify="right")
To:
table.add_column ("Production Budget", justify="right")
I suggest using codecov for that (with a config that disables its comments, so that only PR/commit statuses are reported).
I also suggest having a tox configuration for this then, so that tox -e py38-coverage
could be used on CI, but also locally in the same way.
I'd be happy to contribute whatever you prefer.
I'm looking for a way to write something to my terminal without automatically taking a newline. With the print
builtin, I can pass an empty string as the end
paramter. The end
parameter in Console.print
doesn't seem to work in the same way however.
Example:
print(".", end="")
print(".", end="")
print(".", end="")
console.print(".", end="")
console.print(".", end="")
console.print(".", end="")
Output:
....
.
.
Expected output:
......
It also seems to add a space before the end
character:
Example:
print(".", end="x")
console.print(".", end="x")
Output:
.x. x
Expected output:
.x.x
is it possible to load progress inside table row ?
sep
behaves differently from builtin print. I don't know if this is intentional or not, but the behaviour is slightly different from how the docs describe it. (I didn't expect the sep
to be added to the end of the string, only between the printed items).
Example:
print(".", ".", sep="a")
console.print(".", ".", sep="a")
Output:
.a.
.a.a
Expected output:
.a.
.a.
I've got a table which I created like so:
table = Table(show_header=False, padding=0, show_edge=False, box=0)
table.add_column("outcome", style=theme, width=6, justify="center")
table.add_column("location", style="test-location")
table.add_column("description", style="none")
table.add_row(outcome, location, f"{description} {reason}")
If the description
contains two underscores, such as in many Python function names, the underscores are removed.
For example, in the following screenshot, the top line is the description string. The bottom line is the description as displayed in the table.
This doesn't happen if the description contains a single _
. I was guessing it was trying to render it as Markdown or something, but I get the same issue when setting markup=False
when initialising the Console
. 😄
Any plans/thoughts on including progress bar functionality?
I know they're another big pill to swallow, but they certainly could fit the premise of rich. Integrating outside progress bar libraries isn't great as it is right now.
I guess correct rendering won't let the number of rows be rendered?
However, I actually hope that there is an option to ignore the excess of the long code, because I think that traceback is only to facilitate the location of the faulty code line, and it is not necessary to display everything.
The excess can be marked as an ellipsis at the rear.
I couldn't find a list in the readme.
Hi @willmcgugan! Looks like an awesome library. I'm really interested in using this for terminal rendering of Markdown files, but I need to be able to render Markdown tables. Is that something you think would fit in this library?
from rich.console import Console
Console.print("Where there is a [bold cyan]Will[/bold cyan] there [u]is[/u] a [i]way[/i].")
Traceback (most recent call last):
File "", line 1, in
File "/home/damon/src/virtualenv-16.7.6/bun/lib/python3.8/site-packages/rich/console.py", line 740, in print
self.line()
AttributeError: 'str' object has no attribute 'line'
Great library! Would it be possible to add a sorting by columns feature?
Your blog post refers to rich.logging.RichHandler
, which is present in the code, but doesn't show up in ReadTheDocs.
First of all I want to say that this is an amazing project! Thanks for the work :D
I would like to suggest the possibility of creating plots in the terminal as a future feature.
If I have a variable in my string and it has white space (seems some symbols too?) around it, it seems to take on a default color of blue. So this code:
from rich.console import Console
console = Console()
a = 5
console.print(f"[red]a: {a}[/red]")
give me the output where a:
is red, but the value of a is in blue.
but this code:
console.print(f"[red]a{a}[/red]")
gives me a5
all in red.
console.print(f"[red]a:{a}[/red]")
And that gives me a:
in red and the value of a
in blue.
I tried the example code in a script:-
from rich.console import Console
from rich.markdown import Markdown
console = Console()
with open("README.md") as readme:
markdown = Markdown(readme.read())
console.print(markdown)
When I run the script and pipe it to less
to read a file longer than a page, all the formatting is lost. How can one ensure that the formatting persists?
Hi, thanks for this wonderful library.
I just randomly discovered this error:
$ ./venv36/bin/python -c "from rich.console import Console"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/michal/python/SzT/venv36/lib/python3.6/site-packages/rich/console.py", line 38, in <module>
from .default_styles import DEFAULT_STYLES
File "/home/michal/python/SzT/venv36/lib/python3.6/site-packages/rich/default_styles.py", line 18, in <module>
strike=False,
File "/home/michal/python/SzT/venv36/lib/python3.6/site-packages/rich/style.py", line 73, in __init__
self._color = None if color is None else _make_color(color)
File "/home/michal/python/SzT/venv36/lib/python3.6/site-packages/rich/style.py", line 71, in _make_color
return color if isinstance(color, Color) else Color.parse(color)
AttributeError: type object 'Color' has no attribute 'parse'
Python versions 3.6.2 and 3.6.4 don't exhibit this issue.
The Color
class clearly does have a parse
class method. However:
$ ./venv36/bin/python -c "from rich.color import Color; print(hasattr(Color, 'parse'))"
False
$ ./venv362/bin/python -c "from rich.color import Color; print(hasattr(Color, 'parse'))"
True
$ ./venv364/bin/python -c "from rich.color import Color; print(hasattr(Color, 'parse'))"
True
In 2017 some terminals gained support for hyperlinks.
It would be very nice if in addition to the other BBcode-style formats we can use, like [bold]
, we could also use [url]
.
Python can output hyperlinks like so: print("\033]8;;http://example.com\033\\This is a link\033]8;;\033\\")
An example BBcode-style implementation might be: [url="http://example.com"]This is a link[/url]
Something similar to tqdm's auto
module would be helpful. This would mean I can run the same code in Jupyter or a terminal and get the same rich
experience.
Basically, it would just be a small wrapper that does a simple check to whether or not we are in an IPython environment or a regular Python one, and then import the console
and print
objects from the correct package. Then you could write code like this, knowing it would work wherever it was run:
from rich.auto import print
print("[bold magenta]Hello, world![\]")
Alternatively you could put this functionality into the default imports; I'm not sure why you would ever not want this (other than to avoid the overhead of checking, but that's fairly minimal).
Bold formatting seems to be dropped whenever quotes are places around the square brackets used for format tagging.
from rich.console import Console
console = Console()
console.log("[bold green]hello world![/bold green]")
console.log("'[bold green]hello world![/bold green]'")
rich 1.0.0
Python 3.6.6
macOS High Sierra
It would be nice if we could specify the output stream that console.print() should output to. For example, a terminal based program often needs to print to standard error. With vanilla Python it's possible with print("foo", file=sys.stderr)
. But I didn't find that kind of option in rich.
I can't tell from the documentation, or the PyPI classifiers, whether Windows is supported. I'd like it if it were, but obviously that's up to you as a developer. But could you document more clearly whether you do, so that I don't have to download the library and try it out to check?
Because the width of a CJK character is equal to the width of two letters, special handling may be required.
See: https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms
Test coverage is currently siting at 89%. I'd love to get that up to high nineties before a 1.0.0 release.
If you can, contribute a test. Even if it only adds a single line to coverage, it would be appreciated!
The documentation for Text.assemble()
says:
The positional arguments should be either strings, or a tuple of string + style.
but it looks like bare strings don't work; the code passes *part
to append()
without checking if it's actually a tuple.
So, long strings (exceeding the width of the console) aren't wrapped and result in output like:
cf69f8a0618f3bb8ba0ed2cc31d730827b09c3ca
README.md
2.91 KiB
16 KiB
1
Yes
2020-03-08 15:27:37 -04:00
thorod 2.0.0
magnet:?dn=README.md&xt=urn:btih:cf69f8a0618f3bb8ba0ed2cc31d730827b09c3ca&xl=2984&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://9.rarbg.to:2710/an
where the string is cut and the left column disappears instead of something like:
Info Hash: 212769dc7fdac4030d93b517720914fd575b3ce1
Torrent Name: README.md
Data Size: 2.91 KiB
Piece Size: 16 KiB
Piece Count: 1
Private: Yes
Creation Date: 2020-03-08 15:27:07 -04:00
Created By: thorod 2.0.0
Comment:
Source:
Magnet: magnet:?dn=README.md&xt=urn:btih:212769dc7fdac4030d93b517720914fd575b3ce1&xl=2984&tr=udp://explodie.org:6969/announce
Should rich be wrapping these itself?
Hi! 👋
I've defined a console and theme like so. I think there's some out of date docs around constructing consoles, so I've read the code and this is what I got to:
from rich.theme import Theme, Style as St
theme = Theme({
"pass-tag": St.parse("white on green"),
"fail-tag": St.parse("white on red"),
"skip-tag": St.parse("white on blue"),
"xfail-tag": St.parse("white on magenta"),
"xpass-tag": St.parse("white on yellow"),
"dryrun-tag": St.parse("white on green"),
"test-location": St.parse("dim white"),
})
console = Console(theme=theme)
Is this the intended usage?
P.S. Happy to make a PR updating the docs if so! :)
On some consoles the output width seems to be calculated one character too wide. See the following example:
>>> from rich.console import Console
>>> from rich.table import Table
>>> c = Console()
>>> t = Table("Yo!", "Tables!")
>>> t.add_row("a", "row")
>>> t.add_row("another", "row")
>>> c.print(t)
┏━━━━━━━━━┳━━━━━━━━━┓
┃ Yo! ┃ Tables! ┃
┡━━━━━━━━━╇━━━━━━━━━┩
│ a │ row │
│ another │ row │
└─────────┴─────────┘
>>> c = Console(width=c.width-1)
>>> c.print(t)
┏━━━━━━━━━┳━━━━━━━━━┓
┃ Yo! ┃ Tables! ┃
┡━━━━━━━━━╇━━━━━━━━━┩
│ a │ row │
│ another │ row │
└─────────┴─────────┘
I played around a bit and tested some combinations, some seem fine, others not:
Source System is Win10, the system the console runs on was either Ubuntu 18 or Oracle Linux
A possible workaround is as shown above: get a Console, and then get another one which is one narrower than the first one.
Looking ath the code, i understand that you are retrieving the terminal size via shutil.get_terminal_size()
, so maybe that issue is beyond the reach of the lib.
I'm really liking this library!
One thing ... I seem to be having trouble with tables with widths greater than 80 chars. Tried the various width options, but no luck. Thoughts?
Thanks.
Really nice work! Is there an abstraction for moving the cursor and/or updating several lines (or renderable objects) in place, or should I just use the terminal control codes? I had a brief look at the code but didn't find the place where the actual drawing is done (e.g. for the progress bars).
rich
should have __version__
property.
AttributeError: module 'rich' has no attribute '__version__'
This is a common python convention to tell package version easily.
I'm trying to reconcile the requirements of this (wonderful) library with others in my requirement stack. Most line up; however, colorama seems to be a particular issue with a lot of libraries with the notable one for me being aws-cli
. Would you be open to changing the pinned requirement with something a bit more fluid such as colorama >= 4.0.0
? Not sure how you're using the specific version there, but I know being more flexible here will certainly help me/others 😄 .
Nice module!
I've noticed the following odd behavior: when using rich.print with bbcode tags, if the string contains matching quotes the substring between the quotes is colored green.
from rich import print
# Contains a quote pair, Malley is printed in green
print("[bold]O'Malley's Bar[/bold]")
# Only one quote, prints as expected
print("[bold]O'Malleys Bar[/bold]")
I've tried this with a few different tags, swapping the internal quote types, and using Console.print() but all show the same behavior.
It would be nice to feature of printing ascii arts in rich.
Trying to use yaml
in syntaxt highlighting fails:
from rich.console import Console
from rich.syntax import Syntax
console = Console()
code='''
yaml: true
'''
syntax = Syntax(code, 'yaml')
console.print(syntax)
$ python3 syntax.py
Traceback (most recent call last):
File "syntax.py", line 9, in <module>
console.print(syntax)
File "/home/todoesverso/.local/lib/python3.7/site-packages/rich/console.py", line 752, in print
extend(render(renderable, render_options))
File "/home/todoesverso/.local/lib/python3.7/site-packages/rich/console.py", line 520, in render
yield from self._render(renderable, options)
File "/home/todoesverso/.local/lib/python3.7/site-packages/rich/console.py", line 496, in _render
for render_output in iter_render:
File "/home/todoesverso/.local/lib/python3.7/site-packages/rich/syntax.py", line 209, in __console__
text = self._highlight(self.lexer_name)
File "/home/todoesverso/.local/lib/python3.7/site-packages/rich/syntax.py", line 156, in _highlight
append(token, _get_theme_style(token_type))
File "/home/todoesverso/.local/lib/python3.7/site-packages/rich/syntax.py", line 125, in _get_theme_style
pygments_style = self._pygments_style_class.style_for_token(token_type)
File "/home/todoesverso/.local/lib/python3.7/site-packages/pygments/style.py", line 128, in style_for_token
t = cls._styles[token]
KeyError: Token.Literal.Scalar.Plain
I was using rich for a ML project and find it super useful! Kudos for building this awesome project.
I did have a feature request though
Can you add support for printing into notebooks. Jupyter notebooks does support rendering HTML and your library does export HTML and I was able to hack together some awesome outputs but it would be cool to have native support. Especially some repr_html for attributes like table text etc.
I would love to help add this feature!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.