Skip to main content

aldakit

PyPI version Python 3.10+ License: MIT

A zero-dependency Python parser and MIDI generator for the Alda music programming language1.

Features

  • Alda Parser - Full parser for the Alda music language with AST generation
  • MIDI Playback - Low-latency playback via libremidi (CoreMIDI, ALSA, WinMM)
  • Audio Playback - Built-in synthesis via TinySoundFont (no external synth required)
  • MIDI Export - Save compositions as Standard MIDI Files
  • MIDI Import - Load MIDI files and convert to Alda notation
  • Alda Export - Serialize any AST back to Alda source, round-trip safe
  • Real-time Transcription - Record from MIDI keyboards and convert to Alda
  • Programmatic Composition - Build music with Python using the compose module
  • Music Theory - Scale, chord, and interval utilities
  • Transformers - Transpose, invert, augment, diminish, and more
  • Generative Music - Markov chains, L-systems, cellular automata, Euclidean rhythms
  • Interactive REPL - Syntax highlighting, auto-completion, and live playback
  • CLI Tools - Play, transcribe, and convert from the command line

Installation

Requires Python 3.10+

pip install aldakit

Or with uv:

uv add aldakit

Quick Start

Command Line

# Interactive REPL (default when no args)
aldakit

# Evaluate inline code
aldakit eval "piano: c d e f g"

# Play an Alda file
aldakit play examples/twinkle.alda

# Export to MIDI file
aldakit play examples/bach-prelude.alda -o bach.mid

# Use built-in audio (TinySoundFont) instead of MIDI
aldakit play -sf ~/Music/sf2/FluidR3_GM.sf2 examples/twinkle.alda
aldakit repl -sf ~/Music/sf2/FluidR3_GM.sf2

# Use audio backend with pre-configured soundfont (from config or env)
aldakit play -a examples/twinkle.alda
aldakit repl -a

# Create virtual MIDI port with custom name
aldakit repl -vp MyMIDI

Python API

import aldakit

# Play directly
aldakit.play("piano: c d e f g")

# Save to MIDI file
aldakit.save("piano: c d e f g", "output.mid")

# Play from file
aldakit.play_file("song.alda")

# List available MIDI ports
print(aldakit.list_ports())

For more control, use the Score class:

from aldakit import Score

score = Score("""
piano:
  (tempo 120)
  o4 c4 d e f | g a b > c
""")

# Play, blocking until finished
score.play(port="FluidSynth")

# Or play in the background and keep control of the playback
handle = score.play(port="FluidSynth", wait=False)
handle.is_playing()
handle.stop()

# Save to file
score.save("output.mid")

# Access internals
print(f"Duration: {score.duration}s")
print(score.ast)   # Parsed AST
print(score.midi)  # MIDI sequence

Concurrent Playback

Layer multiple sequences for polyphonic REPL-style playback:

from aldakit.midi.backends import LibremidiBackend

# Create backend with concurrent mode (default)
backend = LibremidiBackend(concurrent=True)

# Play multiple sequences - they layer on top of each other
backend.play(score1.midi)  # Starts immediately
backend.play(score2.midi)  # Layers on top of score1
backend.play(score3.midi)  # Up to 8 concurrent slots

# Check status
print(f"Active slots: {backend.active_slots}")
print(f"Playing: {backend.is_playing()}")

# Wait for all playback to complete
backend.wait()

# Or stop all playback immediately
backend.stop()

# Sequential mode - each play waits for previous to finish
backend.concurrent_mode = False
backend.play(score1.midi)  # Plays first
backend.play(score2.midi)  # Waits, then plays second

MIDI Import

Import existing MIDI files and work with them as Alda:

from aldakit import Score

# Import a MIDI file
score = Score.from_midi_file("recording.mid")

# Or use from_file (auto-detects .mid/.midi)
score = Score.from_file("song.mid")

# View as Alda source
print(score.to_alda())
# piano:
# o4 c4 d e f | g a b > c

# Play the imported MIDI
score.play()

# Export to Alda file
score.save("song.alda")

# Re-export to MIDI
score.save("output.mid")

# Import with custom quantization grid
# Default is 0.25 (16th notes), use 0.5 for 8th notes
score = Score.from_midi_file("recording.mid", quantize_grid=0.5)

Features:

  • Multi-track MIDI files (each channel becomes a separate part, and stays on its own channel when played or re-exported)
  • Channel 10 is imported as a midi-percussion part
  • Tempo detection and preservation
  • General MIDI instrument mapping across all 128 programs
  • Chord detection for simultaneous notes
  • Configurable timing quantization

Real-Time MIDI Transcription

Record MIDI input from a keyboard or controller:

import aldakit

# List available MIDI input ports
print(aldakit.list_input_ports())

# Record for 10 seconds from the first available port
score = aldakit.transcribe(duration=10)

# Play back what was recorded
score.play()

# Export to Alda source
print(score.to_alda())

# Record with options
score = aldakit.transcribe(
    duration=30,
    port_name="My MIDI Keyboard",
    instrument="piano",
    tempo=120,
    quantize_grid=0.25,  # Quantize to 16th notes
)

For more control, use TranscribeSession:

from aldakit.midi.transcriber import TranscribeSession

session = TranscribeSession(quantize_grid=0.25, default_tempo=120)

# Set a callback for note events (optional)
session.on_note(lambda pitch, vel, on: print(f"Note: {pitch}, vel={vel}, on={on}"))

# Start recording
session.start()

# Poll periodically (in a loop or timer)
import time
for _ in range(100):
    session.poll()
    time.sleep(0.1)

# Stop and get the recorded notes
seq = session.stop()
print(seq.to_alda())

Programmatic Composition

Build music programmatically using the compose module:

