Repository: redis/redis-py

Issue:
XTRIM - MINID as in redis 6.2.0

**Version**:3.5

**Platform**: Linux-pycharm

**Description**: XTRIM - eviction based on timestamp IDs using MINID as it is available from redis6.2.0...
will we get upgrades on this?


Discussion:
I just found the xtrim MINID is missing too, but looks like it can be accessed anyway like this:

```
r.execute_command('XTRIM', stream_name, 'MINID', '~', id)
```
Thanks

On Wed, 3 Mar, 2021, 8:38 PM gtrainavicius, <notifications@github.com>
wrote:

> I just found the xtrim MINID is missing too, but looks like it can be
> accessed anyway like this:
>
> r.execute_command('XTRIM', stream_name, 'MINID', '~', id)
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/andymccurdy/redis-py/issues/1454#issuecomment-789782461>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AI5BLPRITRLP7PNJCMCDADLTBZGGHANCNFSM4YNB7LQQ>
> .
>

I need this feature too 👍 
Until it is added to redis-py, I am going to make use of `execute_command`
Thank you

Resolving patch:
diff --git a/redis/client.py b/redis/client.py
--- a/redis/client.py
+++ b/redis/client.py
@@ -2852,17 +2852,35 @@ def xrevrange(self, name, max='+', min='-', count=None):
 
         return self.execute_command('XREVRANGE', name, *pieces)
 
-    def xtrim(self, name, maxlen, approximate=True):
+    def xtrim(self, name, maxlen=None, approximate=True, minid=None,
+              limit=None):
         """
         Trims old messages from a stream.
         name: name of the stream.
         maxlen: truncate old stream messages beyond this size
         approximate: actual stream length may be slightly more than maxlen
+        minin: the minimum id in the stream to query
+        limit: specifies the maximum number of entries to retrieve
         """
-        pieces = [b'MAXLEN']
+        pieces = []
+        if maxlen is not None and minid is not None:
+            raise DataError("Only one of ```maxlen``` or ```minid```",
+                            "may be specified")
+
+        if maxlen is not None:
+            pieces.append(b'MAXLEN')
+        if minid is not None:
+            pieces.append(b'MINID')
         if approximate:
             pieces.append(b'~')
-        pieces.append(maxlen)
+        if maxlen is not None:
+            pieces.append(maxlen)
+        if minid is not None:
+            pieces.append(minid)
+        if limit is not None:
+            pieces.append(b"LIMIT")
+            pieces.append(limit)
+
         return self.execute_command('XTRIM', name, *pieces)
 
     # SORTED SET COMMANDS


Test patch:
diff --git a/tests/test_commands.py b/tests/test_commands.py
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -2783,6 +2783,47 @@ def test_xtrim(self, r):
         # 1 message is trimmed
         assert r.xtrim(stream, 3, approximate=False) == 1
 
+    @skip_if_server_version_lt('6.2.4')
+    def test_xtrim_minlen_and_length_args(self, r):
+        stream = 'stream'
+
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+
+        # Future self: No limits without approximate, according to the api
+        with pytest.raises(redis.ResponseError):
+            assert r.xtrim(stream, 3, approximate=False, limit=2)
+
+        # maxlen with a limit
+        assert r.xtrim(stream, 3, approximate=True, limit=2) == 0
+        r.delete(stream)
+
+        with pytest.raises(redis.DataError):
+            assert r.xtrim(stream, maxlen=3, minid="sometestvalue")
+
+        # minid with a limit
+        m1 = r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        assert r.xtrim(stream, None, approximate=True, minid=m1, limit=3) == 0
+
+        # pure minid
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        m4 = r.xadd(stream, {'foo': 'bar'})
+        assert r.xtrim(stream, None, approximate=False, minid=m4) == 7
+
+        # minid approximate
+        r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        m3 = r.xadd(stream, {'foo': 'bar'})
+        r.xadd(stream, {'foo': 'bar'})
+        assert r.xtrim(stream, None, approximate=True, minid=m3) == 0
+
     def test_bitfield_operations(self, r):
         # comments show affected bits
         bf = r.bitfield('a')