Package: wasabi
wasabi: A lightweight console printing and formatting toolkitOver the years, I've written countless implementations of coloring and
formatting utilities to output messages in our libraries likespaCy,ThincandProdigy. While there are many other great open-source
options, I've always ended up wanting something slightly different or slightly
custom.This package is still a work in progress and aims to bundle those utilities in a
standardised way so they can be shared across our other projects. It's super
lightweight, has zero dependencies and works with Python 3.6+.💬 FAQAre you going to add more features?Yes, there's still a few of helpers and features to port over. However, the new
features will be heavily biased by what we (think we) need. I always appreciate
pull requests to improve the existing functionality – but I want to keep this
library as simple, lightweight and specific as possible.Can I use this for my projects?Sure, if you like it, feel free to adopt it! Just keep in mind that the package
is very specific and not intended to be a full-featured and fully customisable
formatting library. If that's what you're looking for, you might want to try
other packages – for example,colored,crayons,colorful,tabulate,consoleorpy-term, to name a few.Whywasabi?I was looking for a short and descriptive name, but everything was already
taken. So I ended up naming this package after one of my rats, Wasabi. 🐀⌛️ Installationpipinstallwasabi🎛 APIfunctionmsgAn instance ofPrinter, initialized with the default config. Useful as a quick
shortcut if you don't need to customize initialization.fromwasabiimportmsgmsg.good("Success!")classPrintermethodPrinter.__init__fromwasabiimportPrintermsg=Printer()ArgumentTypeDescriptionDefaultprettyboolPretty-print output with colors and icons.Trueno_printboolDon't actually print, just return.FalsecolorsdictAdd or overwrite color values, names mapped to0-256.NoneiconsdictAdd or overwrite icon. Name mapped to unicode.Noneline_maxintMaximum line length (for divider).80animationstrSteps of loading animation forPrinter.loading."⠙⠹⠸⠼⠴⠦⠧⠇⠏"animation_asciistrAlternative animation for ASCII terminals."|/-\\"hide_animationboolDon't display animation, e.g. for logs.Falseignore_warningsboolDon't output messages of typeMESSAGE.WARN.Falseenv_prefixstrPrefix for environment variables, e.g.WASABI_LOG_FRIENDLY."WASABI"timestampboolAdd timestamp before output.FalseRETURNSPrinterThe initialized printer.-methodPrinter.textmsg=Printer()msg.text("Hello world!")ArgumentTypeDescriptionDefaulttitlestrThe main text to print.""textstrOptional additional text to print.""colorunicode / intColor name or value.NoneiconstrName of icon to add.NoneshowboolWhether to print or not. Can be used to only output messages under certain condition, e.g. if--verboseflag is set.TruespacedboolWhether to add newlines around the output.Falseno_printboolDon't actually print, just return. Overwrites global setting.FalseexitsintIf set, perform a system exit with the given code after printing.NonemethodPrinter.good,Printer.fail,Printer.warn,Printer.infoPrint special formatted messages.msg=Printer()msg.good("Success")msg.fail("Error")msg.warn("Warning")msg.info("Info")ArgumentTypeDescriptionDefaulttitlestrThe main text to print.""textstrOptional additional text to print.""showboolWhether to print or not. Can be used to only output messages under certain condition, e.g. if--verboseflag is set.TrueexitsintIf set, perform a system exit with the given code after printing.NonemethodPrinter.dividerPrint a formatted divider.msg=Printer()msg.divider("Heading")ArgumentTypeDescriptionDefaulttextstrHeadline text. If empty, only the line is printed.""charstrSingle line character to repeat."="showboolWhether to print or not. Can be used to only output messages under certain condition, e.g. if--verboseflag is set.TrueiconstrOptional icon to use with title.NonecontextmanagerPrinter.loadingmsg=Printer()withmsg.loading("Loading..."):# Do something here that takes longertime.sleep(10)msg.good("Successfully loaded something!")ArgumentTypeDescriptionDefaulttextstrThe text to display while loading."Loading..."methodPrinter.table,Printer.rowSeeTables.propertyPrinter.countsGet the counts of how often the special printers were fired, e.g.MESSAGES.GOOD. Can be used to print an overview like "X warnings"msg=Printer()msg.good("Success")msg.fail("Error")msg.warn("Error")print(msg.counts)# Counter({'good': 1, 'fail': 2, 'warn': 0, 'info': 0})ArgumentTypeDescriptionRETURNSCounterThe counts for the individual special message types.TablesfunctiontableLightweight helper to format tabular data.fromwasabiimporttabledata=[("a1","a2","a3"),("b1","b2","b3")]header=("Column 1","Column 2","Column 3")widths=(8,9,10)aligns=("r","c","l")formatted=table(data,header=header,divider=True,widths=widths,aligns=aligns)Column 1   Column 2    Column 3
--------   ---------   ----------
      a1      a2       a3
      b1      b2       b3ArgumentTypeDescriptionDefaultdataiterable / dictThe data to render. Either a list of lists (one per row) or a dict for two-column tables.headeriterableOptional header columns.NonefooteriterableOptional footer columns.NonedividerboolShow a divider line between header/footer and body.Falsewidthsiterable /"auto"Column widths in order. If"auto", widths will be calculated automatically based on the largest value."auto"max_colintMaximum column width.30spacingintNumber of spaces between columns.3alignsiterable / unicodeColumns alignments in order."l"(left, default),"r"(right) or"c"(center). If If a string, value is used for all columns.NonemultilineboolIf a cell value is a list of a tuple, render it on multiple lines, with one value per line.Falseenv_prefixunicodePrefix for environment variables, e.g. WASABI_LOG_FRIENDLY."WASABI"color_valuesdictAdd or overwrite color values, name mapped to value.Nonefg_colorsiterableForeground colors, one per column. None can be specified for individual columns to retain the default background color.Nonebg_colorsiterableBackground colors, one per column. None can be specified for individual columns to retain the default background color.NoneRETURNSstrThe formatted table.functionrowfromwasabiimportrowdata=("a1","a2","a3")formatted=row(data)a1   a2   a3ArgumentTypeDescriptionDefaultdataiterableThe individual columns to format.widthslist / int /"auto"Column widths, either one integer for all columns or an iterable of values. If "auto", widths will be calculated automatically based on the largest value."auto"spacingintNumber of spaces between columns.3alignslistColumns alignments in order."l"(left),"r"(right) or"c"(center).Noneenv_prefixunicodePrefix for environment variables, e.g. WASABI_LOG_FRIENDLY."WASABI"fg_colorslistForeground colors for the columns, in order. None can be specified for individual columns to retain the default foreground color.Nonebg_colorslistBackground colors for the columns, in order. None can be specified for individual columns to retain the default background color.NoneRETURNSstrThe formatted row.classTracebackPrinterHelper to output custom formatted tracebacks and error messages. Currently used
