coredis 4.23.1__py3-none-any.whl → 5.0.0rc1__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.
Files changed (77) hide show
  1. coredis/__init__.py +1 -3
  2. coredis/_packer.py +10 -10
  3. coredis/_protocols.py +23 -32
  4. coredis/_py_311_typing.py +20 -0
  5. coredis/_py_312_typing.py +17 -0
  6. coredis/_utils.py +49 -51
  7. coredis/_version.py +3 -3
  8. coredis/cache.py +57 -82
  9. coredis/client/__init__.py +1 -2
  10. coredis/client/basic.py +129 -56
  11. coredis/client/cluster.py +147 -70
  12. coredis/commands/__init__.py +27 -7
  13. coredis/commands/_key_spec.py +11 -10
  14. coredis/commands/_utils.py +1 -1
  15. coredis/commands/_validators.py +30 -20
  16. coredis/commands/_wrappers.py +19 -99
  17. coredis/commands/bitfield.py +10 -2
  18. coredis/commands/constants.py +20 -3
  19. coredis/commands/core.py +1627 -1246
  20. coredis/commands/function.py +29 -22
  21. coredis/commands/monitor.py +0 -71
  22. coredis/commands/pubsub.py +7 -142
  23. coredis/commands/request.py +108 -0
  24. coredis/commands/script.py +9 -9
  25. coredis/commands/sentinel.py +60 -49
  26. coredis/connection.py +14 -15
  27. coredis/exceptions.py +2 -2
  28. coredis/experimental/__init__.py +0 -4
  29. coredis/globals.py +3 -0
  30. coredis/modules/autocomplete.py +28 -30
  31. coredis/modules/base.py +15 -31
  32. coredis/modules/filters.py +269 -245
  33. coredis/modules/graph.py +61 -62
  34. coredis/modules/json.py +172 -140
  35. coredis/modules/response/_callbacks/autocomplete.py +5 -4
  36. coredis/modules/response/_callbacks/graph.py +34 -29
  37. coredis/modules/response/_callbacks/json.py +5 -3
  38. coredis/modules/response/_callbacks/search.py +49 -53
  39. coredis/modules/response/_callbacks/timeseries.py +18 -30
  40. coredis/modules/response/types.py +1 -5
  41. coredis/modules/search.py +186 -169
  42. coredis/modules/timeseries.py +184 -164
  43. coredis/parser.py +6 -19
  44. coredis/pipeline.py +391 -422
  45. coredis/pool/basic.py +7 -7
  46. coredis/pool/cluster.py +3 -3
  47. coredis/pool/nodemanager.py +10 -3
  48. coredis/response/_callbacks/__init__.py +76 -57
  49. coredis/response/_callbacks/acl.py +0 -3
  50. coredis/response/_callbacks/cluster.py +25 -16
  51. coredis/response/_callbacks/command.py +8 -6
  52. coredis/response/_callbacks/connection.py +4 -3
  53. coredis/response/_callbacks/geo.py +17 -13
  54. coredis/response/_callbacks/hash.py +13 -11
  55. coredis/response/_callbacks/keys.py +9 -5
  56. coredis/response/_callbacks/module.py +2 -3
  57. coredis/response/_callbacks/script.py +6 -8
  58. coredis/response/_callbacks/sentinel.py +21 -17
  59. coredis/response/_callbacks/server.py +36 -14
  60. coredis/response/_callbacks/sets.py +3 -4
  61. coredis/response/_callbacks/sorted_set.py +27 -24
  62. coredis/response/_callbacks/streams.py +22 -13
  63. coredis/response/_callbacks/strings.py +7 -6
  64. coredis/response/_callbacks/vector_sets.py +126 -0
  65. coredis/response/types.py +13 -4
  66. coredis/sentinel.py +1 -1
  67. coredis/stream.py +4 -3
  68. coredis/tokens.py +343 -16
  69. coredis/typing.py +432 -79
  70. {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/METADATA +4 -5
  71. coredis-5.0.0rc1.dist-info/RECORD +95 -0
  72. coredis/client/keydb.py +0 -336
  73. coredis/pipeline.pyi +0 -2103
  74. coredis-4.23.1.dist-info/RECORD +0 -93
  75. {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/WHEEL +0 -0
  76. {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/licenses/LICENSE +0 -0
  77. {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,95 @@
1
+ coredis/__init__.py,sha256=SMfOaj8prRC4xyBZycECI-uHL8pP6keNZiqqboh6_ik,951
2
+ coredis/_json.py,sha256=XjrTlG6Up6BjzfIxk-KSU7IhYeD0fLvXdOPpsMZ6Ff8,186
3
+ coredis/_packer.py,sha256=iXaIKyVJiPiNtB5Hryz4nkjhjLeB-xUWqZdyM7oDpk0,2726
4
+ coredis/_protocols.py,sha256=wx2O8JuN1tayprUlxPLtK4jS5p4EYMxKExbLn2JNGyE,1617
5
+ coredis/_py_311_typing.py,sha256=QTh0tPRnwd7E39FXlh0RrWqloFWTeidOkfr4mRnp4K8,557
6
+ coredis/_py_312_typing.py,sha256=zB6scCVDNdSu3YBujf3Hq3rn-i-i8DcsbwbmcT-HrcQ,517
7
+ coredis/_sidecar.py,sha256=ci3hx7RojTdodMqe_zf07HL-E6DlqSliscENTa3dbzI,4404
8
+ coredis/_utils.py,sha256=CWb5T-CUPFX9bozunBCrJIgrTErXydpU2G9uoteiB2E,9998
9
+ coredis/_version.py,sha256=rzh24UEmx_s_DgCOvtV-vrrnwKL8kq20sbeuk5w5bJw,500
10
+ coredis/cache.py,sha256=entnV__Bpv4DjqK9BmejuyEgknLBWQnz-Sp8p1CwjQw,26308
11
+ coredis/config.py,sha256=Ni2uXMNzdfSRDEJl0KxrS78shLszfYM-ZbE7GK_O7Pk,1368
12
+ coredis/connection.py,sha256=0GbYjcBZizz-1fscoXG3fQRHOvh6c4Flc3yDrMNzJV8,30899
13
+ coredis/constants.py,sha256=W_bssjAP5hvf74EENs5wZXioTSvHr2JBwFrlgxkgw_4,1048
14
+ coredis/credentials.py,sha256=iVSZEyMfd6nEePpVRrx3Ora-EuCCwJ9G9NshEI5Qs2A,1102
15
+ coredis/exceptions.py,sha256=8P3npdmixnUso9GdcKit6FzXywSWFJhj6EEyiGja8As,8709
16
+ coredis/globals.py,sha256=R0Ys_wd3v29cMiojSwlyyflA3GK2lFNCjnVL4PMANag,678
17
+ coredis/parser.py,sha256=9pzxtIOqyj1O91DwKGCMCWf807qsJThDBtD5qslBwkY,11754
18
+ coredis/pipeline.py,sha256=SR3zcwOAP37sfEJ7ZljDYbNPt50GpWEtHbu4jyWJkZ0,46046
19
+ coredis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ coredis/retry.py,sha256=WG4FA-lG2ksc2EGOnKmAAUwa-LrdxG06SSYUXZlPycA,8350
21
+ coredis/sentinel.py,sha256=AE0jzHaaDziroxzR-_x9tmCw954Ui3QJ8Jl8c0GL4m8,16293
22
+ coredis/speedups.pyi,sha256=cUYJLKVGVgyGisMNUExWnnoLTYleCuH2v3XwTXOwnFM,109
23
+ coredis/stream.py,sha256=tQStAfamoGr3OTkWLTqxyEV60epVRPBxwaGwPVW6tzc,14935
24
+ coredis/tokens.py,sha256=t8a3Rosho77jMD6rUO15A0qw3WoWOJe-CW-z_DunPpA,36586
25
+ coredis/typing.py,sha256=m2P1982NIvtAtkTVHhB6DiOglUMvweolEBXq6_5pCKE,20684
26
+ coredis/client/__init__.py,sha256=J4r1pi5r68EwodMV8-eHvzM83tkz2mTlWayKy-JScrg,150
27
+ coredis/client/basic.py,sha256=kg9k0pMfIuzVCIhnL_wjJxixzh0NW0sEreJi9N_ycSA,46241
28
+ coredis/client/cluster.py,sha256=EszhB5qxLGZCdEEzmRYKedSMMfr8Vokhf36grdATnwc,50609
29
+ coredis/commands/__init__.py,sha256=ApJE7ZgqrQCMkWusgEwWMBjH10t_h6sbsRvTz7kT25k,1429
30
+ coredis/commands/_key_spec.py,sha256=EDvVhlzY9gP3CA77NNArwfj0R40UbfLV_Qh_eVml-cY,24410
31
+ coredis/commands/_utils.py,sha256=ld6Nii0VUjobOgBI0twHAL4T_wScLcJlS5k3ZnU5MDc,3662
32
+ coredis/commands/_validators.py,sha256=yo0I81uMpy7FMvPxMheqdMPved-ujkpaWUs0WpuOPIU,5426
33
+ coredis/commands/_wrappers.py,sha256=rw-HF3XxsImRRB0ptK1zrgOyMlRXLyz6wbfViblK5e8,5653
34
+ coredis/commands/bitfield.py,sha256=aB-m4KoUbGpI4zxzNU0VCfmPt7HGhB5kt4g8KX5CoRo,3405
35
+ coredis/commands/constants.py,sha256=KZs05uSnn7cg3K723UrqEOGDcClWNAc29EbDPyPk4gQ,30312
36
+ coredis/commands/core.py,sha256=UJr6mDLVPM__HPXHTLhOsOpTFoGuLEAS0hUZSZDHVA4,278545
37
+ coredis/commands/function.py,sha256=mznJds0S09qAAjII8Jw1TjkS8maljAc65QzEtWDhrgk,16301
38
+ coredis/commands/monitor.py,sha256=Zu_PmUggLkRke5XFTE3cb5-5ocCxhfrKjlm_e00-kvI,5766
39
+ coredis/commands/pubsub.py,sha256=_svI6BK5F9MIF7DHKmpW1ob7ypN13O9BFDpwSrLBYKs,34371
40
+ coredis/commands/request.py,sha256=9tMw5q6KdF4y6SyHfcguRe6P7mjArqE8Djk9FSvxKts,3663
41
+ coredis/commands/script.py,sha256=Ld6NiOD2ILeOoIQDUMAm6WVA9fZOvQlubS2qCyu40dk,12223
42
+ coredis/commands/sentinel.py,sha256=9giNW1QyhRD5SaAkPSgiBFEnm9XnGa2QM6vBQDZEwp0,7789
43
+ coredis/experimental/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
44
+ coredis/modules/__init__.py,sha256=eqWwEYNI-B7Lc19R23n6NQaQoKHmpj8mrtkYBcQ2fCA,2917
45
+ coredis/modules/autocomplete.py,sha256=ZqT9wcmuP7_FNdQq4ZrYy3Dv_iStVCUc2LUtQ7cyikc,4945
46
+ coredis/modules/base.py,sha256=KBGla8KM-XiQBVzLYxvq31giz5lYVH7hH_S0EM0kl0c,8597
47
+ coredis/modules/filters.py,sha256=eGY5bv3kn6Cj-lq-OIqQfe1Ym4P8S3snNztSgdHcHe0,43443
48
+ coredis/modules/graph.py,sha256=1NGV1mT0OCIFg7XZe0l-VTQZa0GsbXopH8LK33lDhO8,12544
49
+ coredis/modules/json.py,sha256=iiDjFS1MhUWruzWQ1i-SmkPbg5T5ThnRCsAcxbKhJ3Y,23606
50
+ coredis/modules/search.py,sha256=3Sld2XE4_9dVqVtR1C8dUVvgnxNifQkz4NfRZ0y3eB0,40800
51
+ coredis/modules/timeseries.py,sha256=oLF9NdN_Z4gO1_mWxx8XkcGRz0V-S4W04U64pGrTmHY,47553
52
+ coredis/modules/response/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ coredis/modules/response/types.py,sha256=n3Qds9vUzBBNhm3hRzYcuhqI8UTSa6mTzvIzmFw8btk,5021
54
+ coredis/modules/response/_callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
+ coredis/modules/response/_callbacks/autocomplete.py,sha256=ntQ3cbs6g6rhFU-rujhjidlr9cQBNCt-7MQQG3Rm_xY,1282
56
+ coredis/modules/response/_callbacks/graph.py,sha256=9YSbZqGmdJhgzZ4RpxqhEGkBRBuf1VZlvZ2HXqf8vzo,8208
57
+ coredis/modules/response/_callbacks/json.py,sha256=oErNOm8OxR0iQtnviXhe_GIMP4y4TtPo5HICRMc1cVw,678
58
+ coredis/modules/response/_callbacks/search.py,sha256=BNKJitdfJxqJqIgNVRItL_fCt8qgf-JUUXoeW3PtgaU,7547
59
+ coredis/modules/response/_callbacks/timeseries.py,sha256=BqVgg8jxL4JU_ZFJVomJi6g27urC1UlNrKY4vShf7OI,4759
60
+ coredis/pool/__init__.py,sha256=OXBmGIY5pGgCvLO_x_yF5X1eeT3tve8sINaGwixWzsg,301
61
+ coredis/pool/basic.py,sha256=alpzkl4fE0veX2Jx3r1n7K9h_ka09FnKzwsc3U8M94U,16039
62
+ coredis/pool/cluster.py,sha256=fpyhIqhXLBOAJfopMvWiyl10_MF0hxk_yEKsf-qTlXU,20792
63
+ coredis/pool/nodemanager.py,sha256=Z-85VqK-GffPbApmOjM4kpEJ7hEysO2qc4AP7R_06n0,12576
64
+ coredis/recipes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
+ coredis/recipes/credentials/__init__.py,sha256=AFdVEXL3e3-Yrcmb7qg-CnXIgn2a3RKPMzpv-PtOmCo,123
66
+ coredis/recipes/credentials/iam_provider.py,sha256=GBscr1ky2hloZ0uBMA4GvCSOWasqeo7VFinNX_yspVE,2322
67
+ coredis/recipes/locks/__init__.py,sha256=D20RZ9c3b-8Ruq8UIlIhYhntNAami_swjBk5v61iFMo,89
68
+ coredis/recipes/locks/extend.lua,sha256=62TOOZN07E-FZOi0IuCXDYKFL0QmZo0PiuIZhN9Bn9o,426
69
+ coredis/recipes/locks/lua_lock.py,sha256=C98pcyy785mResVfnFWTWPn3gRZNqqFb7V6rgc65uJ8,9416
70
+ coredis/recipes/locks/release.lua,sha256=HN7Hu2OMpY7pBBPTIuJzVxP_CTr9Qs85YHru7GsQyKo,225
71
+ coredis/response/__init__.py,sha256=jVewqsYZrmFJHVCibiV9-BFnIa8GUP7S9c936ch-ldo,86
72
+ coredis/response/_utils.py,sha256=U9xdzRR8CkEFoPXKKCaJn5D_NllYWDioiLt7LeQGKaY,850
73
+ coredis/response/types.py,sha256=3rSr4i7s3EiQflCc2CPV60NscaPIEmvEhBnW6umCWsg,11910
74
+ coredis/response/_callbacks/__init__.py,sha256=M1DI9v7oeOIjMZtf7TSYwkF-gpOjhGujwfUX5cw3Yis,17636
75
+ coredis/response/_callbacks/acl.py,sha256=pKGXG40BC_DUIYplF2o0hUQEdu75nKFhoU0ZvCnIChA,910
76
+ coredis/response/_callbacks/cluster.py,sha256=JywuaYl5IcApSJbWjUVcQPF_OKi5m0iclF1nwMIGiz0,5981
77
+ coredis/response/_callbacks/command.py,sha256=iEKShD5vvoSTqv5mf_EJbL73xc2mpmUpuryVSHpyf-U,2824
78
+ coredis/response/_callbacks/connection.py,sha256=1izybzZurgUHEFO8Y4aw64AiZLQw5Hs9bxeyV9almcg,861
79
+ coredis/response/_callbacks/geo.py,sha256=OIWqEcrNgxbgOvh_piyOHBTsnlnI85NM6L_PxBX5ddk,1756
80
+ coredis/response/_callbacks/hash.py,sha256=lDjxEZ_YO36IJJ4JIZaF1I5ZRoeDURxRCYSMVn87V68,2658
81
+ coredis/response/_callbacks/keys.py,sha256=fKfzvN91Wwk2TsJ65tDUWFa2_--SVrOaAj5C-3Tlxqg,1546
82
+ coredis/response/_callbacks/module.py,sha256=WLJwHw0Kq3X5HafRrGGNBmxB8eCyThqV4YK1tSDg3DU,886
83
+ coredis/response/_callbacks/script.py,sha256=o_chD_GOj59ObuKvFgMglTheQOFpmOJPjOUBjsAG8C8,3063
84
+ coredis/response/_callbacks/sentinel.py,sha256=xwgbztFRuT3TI2_tSWKROlwme977Cg7YoSXj1RY1z0Y,4721
85
+ coredis/response/_callbacks/server.py,sha256=2bEPZi2nq7X417Ua0qH8vSnawT2TqHl5sc67xnd0pu4,7520
86
+ coredis/response/_callbacks/sets.py,sha256=aaGh3BF0TkW_jGnpFENipAzWA-R9TgnioKudf_6Dk2w,1310
87
+ coredis/response/_callbacks/sorted_set.py,sha256=LrqHBMPluR2MufkCoE8y_FRO4_WrfGq5wsdri4Sxkqo,6335
88
+ coredis/response/_callbacks/streams.py,sha256=vq4C8sidFam32n7rlfUrt1XzkOdmeTtFv0tl0mLRcYA,6241
89
+ coredis/response/_callbacks/strings.py,sha256=sjHY2JwxHl4ndIl9WhHD48VKuGn39FArE8XnRUparu4,1955
90
+ coredis/response/_callbacks/vector_sets.py,sha256=nErA6NvtwObdE8NVirCNeB3nDNw3EkNnQkNdAO72Uq8,3993
91
+ coredis-5.0.0rc1.dist-info/licenses/LICENSE,sha256=pTSTkaH3iX2r6C88El9edMoi6r_Og6Wf4b6Zgq-LSOQ,1107
92
+ coredis-5.0.0rc1.dist-info/METADATA,sha256=pyll4nXS4RM8mi-mViEP9U2A72Uy4eXLm07gSsDi-98,9119
93
+ coredis-5.0.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
+ coredis-5.0.0rc1.dist-info/top_level.txt,sha256=PWp3SlvenceLQUL9VJ1_rKwKoi-U9g3KDJS5ws8tOG8,8
95
+ coredis-5.0.0rc1.dist-info/RECORD,,
coredis/client/keydb.py DELETED
@@ -1,336 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import datetime
4
- import functools
5
- import textwrap
6
- from typing import Any
7
-
8
- from packaging import version
9
-
10
- from coredis._utils import CaseAndEncodingInsensitiveEnum
11
- from coredis.client import Redis, RedisCluster
12
- from coredis.commands import CommandMixin
13
- from coredis.commands._utils import (
14
- check_version,
15
- normalized_milliseconds,
16
- normalized_time_milliseconds,
17
- normalized_time_seconds,
18
- )
19
- from coredis.commands._wrappers import ClusterCommandConfig, CommandDetails
20
- from coredis.commands.constants import CommandFlag, CommandGroup
21
- from coredis.response._callbacks import (
22
- BoolCallback,
23
- BoolsCallback,
24
- IntCallback,
25
- SimpleStringCallback,
26
- )
27
- from coredis.typing import (
28
- AnyStr,
29
- Callable,
30
- CommandArgList,
31
- Coroutine,
32
- Iterable,
33
- KeyT,
34
- Literal,
35
- P,
36
- Parameters,
37
- R,
38
- StringT,
39
- ValueT,
40
- )
41
-
42
-
43
- def _keydb_command_link(command: CommandName) -> str:
44
- canonical_command = str(command).lower().replace(" ", "-").replace(".", "")
45
- return f"`{str(command)} <https://docs.keydb.dev/docs/commands#{canonical_command}>`_"
46
-
47
-
48
- class CommandName(CaseAndEncodingInsensitiveEnum):
49
- """
50
- Enum for listing all keydb extension commands
51
- """
52
-
53
- BITOP = b"BITOP"
54
- CRON = b"KEYDB.CRON"
55
- EXPIREMEMBER = b"EXPIREMEMBER"
56
- EXPIREMEMBERAT = b"EXPIREMEMBERAT"
57
- PEXPIREMEMBERAT = b"PEXPIREMEMBERAT"
58
- HRENAME = b"KEYDB.HRENAME"
59
- MEXISTS = b"KEYDB.MEXISTS"
60
- OBJECT_LASTMODIFIED = b"OBJECT LASTMODIFIED"
61
- PTTL = b"PTTL"
62
- TTL = b"TTL"
63
-
64
-
65
- def keydb_command(
66
- command_name: CommandName,
67
- group: CommandGroup | None = None,
68
- version_introduced: str | None = None,
69
- version_deprecated: str | None = None,
70
- deprecation_reason: str | None = None,
71
- arguments: dict[str, dict[str, str]] | None = None,
72
- cluster: ClusterCommandConfig = ClusterCommandConfig(),
73
- flags: set[CommandFlag] | None = None,
74
- ) -> Callable[[Callable[P, Coroutine[Any, Any, R]]], Callable[P, Coroutine[Any, Any, R]]]:
75
- command_details = CommandDetails(
76
- command_name,
77
- group,
78
- version.Version(version_introduced) if version_introduced else None,
79
- version.Version(version_deprecated) if version_deprecated else None,
80
- arguments,
81
- cluster or ClusterCommandConfig(),
82
- None,
83
- flags or set(),
84
- None,
85
- )
86
-
87
- def wrapper(
88
- func: Callable[P, Coroutine[Any, Any, R]],
89
- ) -> Callable[P, Coroutine[Any, Any, R]]:
90
- @functools.wraps(func)
91
- async def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
92
- await check_version(
93
- args[0], # type: ignore
94
- func.__name__,
95
- command_details,
96
- deprecation_reason,
97
- kwargs,
98
- )
99
- return await func(*args, **kwargs)
100
-
101
- wrapped.__doc__ = textwrap.dedent(wrapped.__doc__ or "")
102
- if group:
103
- wrapped.__doc__ = f"""
104
- {wrapped.__doc__}
105
-
106
- KeyDB command documentation: {_keydb_command_link(command_name)}
107
- """
108
-
109
- setattr(wrapped, "__coredis_command", command_details)
110
- return wrapped
111
-
112
- return wrapper
113
-
114
-
115
- class KeyDBCommands(CommandMixin[AnyStr]):
116
- @keydb_command(
117
- CommandName.BITOP,
118
- CommandGroup.BITMAP,
119
- )
120
- async def bitop(
121
- self,
122
- keys: Parameters[KeyT],
123
- operation: StringT,
124
- destkey: KeyT,
125
- value: int | None = None,
126
- ) -> int:
127
- """
128
- Perform a bitwise operation using :paramref:`operation` between
129
- :paramref:`keys` and store the result in :paramref:`destkey`.
130
- """
131
- pieces: CommandArgList = [operation, destkey, *keys]
132
- if value is not None:
133
- pieces.append(value)
134
- return await self.execute_command(CommandName.BITOP, *pieces, callback=IntCallback())
135
-
136
- @keydb_command(
137
- CommandName.CRON,
138
- CommandGroup.SCRIPTING,
139
- )
140
- async def cron(
141
- self,
142
- name: KeyT,
143
- repeat: bool,
144
- delay: int | datetime.timedelta,
145
- script: StringT,
146
- keys: Parameters[KeyT],
147
- args: Parameters[ValueT],
148
- start: int | datetime.datetime | None = None,
149
- ) -> bool:
150
- """
151
- Schedule a LUA script to run at a specified time and/or intervals.
152
- To cancel the cron delete the key at :paramref:`name`
153
-
154
- :param name: Name of the cron which will be visible in the keyspace,
155
- can be searched, and deleted with DEL.
156
- :param repeat: If the script will run only once, or if it will be repeated
157
- at the specified interval provided by :paramref:`delay`
158
- :param delay: is an integer specified in milliseconds used as the initial delay.
159
- If :paramref:`repeat` is ``True``, this will also be the length of the repeating timer
160
- which will execute the script each time the delay elapses
161
- (will continue to execute indefinitely).
162
- :param start: unix time specified as milliseconds enforcing that the script
163
- should only start executing then this Unix time has been reached.
164
- If :paramref:`delay` is greater than zero, this delay time will need to elapse prior to the
165
- script executing (timer begins to elapse at start time).
166
- If a start time is specified, the delay will always remain in reference
167
- intervals to that start time.
168
- :param script: is the body of the LUA script to execute.
169
- :param keys: The keys expected by the script
170
- :param args: The args required by the script
171
- """
172
- pieces: CommandArgList = [name]
173
- if repeat:
174
- pieces.append(b"REPEAT")
175
- else:
176
- pieces.append(b"SINGLE")
177
- if start is not None:
178
- pieces.append(normalized_time_milliseconds(start))
179
- pieces.append(normalized_milliseconds(delay))
180
- pieces.append(script)
181
- _keys = list(keys)
182
- pieces.append(len(_keys))
183
- pieces.extend(keys)
184
- pieces.extend(args)
185
-
186
- return await self.execute_command(
187
- CommandName.CRON, *pieces, callback=SimpleStringCallback()
188
- )
189
-
190
- @keydb_command(
191
- CommandName.EXPIREMEMBER,
192
- CommandGroup.GENERIC,
193
- )
194
- async def expiremember(
195
- self,
196
- key: KeyT,
197
- subkey: KeyT,
198
- delay: int,
199
- unit: Literal[b"s", b"ms"] | None = None,
200
- ) -> bool:
201
- """
202
- Set a subkey's time to live in seconds (or milliseconds)
203
- """
204
- pieces: CommandArgList = [key, subkey, delay]
205
- if unit:
206
- pieces.append(unit.lower())
207
- return await self.execute_command(
208
- CommandName.EXPIREMEMBER, *pieces, callback=BoolCallback()
209
- )
210
-
211
- @keydb_command(
212
- CommandName.EXPIREMEMBERAT,
213
- CommandGroup.GENERIC,
214
- )
215
- async def expirememberat(
216
- self, key: KeyT, subkey: KeyT, unix_time_seconds: int | datetime.datetime
217
- ) -> bool:
218
- """
219
- Set the expiration for a subkey as a UNIX timestamp
220
- """
221
- pieces: CommandArgList = [
222
- key,
223
- subkey,
224
- normalized_time_seconds(unix_time_seconds),
225
- ]
226
- return await self.execute_command(
227
- CommandName.EXPIREMEMBERAT, *pieces, callback=BoolCallback()
228
- )
229
-
230
- @keydb_command(
231
- CommandName.PEXPIREMEMBERAT,
232
- CommandGroup.GENERIC,
233
- )
234
- async def pexpirememberat(
235
- self,
236
- key: KeyT,
237
- subkey: KeyT,
238
- unix_time_milliseconds: int | datetime.datetime,
239
- ) -> bool:
240
- """
241
- Set the expiration for a subkey as a UNIX timestamp in milliseconds
242
- """
243
- pieces: CommandArgList = [
244
- key,
245
- subkey,
246
- normalized_time_milliseconds(unix_time_milliseconds),
247
- ]
248
- return await self.execute_command(
249
- CommandName.PEXPIREMEMBERAT, *pieces, callback=BoolCallback()
250
- )
251
-
252
- @keydb_command(CommandName.HRENAME, group=CommandGroup.HASH)
253
- async def hrename(self, key: KeyT, source_field: ValueT, destination_field: ValueT) -> bool:
254
- """
255
- Rename a field :paramref:`source_field` to :paramref:`destination_field`
256
- in hash :paramref:`key`
257
- """
258
-
259
- return await self.execute_command(
260
- CommandName.HRENAME,
261
- key,
262
- source_field,
263
- destination_field,
264
- callback=BoolCallback(),
265
- )
266
-
267
- @keydb_command(CommandName.MEXISTS, group=CommandGroup.GENERIC, flags={CommandFlag.READONLY})
268
- async def mexists(self, keys: Iterable[KeyT]) -> tuple[bool, ...]:
269
- """
270
- Returns a tuple of bools in the same order as :paramref:`keys`
271
- denoting whether the keys exist
272
- """
273
-
274
- return await self.execute_command(CommandName.MEXISTS, *keys, callback=BoolsCallback())
275
-
276
- @keydb_command(
277
- CommandName.OBJECT_LASTMODIFIED,
278
- group=CommandGroup.GENERIC,
279
- flags={CommandFlag.READONLY},
280
- )
281
- async def object_lastmodified(self, key: KeyT) -> int:
282
- """
283
- Returns the time elapsed (in seconds) since the key was last modified.
284
- This differs from idletime as it is not affected by reads of a key.
285
-
286
- :return: The time in seconds since the last modification
287
- """
288
-
289
- return await self.execute_command(
290
- CommandName.OBJECT_LASTMODIFIED, key, callback=IntCallback()
291
- )
292
-
293
- @keydb_command(CommandName.PTTL, group=CommandGroup.GENERIC, flags={CommandFlag.READONLY})
294
- async def pttl(self, key: KeyT, subkey: ValueT | None = None) -> int:
295
- """
296
- Returns the number of milliseconds until the key :paramref:`key` will expire.
297
- If :paramref:`subkey` is provided the response will be for the subkey.
298
-
299
- :return: TTL in milliseconds, or a negative value in order to signal an error
300
- """
301
- pieces: CommandArgList = [key]
302
- if subkey is not None:
303
- pieces.append(subkey)
304
-
305
- return await self.execute_command(CommandName.PTTL, *pieces, callback=IntCallback())
306
-
307
- @keydb_command(CommandName.TTL, group=CommandGroup.GENERIC, flags={CommandFlag.READONLY})
308
- async def ttl(self, key: KeyT, subkey: ValueT | None = None) -> int:
309
- """
310
- Get the time to live for a key (or subkey) in seconds
311
-
312
- :return: TTL in seconds, or a negative value in order to signal an error
313
- """
314
-
315
- pieces: CommandArgList = [key]
316
- if subkey is not None:
317
- pieces.append(subkey)
318
- return await self.execute_command(CommandName.TTL, *pieces, callback=IntCallback())
319
-
320
-
321
- class KeyDB(KeyDBCommands[AnyStr], Redis[AnyStr]):
322
- """
323
- Client for `KeyDB <https://keydb.dev>`__
324
-
325
- The client is mostly :class:`coredis.Redis` with a couple of extra
326
- commands specific to KeyDB.
327
- """
328
-
329
-
330
- class KeyDBCluster(KeyDBCommands[AnyStr], RedisCluster[AnyStr]):
331
- """
332
- Cluster client for `KeyDB <https://keydb.dev>`__
333
-
334
- The client is mostly :class:`coredis.RedisCluster` with a couple of extra
335
- commands specific to KeyDB.
336
- """