Skip to main content

GTCaca Python bindings

pybind11 bindings for GTCaca, a libcaca-based terminal UI toolkit: windows, widgets, charts, an editor, and a raw canvas escape hatch — all drawn as text cells.

The bindings compile the GTCaca C sources directly into the extension module, so the only external runtime dependency is libcaca itself. Every widget the toolkit ships is exposed.

pip install gtcaca

Contents


Requirements

  • A C/C++ toolchain and CMake ≥ 3.20
  • libcaca with development headers, discoverable via pkg-config (pkg-config --exists caca should succeed)
  • Python ≥ 3.9

On macOS: brew install libcaca, and if pkg-config cannot find it, export PKG_CONFIG_PATH="$(brew --prefix libcaca)/lib/pkgconfig". On Debian/Ubuntu: apt install libcaca-dev.

Install

pip install gtcaca                 # from PyPI
pip install .                      # from a checkout of src/bindings/python

Building in-tree without installing:

cmake -S . -B build -Dpybind11_DIR="$(python -m pybind11 --cmakedir)"
cmake --build build -j

Quick start

import gtcaca as gt

gt.init()
gt.application_new("Hello")
win = gt.window_new(None, "Demo", 0, 1, 40, 10)
gt.label_new(win, "Press Enter on the button", 2, 2)

btn = gt.button_new(win, "  OK  ", 2, 4)

def on_key(key):
    if key == gt.KEY_RETURN:
        gt.main_quit()
    return 0            # 0 = not consumed; let others see the key

btn.on_key(on_key)
win.set_focus()
gt.main()               # blocking event loop
gt.present_shutdown()

See example.py for a fuller program.


Core concepts

Lifecycle

Call Purpose
gt.init() open the display; must precede any widget creation
gt.main() run the blocking event loop
gt.main_quit() ask the loop to exit (call from a callback)
gt.redraw() repaint now — call after changing state from a callback
gt.present_shutdown() tear the display down
gt.canvas_width(), gt.canvas_height() canvas size in character cells

The display driver is chosen by libcaca; CACA_DRIVER=null runs headless, which is what makes the widgets testable without a terminal.

Widgets and parents

Every widget comes from a *_new() factory whose first argument is the parent — another widget, or None for a top-level/canvas-anchored widget:

win  = gt.window_new(None, "Title", 0, 0, 40, 12)
name = gt.entry_new(win, 2, 3, 20)          # lives inside the window

Widgets are owned by the C library and live for the process; they are never freed by Python. Each exposes the shared preamble x, y, width, height, has_focus, is_visible, id, plus show(), hide() and as_widget().

Focus

Keys go to focused widgets. widget.set_focus() (windows/custom) or assigning widget.has_focus = True moves it; window.focus_next_child() cycles.

Callbacks

  • Key callbacks — widget.on_key(cb), cb(key: int) -> int. Return non-zero to consume the key; returning None means not consumed.
  • Value callbacks — on_toggle(cb) / on_change(cb) on Switch, Expander, Scale, SpinButton. Receive the new value.
  • Menu actions take no arguments.
  • Mouse — Custom.on_mouse(cb), cb(event, x, y, button).

Exceptions inside a callback are reported through sys.unraisablehook and never abort the event loop.

Colours

ANSI colour constants are module attributes: gt.BLACK, gt.RED, gt.GREEN, gt.BROWN, gt.BLUE, gt.MAGENTA, gt.CYAN, gt.LIGHTGRAY, gt.DARKGRAY, gt.LIGHTRED, gt.LIGHTGREEN, gt.YELLOW, gt.LIGHTBLUE, gt.LIGHTMAGENTA, gt.LIGHTCYAN, gt.WHITE. gt.color_name(idx) gives the display name.

Drawing primitives: gt.set_color(fg, bg), gt.set_color_rgb(fg12, bg12) (12-bit 0xRGB), gt.put_str(x, y, s), gt.put_char(x, y, codepoint), gt.fill_box(x, y, w, h, ch), gt.draw_box(...), gt.draw_thin_box(...).


Windows and layout

app = gt.application_new("My app")
win = gt.window_new(None, "Settings", 0, 1, 50, 16)
win2 = gt.window_new_centered(None, "Centered", 30, 8)

