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.7

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.7
File Size Uploaded
gtcaca-0.2.7.tar.gz 409.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for gtcaca 0.2.7
File
gtcaca-0.2.7-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
gtcaca-0.2.7-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.7-cp313-cp313-manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.7-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
gtcaca-0.2.7-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
gtcaca-0.2.7-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.7-cp312-cp312-manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.7-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
gtcaca-0.2.7-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
gtcaca-0.2.7-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.7-cp311-cp311-manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.7-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
gtcaca-0.2.7-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
gtcaca-0.2.7-cp310-cp310-manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.7-cp310-cp310-manylinux_2_28_aarch64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.7-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details
gtcaca-0.2.7-cp39-cp39-win_amd64.whl CPython 3.9 CPython 3.9 Windows x86-64 Details
gtcaca-0.2.7-cp39-cp39-manylinux_2_28_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ x86-64 Details
gtcaca-0.2.7-cp39-cp39-manylinux_2_28_aarch64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ ARM64 Details
gtcaca-0.2.7-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.7.tar.gz

Download URL gtcaca-0.2.7.tar.gz
Size 409.3 kB
Tags Source
SHA-256 checksum
How to use checksums
ccb66c5688b44f544b670ccffcb0a58e899503a11e0c22d3b14583b697cacb23
BLAKE2b-256 checksum
How to use checksums
3f838e84b25924cafff4d491f8914ec930b6b9ab222df2184c02e7db5cb9484c
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-cp313-cp313-win_amd64.whl
Size 1.1 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
fb3bc592a127f88924140f04a305e03c885d730fad359f81a45ca519e44f1012
BLAKE2b-256 checksum
How to use checksums
59e96517392f5a3053b4dfba1965029f87536b70da513a474ec9b4c127ecc8c8
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
a7888de8416af9a64b701cab7e8162fdb9e02af1b362f676daa90a18a7a5fc33
BLAKE2b-256 checksum
How to use checksums
ff2352efc94425de744a196fab587afe582a6958bd38f27476ebf67a6d01df20
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
7595e222fd51dadaf003906326ad36e91545c0602291f2e74cf6d5647eddfcbb
BLAKE2b-256 checksum
How to use checksums
fcd097076ca4972f89196f0ecdce7a83b36716556761edc17f81e1d4e5e86dd3
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
a5beb2c0a3172872cec08812a78a805d671876a804da66ba94d1cfff519fe6c7
BLAKE2b-256 checksum
How to use checksums
da7ed62861451b9c9fc3f0aed060b8195a7035f257d3b9cf61b789d02793ffca
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-cp312-cp312-win_amd64.whl
Size 1.1 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
2d5bba84f7e8463d09f8de2f1398841c1a83a185f32545cff7c61a4bed6e183f
BLAKE2b-256 checksum
How to use checksums
55a6409e7d19000c3239050cb697fb1a9d643af28faa1b741aa0738376e80673
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
6c704acab0d171eb96aa593c8a55bfb9563707795aac730dcffab962d25c91af
BLAKE2b-256 checksum
How to use checksums
51edf04b1ece1cb7f82a4c6c8f24181ab74bab1e123ece0c291dfedccc38ba1f
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
898500fb08dc71b36927ff497ac6ce2799a22ab0f6204362a68fcba686fe4bb1
BLAKE2b-256 checksum
How to use checksums
42c65743a814e63949e1f5c5032d09cc10083daf3bb9d74f5b694f63c1602a76
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
8d30bebac7cd0840a321d0e5fdb2631887cb07163b8cd60b520461cf08682eb1
BLAKE2b-256 checksum
How to use checksums
c1b6d3a92a5aa2aab1e736d2999008e824d45a6bea552ef51423635a000b3e6a
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-cp311-cp311-win_amd64.whl
Size 1.1 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
9daaa504e7928d0012ad34fa27f5952d2ca1ab0b08ea9780e550dda447474013
BLAKE2b-256 checksum
How to use checksums
fe7638ec8ead51574c7a495691c3cc5221b06b6fcdad6eded1389a3372aac920
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
b06a48b91226a796ba6097733bbd3e58e6910d4aa04277765f2b5abf3ddb6086
BLAKE2b-256 checksum
How to use checksums
50abedaac73b2cc03eed3652fd17736cf3937512b59e7857dfc8ea7c15302aee
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
5c77db9938a5b94125a792c48c1af8f9cb25f51435888437cee2d596a34bf51e
BLAKE2b-256 checksum
How to use checksums
5b5178727311c4d6bf61aa6aa5fbbaf37869fe52d3d0113a5ad355111ad5b3f8
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
e039f0d3e7c95eed0693a8e6326db1241975ed73103b0dc56ac71925ee139892
BLAKE2b-256 checksum
How to use checksums
cbee877616f307a4f72896bd182c4fb73e09842fc2a5f49aecce72edbe4ef88b
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-cp310-cp310-win_amd64.whl
Size 1.1 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
9339e6c80b2da0fe9025f27203d33ec4419c9e35c60f5459e5d1c921c7f2e876
BLAKE2b-256 checksum
How to use checksums
73432d75b5df9b09b7daf51c40d3321ff36fe1a8405e4ef2b1579697e858080f
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
a48571806f7b4b0def4037b80ba009a1fbd68806ee609de902650f2a233b079f
BLAKE2b-256 checksum
How to use checksums
049e740bdfc70bee89a25a0abbfb80e5e5cc890f6f600318a038727b2620239a
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
65b994cfe64ea89daaef5365e0f8317dffc290115fa7bc74b016357462aeb7be
BLAKE2b-256 checksum
How to use checksums
b19bb82f3ddf75de8ae904beab2b044e124acd2c504277d73c75416a80f09b76
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
8e97192d4eae2715f64bea615c6b3c3e48a2868dbab62583548ec86ec7804f2e
BLAKE2b-256 checksum
How to use checksums
667647e2670fe8f1ddcba20042c29a64206667424db4a0f532b1e65bbb07a731
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-cp39-cp39-win_amd64.whl
Size 1.1 MB
Tags CPython 3.9 Windows x86-64
SHA-256 checksum
How to use checksums
9ff9daae364cab0135780179775becaab16adeed1d553ce31bbd40a07edbd0bb
BLAKE2b-256 checksum
How to use checksums
603bda124183526444e2b339368a0bf2a1cf75c3f53fb92c3029ec5d575b9634
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
adf0cb69637433486de0fbd36873486dbbd2d6477ff093749b6cf1c57c02bb48
BLAKE2b-256 checksum
How to use checksums
decc76cee2ea8fbf14a732c2433cd7a50d5a1b688a8c3ef3cc544a5381a13052
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
32af336fecd40a40ea2578fdd157bd2c7709c861dc86c624a300f7b169ede914
BLAKE2b-256 checksum
How to use checksums
3b81c6a597632be47f8aa16ae15611707fbc2759e814471272556c13e64fe521
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 25, 2026.

Transparency log

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

Download URL gtcaca-0.2.7-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
3d549024e05b336621e4d41887b0f1e9fbaa3959a7d70822f68f65397fe7e7e2
BLAKE2b-256 checksum
How to use checksums
3827b229aedcb08c8d85df859dc7125e1b9736655de149d0436a24d412194c20
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 25, 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