I am very fond of the returns library in python, and I would like to use it more. I have a little issue right now. Currently, I have a function that uses a redis client and gets the value corresponding to a key, like so:
from redis import Redis
from returns.context import RequiresContext
def get_value(key: str) -> RequiresContext[str, Redis]:
def inner(client: Redis) -> str:
value = client.get(key)
return value.decode("utf-8")
return RequiresContext(inner)
Obviously, that function works like a charm:
with Redis(
host=redis_host,
port=redis_port,
password=redis_password,
) as redis_client:
value = get_value(key="my-key")(redis_client)
print("value = ", value)
Now, I would like to use the asyncio pendant of that code, i.e. use the redis.asyncio.Redis
. Unfortunately, it looks like things become a bit more complicated in that case. I should probably switch from RequiresContext
to RequiresContextFutureResultE
, but I was not able to find a working solution. Here's the best code I was able to come up with:
async def get_value(key: str) -> RequiresContextFutureResultE[str, Redis]:
async def inner(client: Redis) -> FutureResultE[str]:
value = await client.get(key)
return FutureResult.from_value(value.decode("utf-8"))
return RequiresContextFutureResultE(inner)
When I run it like this:
async def main():
async with Redis(
host="localhost",
port=6379,
password="902nks291",
db=15,
) as redis_client:
rcfr = get_value(key="user-id")
value = await rcfr(redis_client)
print("value: ", value)
asyncio.run(main())
I get the error that rcfr
is not a callable. Can someone help me figure out how I should fix my code to make it work the way I want?
If you call a function (get_value
) defined with async def
you get an awaitable which you must use with await
to get its return value. That's why you get the error.
But get_value
shouldn't be async def
. It just defines and returns a function (wrapped by RequiresContextFutureResultE
), it doesn't perform any IO itself.