gt.frame_new(win, "Network", 2, 2, 44, 6)      # labelled box
gt.separator_new(win, 2, 9, 44)                # horizontal rule

Box layouts

A Box positions widgets; it draws nothing itself.

box = gt.vbox_new()                 # or gt.hbox_new() / gt.box_new(gt.BOX_HORIZONTAL)
box.set_spacing(1)
box.set_margin(1)
box.set_align(gt.ALIGN_CENTER)      # ALIGN_START / ALIGN_CENTER / ALIGN_END

box.add(gt.label_new(None, "Name", 0, 0))
box.add_expand(gt.entry_new(None, 0, 0, 20))   # takes leftover space
box.add_spacing(2)
box.add_stretch()

box.apply(0, 0, 40, 12)             # lay out into this rectangle
box.apply_window(win)               # ...or into a window's content area
print(box.preferred_width(), box.preferred_height())

Tabs and expanders

tabs = gt.tabs_new(win, 1, 1, 40, 12)
tabs.set_titles(["General", "Advanced"])
tabs.set_selected(1)
print(tabs.selected())              # 1
tabs.key(gt.KEY_RIGHT)              # feed it keys yourself

exp = gt.expander_new(win, "Details", 2, 14, 30)
exp.add_managed(some_widget)        # shown/hidden with the expander
exp.set_expanded(True)
exp.on_toggle(lambda expanded: print("open" if expanded else "closed"))

Buttons and input

btn = gt.button_new(win, "  Apply  ", 2, 2)
btn.on_key(lambda k: gt.main_quit() if k == gt.KEY_RETURN else 0)

chk = gt.checkbox_new(win, "Enable", 2, 4)
chk.set_checked(True); chk.get_checked()

r1 = gt.radiobutton_new(win, "Fast", 1, 2, 6)   # group id 1
r2 = gt.radiobutton_new(win, "Small", 1, 2, 7)
r1.set_active()                  # takes no argument: selects r1, clears the group
r2.get_active()                  # -> False

cb = gt.combobox_new(win, 2, 9, 20)
cb.append("gzip"); cb.append("zstd")
cb.get_selected(); cb.get_selected_index()

sw = gt.switch_new(win, 2, 11)
sw.set_active(True); sw.get_active()
sw.on_toggle(lambda active: print("switch:", active))

sb = gt.spinbutton_new(win, 2, 13, 0, 100, 5)   # min, max, step
sb.set_value(20); sb.get_value()
sb.on_change(lambda v: print("spin:", v))
sb.handle_key(gt.KEY_UP)

sc = gt.scale_new(win, 2, 15, 30, 0.0, 1.0, 0.05)   # a slider
sc.set_value(0.4); sc.get_value()
sc.on_change(lambda v: print("scale:", v))

Text

Label, Entry, TextView

gt.label_new(win, "Read only text", 2, 2)

e = gt.entry_new(win, 2, 4, 24)
e.set_text("hello"); e.get_text()
e.set_secret(True)                 # password field

tv = gt.textview_new(win, 2, 6, 40, 8)
tv.append("a log line")
tv.clear()

TextList — a scrollable, searchable list

tl = gt.textlist_new(win, 2, 2)
tl.set_view_size(10)
for name in ("alpha", "beta", "gamma"):
    tl.append(name)
tl.set_search_enabled(True)
tl.selection_down()
print(tl.selected_text(), tl.is_searching())
tl.on_key(lambda k: 0)

Editor — a multi-line text editor

A Scintilla-shaped API: positions are byte offsets, lines are 0-based.

ed = gt.editor_new(win, 0, 1, 80, 20)
ed.set_text("def f():\n    return 1\n")
ed.set_line_numbers(True)
ed.set_tab_width(4)
ed.set_caret_line_visible(True)

# navigation and selection
ed.goto_line(1); ed.line_end_extend()
print(ed.selected_text(), ed.current_line(), ed.line_count())

# editing with grouped undo
ed.begin_undo_action()
ed.insert_text(0, "# header\n")
ed.end_undo_action()
ed.undo(); ed.redo()
print(ed.can_undo(), ed.get_modify())

# search
hit = ed.find_text(0, "return", 0, len(ed))     # -> (start, end) or None
ed.set_target_range(0, len(ed))
if ed.search_in_target("return") >= 0:
    ed.replace_target("yield")

