Bazalt
Bazalt is a Python library for the Vulkan API. Use it to prototype GPU and shader work, and to build graphical applications. A C++23 core does the Vulkan work. The Python layer keeps the setup code short.
pip install bazalt
Bazalt supplies wheels for Windows, Linux and macOS, for CPython 3.10 to 3.14. You need a driver with Vulkan 1.2.
On macOS you must also install the Vulkan SDK. The system supplies no Vulkan loader, and the SDK gives you the loader and MoltenVK, which runs Vulkan on Metal. The macOS wheels are for Apple Silicon and need macOS 14 or later.
To build from source, you need a C++23 compiler (GCC 14+, or MSVC 19.36+ from Visual Studio 17.6) and the Vulkan SDK. On macOS, use the newest Xcode you have: bazalt uses C++23 features that Apple Clang received late.
A triangle
Three files: the program, a vertex shader and a fragment shader. Put them in one directory and run the program.
import bazalt as bz
window = bz.Window(1024, 720, "Bazalt - triangle")
ctx = bz.Context()
renderer = ctx.create_renderer(window)
# A pipeline is built against a render target, which supplies the formats.
# The window is one target. An offscreen image is another. Same call.
pipeline = (ctx.graphics_pipeline()
.vertex_shader(ctx.compile_shader("triangle.vert", bz.ShaderStage.VERTEX))
.fragment_shader(ctx.compile_shader("triangle.frag", bz.ShaderStage.FRAGMENT))
.vertex_format([bz.VertexFormat.FLOAT3, bz.VertexFormat.FLOAT3]) # position + colour
.build(renderer))
# Interleaved position (x, y, z) and colour (r, g, b). Vulkan clip space runs
# from -1 to 1, and y points down.
vbuf = ctx.create_buffer([
0.0, -0.5, 0.0, 1.0, 0.0, 0.0,
-0.5, 0.5, 0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 0.0, 0.0, 1.0,
], bz.BufferUsage.VERTEX, bz.MemoryUsage.STATIC)
# You describe a frame as passes on a graph. A pass with a render target draws
# into it. The triangle does not change, so build the graph one time and send
# the same graph every frame.
g = ctx.graph()
with g.add_pass(renderer, clear_color=[0.1, 0.2, 0.3, 1.0]) as p:
p.bind_pipeline(pipeline).bind_vertex_buffer(vbuf).draw(3)
while window.is_open():
bz.poll_events()
ctx.begin_frame() # opens one frame for every window on this Context
if renderer.acquire(): # False when this window sits the frame out
renderer.present(g)
// triangle.vert
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor;
void main() {
gl_Position = vec4(inPosition, 1.0);
fragColor = inColor;
}
// triangle.frag
#version 450
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
}
Vulkan clip space, and the one line every 3D program writes
Vulkan puts the origin of a framebuffer in the top left corner, and +y in clip space points
down. That agrees with the memory: row 0 of an image is the top row, texture coordinates
start at the first texel, set_scissor and copy_image measure from the same corner, and a
display scans the same way. OpenGL puts the origin at the bottom left, which is why OpenGL
code flips images so often.
A projection matrix from GLM or pyrr therefore disagrees with Vulkan twice, because those
build the OpenGL matrix. glm.perspective puts depth in -1 to 1, where Vulkan wants 0
to 1, and it points +y up. Correct both:
# perspectiveRH_ZO, not perspective: the ZO is the 0-to-1 depth range Vulkan uses.
proj = glm.perspectiveRH_ZO(glm.radians(60.0), width / height, 0.1, 100.0)
proj[1][1] *= -1 # GLM builds a y-up matrix; Vulkan clip space is y-down
Every example in examples/ does exactly this. Both lines belong to the matrix, not to
bazalt: a projection written for Vulkan carries the range and the sign already, and needs
neither.
That is why bazalt has no y_up switch. A flipped viewport reverses the triangle winding,
so CullMode and FrontFace would mean opposite things depending on a keyword argument,
and the rasterizer would point up while image.read(), copy_image and set_scissor still
measure from the top left. If you want a flipped viewport anyway, nothing stops you:
p.set_viewport(0, height, width, -height) inside a render pass overrides the one bazalt
emits.
Compute writes an image, and you edit it while it runs
A compute shader fills an image texel by texel. A fullscreen triangle then samples that image. That is two passes, and two things happen here that you do not write:
- Bazalt compares what each pass reads with what the earlier passes wrote. It sees that the compute pass writes the image and the render pass reads it, so it puts the barrier and the layout change between them. It does this for the whole frame at one time, so an image that two passes use in a row keeps the right layout instead of changing back and forth.
hot_reload=Truewatches every file bazalt loaded. Editpattern.compwith the window open and the picture changes. A typo logs aShaderErrorand the last good version stays on screen.
import struct
import time
import bazalt as bz
W = H = 512
window = bz.Window(W, H, "Bazalt - compute")
ctx = bz.Context(hot_reload=True)
renderer = ctx.create_renderer(window)
# Compute: no vertices and no fragment shader. One dispatch per frame.
generate = (ctx.compute_pipeline()
.shader(ctx.compile_shader("pattern.comp", bz.ShaderStage.COMPUTE))
.storage_image(0)
.push_constant(4) # 4 bytes, one float: the time
.build()) # no target, because compute has no attachments
# Graphics: a fullscreen triangle that samples the result.
present = (ctx.graphics_pipeline()
.vertex_shader(ctx.compile_shader("fullscreen.vert", bz.ShaderStage.VERTEX))
.fragment_shader(ctx.compile_shader("present.frag", bz.ShaderStage.FRAGMENT))
.texture(0, bz.ShaderStage.FRAGMENT)
.build(renderer))
# One image, bound two ways: written as a storage image, read as a texture.
image = ctx.create_image(W, H, bz.Format.RGBA8)
pool = ctx.create_descriptor_pool() # no sizes: it grows from the layouts it serves
write_set = pool.allocate_set(generate)
write_set.set_storage_image(0, image)
read_set = pool.allocate_set(present)
read_set.set_image(0, image)
g = ctx.graph()
start = time.time()
while window.is_open():
bz.poll_events()
ctx.begin_frame() # bazalt applies the file edits here
if not renderer.acquire():
continue
# The push constant changes every frame, so build the graph again. Use
# reset() rather than a new graph: it keeps the GPU objects.
g.reset()
(g.add_pass(name="pattern")
.bind_pipeline(generate)
.bind_descriptor_set(write_set, generate)
.push_constants(generate, 0, struct.pack("<f", time.time() - start))
.dispatch((W + 7) // 8, (H + 7) // 8))
with g.add_pass(renderer, name="present") as p:
p.bind_pipeline(present).bind_descriptor_set(read_set, present).draw(3)
renderer.present(g)
// pattern.comp
#version 450
layout(local_size_x = 8, local_size_y = 8) in;
layout(set = 0, binding = 0, rgba8) uniform writeonly image2D img;
layout(push_constant) uniform Push { float time; } pc;
void main() {
ivec2 p = ivec2(gl_GlobalInvocationID.xy);
ivec2 sz = imageSize(img);
if (p.x >= sz.x || p.y >= sz.y) return;
vec2 uv = vec2(p) / vec2(sz);
float v = 0.5 + 0.5 * sin(uv.x * 12.0 + pc.time) * cos(uv.y * 12.0 - pc.time * 0.7);
imageStore(img, p, vec4(v, uv.x, uv.y, 1.0));
}
// fullscreen.vert — a triangle from gl_VertexIndex, with no vertex buffer
#version 450
layout(location = 0) out vec2 uv;
void main() {
uv = vec2(gl_VertexIndex & 2, (gl_VertexIndex << 1) & 2);
gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0);
}
// present.frag
#version 450
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 outColor;
layout(set = 0, binding = 0) uniform sampler2D tex;
void main() {
outColor = texture(tex, uv);
}
The same code, with no window
A render target is an offscreen image with the same interface as the window. Both come from the Context, and everything else in this file works the same against either. Build the pipeline against it, submit, and read the pixels into NumPy. This runs in a test and in CI, where no display exists:
ctx = bz.Context()
target = ctx.create_render_target(800, 600, depth=bz.Format.D32F)
pipeline = ... # the triangle pipeline above, built with .build(target)
g = ctx.graph()
with g.add_pass(target, clear_color=[0.1, 0.2, 0.3, 1.0]) as p:
p.bind_pipeline(pipeline).bind_vertex_buffer(vbuf).draw(3)
ctx.submit(g)
pixels = target.color[0].read() # numpy (600, 800, 4) uint8
In a notebook, and on a machine with no display
The code above is the whole notebook story: render offscreen, read the pixels, show them
with the library you already use. A remote kernel on a university server works the same
way, because bazalt starts the window system only when you ask for a Window.
Use with. Without it, a re-run cell leaves the previous Context's upload worker and
hot-reload watcher running until the garbage collector reaches them, so a shared machine
collects one set of threads per run:
import bazalt as bz
from PIL import Image
with bz.Context() as ctx:
target = ctx.create_render_target(512, 512)
# ...build a graph and submit it...
pixels = target.color[0].read()
Image.fromarray(pixels) # the cell shows it
Read the pixels inside the block. A Context that is closed starts no new work, and
target.color[0].read() after the block raises StateError rather than a black image.
For anything interactive, build the Context once. A device costs tens of milliseconds,
so a slider that calls the function above per event queues work faster than it finishes and
the notebook stops responding. Build the Context, the pipeline and the target once, and let
a redraw be a record, a submit and a read — a few milliseconds. That Context outlives the
cell, which is what ctx.close() is for.
examples/33_notebook/notebook.ipynb shows both shapes, plus a compute cell that uses the
GPU as a calculator.
What you get
- Vulkan, and not an engine. You keep the pipelines, the command buffers and the memory. Bazalt removes the setup code and the object lifetimes.
- Barriers on their own. You describe a frame as passes on a graph. Bazalt compares
what each pass reads with what the earlier passes wrote, then puts the barriers and the
layout changes between them — for the whole frame at one time. It reads the SPIR-V to
find out which resources a shader writes, so a storage image written by a fragment
shader is ordered for you.
add_pass(auto_barriers=False)gives that job back to you throughp.barrier(), for that pass alone. - A pass is a handle, so a frame is editable.
p.enabled = Falsedrops one pass out of the frame andgraph.remove(p)takes it out for good. Bazalt works out the barriers again for the passes that remain, so switching an effect off never leaves a stale barrier behind, and nothing is recorded a second time. This is what an effect chain you are still tuning wants, and it used to mean rebuilding the frame around anif. - Compute beside graphics. One graph holds a compute pass and a render pass. A
dispatch writes the vertices and the draw reads them. Results come back as NumPy arrays.
Each pass names the queue it runs on:
queue=bz.Queue.COMPUTEputs a pass on the compute queue andqueue=bz.Queue.TRANSFERputs a pass of copies on the transfer queue, where each runs beside the graphics work. Bazalt puts the waits between the queues for you, and it does that for the passes of one graph and for a graph you send again. Between two different graphs you say it withsubmit(after=...). The graphics queue stays the default, and the choice stays yours. - Uploads copy on their own queue. A discrete GPU has a transfer-only queue family
that copies while the graphics and compute queues work.
create_buffer,load_imageandimage.updatesubmit there, so a texture that loads during a frame competes with nothing.ctx.supports(bz.Feature.ASYNC_TRANSFER)says whether the family is real; a device without one runs the same program with the same order. - The graph explains itself.
graph.explain()prints what the compile decided: each pass, its queue, and every barrier and wait, with the pass that produced it. Resources keep thename=you gave them, so the report and the validation layer both name your image rather than a handle. A pass withauto_barriers=Falsegets a warning when it uses a resource no barrier in it covers, and the warning names thep.barrier()call that fixes it. - Images in every shape. 2D textures, texture arrays, cubemaps and 3D volumes come from
one function:
create_image(w, h, cube=True)orcreate_image(w, h, depth=n). A volume is asampler3Din the shader — colour-grading LUTs, volumetric noise, raymarched clouds — and a NumPy array of the matching shape uploads straight into any of them. - Every pipeline stage. Vertex, fragment and compute, plus tessellation for displacement and adaptive detail, and geometry for a primitive that becomes a different one. A dispatch or a draw can also read its own arguments from a buffer the GPU filled, so the count never travels back to the CPU.
- Data larger than a binding. A descriptor sees at most
ctx.limits.max_storage_bufferof a buffer, which is 4 GB on most desktop drivers.buffer.addressgoes around it: the shader reads a pointer from a push constant, so the size the device can allocate becomes the only limit.ctx.limitsreports the numbers behind decisions like this one, and a large upload is staged in pieces, so it costs GPU memory and not that much RAM as well. - One rule for what blocks. Every write is asynchronous and every read blocks. A handle
is its own future, so normal code waits nowhere.
buf.read()blocks, because it has nothing to give you until the bytes arrive. Every submit hands back aSerial, soctx.submit(g, wait=False, after=earlier)orders one submit behind another on the GPU while the CPU carries on. - Hot reload. Bazalt watches the shaders you loaded, their
#includefiles and your images, then applies the edits in place. A mistake does not stop the application. - Headless, and notebook-ready. Draw into an offscreen target and read the pixels as a
NumPy array — no window and no display, so a Jupyter kernel on a remote server works.
with bz.Context() as ctx:releases the device's worker threads when the block ends, instead of when the garbage collector notices. - The window, and what arrives through it. Keys, the mouse and the scroll wheel, plus
the characters the user typed through
window.text_input(), files dropped on the window, the clipboard throughbz.get_clipboard()andbz.set_clipboard(), an icon throughwindow.set_icon(), and the pointer throughwindow.set_cursor()andwindow.set_cursor_position(). A gamepad reports both the level and the edge.bz.list_monitors()says which displays exist, so a fullscreen window can name one.bz.poll_events()pumps a program that animates;bz.wait_events()sleeps until something happens, for one that does not. - Tools for a picture that looks wrong. The validation layers report through a Python
logger.
Context(shader_printf=True)sendsdebugPrintfEXT()from a shader to that logger.Context(gpu_timing=True)andp.timer()measure a frame or one part of a pass.p.label()and the pass name make a RenderDoc capture readable. A compiled shader also tells you what bazalt read out of it:shader.writes,shader.writes_unknownandshader.prints. - Wide reach. Vulkan 1.2 is the baseline and bazalt uses 1.3 where the driver has it. You ask for a capability by what it does, never by a version or an extension name.
- No ceiling. A manual pass with
p.barrier(),submit(after=...)to order whole submits by hand,raw_extensionsand the Vulkan handles stay open for the work bazalt does not cover.
Design rules
Four rules decide what goes into the API. DESIGN.md holds them with their reasons.
- One obvious way to do one thing. A resource that differs by one parameter is a keyword argument, not a new function.
- Never cap the ceiling. Each layer keeps an escape hatch to the Vulkan below it.
- It must run on more than 90% of machines.
- Prototyping comes first. A feature that makes pictures ranks before plumbing.
Examples
Every directory in examples/ runs on its own.
| Subject | Examples |
|---|---|
| Basics | 01_empty_window, 02_triangle, 03_textured_quad, 04_colored_cube, 05_textured_cube, 06_multiple_cubes, 07_model_loading |
| The graph | 42_pass_toggles (switch a pass off, take one out), 43_manual_barriers (one manual pass beside the automatic ones), 44_submit_order (Serial handles and after=), 45_async_compute (a pass on the compute queue), 46_async_overlap (switch a simulation between the queues and measure it) |
| Compute | 11_particles (compute writes the vertices), 13_compute_postprocess, 41_buffer_address (a buffer larger than a descriptor can bind) |
| Shadows and deferred | 09_shadow_map, 17_cascade_shadows, 10_gbuffer_mrt |
| Cubemaps and layers | 14_skybox, 16_env_capture (six faces), 18_multiview |
| 3D textures | 31_volume_raymarch (a raymarched cloud), 32_lut_grading (colour grading through a LUT baked by render-to-slice) |
| Image quality | 15_msaa, 36_msaa_resolve (reading the samples one at a time), 23_outline (stencil), 39_two_sided_stencil (front faces against back faces) |
| Pipeline stages | 25_tessellation (displacement and adaptive detail), 26_geometry_normals (triangles become lines), 38_topologies (one blade drawn as a list, a fan and a strip), 40_primitive_restart (three strips in one draw) |
| GPU-driven work | 28_gpu_culling (indirect draw, two windows), 29_bindless (one draw, many textures) |
| Data in and out | 24_video_texture (per-frame updates), 22_instancing (20000 instances) |
| Windows and devices | 19_multi_window, 20_multi_context (two GPUs), 21_window_modes, 08_pyqt_integration |
| Tools | 12_hot_reload, 27_drop_and_icon (drag a picture onto the window), 30_gamepad, 35_imgui_overlay (an ImGui panel that tunes a running shader), 37_occlusion_query (how much of a thing was drawn) |
| Notebooks | 33_notebook (headless rendering, a slider, GPU compute — needs Jupyter) |
| Showcase | 34_showcase (San Miguel with GPU culling, bindless materials, a day-night cycle, PCF shadows, MSAA and an HDR post chain) |
CHANGELOG.md lists what each release added. DESIGN.md gives the reasons behind the API.
License
MIT. See LICENSE.txt.
Metadata
Release files for bazalt 0.30.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bazalt-0.30.0.tar.gz | 2.0 MB | With provenance | Details |
Built distributions (wheels)
Total release size: 59.6 MB
Release files / bazalt-0.30.0.tar.gz
| Download URL | bazalt-0.30.0.tar.gz |
|---|---|
| Size | 2.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
289170253e356a0eb8e1fc4b43374f7c95e7181e6279e297ab7a248d89047f0b
|
|
BLAKE2b-256 checksum How to use checksums |
c273a8ff2b1cdebf340a22cc40ee380045f950d841f130525b3a08f8a0e57ef1
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp314-cp314-win_amd64.whl
| Download URL | bazalt-0.30.0-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
a4479cf1a07f201d075cf9010caca5cbd97298abbd4caab8253c216545c95afc
|
|
BLAKE2b-256 checksum How to use checksums |
8ebfb26cfcf6fed235ab14cdcf4a63e29be0ccf5ad8abce07bfdb12368457c77
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | bazalt-0.30.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
e3bb7f0fd1fa615d6a2ee7849c426677a9cbc321ad87506fbf9945d5b8233cf9
|
|
BLAKE2b-256 checksum How to use checksums |
3d2c170cf16c9ae912e98c593da501596400235be96f8a79991a3a049903c7b2
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp314-cp314-macosx_14_0_arm64.whl
| Download URL | bazalt-0.30.0-cp314-cp314-macosx_14_0_arm64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.14 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
084654da4e31c29411a6db90227bc3acd9c2185c1571c5aaaab9e7ca6eb2d9e5
|
|
BLAKE2b-256 checksum How to use checksums |
e2df96d7e89d788be73ce5c3e291c30c59b55482973fbc0daac1695d4fd1c535
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp313-cp313-win_amd64.whl
| Download URL | bazalt-0.30.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
d813b3903d5fdf335c8852100a20af28499f0f4e564c752aed3ba6dd141ccf03
|
|
BLAKE2b-256 checksum How to use checksums |
11ee345c70da7ffa2cff04e1f773ce0545a271f1479774337a98cd9623d2c354
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | bazalt-0.30.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
ef072ab7d897d17275aefda1c9e93c441ff812b772204b403cb08789c19a99b9
|
|
BLAKE2b-256 checksum How to use checksums |
c497fb0376a25e9c590327b9054855b6498ad1912fe488fc53caec671c3b28e8
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp313-cp313-macosx_14_0_arm64.whl
| Download URL | bazalt-0.30.0-cp313-cp313-macosx_14_0_arm64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.13 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
adfcb8cd66f90fa29bb05cdb19c2e4a3ef2c8d05a9b45fff05c43c57dd5a1101
|
|
BLAKE2b-256 checksum How to use checksums |
3326d7c3add0329296f961a2b501062ff83177f71e9251874b05fdec1447f405
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp312-cp312-win_amd64.whl
| Download URL | bazalt-0.30.0-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
3b9e48da77b7f941cfed93f2e1485535080e3fd0834265b91c0cdf0691a2c8d9
|
|
BLAKE2b-256 checksum How to use checksums |
7c4bd37aaf669685f38a0655a2d55238f68a007203ec3928bc4b36d256555694
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | bazalt-0.30.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
fca1755f4f1e14e0be627bc120c235467b02b2db1da56b51759cfec622f1af72
|
|
BLAKE2b-256 checksum How to use checksums |
225fb7119aeb02014f0ea857657a6a4b8ab70607a00fe0d73e6ca2699b2a133e
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp312-cp312-macosx_14_0_arm64.whl
| Download URL | bazalt-0.30.0-cp312-cp312-macosx_14_0_arm64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.12 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
99725935462a043023db8b02e52eb2ee75646caceb12a78aab41913f8cf348ac
|
|
BLAKE2b-256 checksum How to use checksums |
74c4cb572cb990a67c1c4d929d57b2edd62dc605ddc677b8dea6bb1493af57ef
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp311-cp311-win_amd64.whl
| Download URL | bazalt-0.30.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
57ca3ba3a89d8cf803a71b004380be38ef13040f8ba54892ab501492aa9eac5a
|
|
BLAKE2b-256 checksum How to use checksums |
39b0b4ba136b1d8b3412e24c0791067e5c2255e04f8a5e6130dedc379592ac51
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | bazalt-0.30.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
72b68698badbee8546d4d390c74092fbdfe705c2e60a9902a6c509e6a7b81543
|
|
BLAKE2b-256 checksum How to use checksums |
eb9da0d62826b2830ae1061dd1ab59e6e570f5df82fbd3a41df25ea54840edf2
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp311-cp311-macosx_14_0_arm64.whl
| Download URL | bazalt-0.30.0-cp311-cp311-macosx_14_0_arm64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.11 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
382f87b10639452d5a1f53226a05ab427cfc2f465df46ece21bd674de837eb06
|
|
BLAKE2b-256 checksum How to use checksums |
2477a579c77385ca15ca22af2feab5acb1665762396521648521e7c79bbff5f7
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp310-cp310-win_amd64.whl
| Download URL | bazalt-0.30.0-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
54a3a40112560ca3987ec92a5e5e3d6c7eaf2ec4f1fa643a2b2b0f0636d48a2b
|
|
BLAKE2b-256 checksum How to use checksums |
6655a99d871a10dcb6bff9cc5753ab490e4a11ca2bdc245431eb51f154a783b7
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | bazalt-0.30.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.2 MB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
369de6ab1e5c55599e5e322f356a80d756084263a15f71c7e89289d7fdc61bb5
|
|
BLAKE2b-256 checksum How to use checksums |
19bdda824117805afe4bb25f988bbc2bb983c7ca70b15c46357c67f1f8bcbffb
|
| 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 Aug 24, 2026.
Transparency logRelease files / bazalt-0.30.0-cp310-cp310-macosx_14_0_arm64.whl
| Download URL | bazalt-0.30.0-cp310-cp310-macosx_14_0_arm64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.10 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
2b6eeb29de42a81714b26c6631eb95bf8466a8645f32519e51a9cca2499a98a9
|
|
BLAKE2b-256 checksum How to use checksums |
9ed2b957b916f2074777921f76979cb7773a07e924dc2cad6a81eca326b4fabb
|
| 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 Aug 24, 2026.
Transparency logSecurity for bazalt 0.30.0
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.
Full provenance
All 16 files in this release have been uploaded with provenance metadata.
Attestation for bazalt-0.30.0.tar.gz
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 Aug 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.