from aldakit import Score
from aldakit.compose import part, note, rest, chord, seq, tempo, volume

# Create a score from compose elements
score = Score.from_elements(
    part("piano"),
    tempo(120),
    note("c", duration=4),
    note("d"),
    note("e"),
    chord("c", "e", "g", duration=2),
)
score.play()

# Builder pattern with method chaining
score = (
    Score.from_elements(part("violin"))
    .with_tempo(90)
    .add(note("g", duration=8), note("a"), note("b"))
)

# Note transformations
c = note("c", duration=4)
c_sharp = c.sharpen()           # C#
c_up_octave = c.transpose(12)   # Up one octave

# Repeat syntax
pattern = seq(note("c"), note("d"), note("e"))
repeated = pattern * 4  # Repeat 4 times

# Export to Alda source
print(score.to_alda())  # "violin: (tempo 90) g8 a b"

Available compose elements:

  • Notes: note("c", duration=4, octave=5, accidental="+", dots=1)
  • Rests: rest(duration=4), rest(ms=500)
  • Chords: chord("c", "e", "g"), chord(note("c"), note("e", accidental="+"))
  • Sequences: seq(note("c"), note("d")), Seq.from_alda("c d e")
  • Parts: part("piano"), part("violin", alias="v1")
  • Attributes: tempo(120), volume(80), octave(5), panning(50)
  • Dynamics: pp(), p(), mp(), mf(), f(), ff()
  • Advanced: cram(), voice(), voice_group(), var(), var_ref(), marker(), at_marker()

Accidentals use Alda's characters: "+" (sharp), "-" (flat), "_" (natural), repeated for double accidentals. Anything else raises ValueError.

The octave a note declares is preserved through both to_alda() and MIDI generation. Octave is stateful in Alda, so a note only emits an octave change where the octave actually changes:

from aldakit import Score
from aldakit.compose import part, note

score = Score.from_elements(part("piano"), note("c", octave=5), note("d"))
print(score.to_alda())  # 'piano: o5 c d'
print([n.pitch for n in score.midi.notes])  # [72, 74]

Instrument Names

All 128 General MIDI programs are available under their Alda names. Canonical names carry the midi- prefix, and most have shorter aliases:

midi-acoustic-grand-piano:  # canonical
piano:                      # alias for the same program
midi-square-lead:           # synth lead
midi-percussion:            # drum kit on MIDI channel 10

See docs/alda-language/list-of-instruments.md for the full list. An unrecognised instrument name falls back to acoustic grand piano and reports a warning rather than failing silently:

score = Score("bogus-instrument: c d e")
print([str(d) for d in score.diagnostics])
# ["<input>:1:1: Unknown instrument 'bogus-instrument'; falling back to acoustic grand piano."]

midi-percussion (alias percussion) is placed on MIDI channel 10, where note numbers select drum sounds; key signatures and transposition do not apply to it. Melodic parts never use that channel. There are 15 melodic channels, so a score with more than 15 pitched parts reports a diagnostic that instrument assignments will collide.

Scales and Chords

Build melodies and harmonies using music theory helpers:

from aldakit import Score
from aldakit.compose import part, tempo
from aldakit.compose import (
    # Scale functions
    scale, scale_notes, scale_degree, mode,
    relative_minor, relative_major,
    # Chord builders
    major, minor, dim, aug, maj7, min7, dom7,
    arpeggiate, invert_chord, voicing,
)

# Get scale pitches
c_major = scale("c", "major")       # ['c', 'd', 'e', 'f', 'g', 'a', 'b']
a_blues = scale("a", "blues")       # ['a', 'c', 'd', 'd+', 'e', 'g']

# Generate scale as playable notes
melody = scale_notes("c", "pentatonic", duration=8)

# Key relationships
rel_min = relative_minor("c")  # 'a' (C major -> A minor)
rel_maj = relative_major("a")  # 'c' (A minor -> C major)

# Build chords
c_maj = major("c")                    # C E G
a_min7 = min7("a")                    # A C E G
g_dom7 = dom7("g", inversion=1)       # B D F G (first inversion)

# Arpeggiate a chord
arp = arpeggiate(maj7("c"), pattern=[0, 1, 2, 3, 2, 1], duration=16)

# Custom voicing (spread chord across octaves)
spread = voicing(major("c"), [3, 4, 5])  # C3 E4 G5

# Create a I-IV-V-I progression
pitches = scale("c", "major")
progression = [
    major(pitches[0], duration=2),  # C major (I)
    major(pitches[3], duration=2),  # F major (IV)
    major(pitches[4], duration=2),  # G major (V)
    major(pitches[0], duration=1),  # C major (I)
]

score = Score.from_elements(
    part("piano"),
    tempo(100),
    *progression,
)
score.play()

Available scales: major, minor, harmonic-minor, melodic-minor, pentatonic, blues, chromatic, whole-tone, dorian, phrygian, lydian, mixolydian, locrian, japanese, arabic, hungarian-minor, spanish, bebop-dominant, bebop-major

Available chords: major, minor, dim, aug, sus2, sus4, maj7, min7, dom7, dim7, half_dim7, min_maj7, aug7, maj6, min6, dom9, maj9, min9, add9, power

Transformers

Transform sequences with pitch and structural operations:

from aldakit.compose import (
    note, seq,
    transpose, invert, reverse, shuffle,
    augment, diminish, fragment, loop, interleave,
    pipe,
)

# Create a motif
motif = seq(note("c", duration=8), note("d", duration=8), note("e", duration=8))

# Pitch transformers
up_fourth = transpose(motif, 5)      # Transpose up 5 semitones
inverted = invert(motif)             # Invert intervals around first note
backwards = reverse(motif)           # Retrograde