inThinc.methodTracebackPrinter.__init__Initialize a traceback printer.fromwasabiimportTracebackPrintertb=TracebackPrinter(tb_base="thinc",tb_exclude=("check.py",))ArgumentTypeDescriptionDefaultcolor_errorstr / intColor name or code for errors (passed tocolorhelper)."red"color_tbstr / intColor name or code for traceback headline (passed tocolorhelper)."blue"color_highlightstr / intColor name or code for highlighted text (passed tocolorhelper)."yellow"indentintNumber of spaces to use for indentation.2tb_basestrName of directory to use to show relative paths. For example,"thinc"will look for the last occurence of"/thinc/"in a path and only show path to the right of it.Nonetb_excludetupleList of filenames to exclude from traceback.tuple()RETURNSTracebackPrinterThe traceback printer.methodTracebackPrinter.__call__Output custom formatted tracebacks and errors.fromwasabiimportTracebackPrinterimporttracebacktb=TracebackPrinter(tb_base="thinc",tb_exclude=("check.py",))error=tb("Some error","Error description",highlight="kwargs",tb=traceback.extract_stack())raiseValueError(error)Some error
  Some error description

  Traceback:
  ├─ <lambda> [61] in .env/lib/python3.6/site-packages/pluggy/manager.py
  ├─── _multicall [187] in .env/lib/python3.6/site-packages/pluggy/callers.py
  └───── pytest_fixture_setup [969] in .env/lib/python3.6/site-packages/_pytest/fixtures.py
         >>> result = call_fixture_func(fixturefunc, request, kwargs)ArgumentTypeDescriptionDefaulttitlestrThe message title.*textsstrOptional texts to print (one per line).highlightstrOptional sequence to highlight in the traceback, e.g. the bad value that caused the error.FalsetbiterableThe traceback, e.g. generated bytraceback.extract_stack().NoneRETURNSstrThe formatted traceback. Can be printed or raised by custom exception.classMarkdownRendererHelper to create Markdown-formatted content. Will store the blocks added to the
