Skip to content

Commit 3c244af

Browse files
getex (#1515)
* getex * flake8 fix * comments
1 parent 9ce7bb2 commit 3c244af

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

redis/client.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,57 @@ def get(self, name):
16891689
"""
16901690
return self.execute_command('GET', name)
16911691

1692+
def getex(self, name,
1693+
ex=None, px=None, exat=None, pxat=None, persist=False):
1694+
"""
1695+
Get the value of key and optionally set its expiration.
1696+
GETEX is similar to GET, but is a write command with
1697+
additional options. All time parameters can be given as
1698+
datetime.timedelta or integers.
1699+
1700+
``ex`` sets an expire flag on key ``name`` for ``ex`` seconds.
1701+
1702+
``px`` sets an expire flag on key ``name`` for ``px`` milliseconds.
1703+
1704+
``exat`` sets an expire flag on key ``name`` for ``ex`` seconds,
1705+
specified in unix time.
1706+
1707+
``pxat`` sets an expire flag on key ``name`` for ``ex`` milliseconds,
1708+
specified in unix time.
1709+
1710+
``persist`` remove the time to live associated with ``name``.
1711+
"""
1712+
1713+
pieces = []
1714+
# similar to set command
1715+
if ex is not None:
1716+
pieces.append('EX')
1717+
if isinstance(ex, datetime.timedelta):
1718+
ex = int(ex.total_seconds())
1719+
pieces.append(ex)
1720+
if px is not None:
1721+
pieces.append('PX')
1722+
if isinstance(px, datetime.timedelta):
1723+
px = int(px.total_seconds() * 1000)
1724+
pieces.append(px)
1725+
# similar to pexpireat command
1726+
if exat is not None:
1727+
pieces.append('EXAT')
1728+
if isinstance(exat, datetime.datetime):
1729+
s = int(exat.microsecond / 1000000)
1730+
exat = int(mod_time.mktime(exat.timetuple())) + s
1731+
pieces.append(exat)
1732+
if pxat is not None:
1733+
pieces.append('PXAT')
1734+
if isinstance(pxat, datetime.datetime):
1735+
ms = int(pxat.microsecond / 1000)
1736+
pxat = int(mod_time.mktime(pxat.timetuple())) * 1000 + ms
1737+
pieces.append(pxat)
1738+
if persist:
1739+
pieces.append('PERSIST')
1740+
1741+
return self.execute_command('GETEX', name, *pieces)
1742+
16921743
def __getitem__(self, name):
16931744
"""
16941745
Return the value at key ``name``, raises a KeyError if the key

tests/test_commands.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,21 @@ def test_get_and_set(self, r):
727727
assert r.get('integer') == str(integer).encode()
728728
assert r.get('unicode_string').decode('utf-8') == unicode_string
729729

730+
@skip_if_server_version_lt('6.2.0')
731+
def test_getex(self, r):
732+
r.set('a', 1)
733+
assert r.getex('a') == b'1'
734+
assert r.ttl('a') == -1
735+
assert r.getex('a', ex=60) == b'1'
736+
assert r.ttl('a') == 60
737+
assert r.getex('a', px=6000) == b'1'
738+
assert r.ttl('a') == 6
739+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=1)
740+
assert r.getex('a', pxat=expire_at) == b'1'
741+
assert r.ttl('a') <= 60
742+
assert r.getex('a', persist=True) == b'1'
743+
assert r.ttl('a') == -1
744+
730745
def test_getitem_and_setitem(self, r):
731746
r['a'] = 'bar'
732747
assert r['a'] == b'bar'

0 commit comments

Comments
 (0)