Quick-Start Guide

Welcome to the quick-start guide! (Well, it’s more of a formal documentation)

We will go through and explain each element of framed_text, from simple frames to complex data structures and progress bars!

More specifically, this guide will cover:

  • framed_text.FramedText

  • framed_text.LabeledData

  • framed_text.Status

  • framed_text.FramedHeader

  • framed_text.ShortenText

  • framed_text.ProgressBar

  • framed_text.Spinner

Important

Make sure to import the module first!

1from framed_text import FramedText, LabeledData, Status, ... # Any other items you need

Adding Frames around Text

The basic parameters for FramedText include:

  • framed_color: The color of the frame

  • title: The title of the frame

  • title_color: The color of the title

  • attrs: The attributes of the title

  • text: The text to display

We’ll go over each of these parameters in detail.

Creating a Simple Frame with Text

You can create a simple frame using the following code:

Using the FramedText class
1ft: FramedText = FramedText(
2  text=[
3    "Hello world"
4  ]
5)
6print(ft)
_images/quickstart_1.png

We can add more text by adding more strings to the text list:

Multiple lines can be added to the text list
1ft: FramedText = FramedText(
2  text=[
3    "Hello world",
4    "Another line",
5    "Another Another line"
6  ]
7)
8print(ft)
_images/quickstart_2.png

Styling the Frame and Adding a Title

You can color the frame using the framed_color parameter:

Coloring the frame red
1ft: FramedText = FramedText(
2  frame_color="red",
3  text=[
4    "Hello world"
5  ]
6)
7print(ft)
_images/quickstart_5.png

You can add a title to the frame using the title parameter:

A simple title for the frame
1ft: FramedText = FramedText(
2  title="This is a title",
3  frame_color="red",
4  text=[
5    "Hello world"
6  ]
7)
8print(ft)
_images/quickstart_6.png

To color the title, use title_color:

Coloring the title green. Note that the frame color is still red.
1ft: FramedText = FramedText(
2  title="This is a title",
3  frame_color="red",
4  title_color="green",
5  text=[
6    "Hello world"
7  ]
8)
9print(ft)
_images/quickstart_7.png

The title supports termcolor’s formatting options using attrs parameter:

Applying a bold and underline style to the title. The title color is still green.
 1ft: FramedText = FramedText(
 2  title="This is a title",
 3  frame_color="red",
 4  title_color="green",
 5  attrs=["bold", "underline"],
 6  text=[
 7    "Hello world"
 8  ]
 9)
10print(ft)
_images/quickstart_8.png

Advanced Parameters

In addition to the above parameters, FramedText also features:

  • cutoff: If true, will cut off text if it exceeds the terminal width

  • mode: Determines how text is cut off. Used with cutoff

  • allow_ansi: If true, will allow ANSI codes to be displayed. By default, this is false for reasons we’ll get to.

  • center_text: If true, will center the text display to the middle of the frame.

Added in version 2026.06.03.18.00:

  • frame_size: Determines how the frame is rendered. See frame_size for more information.

mode

Changed in version 2026.05.04.17.15: mode now applies to all str objects in the text parameter, not just LabeledData and Status objects.

mode can be one of the following:

  • "char": Cut off the line based on which character surpasses the terminal width

  • "word": Cut off the line based on which character surpasses the terminal width

  • "middle": Trim the middle of the line until it fits the terminal width

Below are examples of each mode:

When mode is set to "char"
"The quick brown fox jumped ove…"
When mode is set to "word"
"The quick brown fox jumped…"
When mode is set to "middle"
"The quick brown…the lazy dog"

Note

LabeledData.Path behaves differently when mode is set to "word".

Parts of the path will be cut and replaced with an ellipsis if the path exceeds the limit:

  • "/home/user/path/to/a/file.txt" becomes "/home/user/path/…/file.text"

allow_ansi

This parameter is present due to the way cutoff works.

