Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to aioredis 2 #611

Merged
merged 18 commits into from
Aug 30, 2021
22 changes: 6 additions & 16 deletions aiohttp_session/redis_storage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import uuid
import warnings
from distutils.version import StrictVersion
from typing import Any, Callable, Optional

Expand All @@ -11,15 +10,15 @@
try:
import aioredis
except ImportError: # pragma: no cover
aioredis = None
aioredis = None # type: ignore[assignment]


class RedisStorage(AbstractStorage):
"""Redis storage"""

def __init__( # type: ignore[no-any-unimported] # TODO: aioredis
def __init__(
self,
redis_pool: 'aioredis.commands.Redis', *,
redis_pool: "aioredis.Redis", *,
cookie_name: str = "AIOHTTP_SESSION",
domain: Optional[str] = None,
max_age: Optional[int] = None,
Expand All @@ -39,15 +38,8 @@ def __init__( # type: ignore[no-any-unimported] # TODO: aioredis
if StrictVersion(aioredis.__version__).version < (1, 0):
raise RuntimeError("aioredis<1.0 is not supported")
self._key_factory = key_factory
if isinstance(redis_pool, aioredis.pool.ConnectionsPool):
warnings.warn(
"using a pool created with aioredis.create_pool is deprecated"
"please use a pool created with aioredis.create_redis_pool",
DeprecationWarning
)
redis_pool = aioredis.commands.Redis(redis_pool)
elif not isinstance(redis_pool, aioredis.commands.Redis):
raise TypeError("Expected aioredis.commands.Redis got {}".format(type(redis_pool)))
if not isinstance(redis_pool, aioredis.Redis):
raise TypeError("Expected aioredis.Redis got {}".format(type(redis_pool)))
self._redis = redis_pool

async def load_session(self, request: web.Request) -> Session:
Expand Down Expand Up @@ -90,6 +82,4 @@ async def save_session(
data = self._encoder(self._get_session_data(session))
max_age = session.max_age
expire = max_age if max_age is not None else 0
await self._redis.set(self.cookie_name + '_' + key,
data,
expire=expire)
await self._redis.set(self.cookie_name + '_' + key, data, ex=expire)
6 changes: 3 additions & 3 deletions demo/redis_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ async def handler(request: web.Request) -> web.Response:
return web.Response(text=text)


async def redis_pool(app: web.Application) -> AsyncIterator[aioredis.commands.Redis]: # type: ignore[no-any-unimported] # noqa: B950
redis_address = ('127.0.0.1', '6379')
async with await aioredis.create_redis_pool(redis_address, timeout=1) as redis:
async def redis_pool(app: web.Application) -> AsyncIterator[None]:
redis_address = "redis://127.0.0.1:6379"
async with await aioredis.from_url(redis_address, timeout=1) as redis: # type: ignore[no-untyped-call] # noqa: B950
storage = RedisStorage(redis)
setup(app, storage)
yield
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ flake8-requirements==1.5
sphinx==4.0.2
pep257==0.7.0
-e .
aioredis==1.2
aioredis==2.0.0
cryptography==3.4.7
docker==5.0.0
pynacl==1.4.0
Expand Down
73 changes: 23 additions & 50 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import asyncio
import gc
import socket
import sys
import time
import uuid
from typing import Generator, Tuple
from typing import AsyncIterator, Iterator

import aiomcache
import aioredis
Expand All @@ -23,10 +21,6 @@ class _ContainerInfo(TypedDict):
container: docker_models.containers.Container


class _RedisParams(TypedDict):
address: Tuple[str, int]


class _MemcachedParams(TypedDict):
host: str
port: int
Expand All @@ -41,21 +35,6 @@ def unused_port() -> int:
return port


@pytest.fixture(scope='session')
def loop() -> Generator[asyncio.AbstractEventLoop, None, None]:
loop = asyncio.new_event_loop()
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved
asyncio.set_event_loop(None)

yield loop

if not loop.is_closed():
loop.call_soon(loop.stop)
loop.run_forever()
loop.close()
gc.collect()
asyncio.set_event_loop(None)


@pytest.fixture(scope='session')
def session_id() -> str:
"""Unique session identifier, random string."""
Expand All @@ -69,11 +48,10 @@ def docker() -> DockerClient: # type: ignore[misc] # No docker types.


@pytest.fixture(scope='session')
def redis_server( # type: ignore[misc] # No docker types.
async def redis_server( # type: ignore[misc] # No docker types.
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved
docker: DockerClient,
session_id: str,
loop: asyncio.AbstractEventLoop,
) -> Generator[_ContainerInfo, None, None]:
) -> AsyncIterator[_ContainerInfo]:
image = 'redis:{}'.format('latest')

if sys.platform.startswith('darwin'):
Expand Down Expand Up @@ -104,10 +82,8 @@ def redis_server( # type: ignore[misc] # No docker types.
delay = 0.1
for _i in range(20):
try:
conn = loop.run_until_complete(
aioredis.create_connection((host, port), loop=loop)
)
loop.run_until_complete(conn.execute('SET', 'foo', 'bar'))
conn = await aioredis.from_url("redis://{}:{}".format(host, port)) # type: ignore[no-untyped-call] # noqa: B950
await conn.execute('SET', 'foo', 'bar')
break
except ConnectionRefusedError:
time.sleep(delay)
Expand All @@ -122,30 +98,28 @@ def redis_server( # type: ignore[misc] # No docker types.


@pytest.fixture
def redis_params(redis_server: _ContainerInfo) -> _RedisParams: # type: ignore[misc]
return dict(address=(redis_server['host'], redis_server['port']))
def redis_url(redis_server: _ContainerInfo) -> str: # type: ignore[misc]
return "redis://{}:{}".format(redis_server["host"], redis_server["port"])


@pytest.fixture
def redis( # type: ignore[misc] # TODO: aioredis
loop: asyncio.AbstractEventLoop,
redis_params: _RedisParams,
) -> Generator[aioredis.commands.Redis, None, None]:
async def start() -> aioredis.commands.Redis:
return await aioredis.create_redis_pool(loop=loop, **redis_params)
async def redis(redis_url: str) -> AsyncIterator[aioredis.Redis]:
async def start(pool: aioredis.ConnectionPool) -> aioredis.Redis:
return aioredis.Redis(connection_pool=pool)

pool = loop.run_until_complete(start())
yield pool
if pool is not None:
pool.close()
loop.run_until_complete(pool.wait_closed())
pool = aioredis.ConnectionPool.from_url(redis_url)
redis = await start(pool)
yield redis
if redis is not None:
redis.close() # type: ignore[no-untyped-call]
await pool.disconnect()


@pytest.fixture(scope='session')
def memcached_server( # type: ignore[misc] # No docker types.
async def memcached_server( # type: ignore[misc] # No docker types.
docker: DockerClient,
session_id: str, loop: asyncio.AbstractEventLoop,
) -> Generator[_ContainerInfo, None, None]:
session_id: str,
) -> AsyncIterator[_ContainerInfo]:

image = 'memcached:{}'.format('latest')

Expand Down Expand Up @@ -177,8 +151,8 @@ def memcached_server( # type: ignore[misc] # No docker types.
delay = 0.1
for _i in range(20):
try:
conn = aiomcache.Client(host, port, loop=loop)
loop.run_until_complete(conn.set(b'foo', b'bar'))
conn = aiomcache.Client(host, port)
await conn.set(b'foo', b'bar')
break
except ConnectionRefusedError:
time.sleep(delay)
Expand All @@ -199,9 +173,8 @@ def memcached_params(memcached_server: _ContainerInfo) -> _MemcachedParams: # t

@pytest.fixture
def memcached( # type: ignore[misc]
loop: asyncio.AbstractEventLoop,
memcached_params: _MemcachedParams
) -> Generator[aiomcache.Client, None, None]:
conn = aiomcache.Client(loop=loop, **memcached_params)
) -> Iterator[aiomcache.Client]:
conn = aiomcache.Client(**memcached_params)
yield conn
conn.close()
Loading