# Structural transformers
longer = augment(motif, 2)           # Double durations (8th -> quarter)
shorter = diminish(motif, 2)         # Halve durations (8th -> 16th)
first_two = fragment(motif, 2)       # Take first 2 elements
repeated = loop(motif, 4)            # Repeat 4 times (explicit)

# Chain transformations with pipe
result = pipe(
    motif,
    lambda s: transpose(s, 5),
    reverse,
    lambda s: augment(s, 2),
)

# All transforms preserve to_alda() export
print(result.to_alda())

MIDI Transformers

For post-MIDI-generation processing, use MIDI-level transformers that operate on absolute timing:

from aldakit import Score
from aldakit.midi.transform import (
    quantize, humanize, swing, stretch,
    accent, crescendo, normalize,
    filter_notes, trim, merge,
)

# Get MIDI sequence from a score
score = Score("piano: c d e f g a b > c")
midi_seq = score.midi

# Timing transformers
quantized = quantize(midi_seq, grid=0.25, strength=0.8)  # Snap to quarter-note grid
humanized = humanize(midi_seq, timing=0.02, velocity=10)  # Add subtle variations
swung = swing(midi_seq, grid=0.5, amount=0.3)            # Apply swing feel

# Velocity transformers
accented = accent(midi_seq, pattern=[1.0, 0.5, 0.5, 0.5])  # 4/4 accent pattern
crescendo_seq = crescendo(midi_seq, start_velocity=50, end_velocity=100)
normalized = normalize(midi_seq, target=100)

# Filtering and combining
filtered = filter_notes(midi_seq, lambda n: n.pitch >= 60)  # Keep notes >= middle C
trimmed = trim(midi_seq, start=0.0, end=2.0)               # First 2 seconds
merged = merge(midi_seq, another_seq)                       # Combine sequences

Note: MIDI transformers operate on absolute timing (seconds) and cannot be converted back to Alda notation.

Generative Functions

Create algorithmic compositions with generative functions:

from aldakit import Score
from aldakit.compose import part, tempo
from aldakit.compose.generate import (
    random_walk, euclidean, markov_chain, lsystem, cellular_automaton,
    shift_register, turing_machine,
)

# Random walk melody
melody = random_walk("c", steps=16, intervals=[-2, -1, 1, 2], duration=8, seed=42)

# Euclidean rhythms (e.g., Cuban tresillo: 3 hits over 8 steps)
rhythm = euclidean(hits=3, steps=8, pitch="c", duration=16)

# Markov chain
chain = markov_chain({
    "c": {"d": 0.5, "e": 0.3, "g": 0.2},
    "d": {"e": 0.6, "c": 0.4},
    "e": {"c": 0.5, "g": 0.5},
    "g": {"c": 1.0},
})
markov_melody = chain.generate(start="c", length=16, duration=8, seed=42)

# L-System (Fibonacci pattern)
from aldakit.compose import note, rest
fib = lsystem(
    axiom="A",
    rules={"A": "AB", "B": "A"},
    iterations=5,
    note_map={"A": note("c", duration=8), "B": note("e", duration=8)},
)

# Cellular automaton (Rule 110)
automaton = cellular_automaton(rule=110, width=8, steps=4, pitch_on="c", duration=16)

# Shift register (LFSR) - classic analog sequencer
lfsr = shift_register(16, bits=4, scale=["c", "e", "g", "b"], duration=16)

# Turing Machine - evolving loop (probability=0 for locked, higher for chaos)
turing = turing_machine(32, bits=8, probability=0.1, seed=42)

# Combine into a score
score = Score.from_elements(
    part("piano"),
    tempo(120),
    *melody.elements,
)
score.play()

CLI Reference

aldakit [--version] [-h] {repl,play,eval,ports,transcribe} ...

Subcommands

Command Description
(none) Opens the interactive REPL (default when no args)
repl Interactive REPL with syntax highlighting and auto-completion
play Play an Alda file
eval Evaluate Alda code directly
ports List available MIDI ports (both input and output)
transcribe Record MIDI input and output Alda code

Global Options

Option Description
--version Show version number and exit
-h, --help Show help message

play Subcommand

aldakit play [-v] [-o FILE] [--port NAME|INDEX] [-sf FILE] [-a] [-vp NAME] [--stdin] [--parse-only] [--no-wait] FILE
Option Description
FILE Alda file to play (use - for stdin)
-v, --verbose Verbose output
-o, --output FILE Save to MIDI file instead of playing
--port NAME|INDEX MIDI port by name or index (see aldakit ports)
-sf, --soundfont FILE Use TinySoundFont audio backend with specified SoundFont
-a, --audio Use audio backend with pre-configured soundfont
-vp, --virtual-port NAME Custom virtual MIDI port name (default: AldakitMIDI)
--stdin Read from stdin (blank line to play)
--parse-only Print AST without playing
--no-wait Return without waiting for playback to finish (playback stops when the command exits)

eval Subcommand

aldakit eval [-v] [-o FILE] [--port NAME|INDEX] [-sf FILE] [-a] [-vp NAME] [--parse-only] [--no-wait] CODE
Option Description
CODE Alda code to evaluate
-v, --verbose Verbose output
--parse-only Print AST without playing
--no-wait Return without waiting for playback to finish
-o, --output FILE Save to MIDI file instead of playing
--port NAME|INDEX MIDI port by name or index
-sf, --soundfont FILE Use TinySoundFont audio backend
-a, --audio Use audio backend with pre-configured soundfont
-vp, --virtual-port NAME Custom virtual MIDI port name (default: AldakitMIDI)

repl Subcommand