termcolor formatted strings contain ANSI codes (e.g. \x1b[31m for red). Normally, this wouldn’t be an issue, however, when cutoff is enabled, there is the issue of the ANSI codes being cut off, which could mess up the display of the framed text.

Because of this, any strings containing ANSI codes will have their codes removed! The only exceptions are for the objects provided by framed_text (e.g. Status and LabeledData).

However, if you want to allow ANSI codes to be displayed, you can set allow_ansi to true.

frame_size

Added in version 2026.06.03.18.00.

This parameter controls how the frame is rendered. It has the following options:

  • "full": The default mode. Frame size is based on terminal width

 1ft: FramedText = FramedText(
 2    title="Frame Size",
 3    frame_color="blue",
 4    text=[
 5        "A plain string",
 6        LabeledData.String(
 7            label="LabeledData.String",
 8            value="A String value",
 9            suffix="with a suffix"
10        ),
11        Status.Info(msg="An info message"),
12    ]
13)
14print(ft)
_images/quickstart_20.png
  • "dynamic": Frame size is based on text length

 1ft: FramedText = FramedText(
 2    title="Frame Size",
 3    frame_color="blue",
 4    frame_size="dynamic",
 5    text=[
 6        "A plain string",
 7        LabeledData.String(
 8            label="LabeledData.String",
 9            value="A String value",
10            suffix="with a suffix"
11        ),
12        Status.Info(msg="An info message"),
13    ]
14)
15print(ft)
_images/quickstart_21.png

When using center_text in conjunction with "dynamic", the entire frame will be centered.

 1ft: FramedText = FramedText(
 2    title="Frame Size",
 3    frame_color="blue",
 4    center_text=True,
 5    frame_size="dynamic",
 6    text=[
 7        "A plain string",
 8        LabeledData.String(
 9            label="LabeledData.String",
10            value="A String value",
11            suffix="with a suffix"
12        ),
13        Status.Info(msg="An info message"),
14    ]
15)
16print(ft)
_images/quickstart_22.png

Data with Labels

To add data to the text with a label, it’s recommended to use LabeledData.

LabeledData is a collection of typed objects that can be used to display data in a frame.

Each class of LabeledData has the following base parameters:

  • label: A label to assign to the text

  • value: The value to display

  • quotes: Whether to add quotes around the value

Added in version 2026.05.15.14.30: Added LabeledData.Date

Added in version 2026.05.21.16.30:

  • Added LabeledData.Bytes

  • Changed default colors for LabeledData.Number and LabeledData.Date

Changed in version 2026.04.03.16.00: Used to be color and attrs.

  • val_color: The color for the value [1].

  • val_attrs: The attribute(s) for the value [2].

Added in version 2026.04.03.16.00:

  • label_color: The color for the label [1].

  • label_attrs: The attribute(s) for the label [2].

  • colon_match: If true, label_color and label_attrs will be applied to the colon.

Added in version 2026.05.03.14.45:

  • no_colon: If true, the colon will be omitted from the text. Overrides colon_match

All LabeledData classes using colon_match
 1ft: FramedText = FramedText(
 2text=[
 3        LabeledData.String(
 4            label="LabeledData.String",
 5            value="A String value",
 6            no_colon=True
 7        ),
 8        LabeledData.Number(
 9            label="LabeledData.Number",
10            value=3.14159,
11            no_colon=True
12        ),
13        LabeledData.Boolean(
14            label="LabeledData.Boolean",
15            value=True,
16            no_colon=True
17        ),
18        LabeledData.Path(
19            label="LabeledData.Path",
20            value=Path("/path/to/a/file.txt"),
21            no_colon=True
22        ),
23        LabeledData.Date(
24            label="LabeledData.Date",
25            no_colon=True
26        ),
27        LabeledData.Bytes(
28            label="LabeledData.Bytes",
29            value=65535,
30            no_colon=True
31        ),
32    ]
33)
34print(ft)
_images/quickstart_14.png

Added suffix support to each type of LabeledData. Suffixes will appear after the value. The following parameters apply to the suffix:

  • suffix: Optional text to appear after the value

  • suffix_color: The color for the suffix [1].

  • suffix_attrs: The attribute(s) for the suffix [2].

Note

The cut-off mode for suffixes is always "word". See mode for more information.

All LabeledData classes with suffixes
 1ft: FramedText = FramedText(
 2text=[
 3        LabeledData.String(
 4            label="LabeledData.String",
 5            value="A String value",
 6            suffix="with a suffix"
 7        ),
 8        LabeledData.Number(
 9            label="LabeledData.Number",
10            value=3.14159,
11            suffix="with a suffix"
12        ),
13        LabeledData.Boolean(
14            label="LabeledData.Boolean",
15            value=True,
16            suffix="with a suffix"
17        ),
18        LabeledData.Path(
19            label="LabeledData.Path",
20            value=Path("/path/to/a/file.txt"),
21            suffix="with a suffix"
22        ),
23        LabeledData.Date(
24            label="LabeledData.Date",
25            suffix="with a suffix"
26        ),
27        LabeledData.Bytes(
28            label="LabeledData.Bytes",
29            value=65535,
30            suffix="with a suffix"
31        ),
32    ]
33)
34print(ft)
_images/quickstart_15.png

Below lists the classes with additional parameters or those that differ from the base parameters:

LabeledData.Number
  • round_to: Number of decimal places to round to

  • leading_zeros: Number of leading zeros to add

  • int_no_round: Whether to display the value as an integer without rounding

LabeledData.Boolean

This class splits text and color across seperate parameters for True and False values.

  • t_text: Text to display when the value is True

  • f_text: Text to display when the value is False

  • t_color: Color to use when the value is True

  • f_color: Color to use when the value is False

LabeledData.Date
  • strftime: Date formatter for when value is a datetime object or value is not passed

LabeledData.Bytes
  • show_unit: Whether to show the unit (e.g. “KiB”) and convert the bytes. If False, will show the raw bytes.

  • unit_type: "iec" uses the IEC format (e.g. “KiB” -> Kibibytes), "si" uses the SI format (e.g. “KB” -> Kilobytes)

  • unit_match: If True, the unit will match the styling of the value

  • unit_color: The color of the unit [1] [4]

  • unit_attrs: The attribute(s) of the unit [2] [4]

The following LabeledData types are supported:

Class

Supported Types

LabeledData.String

str

LabeledData.Number

int, float

LabeledData.Boolean

bool

LabeledData.Path

pathlib.Path

LabeledData.Date

datetime.datetime, str

LabeledData.Bytes

int

Here is an example of using LabeledData to display a string value:

Using the LabeledData class with FramedText
1ft: FramedText = FramedText(
2    text=[
3        LabeledData.String(
4            label="LabeledData.String",
5            value="A String value",
6        )
7    ]
8)
9print(ft)
_images/quickstart_3.png
_images/quickstart_4.png

Ouptut of all of the LabeledData types printed together

Displaying Statuses

framed_text also features Status objects to display messages with a status icon.

Status takes the following parameters:

  • icon: The icon to display

  • icon_color: The color of the icon

  • sep: The seperator between the icon and message

  • msg: The message to display

  • text_color: The color of the message

Added in version 2026.05.09.14.45:

  • overwrite: If true, will overwrite the previous line with the new status

The Status is constructed as: <icon><sep><message>

Changed in version 2026.04.04.14.00:

  • If the icon is an empty string, the seperator will not be displayed.

  • The Status will be constructed as: <message>

  • text_color will still be applied to msg


The default Status format is: <I>: <message>

Below is a full list of each Status and their default output:

Added in version 2026.04.29.16.30: Added Status.Hidden

Each status is printed on a new line. Note that some messages are colored.
 1ft: FramedText = FramedText(
 2  title="Status",
 3  frame_color="red",
 4  text=[
 5    Status.Info(msg="This is an info message"),
 6    Status.Action(msg="This is an action message"),
 7    Status.Success(msg="This is a success message"),
 8    Status.Warn(msg="This is a warning message"),
 9    Status.Fail(msg="This is a fail message")
10
11    # You can omit the 'msg=' parameter and achieve the same result
12    Status.Hidden("This is a hidden message. It just makes the text darker.")
13  ]
14)
15print(ft)
_images/quickstart_9.png

Displaying a Header and Divider

FramedHeader is like FramedText, but it only displays a single line of the ‘frame’:

A basic FramedHeader. Without arguments, this is effectively a divider.
1fh: FramedHeader = FramedHeader()
_images/quickstart_10.png

Like FramedText, we can color the header:

Coloring the ‘divider’ red
1fh: FramedHeader = FramedHeader(
2  frame_color="red"
3)
_images/quickstart_11.png

Currently, this ‘header’ is more of a divider. To actually make it a header and add a title, we can add:

Adding a title makes it a header
1fh: FramedHeader = FramedHeader(
2  title="Header",
3  frame_color="red"
4)
_images/quickstart_12.png

FrameHeader also supports the same title formatting as FramedText:

Same example as FramedText, but adapted for FramedHeader
1fh: FramedHeader = FramedHeader(
2  title="Header",
3  frame_color="red",
4  title_color="green",
5  attrs=["bold", "underline"]
6)
_images/quickstart_13.png

Shortening Text

Added in version 2026.05.04.17.15: Added ShortenText

ShortenText allows for shortening a string to a specified length. The main parameters are:

  • text: The string to shorten

  • limit: The maximum length of the string

  • mode: The mode to use for shortening

By default, if no limit is provided, the string will be shortened to the width of the terminal using os.get_terminal_size().columns.

The mode behaves the same as FramedText’s mode parameter. See mode for more information.

The text parameter currently supports the following types:

  • str objects

  • Any LabeledData object [3]

  • Any Status object [3]

ShortenText can be used on its own or in other classes, such as FramedText.

ShortenText used on its own
1text: str = "This is a very long message that should be cut off at some point. Ideally, this should be cut off earlier than later."
2short_text = ShortenText(text=text)
3
4# Or for a direct str type:
5# short_text: str = ShortenText(text=text).__str__()
6# short_text: str = ShortenText(text=text).text_shorten
7
8print(short_text)
ShortenText used with FramedText. Notice the use of mode="word"
 1line: str = "This is a very long message that should be cut off at some point. Ideally, this should be cut off earlier than later."
 2text: list = [
 3    ShortenText(text=line)
 4]
 5ft: FramedText = FramedText(
 6    title="Shorten Text",
 7    text=text,
 8    frame_color="red",
 9    mode="word"
10)
11print(ft)
_images/quickstart_16.png

str objects in the text list parameter of FramedText will use ShortenText to shorten strings, so no need to use ShortenText directly on them!

 1text: list = [
 2    "This is a very long message that should be cut off at some point. Ideally, this should be cut off earlier than later."
 3]
 4ft: FramedText = FramedText(
 5    title="Shorten Text built-in to FramedText",
 6    text=text,
 7    frame_color="blue",
 8    mode="middle"
 9)
10print(ft)
_images/quickstart_17.png

Creating a Progress Bar

Added in version 2026.05.09.14.45: Added ProgressBar

Progress bars can be created using the ProgressBar class. This will create a progress bar that snaps to the bottom of the terminal. It will look something like this:

_images/quickstart_18.png

A basic progress bar with value=3 and total=10

ProgressBar takes a few parameters, however not all of them are required.

Required Parameters

  • value: The current value

  • total: The total value

Data Parameters

  • show_percent: If true, will display the percentage of the progress bar (value / total)

  • show_values: If true, will display the current value and total value formatted as "<value>/<total>"

Customization Parameters

  • label: A text label for the progress bar

  • show_frame: If true, will display a frame around the progress bar, just like FramedText

  • progress_icon: The icon to use for the progress bar

  • empty_icon: The icon to use for the empty space in the progress bar

  • brackets: The brackets to use for the progress bar. The input is formatted as (<left>, <right>)

Color Parameters [1]

  • value_color: Color of the label

  • label_color: Color of the label

  • percent_color: Color of the percentage

  • progress_color: Color of the progress display

  • brackets_color: Color of the brackets

  • frame_color: Color of the frame

Other Parameters

  • safe_mode: If true, will clear the terminal and move cursor to top to ensure room for progress bar and any other data.

  • skip_init: If true, will only initialize when display or update_progress is called

The Basics of Creating a Progress Bar

The basic setup for a working progress bar looks something like this:

 1from time import sleep
 2try:
 3    val = 0
 4    total = 100
 5    pb: ProgressBar = ProgressBar(
 6        value=val,
 7        total=total,
 8    )
 9    # Loop can iterate over anything
10    for i in range(total):
11        # This is where code for doing stuff goes
12        # ...
13        # Update the progress
14        pb.update_progress(value=i+1)
15        sleep(0.1)
16    pb.reset()
17except (EOFError, KeyboardInterrupt):
18    ProgressBar.force_reset(show_frame=False, label=False)

This is a lot, so let’s break it down:

  • First, we define our ProgressBar. Here, we are just passing values to the value and total parameters.

  • Next, we loop over the total value and update the value of the progress bar with i+1. This will increment the progress bar by 1.

  • After the loop, we call reset to reset the terminal back to the state before the progress bar was displayed. We have to do this otherwise we won’t be able to reach the bottom lines of our terminal.

Now, the try-except block is in case there is an error in the program while the progress bar is running. Without it, we would have the same issue as if we omitted the pb.reset() call. The (EOFError, KeyboardInterrupt) used are for demonstration, but you can use any exception you want.

Warning

The parameters for ProgressBar.force_reset MUST match the parameters for ProgressBar. Otherwise, unexpected results may occur.

The 2 parameters needed are:

  • show_frame: Same as ProgressBar

  • label: Set this to True if a label was used for the ProgressBar. Otherwise, leave it False

A more advanced example looks something like this:

Notice the params in ProgressBar.force_reset matches the params in pb
 1from time import sleep
 2try:
 3    val = 0
 4    total = 50
 5    print(Status.Action("Batch processing information..."))
 6    pb: ProgressBar = ProgressBar(
 7        value=val,
 8        total=total,
 9        label="Test Progress Bar",
10        show_percent=True,
11        show_frame=True,
12        frame_color="blue",
13        progress_icon='|',
14        empty_icon=' ',
15    )
16    for i in range(total):
17        print(Status.Hidden(icon='>>', msg=f"Processing file-{i+1}.txt..."))
18        pb.update_progress(value=i+1)
19        sleep(0.1)
20        print(Status.Hidden(icon='>>', msg=f"Processed file-{i+1}.txt", overwrite=True))
21    pb.reset()
22    print(Status.Success("Batch processing complete!"))
23except (EOFError, KeyboardInterrupt):
24    ProgressBar.force_reset(show_frame=True, label=True)

Here, we are printing a status message each iteration. These print statements will not overwrite the progress bar as when ProgressBar is initialized, it will change the scrollable region of the terminal to exclude the progress bar.

We also customized the appearance of the progress bar, so it now looks something like this:

_images/quickstart_19.png

A full run of the above example looks like this:

_images/quickstart_g2.webp

Important Notes

ProgressBar is designed to be used on its own, not in any other class within framed_text.

Additionally, it is important to call reset on the progress bar when you are done with it. Not doing so may lead to unexpected behavior.

Currently, the progress bar does not handle resizing of the terminal window. Avoid resizing the window while the progress bar is running.

Creating a Spinner

Added in version 2026.05.12.17.00: Added Spinner class

Spinners are similar to progress bars, but don’t show any information by themselves. However, the Spinner class can accept text to display next to the spinner.

Spinner takes the following parameters:

  • text: Text to display next to the spinner. Omit for no text.

  • icons_id: ID string of one of the built-in icon sets.

  • done_icon: Icon to use for when the spinner is complete.

  • custom_icons: A list of strings to use as the spinner icon. Overrides icons_id

  • interval: The delay between spinner icon updates.

  • position: Where the spinner should be placed on a line.

  • indent: How many spaces the line should be indented.

  • spinner_color: Color of the spinner icon while active. [1]

  • done_color: Color for the spinner icon when stopped. [1]

Spinner.BUILTIN_ICONS contains all the spinner animations built into the library. It’s formatted as <id>: <frames>, with the id being used for the icons_id parameter. Each string in the list is one frame of the spinner animation.

The main functions of Spinner include:

  • start(): The main method of starting the spinner. It optionally takes a text parameter.

  • stop(): Will preform the following actions:

    1. Stops the current spinner

    2. Removes or replaces the spinner on the line

      1. If a done_icon was provided OR one was set earlier, it will replace the spinner.

      2. If none was provided OR done_icon wasn’t set earlier, the spinner will be removed.

Warning

Spinner.start() will hide the cursor until Spinner.stop() is called. To prevent cases where the cursor remains invisible after force exiting the program, include Spinner.stop() in your try-except block as shown in the examples below.

  • update(): Allows changing values of the spinner.

Note

The following are the only values that can be changed while the spinner is running:

  • done_icon

  • done_color

  • text

Examples

A very simple spinner looks something like this:

1from time import sleep
2sp: Spinner = Spinner()
3try:
4    sp.start()
5    sleep(10)  # Some task here
6    sp.stop()
7except (EOFError, KeyboardInterrupt):
8    sp.stop()
_images/quickstart_g3.webp

Colors

Most classes in framed_text have parameters for termcolor colors.

The value can be either a termcolor color code or an (R, G, B) tuple, where each value is between 0 and 255.

For a full list of termcolor color codes, see termcolor’s Text Properties.

Attributes

Attention

Not all of termcolor’s attributes are supported by every terminal emulator or operating system.

Your milage may vary

Most classes in framed_text have parameters for termcolor attributes.

All termcolor attributes are supported. Below is a list of all valid attributes currently available:

  • bold

  • dark

  • italic

  • underline

  • blink

  • reverse

  • concealed

  • strike

_images/quickstart_g1.webp

Showcase of all attributes using FramedText and LabeledData.String


Notes