redis-lua-py 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ """Write Redis Lua scripts as real Python functions, not strings.
2
+
3
+ from redis_lua_py import Key, redis, script
4
+
5
+ @script
6
+ def rate_limit(key: Key, limit: int, ttl: int) -> int:
7
+ current = redis.incr(key)
8
+ if current == 1:
9
+ redis.expire(key, ttl)
10
+ if current > limit:
11
+ return -1
12
+ return limit - current
13
+
14
+ remaining = rate_limit(client, key="u:42", limit=10, ttl=60)
15
+
16
+ The body is never executed by Python: it is read as source at import time and
17
+ compiled to Lua, which you can inspect at ``rate_limit.lua``.
18
+
19
+ The ``redis`` namespace above is resolved by value, not by spelling, so import
20
+ it under whatever name suits the module::
21
+
22
+ from redis_lua_py import redis as r # frees the name for redis-py
23
+
24
+ Binding a client once is often tidier than passing it to every call::
25
+
26
+ limiter = rate_limit.bind(client)
27
+ limiter(key="u:42", limit=10, ttl=60)
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ from collections.abc import Callable
33
+ from typing import Any, overload
34
+
35
+ from ._compile import compile_function
36
+ from ._runtime import Key, call, cjson, redis
37
+ from ._script import BoundScript, CompiledScript
38
+ from .errors import (
39
+ CompileError,
40
+ RedisLuaError,
41
+ ScriptArgumentError,
42
+ UnsupportedSyntax,
43
+ )
44
+
45
+ __all__ = [
46
+ "BoundScript",
47
+ "CompileError",
48
+ "CompiledScript",
49
+ "Key",
50
+ "RedisLuaError",
51
+ "ScriptArgumentError",
52
+ "UnsupportedSyntax",
53
+ "call",
54
+ "cjson",
55
+ "redis",
56
+ "script",
57
+ ]
58
+
59
+ __version__ = "0.1.0" # x-release-please-version
60
+
61
+
62
+ @overload
63
+ def script(func: Callable[..., Any], /) -> CompiledScript: ...
64
+
65
+
66
+ @overload
67
+ def script(*, name: str | None = ...) -> Callable[[Callable[..., Any]], CompiledScript]: ...
68
+
69
+
70
+ def script(
71
+ func: Callable[..., Any] | None = None, /, *, name: str | None = None
72
+ ) -> CompiledScript | Callable[[Callable[..., Any]], CompiledScript]:
73
+ """Compile a function into a Redis Lua script.
74
+
75
+ Parameters annotated :class:`Key` become ``KEYS``, in declaration order;
76
+ every other parameter becomes ``ARGV``. An ``int`` or ``float`` annotation
77
+ additionally wraps the argument in ``tonumber``, since ARGV always arrives
78
+ as a string.
79
+
80
+ Raises :class:`UnsupportedSyntax` at decoration time, pointing at the line
81
+ at fault, if the body strays outside the supported subset.
82
+ """
83
+
84
+ def wrap(target: Callable[..., Any]) -> CompiledScript:
85
+ return compile_function(target, name=name)
86
+
87
+ return wrap if func is None else wrap(func)