aldakit repl [-v] [--port NAME|INDEX] [-sf FILE] [-a] [-vp NAME] [--sequential] [FILE]
Option Description
FILE Alda file to load on startup (use :play to hear it)
-v, --verbose Verbose output
--port NAME|INDEX MIDI port by name or index
-sf, --soundfont FILE Use TinySoundFont audio backend
-a, --audio Use audio backend with pre-configured soundfont
-vp, --virtual-port NAME Custom virtual MIDI port name (default: AldakitMIDI)
--sequential Start in sequential mode (wait for each input)

transcribe Subcommand

aldakit transcribe [-d SEC] [-i INST] [-t BPM] [-q GRID] [-o FILE] [--port NAME] [--play] [-v] [--alda-notes] [--feel FEEL] [--swing-ratio RATIO]
Option Description
-d, --duration SEC Recording duration in seconds (default: 10)
-i, --instrument NAME Instrument name (default: piano)
-t, --tempo BPM Tempo for quantization (default: 120)
-q, --quantize GRID Quantize grid in beats (default: 0.25 = 16th notes)
-o, --output FILE Save to file (.alda or .mid)
--port NAME MIDI input port name
--play Play back the recording after transcription
-v, --verbose Show notes as they are played
--alda-notes Show notes in Alda notation (with -v)
--feel FEEL Rhythm feel: straight, swing, triplet, quintuplet
--swing-ratio RATIO Swing ratio between 0 and 1 (default: 0.67)

Examples

# Interactive REPL (default when no args)
aldakit
aldakit repl

# Evaluate inline code
aldakit eval "piano: c d e f g"

# Play a file
aldakit play examples/jazz.alda
aldakit play -v examples/jazz.alda  # verbose

# Play to a specific port (by index or name)
aldakit play --port 0 examples/twinkle.alda
aldakit play --port FluidSynth examples/twinkle.alda

# Use built-in audio (TinySoundFont) instead of MIDI
aldakit play -sf ~/Music/sf2/FluidR3_GM.sf2 examples/twinkle.alda
aldakit repl -sf ~/Music/sf2/FluidR3_GM.sf2

# Read from stdin
echo "piano: c d e f g" | aldakit play -
aldakit play --stdin

# Parse and show AST
aldakit play --parse-only examples/twinkle.alda
aldakit eval --parse-only "piano: c/e/g"

# Export to MIDI file
aldakit play examples/twinkle.alda -o twinkle.mid
aldakit eval "piano: c d e f g" -o output.mid

# List available MIDI ports
aldakit ports
aldakit ports -o  # output ports only
aldakit ports -i  # input ports only

# Record MIDI input for 10 seconds (default)
aldakit transcribe

# Record from a specific input port
aldakit transcribe --port 0
aldakit transcribe --port "My MIDI Keyboard"

# Record for 30 seconds with verbose note display
aldakit transcribe -d 30 -v

# Record with Alda-style note display
aldakit transcribe -d 10 -v --alda-notes

# Record and save to file
aldakit transcribe -o recording.alda
aldakit transcribe -o recording.mid

# Record and play back
aldakit transcribe --play

# Record with custom settings (swing feel, triplet quantization)
aldakit transcribe -d 20 -t 90 -i guitar --feel triplet --play

Configuration File

aldakit supports INI-format configuration files to set default values for common options. Configuration is loaded from these locations (in priority order):

  1. ./aldakit.ini - Project-local config (current working directory)
  2. ~/.aldakit/config.ini - User config (home directory)
  3. ALDAKIT_SOUNDFONT environment variable (for soundfont only)

CLI arguments always override config file settings.

Example Configuration

Create ~/.aldakit/config.ini:

[aldakit]
# Default SoundFont for audio backend
soundfont = ~/Music/sf2/FluidR3_GM.sf2

# Default backend: "midi" or "audio"
backend = midi

# Default MIDI output port (name or index)
port = FluidSynth

# Default tempo for REPL (BPM)
tempo = 120

# Enable verbose output by default
verbose = false

Available Options

Option Type Default Description
soundfont path none SoundFont path for audio backend
backend string midi midi = external synths/DAWs/virtual port; audio = built-in TinySoundFont
port string none Default MIDI output port name
tempo integer 120 Default tempo for REPL (BPM)
verbose boolean false Enable verbose output

Backend values:

  • midi (default): Uses libremidi for MIDI output. Sends to external synthesizers (FluidSynth, hardware), DAWs, or creates a virtual port ("AldakitMIDI") for routing.
  • audio: Uses built-in TinySoundFont for direct audio output. Requires a soundfont to be configured. No external MIDI setup needed.

Backend Selection Priority

  1. CLI -sf /path/to/soundfont.sf2 forces the audio backend with that SoundFont
  2. CLI -a / --audio forces the audio backend, using a configured or discovered SoundFont
  3. Config backend = audio uses the audio backend
  4. If MIDI output ports are available, use MIDI (default)
  5. If no MIDI ports are available and a SoundFont can be found, use audio
  6. Otherwise create a virtual MIDI port ("AldakitMIDI") and warn that nothing will be heard until a synth or DAW connects to it

A SoundFont counts as available if it is named by -sf, by soundfont in the config file, or by ALDAKIT_SOUNDFONT, or if one is discovered in a standard location such as ~/.aldakit/soundfonts/ or ~/Music/sf2/.

If aldakit play produces no sound, run aldakit ports to see whether any MIDI destination exists. With no ports and no SoundFont, MIDI is being sent to a virtual port that nothing is listening to.

Project-Local Configuration

Create aldakit.ini in your project directory to override user settings:

[aldakit]
# Use audio backend with project-specific SoundFont
backend = audio
soundfont = ./sounds/project-soundfont.sf2
tempo = 140

Interactive REPL

The REPL provides an interactive environment for composing and playing Alda code:

aldakit repl