Markdown document in order.fromwasabiimportMarkdownRenderermd=MarkdownRenderer()md.add(md.title(1,"Hello world"))md.add("This is a paragraph")print(md.text)methodMarkdownRenderer.__init__Initialize a Markdown renderer.fromwasabiimportMarkdownRenderermd=MarkdownRenderer()ArgumentTypeDescriptionDefaultno_emojiboolDon't include emoji in titles.FalseRETURNSMarkdownRendererThe renderer.methodMarkdownRenderer.addAdd a block to the Markdown document.fromwasabiimportMarkdownRenderermd=MarkdownRenderer()md.add("This is a paragraph")ArgumentTypeDescriptionDefaulttextstrThe content to add.propertyMarkdownRenderer.textThe rendered Markdown document.md=MarkdownRenderer()md.add("This is a paragraph")print(md.text)ArgumentTypeDescriptionDefaultRETURNSstrThe document as a single string.methodMarkdownRenderer.tableCreate a Markdown-formatted table.md=MarkdownRenderer()table=md.table([("a","b"),("c","d")],["Column 1","Column 2"])md.add(table)| Column 1 | Column 2 |
| --- | --- |
| a | b |
| c | d |ArgumentTypeDescriptionDefaultdataIterable[Iterable[str]]The body, one iterable per row, containig an interable of column contents.headerIterable[str]The column names.alignsIterable[str]Columns alignments in order."l"(left, default),"r"(right) or"c"(center).NoneRETURNSstrThe table.methodMarkdownRenderer.titleCreate a Markdown-formatted heading.md=MarkdownRenderer()md.add(md.title(1,"Hello world"))md.add(md.title(2,"Subheading","💖"))# Hello world## 💖 SubheadingArgumentTypeDescriptionDefaultlevelintThe heading level, e.g.3for###.textstrThe heading text.emojistrOptional emoji to show before heading.NoneRETURNSstrThe rendered title.methodMarkdownRenderer.listCreate a Markdown-formatted non-nested list.md=MarkdownRenderer()md.add(md.list(["item","other item"]))md.add(md.list(["first item","second item"],numbered=True))-item-other item1.first item2.second itemArgumentTypeDescriptionDefaultitemsIterable[str]The list items.numberedboolWhether to use a numbered list.FalseRETURNSstrThe rendered list.methodMarkdownRenderer.linkCreate a Markdown-formatted link.md=MarkdownRenderer()md.add(md.link("Google","https://google.com"))[Google](https://google.com)ArgumentTypeDescriptionDefaulttextstrThe link text.urlstrThe link URL.RETURNSstrThe rendered link.methodMarkdownRenderer.code_blockCreate a Markdown-formatted code block.md=MarkdownRenderer()md.add(md.code_block("import spacy","python"))```pythonimportspacy```ArgumentTypeDescriptionDefaulttextstrThe code text.langstrOptional code language.""RETURNSstrThe rendered code block.methodMarkdownRenderer.code,MarkdownRenderer.bold,MarkdownRenderer.italicCreate a Markdown-formatted text.md=MarkdownRenderer()md.add(md.code("import spacy"))md.add(md.bold("Hello!"))md.add(md.italic("Emphasis"))`import spacy`**Hello!**_Emphasis_Utilitiesfunctioncolorfromwasabiimportcolorformatted=color("This is a text",fg="white",bg="green",bold=True)ArgumentTypeDescriptionDefaulttextstrThe text to be formatted.-fgstr / intForeground color. String name or0-256.Nonebgstr / intBackground color. String name or0-256.NoneboldboolFormat the text in bold.FalseunderlineboolFormat the text by underlining.FalseRETURNSstrThe formatted string.functionwrapfromwasabiimportwrapwrapped=wrap("Hello world, this is a text.",indent=2)ArgumentTypeDescriptionDefaulttextstrThe text to wrap.-wrap_maxintMaximum line width, including indentation.80indentintNumber of spaces used for indentation.4RETURNSstrThe wrapped text with line breaks.functiondiff_stringsfromwasabiimportdiff_stringsdiff=diff_strings("hello world!","helloo world")ArgumentTypeDescriptionDefaultastrThe first string to diff.bstrThe second string to diff.fgstr / intForeground color. String name or0-256."black"bgtupleBackground colors as(insert, delete)tuple of string name or0-256.("green", "red")RETURNSstrThe formatted diff.Environment variablesWasabi also respects the following environment variables. The prefix can be
customised on thePrintervia theenv_prefixargument. For example, settingenv_prefix="SPACY"will expect the environment variableSPACY_LOG_FRIENDLY.NameDescriptionANSI_COLORS_DISABLEDDisable colors.WASABI_LOG_FRIENDLYMake output nicer for logs (no colors, no animations).WASABI_NO_PRETTYDisable pretty printing, e.g. colors and icons.🔔 Run testsFork or clone the repo, make sure you havepytestinstalled and then run it on
the package directory. The tests are located in/wasabi/tests.pipinstallpytestcdwasabi
python-mpytestwasabi