API reference¶
Everything in redis_lua_py.__all__. The package is small on purpose: one
decorator, one annotation, two namespaces, and the errors.
from redis_lua_py import Key, call, cjson, redis, script
from redis_lua_py import BoundScript, CompiledScript
script¶
def script(
func: Callable[..., R] | None = None,
/,
*,
name: str | None = None,
header: bool = True,
) -> CompiledScript[R] | Callable[[Callable[..., R]], CompiledScript[R]]
Compile a function into a Redis Lua script. Usable bare or called:
@script
def touch(key: Key) -> int: ...
@script(name="touch_v2", header=False)
def touch(key: Key) -> int: ...
| Parameter | Meaning |
|---|---|
name |
overrides the name in the generated header and in errors |
header |
False drops the provenance comment entirely, for anyone who wants the script body and nothing else |
Parameters annotated Key become KEYS, in declaration order; every
other parameter becomes ARGV. See
Keys and arguments.
The return annotation describes what the caller gets back, and is carried
through to the call: -> int makes the script a CompiledScript[int]. The
compiler itself does not read it. See
What the caller gets.
Define scripts at module level, where they compile once at import.
Raises UnsupportedSyntax at decoration time,
pointing at the line at fault, if the body strays outside
the supported subset.
Key¶
Marks a parameter as a Redis key. A str subclass, so it is inert at runtime
and the annotation is the whole of it.
Getting this right matters: Redis Cluster routes a script by its declared keys, so a key passed as an argument will be invisible to the router.
redis¶
The script namespace. redis.incr(key) becomes redis.call('INCR', key);
underscores split into subcommand tokens, so redis.script_load(x) becomes
redis.call('SCRIPT', 'LOAD', x).
Names are checked at compile time against Redis' own command table;
redis.call(...) itself is never checked and is the escape hatch. See
Calling Redis commands.
The compiler identifies the namespace by value rather than by the name it is imported under, so every alias works and nothing is reserved.
call¶
An alias of redis, for modules that would rather not rename
anything.
cjson¶
The JSON library Redis exposes to scripts: cjson.encode and cjson.decode,
which pass through under their own names.
CompiledScript¶
What @script returns. Calling it runs EVALSHA and falls back to EVAL the
first time, or whenever the server has dropped the script from its cache.
script(client, /, *positional, **keyword) -> R # sync client
script(client, /, *positional, **keyword) -> Awaitable[R] # async client
| Attribute | Type | What it is |
|---|---|---|
name |
str |
the script's name, in the header and in errors |
lua |
str |
the full Lua source, exactly as sent to Redis |
params |
tuple[str, ...] |
every parameter, in declaration order |
keys |
tuple[str, ...] |
the parameters annotated Key |
args |
tuple[str, ...] |
everything else |
doc |
str \| None |
the function's docstring |
source |
str |
where it was defined, repo-relative |
bind¶
def bind(self, client) -> BoundScript[R] # sync client
def bind(self, client) -> BoundScript[Awaitable[R]] # async client
Attach a client, so calls do not have to pass one. See Binding a client.
BoundScript¶
A script with its client already attached, produced by
bind. The type parameter is what a call returns: the script's own
return type for a sync client, an awaitable of it for an async one.
Exposes name, lua, params, keys, args and doc from the script it
wraps, and leaves that script usable against any other client.
Errors and warnings¶
CompileError, UnsupportedSyntax, ScriptArgumentError, RedisLuaError,
RedisLuaWarning and NilTruncationWarning have
their own page.