# syntax configuration
cfg = gt.editor_langcfg_new()
cfg.set_line_comment("#")
cfg.set_block_comment('"""', '"""')
cfg.add_bracket("(", ")")
cfg.set_keywords(["def", "class", "return"])
ed.set_langcfg(cfg)
ed.colourize()

# folding and annotations
ed.fold_by_indentation()
ed.toggle_fold(0)
ed.annotation_set_text(1, "returns an int")

Also available: rectangular selection (set_rectangular_selection, rect_copy, rect_yank, …), word motion (word_left, del_word_right, …), styling (style_set_fore, style_set_bold, set_bg_rgb12, …), set_read_only, set_overtype, set_wrap, set_view_whitespace, brace_match, and JSON mode (set_json_mode, fold_json).


Data views

Table — a lazy model/view

Rows live behind a model: any object with these methods. Only visible rows are queried, so the row count may be huge.

class FileModel:
    def __init__(self, rows): self.rows = rows
    def row_count(self):      return len(self.rows)
    def col_count(self):      return 2
    def header(self, col):    return ("Name", "Size")[col]
    def cell(self, row, col): return str(self.rows[row][col])
    # optional — Wireshark-style row colouring; None = theme default
    def row_color(self, row):
        return (gt.BLACK, gt.YELLOW) if self.rows[row][1] > 1_000_000 else None

t = gt.table_new(win, 0, 1, 60, 20)
t.set_model(FileModel([("a.txt", 12), ("big.iso", 4_000_000)]))
t.set_column_widths([30, 12])
t.set_title("Files")
t.key(gt.KEY_DOWN)
print(t.current_row(), t.current_col(), t.selected_row())

Tree — a lazy hierarchical view

Nodes are integers you choose; the invisible super-root is None.

NODES = {1: ("root", [2, 3]), 2: ("child A", []), 3: ("child B", [4]), 4: ("leaf", [])}

class TreeModel:
    def child_count(self, node):  return len(NODES[node][1]) if node else 1
    def child(self, node, i):     return NODES[node][1][i] if node else 1
    def label(self, node):        return NODES[node][0]
    def has_children(self, node): return bool(NODES[node][1]) if node else True
    # optional: paint the row yourself instead of using label()
    # def draw_row(self, node, x, y, width, selected): ...

tr = gt.tree_new(win, 0, 1, 40, 20)
tr.set_model(TreeModel())
tr.select(3)
print(tr.selected_node(), tr.visible_count())

HexView — byte viewer and editor

As a viewer:

hv = gt.hexview_new(win, 0, 1, 78, 20)
data = open("file.bin", "rb").read()
hv.set_data(data)            # keep `data` alive: the widget does not copy it
hv.set_highlight(16, 8)      # one reverse-video range
hv.set_title("file.bin")
hv.key(gt.KEY_DOWN)          # arrows/page/home/end move, TAB swaps panes
print(hv.cursor(), len(hv))

Layout — every dimension is adjustable:

hv.set_bytes_per_row(0)      # 0 = fit as many as the width allows
hv.bytes_per_row()           # the effective value
hv.set_group_size(4)         # blank column every 4 bytes (0 = no grouping)
hv.set_addr_digits(8)        # 0 = derive from the data length
hv.set_base_addr(0x400000)   # show file offsets as load addresses
hv.set_show_ascii(False)     # hex only
hv.set_box(False)            # borderless, for a full-width pane

Colouring — one hook, called for every painted byte (twice: hex cell and ASCII cell). Returning None falls through to the widget's own colouring, which is cursor → selection → tags → highlight range.

def cell(off, is_ascii):
    if off in bookmarks:
        return (0x000, 0xF66)          # 12-bit 0xRGB
    return None

hv.on_cell(cell)
hv.on_cell(None)                       # remove

Named coloured regions, for bookmarks or parsed fields — later tags paint over earlier ones:

hv.add_tag(0, 8, 0xFFF, 0x006, "header")
hv.add_tag(4, 2, 0x000, 0x0F0, "length")
print(hv.tag_at(4))                    # "length"
hv.clear_tags()

Cursor and selection:

hv.set_cursor(0x100); hv.cursor()
hv.set_pane(True); hv.pane()           # True = ASCII pane
hv.set_nibble(True); hv.nibble()       # which half-byte is being typed
hv.set_selection(10, 40); hv.selection()   # -> (10, 40) inclusive
hv.clear_selection()