Features:

  • Syntax highlighting
  • Auto-completion for instruments (3+ characters)
  • Command history (persistent across sessions)
  • Multi-line paste (use platform-specific paste: ctrl-v, shift-ctrl-v, cmd-v, etc.)
  • Multi-line input (Alt+Enter)
  • MIDI playback control (Ctrl+C to stop)

REPL Commands:

Command Description
:load FILE Load an Alda file (does not play)
:play [FILE] Play the loaded score, or load and play FILE
:save FILE Save the session to .alda or .mid
:ls [DIR] List Alda files and directories
:cd [DIR] Change directory
:pwd Show the current directory
:clear Forget the session so far
:ports List MIDI ports
:instruments List available instruments
:tempo [BPM] Show/set the default tempo
:stop Stop playback
:status Show playback status
:concurrent / :sequential Switch playback mode
:help Show help
:quit Exit the REPL

Open a file directly from the command line. It is loaded, not played, so the REPL is ready immediately:

$ aldakit repl examples/twinkle.alda
Loaded examples/twinkle.alda (1 part, 42 notes, 28.7s)
Type :play to hear it.

aldakit> :play
Playing examples/twinkle.alda...

Working with files inside the REPL:

aldakit> :ls
  examples/
  sketch.alda
aldakit> :load sketch.alda
Loaded sketch.alda (2 parts, 64 notes, 12.4s)
Type :play to hear it.
aldakit> :play
Playing sketch.alda...
aldakit> piano: c d e f g
aldakit> :save take-2.alda
Saved /home/you/music/take-2.alda

:load never plays: a file can be inspected, saved or edited before it is heard, and opening a long score does not tie up the prompt. :play with no argument replays whatever is loaded; :play FILE is shorthand for loading and playing in one step. Typed input still plays as soon as you press Enter.

:save writes everything accepted during the session -- typed, pasted or loaded -- as a single score. A .mid or .midi extension exports MIDI instead. Note that this is the session's source, not a recording of what you heard: in concurrent mode inputs are layered as they play, whereas the saved file is one score read top to bottom.

A file opened with :load (or given on the command line) keeps its own tempo. The REPL only prepends its default tempo to input you type that does not set one.

Alda Syntax Reference

Notes and Rests

piano:
  c d e f g a b   # Notes
  r               # Rest
  c4 d8 e16       # With duration (4=quarter, 8=eighth, etc.)
  c4. d4..        # Dotted notes
  c500ms d2s      # Milliseconds and seconds

Accidentals

c+    # Sharp
c-    # Flat
c_    # Natural
c++   # Double sharp

Octaves

o4 c    # Set octave to 4
> c     # Octave up
< c     # Octave down

Chords

c/e/g           # C major chord
c1/e/g          # Whole note chord
c/e/g/>c        # With octave change

Ties and Slurs

c1~1            # Tied notes (duration adds)
c4~d~e~f        # Slurred notes (legato)

Parts

piano: c d e

violin "v1": c d e    # With alias

violin/viola/cello "strings":   # Multi-instrument
  c d e

Attributes

(tempo 120)     # Set tempo (BPM)
(tempo! 120)    # Global tempo

(vol 80)        # Volume (0-100)
(volume 80)

(quant 90)      # Quantization/legato (0-100)

(panning 50)    # Pan (0=left, 100=right)

# Dynamic markings
(pp) (p) (mp) (mf) (f) (ff)

