scriptling.runtime.kv
Thread-safe key-value store for sharing state across requests and background tasks.
The kv sub-library exposes a default system store and the ability to open additional named stores via kv.open(). All stores share the same interface — a store object with methods for getting, setting, and managing keys.
Store Object Methods
| Method | Description |
|---|---|
set(key, value, ttl=0) |
Store value with optional TTL |
get(key, default=None) |
Retrieve value by key |
delete(key) |
Remove a key from the store |
exists(key) |
Check if key exists |
ttl(key) |
Get remaining TTL for a key |
keys(pattern="*") |
Get keys matching glob pattern |
clear() |
Remove all keys from store |
close() |
Close the store immediately (no-op on default) |
Library Functions
| Function | Description |
|---|---|
open(name) |
Open or reuse a named KV store |
Library Constants
| Constant | Description |
|---|---|
default |
The system-wide default KV store |
Setup
import "github.com/paularlott/scriptling/extlibs"
// Register the KV sub-library (call after InitKVStore)
extlibs.RegisterRuntimeKVLibrary(p)
// Or register all runtime sub-libraries at once
extlibs.RegisterRuntimeLibraryAll(p, nil)Store Methods
set(key, value, ttl=0)
Store a value with optional TTL.
Parameters:
key(string): Key to store undervalue: Value to store (string, int, float, bool, list, dict)ttl(int, optional): Time-to-live in seconds (0 = no expiration)
get(key, default=None)
Retrieve a value by key.
Parameters:
key(string): Key to retrievedefault: Value to return if key doesn’t exist
Returns: Stored value (deep copy) or default
delete(key)
Remove a key from the store.
exists(key)
Check if a key exists and is not expired.
Returns: Boolean
ttl(key)
Get remaining time-to-live for a key.
Returns: Seconds remaining, -1 if no expiration, -2 if key doesn’t exist
keys(pattern="*")
Get all keys matching a glob pattern.
Parameters:
pattern(string, optional): Glob pattern (default:"*")
Returns: List of matching keys
clear()
Remove all keys from the store.
close()
Close the store immediately and remove it from the registry. The next call to kv.open() with the same name will reopen it. Calling close() on kv.default is a no-op.
Library Functions
kv.open(name)
Open or reuse a named KV store. If a store with the given name is already open, the existing database is returned. If not, a new store is opened and registered.
Parameters:
name(string): Store name.- Use
":memory:name"for an in-memory store shared by that name. - Use a filesystem path (e.g.
"/data/agent.db") for a persistent store. - Empty string is not permitted.
- Use
Returns: Store object
Examples
Default Store
import scriptling.runtime.kv as kv
# Store values in the system default store
kv.default.set("api_key", "secret123")
kv.default.set("session:abc", {"user": "bob"}, ttl=3600)
# Retrieve values
api_key = kv.default.get("api_key")
session = kv.default.get("session:abc", default={})
# Check existence
if kv.default.exists("session:abc"):
print("Session exists")Named In-Memory Store
import scriptling.runtime.kv as kv
# Open a named in-memory store — shared across all callers using the same name
scratch = kv.open(":memory:scratch")
scratch.set("temp", 42)
val = scratch.get("temp")
# No close() needed — store stays open for subsequent callsPersistent Store
import scriptling.runtime.kv as kv
db = kv.open("/data/agent.db")
db.set("last_topic", "python async")
topic = db.get("last_topic", default="")
# Store remains open between interpreter invocationsPattern Matching
import scriptling.runtime.kv as kv
kv.default.set("user:1", {"name": "Alice"})
kv.default.set("user:2", {"name": "Bob"})
kv.default.set("session:abc", {"user_id": 1})
# Get all user keys
user_keys = kv.default.keys("user:*") # ["user:1", "user:2"]Sharing State Across Requests
import scriptling.runtime.kv as kv
# In HTTP handler
def handler(request):
users = kv.default.get("users", default=[])
users.append(request.json())
kv.default.set("users", users)
return runtime.http.json(200, {"count": len(users)})
# In background task
def worker():
users = kv.default.get("users", default=[])
print(f"Total users: {len(users)}")Shared Named Store Across Background Tasks
import scriptling.runtime.kv as kv
import scriptling.runtime as runtime
def task_a():
store = kv.open(":memory:shared")
store.set("result_a", "done")
def task_b():
store = kv.open(":memory:shared")
store.set("result_b", "done")
runtime.background("a", "task_a")
runtime.background("b", "task_b")Notes
- All operations are thread-safe
- Values are deep-copied on retrieval
- TTL expiration is automatic
- Supports glob patterns for key matching
kv.defaultis always available and itsclose()is a no-op- Named stores persist in the registry until explicitly closed —
kv.open()with the same name always returns the existing open store - Calling
close()on a named store immediately closes and removes it from the registry; the nextkv.open()will reopen it - In-memory stores use the
":memory:name"prefix; persistent stores use a filesystem path