Editing. The widget never mutates the bytes. It reports the intended change and your code applies it — which is what lets an application keep its own undo history, layers, or a memory-mapped file behind the view:

buf = bytearray(open("file.bin", "rb").read())

def on_edit(off, value):        # a byte was typed over
    buf[off] = value
    return True                 # False rejects it; the cursor does not advance

def on_splice(off, is_insert):  # one byte inserted or deleted
    buf.insert(off, 0) if is_insert else buf.pop(off)
    hv.set_data(buf)            # re-point: the buffer may have moved
    return True

hv.set_editable(True)
hv.on_edit(on_edit)
hv.on_splice(on_splice)
hv.set_insert_mode(True)        # INSERT toggles it too

Once editable, key() also handles hex digits (two nibbles per byte), printable ASCII in the ASCII pane, DELETE, BACKSPACE and INSERT.

Large data. Instead of a flat buffer, serve bytes on demand — for files bigger than memory, a remote target, or a stream decompressed as you scroll:

fh = open("huge.iso", "rb")
def read(off, n):
    fh.seek(off)
    return fh.read(n)

hv.on_read(read, os.path.getsize("huge.iso"))    # replaces set_data()

Search:

hv.find(b"\x89PNG")                       # -> offset, or -1
hv.find(b"PNG", from_offset=100)
hv.find(b"PNG", from_offset=len(hv), backwards=True)

Indicators

pb = gt.progressbar_new(win, 2, 2, 30); pb.set_value(0.5)

g = gt.gauge_new(win, 2, 4, 30)
g.set_percent(80)                        # or set_value(0.8)
g.set_label("CPU")                       # None shows the percentage
g.set_colors(gt.GREEN, gt.DARKGRAY)

sp = gt.spinner_new(win, 2, 6)
sp.set_spinning(True); sp.step()         # advance one frame

sd = gt.segdisplay_new(win, 2, 8, 30, 6) # seven-segment display
sd.set_text("42.7"); sd.set_colour(gt.LIGHTRED); sd.set_box(True)

sl = gt.sparkline_new(win, 2, 15, 30, 4)
sl.set_data([1.0, 4.0, 2.0, 8.0])
sl.push(5.0)                             # rolling append
sl.set_style(gt.SPARKLINE_AREA)          # or SPARKLINE_BLOCKS / set_style_auto()

bar = gt.statusbar_new(" ready ")
bar.set_text(" saved ")

Charts and maps

bc = gt.barchart_new(win, 0, 1, 40, 12)
bc.set_data([3.0, 7.0, 5.0], ["red", "green", "blue"])
bc.set_show_values(True); bc.set_bar_width(3, 1); bc.set_max(0)   # 0 = auto

pc = gt.piechart_new(win, 0, 1, 40, 14)
pc.set_data([30.0, 50.0, 20.0], ["a", "b", "c"])
pc.set_colors([gt.RED, gt.GREEN, gt.BLUE])
pc.set_donut(True); pc.set_show_legend(True)
gt.piechart_palette(0)                      # default palette entry

lc = gt.linechart_new(win, 0, 1, 60, 16)
lc.add_series([1.0, 3.0, 2.0, 5.0], gt.LIGHTGREEN)
lc.set_range(0, 6); lc.set_xspan(10, "s"); lc.set_log_y(False)

sp = gt.scatter_new(win, 0, 1, 60, 16)
sp.add_point(1.0, 2.0, gt.CYAN)
sp.set_data([1.0, 2.0, 3.0], [2.0, 4.0, 8.0], gt.YELLOW)
sp.set_autoscale(True)                      # or set_bounds(xmin, xmax, ymin, ymax)

Map

m = gt.map_new(win, 0, 1, 80, 24)
m.add_world(gt.BLUE)
m.set_graticule(True)
m.add_city("Paris", colour=gt.LIGHTRED)     # built-in city table
m.add_point(35.68, 139.69, label="Tokyo", colour=gt.YELLOW)
m.add_polyline([2.35, 48.85, 139.69, 35.68], gt.GREEN)   # flat lon,lat,lon,lat
print(m.project(2.35, 48.85))               # -> (x, y) or None if off-map
print(gt.map_find_city("Tokyo"))            # ('Tokyo', 35.68, 139.69)
print(len(gt.map_cities()))

