Runtime Registry¶
The runtime registry defines how each programming language is executed inside Kubernetes pods. It maps language/version pairs to Docker images, file extensions, and interpreter commands. Adding a new language or version is a matter of extending the specification dictionary.
Supported Languages¶
| Language | Versions | Image Template | File Extension |
|---|---|---|---|
| Python | 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 | python:{version}-slim |
.py |
| Node.js | 18, 20, 22 | node:{version}-alpine |
.js |
| Ruby | 3.1, 3.2, 3.3 | ruby:{version}-alpine |
.rb |
| Go | 1.20, 1.21, 1.22 | golang:{version}-alpine |
.go |
| Bash | 5.1, 5.2, 5.3 | bash:{version} |
.sh |
Language Specification¶
Each language is defined by a LanguageSpec dictionary containing the available versions, Docker image template, file
extension, and interpreter command:
class LanguageSpec(TypedDict):
versions: list[str]
image_tpl: str
file_ext: str
interpreter: list[str]
The full specification for all languages:
LANGUAGE_SPECS: dict[str, LanguageSpec] = {
"python": {
"versions": ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"],
"image_tpl": "python:{version}-slim",
"file_ext": "py",
"interpreter": ["python"],
},
"node": {
"versions": ["18", "20", "22"],
"image_tpl": "node:{version}-alpine",
"file_ext": "js",
"interpreter": ["node"],
},
"ruby": {
"versions": ["3.1", "3.2", "3.3"],
"image_tpl": "ruby:{version}-alpine",
"file_ext": "rb",
"interpreter": ["ruby"],
},
"bash": {
"versions": ["5.1", "5.2", "5.3"],
"image_tpl": "bash:{version}",
"file_ext": "sh",
"interpreter": ["bash"],
},
"go": {
"versions": ["1.20", "1.21", "1.22"],
"image_tpl": "golang:{version}-alpine",
"file_ext": "go",
"interpreter": ["go", "run"],
},
}
Runtime Configuration¶
The registry generates a RuntimeConfig for each language/version combination. This contains everything needed to run a
script in a pod:
class RuntimeConfig(NamedTuple):
image: str # Full Docker image reference
file_name: str # Name that will be mounted under /scripts/
command: list[str] # Entrypoint executed inside the container
- image: The full Docker image reference (e.g.,
python:3.11-slim) - file_name: The script filename mounted at
/scripts/(e.g.,main.py) - command: The command to execute (e.g.,
["python", "/scripts/main.py"])
Adding a New Language¶
To add support for a new programming language:
- Add an entry to
LANGUAGE_SPECSwith versions, image template, file extension, and interpreter - Add an example script to
EXAMPLE_SCRIPTSdemonstrating version-specific features - The
_make_runtime_configs()function automatically generates runtime configs
For example, to add Rust support:
"rust": {
"versions": ["1.75", "1.76", "1.77"],
"image_tpl": "rust:{version}-slim",
"file_ext": "rs",
"interpreter": ["rustc", "-o", "/tmp/main", "{file}", "&&", "/tmp/main"],
}
The image template uses {version} as a placeholder, which gets replaced with each version number when generating the
registry.
Example Scripts¶
Each language includes an example script that demonstrates both universal features and version-specific syntax. These scripts are shown in the frontend editor as templates:
EXAMPLE_SCRIPTS: dict[str, str] = {
"python": """
# This f-string formatting works on all supported Python versions (3.7+)
py_version = "3.x"
print(f"Hello from a Python {py_version} script!")
# The following block uses Structural Pattern Matching,
# which was introduced in Python 3.10.
# THIS WILL CAUSE A SYNTAX ERROR ON VERSIONS < 3.10.
lang_code = 1
match lang_code:
case 1:
print("Structural Pattern Matching is available on this version (Python 3.10+).")
case _:
print("Default case.")
# Union types using | operator (Python 3.10+)
def process_data(value: int | str | None) -> str:
if value is None:
return "No value"
return f"Got: {value}"
print(process_data(42))
print(process_data("hello"))
print(process_data(None))
""",
"node": """
// This works on all supported Node versions (18+)
console.log(`Hello from Node.js ${process.version}!`);
// The Promise.withResolvers() static method was introduced in Node.js 22.
// This will throw a TypeError on versions < 22.
if (typeof Promise.withResolvers === 'function') {
const { promise, resolve } = Promise.withResolvers();
console.log("Promise.withResolvers() is supported (Node.js 22+).");
resolve('Success');
promise.then(msg => console.log(`Resolved with: ${msg}`));
} else {
console.log("Promise.withResolvers() is not supported on this version.");
}
""",
"ruby": """
# This works on all supported Ruby versions (3.1+)
puts "Hello from Ruby #{RUBY_VERSION}!"
# The Data class for immutable value objects was introduced in Ruby 3.2.
# This will cause an error on Ruby 3.1.
begin
# This line will fail on Ruby < 3.2
Point = Data.define(:x, :y)
p = Point.new(1, 2)
puts "Data objects are supported (Ruby 3.2+). Created point: #{p.inspect}"
rescue NameError
puts "Data objects are not supported on this version."
end
""",
"bash": """
# This works on any modern Bash version
echo "Hello from Bash version $BASH_VERSION"
# BASH_VERSINFO is an array holding version details.
# We can check the major and minor version numbers.
echo "Bash major version: ${BASH_VERSINFO[0]}"
echo "Bash minor version: ${BASH_VERSINFO[1]}"
# The ${var@U} expansion for uppercasing was added in Bash 5.2
if [[ "${BASH_VERSINFO[0]}" -ge 5 && "${BASH_VERSINFO[1]}" -ge 2 ]]; then
my_var="hello"
echo "Testing variable expansion (Bash 5.2+ feature)..."
echo "Original: $my_var, Uppercased: ${my_var@U}"
else
echo "The '${var@U}' expansion is not available in this Bash version."
fi
""",
"go": """
package main
import (
"fmt"
"runtime"
)
// This function uses generics, available since Go 1.18,
// so it will work on all supported versions (1.20+).
func Print[T any](s T) {
fmt.Println(s)
}
func main() {
Print(fmt.Sprintf("Hello from Go version %s!", runtime.Version()))
// The built-in 'clear' function for maps and slices
// was introduced in Go 1.21.
// THIS WILL FAIL TO COMPILE on Go 1.20.
myMap := make(map[string]int)
myMap["a"] = 1
Print(fmt.Sprintf("Map before clear: %v", myMap))
clear(myMap) // This line will fail on Go < 1.21
Print(fmt.Sprintf("Map after 'clear' (Go 1.21+ feature): length is %d", len(myMap)))
}
""",
}
The example scripts intentionally use features that may not work on older versions, helping users understand version
compatibility. For instance, Python's match statement (3.10+), Node's Promise.withResolvers() (22+), and Go's
clear() function (1.21+).
API Endpoints¶
The runtime information is exposed via two public GET endpoints:
- GET /api/v1/k8s-limits — returns resource limits (
cpu_limit,memory_limit,execution_timeout) and a map of supported runtimes with their available versions and file extensions. The frontend uses this to populate the language/version picker and show resource constraints. - GET /api/v1/example-scripts — returns a map of language → example script string. Shown in the editor as starter templates when a user picks a language.
Key Files¶
-
Language specifications and runtime config generation
-
API endpoints including k8s-limits and example-scripts