Skip to content

Commit

Permalink
Python: adds GEOHASH command (valkey-io#1281)
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamazon authored and cyip10 committed Jun 24, 2024
1 parent 4d65b39 commit bacc38a
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Python: Added RENAME command ([#1252](https://github.com/aws/glide-for-redis/pull/1252))
* Python: Added APPEND command ([#1152](https://github.com/aws/glide-for-redis/pull/1152))
* Python: Added GEOADD command ([#1259](https://github.com/aws/glide-for-redis/pull/1259))
* Python: Added GEOHASH command ([#1281](https://github.com/aws/glide-for-redis/pull/1281))

#### Fixes
* Python: Fix typing error "‘type’ object is not subscriptable" ([#1203](https://github.com/aws/glide-for-redis/pull/1203))
Expand Down
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ enum RequestType {
SMIsMember = 118;
LastSave = 120;
GeoAdd = 121;
GeoHash = 122;
}

message Command {
Expand Down
3 changes: 3 additions & 0 deletions glide-core/src/request_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ pub enum RequestType {
SMIsMember = 118,
LastSave = 120,
GeoAdd = 121,
GeoHash = 122,
}

fn get_two_word_command(first: &str, second: &str) -> Cmd {
Expand Down Expand Up @@ -261,6 +262,7 @@ impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
ProtobufRequestType::SMIsMember => RequestType::SMIsMember,
ProtobufRequestType::LastSave => RequestType::LastSave,
ProtobufRequestType::GeoAdd => RequestType::GeoAdd,
ProtobufRequestType::GeoHash => RequestType::GeoHash,
}
}
}
Expand Down Expand Up @@ -389,6 +391,7 @@ impl RequestType {
RequestType::SMIsMember => Some(cmd("SMISMEMBER")),
RequestType::LastSave => Some(cmd("LASTSAVE")),
RequestType::GeoAdd => Some(cmd("GEOADD")),
RequestType::GeoHash => Some(cmd("GEOHASH")),
}
}
}
25 changes: 25 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,31 @@ async def geoadd(
await self._execute_command(RequestType.GeoAdd, args),
)

async def geohash(self, key: str, members: List[str]) -> List[Optional[str]]:
"""
Returns the GeoHash strings representing the positions of all the specified members in the sorted set stored at
`key`.
See https://valkey.io/commands/geohash for more details.
Args:
key (str): The key of the sorted set.
members (List[str]): The list of members whose GeoHash strings are to be retrieved.
Returns:
List[Optional[str]]: A list of GeoHash strings representing the positions of the specified members stored at `key`.
If a member does not exist in the sorted set, a None value is returned for that member.
Examples:
>>> await client.geoadd("my_geo_sorted_set", {"Palermo": GeospatialData(13.361389, 38.115556), "Catania": GeospatialData(15.087269, 37.502669)})
>>> await client.geohash("my_geo_sorted_set", ["Palermo", "Catania", "some city])
["sqc8b49rny0", "sqdtr74hyu0", None] # Indicates the GeoHash strings for the specified members.
"""
return cast(
List[Optional[str]],
await self._execute_command(RequestType.GeoHash, [key] + members),
)

async def zadd(
self,
key: str,
Expand Down
17 changes: 17 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,23 @@ def geoadd(

return self.append_command(RequestType.GeoAdd, args)

def geohash(self: TTransaction, key: str, members: List[str]) -> TTransaction:
"""
Returns the GeoHash strings representing the positions of all the specified members in the sorted set stored at
`key`.
See https://valkey.io/commands/geohash for more details.
Args:
key (str): The key of the sorted set.
members (List[str]): The list of members whose GeoHash strings are to be retrieved.
Commands response:
List[Optional[str]]: A list of GeoHash strings representing the positions of the specified members stored at `key`.
If a member does not exist in the sorted set, a None value is returned for that member.
"""
return self.append_command(RequestType.GeoHash, [key] + members)

def zadd(
self: TTransaction,
key: str,
Expand Down
31 changes: 31 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,37 @@ async def test_geoadd_invalid_args(self, redis_client: TRedisClient):
with pytest.raises(RequestError):
await redis_client.geoadd(key, {"Place": GeospatialData(0, -86)})

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_geohash(self, redis_client: TRedisClient):
key = get_random_string(10)
members_coordinates = {
"Palermo": GeospatialData(13.361389, 38.115556),
"Catania": GeospatialData(15.087269, 37.502669),
}
assert await redis_client.geoadd(key, members_coordinates) == 2
assert await redis_client.geohash(key, ["Palermo", "Catania", "Place"]) == [
"sqc8b49rny0",
"sqdtr74hyu0",
None,
]

assert (
await redis_client.geohash(
"non_existing_key", ["Palermo", "Catania", "Place"]
)
== [None] * 3
)

# Neccessary to check since we are enforcing the user to pass a list of members while redis don't
# But when running the command with key only (and no members) the returned value will always be an empty list
# So in case of any changes, this test will fail and inform us that we should allow not passing any members.
assert await redis_client.geohash(key, []) == []

assert await redis_client.set(key, "value") == OK
with pytest.raises(RequestError):
await redis_client.geohash(key, ["Palermo", "Catania"])

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_zadd_zaddincr(self, redis_client: TRedisClient):
Expand Down
2 changes: 2 additions & 0 deletions python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ async def transaction_test(
},
)
args.append(2)
transaction.geohash(key9, ["Palermo", "Catania", "Place"])
args.append(["sqc8b49rny0", "sqdtr74hyu0", None])
return args


Expand Down

0 comments on commit bacc38a

Please sign in to comment.