MindMap

mm = gt.mindmap_new(win, 0, 1, 60, 20)
mm.clear("Project")
root = mm.root()
a = mm.add_child(root, "design")
mm.add_sibling(a, "build")
a.set_text("design docs")
a.toggle_fold()
mm.select(a)
print(mm.selected())

Menus

The library binds F10 to toggle menu focus and gives the menu exclusive key dispatch while it is open; it closes a dropdown before running the action, so an action may safely open a modal dialog.

menu = gt.menu_new()

f = menu.add_entry("File")
menu.add_item(f, "Save", "Ctrl-S", lambda: save())
menu.add_item(f, "Save As...", "", lambda: save_as())
menu.add_separator(f)
menu.add_item(f, "Quit", "Ctrl-X", gt.main_quit)

h = menu.add_entry("Help")
menu.add_item(h, "About", "", lambda: gt.dialog_message("About", "v1.0"))

menu.set_focus(True)             # open it from your own key handler
menu.is_focused()
menu.set_item_enabled(f, 0, False)   # grey out File▸Save

Limits: 8 top-level entries, 20 items each, 31-character labels, 11-character shortcut strings.


Dialogs and choosers

The blocking helpers run their own event loop and return the answer, so they can be called straight from a key handler or a menu action.

if gt.dialog_confirm("Unsaved changes", "Quit anyway?"):
    gt.main_quit()

gt.dialog_message("Done", "Export finished.")

idx = gt.dialog_run("Conflict", "The file changed on disk.",
                    ["Reload", "Overwrite", "Cancel"])   # index, or -1 if ESC

For a non-blocking dialog driven by your own loop, use the widget form: gt.dialog_new(...), .set(title, message, buttons), .draw(), .key(k), .result() (which is gt.DIALOG_ONGOING until a button is chosen).

File chooser

path = gt.filechooser_run(".", save_mode=False)      # -> path or None
path = gt.filechooser_run_named(".", "untitled.txt") # save dialog, name pre-filled

path, flags = gt.filechooser_run_opts(".", True, [("compress", True), ("backup", False)])

Or embed it: gt.filechooser_new(parent, x, y, w, h), .set_dir(), .draw(), .key().

Colour picker and calendar

colour = gt.colordialog_run("Pick a colour", gt.RED)   # ANSI index, or -1

cal = gt.calendar_new(win, 0, 1, 24, 10)
cal.set_date(2026, 8, 3)
cal.set_marker(lambda y, m, d: d in (1, 15))           # mark those days
print(cal.get_date())
gt.calendar_days_in_month(2026, 2)    # 28
gt.calendar_day_of_week(2026, 8, 3)   # 0=Sunday .. 6=Saturday

Image

img = gt.image_new(win, 0, 1, 40, 20)
if img.load("photo.png"):             # also load_memory(bytes)
    img.draw()

Custom widgets

When no stock widget fits, take the canvas. This is how you get per-cell colour.

def draw():
    W, H = gt.canvas_width(), gt.canvas_height()
    gt.set_color(gt.WHITE, gt.BLUE)
    gt.fill_box(0, 0, W, 1, ord(" "))
    gt.put_str(1, 0, "custom widget")
    gt.set_color_rgb(0x9CF, 0x000)       # 12-bit RGB
    gt.put_str(1, 2, "coloured text")

def key(k):
    if k == 24:                          # Ctrl-X
        gt.main_quit()
    return 1

def mouse(event, x, y, button):
    if event == gt.MOUSE_PRESS:
        print("click", x, y, button)
    return 0

w = gt.custom_new(None, 0, 0, gt.canvas_width(), gt.canvas_height())
w.on_draw(draw)
w.on_key(key)
w.on_mouse(mouse)
w.set_focusable(True)
w.set_focus()

Mouse events are MOUSE_PRESS, MOUSE_RELEASE, MOUSE_MOTION, MOUSE_WHEEL, MOUSE_DOUBLE; buttons are 1 left, 2 middle, 3 right, 4/5 wheel. gt.set_double_click_time(ms) tunes double-click detection. Motion only arrives while a button is held, and the press that starts a drag owns the whole gesture.


Utilities

Rope — a text buffer with cheap edits anywhere

