Skip to content
This repository was archived by the owner on Feb 21, 2023. It is now read-only.

Commit a389184

Browse files
getex (redis/redis-py#1515) * Removed small doc saying all time parameters can be datetime.timedelta. This is not needed with typing and can also be confusing with PXAT and EXAT Signed-off-by: Andrew-Chen-Wang <[email protected]>
1 parent 68a7de7 commit a389184

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

aioredis/client.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,63 @@ def get(self, name: KeyT) -> Awaitable:
18531853
"""
18541854
return self.execute_command("GET", name)
18551855

1856+
def getex(
1857+
self,
1858+
name: str,
1859+
ex: Union[int, datetime.timedelta] = None,
1860+
px: Union[int, datetime.timedelta] = None,
1861+
exat: Union[int, datetime.datetime] = None,
1862+
pxat: Union[int, datetime.datetime] = None,
1863+
persist: bool = False,
1864+
):
1865+
"""
1866+
Get the value of key and optionally set its expiration.
1867+
GETEX is similar to GET, but is a write command with
1868+
additional options.
1869+
1870+
``ex`` sets an expire flag on key ``name`` for ``ex`` seconds.
1871+
1872+
``px`` sets an expire flag on key ``name`` for ``px`` milliseconds.
1873+
1874+
``exat`` sets an expire flag on key ``name`` for ``ex`` seconds,
1875+
specified in unix time.
1876+
1877+
``pxat`` sets an expire flag on key ``name`` for ``ex`` milliseconds,
1878+
specified in unix time.
1879+
1880+
``persist`` remove the time to live associated with ``name``.
1881+
"""
1882+
1883+
pieces = []
1884+
# similar to set command
1885+
if ex is not None:
1886+
pieces.append("EX")
1887+
if isinstance(ex, datetime.timedelta):
1888+
ex = int(ex.total_seconds())
1889+
pieces.append(ex)
1890+
if px is not None:
1891+
pieces.append("PX")
1892+
if isinstance(px, datetime.timedelta):
1893+
px = int(px.total_seconds() * 1000)
1894+
pieces.append(px)
1895+
# similar to pexpireat command
1896+
if exat is not None:
1897+
pieces.append("EXAT")
1898+
if isinstance(exat, datetime.datetime):
1899+
s = int(exat.microsecond / 1000000)
1900+
exat = int(mod_time.mktime(exat.timetuple())) + s
1901+
pieces.append(exat)
1902+
if pxat is not None:
1903+
pieces.append("PXAT")
1904+
if isinstance(pxat, datetime.datetime):
1905+
ms = int(pxat.microsecond / 1000)
1906+
pxat = int(mod_time.mktime(pxat.timetuple())) * 1000 + ms
1907+
pieces.append(pxat)
1908+
if persist:
1909+
pieces.append("PERSIST")
1910+
1911+
return self.execute_command("GETEX", name, *pieces)
1912+
18561913
def getbit(self, name: KeyT, offset: int) -> Awaitable:
18571914
"""Returns a boolean indicating the value of ``offset`` in ``name``"""
18581915
return self.execute_command("GETBIT", name, offset)

tests/test_commands.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,21 @@ async def test_get_and_set(self, r: aioredis.Redis):
806806
assert await r.get("integer") == str(integer).encode()
807807
assert (await r.get("unicode_string")).decode("utf-8") == unicode_string
808808

809+
@skip_if_server_version_lt("6.2.0")
810+
async def test_getex(self, r: aioredis.Redis):
811+
await r.set("a", 1)
812+
assert await r.getex("a") == b"1"
813+
assert await r.ttl("a") == -1
814+
assert await r.getex("a", ex=60) == b"1"
815+
assert await r.ttl("a") == 60
816+
assert await r.getex("a", px=6000) == b"1"
817+
assert await r.ttl("a") == 6
818+
expire_at = await redis_server_time(r) + datetime.timedelta(minutes=1)
819+
assert await r.getex("a", pxat=expire_at) == b"1"
820+
assert await r.ttl("a") <= 60
821+
assert await r.getex("a", persist=True) == b"1"
822+
assert await r.ttl("a") == -1
823+
809824
async def test_get_set_bit(self, r: aioredis.Redis):
810825
# no value
811826
assert not await r.getbit("a", 5)

0 commit comments

Comments
 (0)