# Key signatures
(key-sig '(g major))     # G major (F#)
(key-sig '(d minor))     # D minor (Bb)
(key-sig "f+ c+")        # Explicit accidentals

# Transposition
(transpose 5)   # Up 5 semitones
(transpose -2)  # Down 2 semitones (Bb instrument)

Variables

riff = c8 d e f g4

piano:
  riff riff > riff

Repeats

c*4             # Repeat note 4 times
[c d e]*4       # Repeat sequence
[c d e f]*8     # 8 times

Cram (Tuplets)

{c d e}4        # Triplet in quarter note
{c d e f g}2    # Quintuplet in half note
{c {d e} f}4    # Nested cram

Voices

piano:
  V1: c4 d e f
  V2: e4 f g a
  V0:           # End voices

Markers

piano:
  c d e f
  %chorus
  g a b > c

violin:
  @chorus       # Jump to chorus marker
  e f g a

Supported Instruments

All 128 General MIDI instruments are supported. Common examples:

  • piano, acoustic-grand-piano
  • violin, viola, cello, contrabass
  • flute, oboe, clarinet, bassoon
  • trumpet, trombone, french-horn, tuba
  • acoustic-guitar, electric-guitar-clean, electric-bass
  • choir, strings, brass-section

See midi/types.py for the complete mapping.

MIDI Backend

aldakit uses libremidi via nanobind for cross-platform MIDI I/O:

  • Low-latency realtime playback
  • Virtual MIDI port support (AldakitMIDI), makes it easy to just send to your DAW.
  • Pure Python MIDI file writing (no external dependencies)
  • Cross-platform: macOS (CoreMIDI), Linux (ALSA), Windows (WinMM)
  • Supports hardware and software/virtual MIDI ports (FluidSynth, IAC Driver, etc.)
import aldakit

# List available ports
print(aldakit.list_ports())

# Play to virtual port (visible in DAWs like Ableton Live)
aldakit.play("piano: c d e f g")

# Play to a specific port
aldakit.play("piano: c d e f g", port="FluidSynth")

# Save to MIDI file
aldakit.save("piano: c d e f g", "output.mid")

Audio Backend (Built-in)

For self-contained audio playback without external synthesizers, aldakit includes a built-in audio backend powered by TinySoundFont and miniaudio:

  • Direct audio output (no FluidSynth or DAW required)
  • Cross-platform: macOS (CoreAudio), Linux (ALSA/PulseAudio), Windows (WASAPI)
  • Requires a SoundFont file (.sf2) for instrument sounds
  • Header-only libraries for minimal binary size

Basic Usage

from aldakit import Score

# Play with built-in audio (requires SoundFont)
score = Score("piano: c d e f g")
score.play(backend="audio")

# Specify SoundFont explicitly
score.play(backend="audio", soundfont="/path/to/FluidR3_GM.sf2")

SoundFont Setup

The audio backend requires a General MIDI SoundFont file. aldakit searches these locations automatically:

  • $ALDAKIT_SOUNDFONT environment variable
  • ~/Music/sf2/
  • ~/.aldakit/soundfonts/
  • /usr/share/soundfonts/ (Linux)

Option 1: Download manually

Download a SoundFont and place it in a folder such as ~/Music/sf2/:

Suggest using a sha256sum (macOs or Linux) or similar to verify file integrity after download:

% sha256sum FluidR3_GM.sf2
74594e8f4250680adf590507a306655a299935343583256f3b722c48a1bc1cb0  FluidR3_GM.sf2

% sha256sum GeneralUser-GS.sf2
c278464b823daf9c52106c0957f752817da0e52964817ff682fe3a8d2f8446ce  GeneralUser-GS.sf2

% sha256sum TimGM6mb.sf2
82475b91a76de15cb28a104707d3247ba932e228bada3f47bba63c6b31aaf7a1  TimGM6mb.sf2

On Windows (PowerShell): Get-FileHash -Algorithm SHA256

Option 2: Auto-download

from aldakit.midi.soundfont import setup_soundfont, setup_all_soundfonts

# Downloads TimGM6mb.sf2 (~6 MB) to ~/.aldakit/soundfonts/
setup_soundfont()

# Or download all available SoundFonts from the catalog
setup_all_soundfonts()

Option 3: Using SoundFontManager

For more control, use the SoundFontManager class:

from aldakit.midi.soundfont import SoundFontManager

manager = SoundFontManager()

# Find existing SoundFont
sf = manager.find()

# List all found SoundFonts
for path in manager.list():
    print(path)

# Download a specific SoundFont (with SHA256 verification)
path = manager.download("FluidR3_GM")

# Download all SoundFonts from catalog
paths = manager.setup_all()

# Verify checksums of downloaded files
results = manager.verify_checksums()
for name, valid in results.items():
    print(f"{name}: {'OK' if valid else 'FAILED'}")

# List available downloads
for name, info in manager.list_available_downloads().items():
    print(f"{name}: {info['size_mb']} MB - {info['description']}")

Option 4: Environment variable

export ALDAKIT_SOUNDFONT=/path/to/your/soundfont.sf2

Using TsfBackend Directly

from aldakit import Score
from aldakit.midi.backends import TsfBackend

# Create backend with specific SoundFont
with TsfBackend(soundfont="~/Music/sf2/FluidR3_GM.sf2") as backend:
    score = Score("piano: c/e/g")
    backend.play(score.midi)
    backend.wait()  # Block until playback completes

# Inspect SoundFont presets
backend = TsfBackend()
print(f"Presets: {backend.preset_count}")
for i in range(min(10, backend.preset_count)):
    print(f"  {i}: {backend.preset_name(i)}")

Audio vs MIDI Backend

Feature Audio (backend="audio") MIDI (backend="midi")
External synth required No Yes (FluidSynth, DAW, hardware)
Setup complexity Just needs SoundFont Requires MIDI routing
Sound quality Depends on SoundFont Depends on synth
DAW integration No Yes (virtual port)
Latency Very low Very low
Effects (reverb, etc.) No Depends on synth

Recommendation: Use backend="audio" for quick playback and standalone use. Use backend="midi" (default) for DAW integration, hardware synths, or when you need effects.

MIDI Playback Setup

Virtual Port (Recommended)

When no hardware MIDI ports are available, aldakit creates a virtual port named "AldakitMIDI". This port is visible to DAWs and other MIDI software:

  1. Start the REPL: aldakit repl
  2. In your DAW (Ableton Live, Logic Pro, etc.), look for "AldakitMIDI" in MIDI input settings
  3. Play code in the REPL - notes will be sent to your DAW

Software Synthesizer (FluidSynth)

For high-quality General MIDI playback without hardware, use FluidSynth:

# Install FluidSynth (macOS)
brew install fluidsynth

# Install FluidSynth (Debian/Ubuntu)
sudo apt install fluidsynth 

# Download a SoundFont (e.g., FluidR3_GM.sf2)
# eg. sudo apt install fluid-soundfont-gm
# Place in ~/Music/sf2/

# Start FluidSynth with CoreMIDI (macOS)
fluidsynth -a coreaudio -m coremidi ~/Music/sf2/FluidR3_GM.sf2

# In another terminal, start aldakit
aldakit repl
# aldakit> piano: c d e f g

A helper script is available in the repository:

# Set the SoundFont directory (add to your shell profile)
export ALDAPY_SF2_DIR=~/Music/sf2

# Run with default SoundFont (FluidR3_GM.sf2)
python scripts/fluidsynth-gm.py

# Or specify a SoundFont directly
python scripts/fluidsynth-gm.py /path/to/soundfont.sf2

# List available SoundFonts
python scripts/fluidsynth-gm.py --list

Hardware MIDI

Connect a USB MIDI interface or synthesizer, then:

# List available ports
aldakit ports

# Play to a specific port
aldakit play --port "My MIDI Device" examples/twinkle.alda

MIDI File Export

If you don't have MIDI playback set up, export to a file:

# Save to MIDI file
aldakit play examples/twinkle.alda -o twinkle.mid

# Open with default app
open twinkle.mid

Development

Setup

git clone https://github.com/shakfu/aldakit.git
cd aldakit
make  # Build the libremidi extension

Run Tests

make test
# or
uv run pytest tests/ -v

Architecture

aldakit architecture

License

MIT

See Also

  • Alda - The original Alda language and reference implementation
  • Alda Cheat Sheet - Syntax reference
  • Extending aldakit - Design document for programmatic API
  • libremidi - A modern C++ MIDI 1 / MIDI 2 real-time & file I/O library. Supports Windows, macOS, Linux and WebMIDI.
  • TinySoundFont - SoundFont2 synthesizer library in a single C/C++ header
  • miniaudio - Single-header audio playback and capture library
  • nanobind - a tiny and efficient C++/Python bindings
  1. Includes a rich REPL, native MIDI, and built-in audio via bundled prompt-toolkit, libremidi, and TinySoundFont respectively.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aldakit-0.2.0.tar.gz (2.2 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

aldakit-0.2.0-cp314-cp314-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.14Windows x86-64

aldakit-0.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (863.4 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

aldakit-0.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (851.5 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

aldakit-0.2.0-cp314-cp314-macosx_11_0_x86_64.whl (800.1 kB view details)

Uploaded CPython 3.14macOS 11.0+ x86-64

aldakit-0.2.0-cp314-cp314-macosx_11_0_arm64.whl (777.0 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

aldakit-0.2.0-cp313-cp313-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.13Windows x86-64

aldakit-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (863.5 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

aldakit-0.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (851.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

aldakit-0.2.0-cp313-cp313-macosx_11_0_x86_64.whl (799.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ x86-64

aldakit-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (776.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

aldakit-0.2.0-cp312-cp312-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.12Windows x86-64

aldakit-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (863.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

aldakit-0.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (851.5 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

aldakit-0.2.0-cp312-cp312-macosx_11_0_x86_64.whl (800.1 kB view details)

Uploaded CPython 3.12macOS 11.0+ x86-64

aldakit-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (777.0 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

aldakit-0.2.0-cp311-cp311-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.11Windows x86-64

aldakit-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (865.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

aldakit-0.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (853.5 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

aldakit-0.2.0-cp311-cp311-macosx_11_0_x86_64.whl (801.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

aldakit-0.2.0-cp311-cp311-macosx_11_0_arm64.whl (779.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

aldakit-0.2.0-cp310-cp310-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.10Windows x86-64

aldakit-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (866.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

aldakit-0.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (853.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

aldakit-0.2.0-cp310-cp310-macosx_11_0_x86_64.whl (801.4 kB view details)

Uploaded CPython 3.10macOS 11.0+ x86-64

aldakit-0.2.0-cp310-cp310-macosx_11_0_arm64.whl (779.4 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file aldakit-0.2.0.tar.gz.

File metadata

  • Download URL: aldakit-0.2.0.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5ef46235c9a628e2b3176099e83ade6e000e31104c08cfb2612fed12b4033e49
MD5 ad0dc4cfa68356f86b7000a50eadf90c
BLAKE2b-256 a921854394b216a636bb5f812e77d20eccd3142e66664e919c96f5ea5533fd50

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: aldakit-0.2.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.2.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 e3c63530f23abf4f60f2271c747fcfcf859b559b52afed7d63c5806f50fcebad
MD5 690bbc318b96577c79c0743d5d6f4518
BLAKE2b-256 fee96501508941684221ef574ecc3f441bc2df453a3796af71129dbc8ebc803a

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a17eb52969200413d7b35330e355cf3f35c64cb31e06a9eafd53f6abb9217ace
MD5 3d8d818661ff0f8d5db158db866f2b55
BLAKE2b-256 79b992efd69e7a9583ab825b126067551616a3dbd834a0876ad4ba8e6f963515

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1958d95ae1fbf855b74f8ff76d1d00d05a716ed69fa6fc9470d2d86e2702e707
MD5 bf7229f6a7e8aef4045a251091ba851e
BLAKE2b-256 9e7cbd6736b7a5d9eb82847bd976cdee9ee6455da66a7cfdb2a120d715f20732

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp314-cp314-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp314-cp314-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 fcd8e143d43fb2d957dd67f9434bac87b73ef3501aa6fc6d32e70517da382baa
MD5 fa40a839094ee85412effffabe2d9787
BLAKE2b-256 f061c2f7bcf518f210ebfca873d4ce4eb339af558b4ae2226beb910d59e38777

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a1608b2bc48d432b478790b09f6a90c1af95b87ed1fb5c160babd7963099e78
MD5 6abd8f353b9a39a415b6ebcf437610ec
BLAKE2b-256 697c35b75a39148b860d86f57d4a23f821710d217e62f8637dc8520fcea170b8

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: aldakit-0.2.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 c58775e4e12a60bf4c9e78d80c3f64cea91ab1d8c7f468a257fe276b014301be
MD5 67eed9e10d1937ee3c6464a83839ec3d
BLAKE2b-256 407cdec045b2ac49194b891bbe26f3334d0ee42365ed59501da33c46fee2a258

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a10dc6ed15348d05e16044dbfefc5760e42fb83776f08dabc9b02b64f4376898
MD5 686d1f953ab75dc39bc7bab107004ebd
BLAKE2b-256 dad6cad86113f33ca310d36e9da2d90a77831fbf2f708fa2db998f66ccd121fe

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 be89364351e40b34a799ebd4071a02672fef23e5c25e9bb0f1b8c3ac8afd69e1
MD5 9177f5b6e8a480642381cc2c52b6c4d6
BLAKE2b-256 c0a86487d3336de756eb9d26e895bce61d18218ec06b5040613b5d68443424f3

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp313-cp313-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp313-cp313-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 a3b7c1bad2f3df02f257f1883b3cf5dddad9409824cc0b2b90fc139cfe04cddd
MD5 5a254aefc0302d4692181e0a939e4add
BLAKE2b-256 beec3ee13a838111f767aca46a2de30a0f91b09c204b2bf2551e06435b306a56

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 beb8ea366adb6af707df1feb30f62d0e5e7e6ac9ee85fc43a7b196ed7beb255d
MD5 545e664b6691b2e63bc3a80b90ea46e8
BLAKE2b-256 2a6020da01da4417b31320c6edba92207999c467131ca99c7798b7d54c6baa2a

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: aldakit-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 4bfd78f480c810d2e5339b8fa5dc883b4995532dedddd840e9be2d023acf7e02
MD5 feb572512d723013ffd271f67ec4a409
BLAKE2b-256 dbbd6425be9e48a2f501a447f430623a2a2526fc07980ab149d09d86e3c5a5d5

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 de9d5fb94ff5a38d946508a549aab7474aefccdb218496ca0742cacaafe23d97
MD5 e314a7b6e037fc1f648d68e573c6e086
BLAKE2b-256 2e532271a3e483df2d5164177d197dd0df285bee4e4664b2004ce5fc8bcb5f43

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 88f56520c5bd709edbc9540e1161b1371411ed8deacbd28fef8f488b553d4834
MD5 b2f407637410ac5f8b31b39961656943
BLAKE2b-256 ebcc762f0da4bdbe7a96b1fc0546cad17696201a997eec6c5e709134bc69de7d

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp312-cp312-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp312-cp312-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 b1a74fe71977fc841b7f4ac0346da73c9e0e43ede51ef85060f79c10232e1168
MD5 1c3935a575d55065e4cd00eb087e84b1
BLAKE2b-256 4156e43e54118809fc8fbba52575749fed909558e08d158d63584ff1e7ad35b8

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0bcda3ec9c26ce6057878859eb61d1ce8430d4ec1bb0772a31e4ed6a258c9435
MD5 2f63dc7e85782247b6e9245e566ac8eb
BLAKE2b-256 3dc6fb99b97516fec11b9ce76046fffe19ee1593c9797cae63711a8ea9c6ca35

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: aldakit-0.2.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3a11cf2dc6ad47351389740d81b82b1d505a9956d26b2eaf75be13e1eaba612f
MD5 3c1375c61704e98762c3b43cf374d00d
BLAKE2b-256 7fa8a4c64ce27b7b3d0fa555112e5cf2900b842c2dcd3927b7b0d0c39a9b6437

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fc08113e47f8a6a35f0aea7c00e0ba04f74aa3046f55b83d0ff69f9fbcc8b914
MD5 b608f7048f94b63da55d846e8bcf729d
BLAKE2b-256 9330ec39ee267e38799b6eb76f497660cede197b170af7d76daa026b8f0c19f4

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8985b07acddff19c0cb7464303d57f1085c13537aa7f9ac2ba48cd8e4ac20136
MD5 c37bc33cb5877dce4e570cae75655d1c
BLAKE2b-256 6aa50408514800c8b93e433da0972d3069d05a3e050729e74aba16b6d39d3618

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 f2382f16d25218c4c630ca1c19db0ffe3221084cf62316ae1cd491fdbaa87435
MD5 44d0256aa4dfbb2bc77f5d5c5b78fcb1
BLAKE2b-256 bdc90af942db77f768df424d3d3ee826af2da098e44e1d5fcd2752828b1ff71a

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7eb8a8a805995342400d8a8b78e1d2b5126fc4af56f43a9d8fd2bbb62f71d47c
MD5 8b9f352808a8615dd52d70654c659be1
BLAKE2b-256 4f50740ef08f112fef0bf5d8e5f6add525d0539c38f02e9a3dee5e78c961877f

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: aldakit-0.2.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.2.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 3f7c7f1dd027d2ab724bfa39fc9e074e5b96146d09dc12f1364d177e23926a3e
MD5 4ed9d0594532cd6bcd9c04102d34aa75
BLAKE2b-256 5aa62d0a30e8b93c1b0f43290508b0dc0b2316d9aa00769e4d423d18b4f73774

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 faa113cd96e80791fc24b417af37cc039d620a40ae96f2c3d7d131009e8123d5
MD5 13e0d8480e9bc6b456812957c653b2d8
BLAKE2b-256 da31f1f7e4b381a7717e71e053a2c8bcec6cef10667c361a10405276d5f4519c

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e6bb9fcba1220c9a15a5c362a81d9326d2862c59da576944db995fc5e46c964d
MD5 a6d1cc0fba58df46da6b2ac351b48caa
BLAKE2b-256 6bfad2f7d2d94918a233037a20a5453da6a922b80d699f05769ef1e9382770db

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 fbe4b4ce0f46cfcdadee4c33aff46c84c46271d1e5f39134f9455bf8e44d268a
MD5 f8df25cc6d84415b7bae35cd5a3fb6ef
BLAKE2b-256 8d7a3cbe35a4d16da7d2674e245a2a8bc92a20072070f94bfa17b14d1f039824

See more details on using hashes here.

File details

Details for the file aldakit-0.2.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d25e006681cd015561f6e19214446b879936a62a252c153b09bd428fb75a1aa2
MD5 a9dfeee0d0630105779941039cd32493
BLAKE2b-256 572aadedc163ad6858251e10a49ec38280a1b488cd8e23b7c9aeba5f49264444

See more details on using hashes here.

Release history Release notifications | RSS feed

0.4.0

26 files

0.3.1

26 files

0.2.1

26 files

This release

0.2.0 This release

26 files

0.1.10

26 files

0.1.9

26 files

0.1.8

26 files

0.1.7

26 files

0.1.6

31 files

0.1.5

26 files

0.1.4

6 files

0.1.3

6 files

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