r = gt.rope_from("hello world")
r.insert(5, ",")
r.delete(0, 1)
print(str(r), len(r), r.lines())
print(r.copy(0, 4), r.at(0))
print(r.line_of(3), r.line_start(0))
print(r.find(0, "w"), r.rfind(len(r), "o"))

Threading and the GIL

The GIL is released while gt.main() blocks and re-acquired inside every callback, so callbacks can safely touch Python state. The modal dialog helpers (dialog_run, dialog_confirm, filechooser_run, colordialog_run) hold the GIL for their duration because their internal redraws call back into Python.


API index

Lifecycle & canvas — init, main, main_quit, redraw, present_shutdown, canvas_width, canvas_height, set_double_click_time

Drawing — set_color, set_color_rgb, put_str, put_char, fill_box, draw_box, draw_thin_box, color_name

Containers — application_new, window_new, window_new_centered, frame_new, separator_new, vbox_new, hbox_new, box_new, tabs_new, expander_new

Input — button_new, entry_new, checkbox_new, radiobutton_new, combobox_new, switch_new, spinbutton_new, scale_new

Text — label_new, textview_new, textlist_new, editor_new, editor_langcfg_new, editor_grammar_load, rope_new, rope_from

Data views — table_new, tree_new, hexview_new

Indicators — progressbar_new, gauge_new, spinner_new, segdisplay_new, sparkline_new, statusbar_new

Charts — barchart_new, piechart_new, piechart_palette, linechart_new, scatter_new, map_new, map_cities, map_find_city, mindmap_new

Menus & dialogs — menu_new, dialog_new, dialog_run, dialog_confirm, dialog_message, filechooser_new, filechooser_run, filechooser_run_named, filechooser_run_opts, colordialog_new, colordialog_run, calendar_new, calendar_days_in_month, calendar_day_of_week, image_new

Escape hatch — custom_new

Constants — colours (BLACK … WHITE), keys (KEY_RETURN, KEY_ESCAPE, KEY_TAB, KEY_UP/DOWN/LEFT/RIGHT, KEY_HOME, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, KEY_BACKSPACE, KEY_DELETE, KEY_F1–KEY_F10), mouse (MOUSE_PRESS, MOUSE_RELEASE, MOUSE_MOTION, MOUSE_WHEEL, MOUSE_DOUBLE), layout (BOX_VERTICAL, BOX_HORIZONTAL, ALIGN_START, ALIGN_CENTER, ALIGN_END), SPARKLINE_BLOCKS, SPARKLINE_AREA, DIALOG_ONGOING

Every binding lives in gtcaca_module.cpp; help(gtcaca) and help(gtcaca.Editor) work at the REPL for per-method signatures.

Licence

Public domain, like GTCaca itself.

Release files for gtcaca 0.2.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gtcaca 0.2.6
File Size Uploaded
gtcaca-0.2.6.tar.gz 408.8 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for gtcaca 0.2.6
File
gtcaca-0.2.6-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
gtcaca-0.2.6-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.6-cp313-cp313-manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.6-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
gtcaca-0.2.6-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
gtcaca-0.2.6-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.6-cp312-cp312-manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.6-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
gtcaca-0.2.6-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
gtcaca-0.2.6-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.6-cp311-cp311-manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.6-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
gtcaca-0.2.6-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
gtcaca-0.2.6-cp310-cp310-manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.6-cp310-cp310-manylinux_2_28_aarch64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.6-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details
gtcaca-0.2.6-cp39-cp39-win_amd64.whl CPython 3.9 CPython 3.9 Windows x86-64 Details
gtcaca-0.2.6-cp39-cp39-manylinux_2_28_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.6-cp39-cp39-manylinux_2_28_aarch64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.6-cp39-cp39-macosx_11_0_arm64.whl CPython 3.9 CPython 3.9 macOS 11.0+ ARM64 Details

Total release size: 21.1 MB

Release files / gtcaca-0.2.6.tar.gz

Download URL gtcaca-0.2.6.tar.gz
Size 408.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e24d170b73abd212efb07e6904b00b521bb096ca6b6ae9d59534afcff8210f1c
BLAKE2b-256 checksum
How to use checksums
7f87fda561de4c092a6e6e8a16326beab39897cb0ea27b9a54f7f7bc947aae2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp313-cp313-win_amd64.whl

Download URL gtcaca-0.2.6-cp313-cp313-win_amd64.whl
Size 1.1 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
af867825bc036f8bcdd3a4b4eb53663657e558571ae8debda4ef9ab74884ed86
BLAKE2b-256 checksum
How to use checksums
7e5582e2c4357a6fbcf8d63dc9b7afca14894e68294eb352f39fbf7658225c56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL gtcaca-0.2.6-cp313-cp313-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
d0bf4a505b81084bafbb9cf93c2840c202eec8eeb615d2c658c15bbf91d97efd
BLAKE2b-256 checksum
How to use checksums
d7f90a0dae172117951c9ece34bbcc7d871f8348913fa312ab6dda625bf9e796
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp313-cp313-manylinux_2_28_aarch64.whl

Download URL gtcaca-0.2.6-cp313-cp313-manylinux_2_28_aarch64.whl
Size 1.1 MB
Tags CPython 3.13 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
395df5b4f784c43b067551b1fec221fe4e50b7a3bd688997f64f79c8bf1ad4d9
BLAKE2b-256 checksum
How to use checksums
c45223f635f8c8f424cf2e692bdb9fc2d213b2ab264da2da70876c7dcdf5e53b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp313-cp313-macosx_11_0_arm64.whl

Download URL gtcaca-0.2.6-cp313-cp313-macosx_11_0_arm64.whl
Size 727.5 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d8833495161094d7d000b36d8b3dc3949daab6d7934e0e02df416ebe1559169b
BLAKE2b-256 checksum
How to use checksums
624800a702bd74e17203a39fa7832aeb764e827e57ae80b25b475abaad5a2084
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp312-cp312-win_amd64.whl

Download URL gtcaca-0.2.6-cp312-cp312-win_amd64.whl
Size 1.1 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
d8d9bfaa49c60addec8c039964c11833d65cd1b8d0dbc7c8110aab0a77742dc5
BLAKE2b-256 checksum
How to use checksums
6c1a3d1c824915419be7bf9e176a290aa138d002b25cab6da9e7bda71cc3cc37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL gtcaca-0.2.6-cp312-cp312-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
7ec4041f094399bf1c1f6886857c04850e60ed214d336946dff03eabae27c516
BLAKE2b-256 checksum
How to use checksums
a0bea44c9eb0a50ecdd61f595dd2d470a7a3437927150d000e9799bc65afd66a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp312-cp312-manylinux_2_28_aarch64.whl

Download URL gtcaca-0.2.6-cp312-cp312-manylinux_2_28_aarch64.whl
Size 1.1 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
d7b182d56536b5e3db0d99c67708e32ed29fd3ef6671066b1c371e0cbb73b6cc
BLAKE2b-256 checksum
How to use checksums
f1b7e333bf5a1b1f60748edd64869a079a741afd0be3a70833bb73380ede59c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp312-cp312-macosx_11_0_arm64.whl

Download URL gtcaca-0.2.6-cp312-cp312-macosx_11_0_arm64.whl
Size 727.5 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6c0e6c00c8320bd4fa905fa7959aa25dd2d5c7e1b64724f948f88012d9d3db9a
BLAKE2b-256 checksum
How to use checksums
d6ada09a1adcbed71fcc736ff2153548e1dcb5af65452ec3e5372b71625764d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp311-cp311-win_amd64.whl

Download URL gtcaca-0.2.6-cp311-cp311-win_amd64.whl
Size 1.1 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
1d8508672dcccc9a4f1b59f69a427c0318e35c9dd54b029712554f67c62bd698
BLAKE2b-256 checksum
How to use checksums
87fe3bc477fb3e75b2eb024c9d27bc5ea7587469bb41dd92be3edade95f1fbb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL gtcaca-0.2.6-cp311-cp311-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
9ec80f6476be6fbc50476abe008138aacd80a22d78c9df42bf111a0bfe230f8c
BLAKE2b-256 checksum
How to use checksums
005e0dbb75a160323477a2cefa17054d94d8f85d1f825676931ffc9a8e219ae2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp311-cp311-manylinux_2_28_aarch64.whl

Download URL gtcaca-0.2.6-cp311-cp311-manylinux_2_28_aarch64.whl
Size 1.1 MB
Tags CPython 3.11 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
a2c8b7ff6e782cb1bf1f929e63827f73f40eab1628cb66aca1b71f00d2f2b681
BLAKE2b-256 checksum
How to use checksums
219d380f57e094bfdca1632008d91f25dc24c969c2417b9ec7c675d232bf7133
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp311-cp311-macosx_11_0_arm64.whl

Download URL gtcaca-0.2.6-cp311-cp311-macosx_11_0_arm64.whl
Size 723.9 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
64cfb7bfe57e949fadcbc432794929f147afbd7672a03cfe5169d16518b59026
BLAKE2b-256 checksum
How to use checksums
448fef40af051645788b41ab1b7b1c4ab3ffcf3bf3b0bfd18479e0af1f7bda88
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp310-cp310-win_amd64.whl

Download URL gtcaca-0.2.6-cp310-cp310-win_amd64.whl
Size 1.1 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
4f7461b3cd35b05398106eb5c619ac406781b3aaa4f85ddaedf0b9506f6c4bea
BLAKE2b-256 checksum
How to use checksums
1fda6d65450a53c9131eee961651bf961f311b6db78cc48f134eea44aac23ecc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp310-cp310-manylinux_2_28_x86_64.whl

Download URL gtcaca-0.2.6-cp310-cp310-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
36f229db9130746e2cfa1c9507b072ac4a2ceabb290d5e378256bc57324b7d83
BLAKE2b-256 checksum
How to use checksums
3e0237b04c3204084198d99999ae8ab9cff57fe6af13aa02dfb3b591cee18cb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp310-cp310-manylinux_2_28_aarch64.whl

Download URL gtcaca-0.2.6-cp310-cp310-manylinux_2_28_aarch64.whl
Size 1.1 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
6b04ed0f43e5b9f6dfd6de4ae300e26ae24169fa1293157215dcaa7bd8a5e52b
BLAKE2b-256 checksum
How to use checksums
b903799e8865492ae79f78cf5e602eddff744961cea7d1ed72d8c139981677db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp310-cp310-macosx_11_0_arm64.whl

Download URL gtcaca-0.2.6-cp310-cp310-macosx_11_0_arm64.whl
Size 723.1 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d7be1b51a14f887e832450b682bb29974ca80965555ab8e6bce8a2501eed6210
BLAKE2b-256 checksum
How to use checksums
0e70992354d7ee1907140a1c578f388267b2e6a60ea8a61f50075649b3259454
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp39-cp39-win_amd64.whl

Download URL gtcaca-0.2.6-cp39-cp39-win_amd64.whl
Size 1.1 MB
Tags CPython 3.9 Windows x86-64
SHA-256 checksum
How to use checksums
d53980fccec9606a3fae8c4ed674f4fd2fd784c4b0a08acae39691cac01d2c80
BLAKE2b-256 checksum
How to use checksums
c6997b2235ac28963f5f3d4615dbfc4c60aba748c0c9f2e34523ffbaa409080f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp39-cp39-manylinux_2_28_x86_64.whl

Download URL gtcaca-0.2.6-cp39-cp39-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.9 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
81234f7ad3db68645e9ab6256d66810794c0f8f0f9b652f9c2206e0d0649c996
BLAKE2b-256 checksum
How to use checksums
d8a41b07e81cb5aaf9f61d1ef72df22c3b020a1edd60555c836d517713d4eda8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp39-cp39-manylinux_2_28_aarch64.whl

Download URL gtcaca-0.2.6-cp39-cp39-manylinux_2_28_aarch64.whl
Size 1.1 MB
Tags CPython 3.9 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
9f22662a2f779e6598a4120f18c225ee61f69356d6e6d390b73539a74e8f59a8
BLAKE2b-256 checksum
How to use checksums
3b09105d66c29f71086ba2ddf13f00e733f402a069962767e5eb4dab6d84f090
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / gtcaca-0.2.6-cp39-cp39-macosx_11_0_arm64.whl

Download URL gtcaca-0.2.6-cp39-cp39-macosx_11_0_arm64.whl
Size 723.1 kB
Tags CPython 3.9 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d091ccd8dc32c54ed2f895e4f3cbbf663a9feb87c21f9df2325bbe63970f52fc
BLAKE2b-256 checksum
How to use checksums
906a713501bee70ccd329b4d4ef10b574ca8053dc12fc3a970e93365261ab7be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page