Skip to content

Commit

Permalink
Add duplicated key exceptions and some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ri-gilfanov committed Apr 19, 2021
1 parent 4592eda commit a084021
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
11 changes: 8 additions & 3 deletions aiohttp_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from functools import wraps
from sqlalchemy.ext.asyncio import AsyncSession
from typing import TYPE_CHECKING
from aiohttp_sqlalchemy.exceptions import DuplicatedAppKeyError, DuplicatedRequestKeyError

if TYPE_CHECKING:
from aiohttp.web import Application, Request, StreamResponse
Expand All @@ -21,12 +22,16 @@ async def wrapped(*args, **kwargs):
# Class based view decorating
if isinstance(args[0], AbstractView):
request = args[0].request
if key in request:
raise DuplicatedRequestKeyError(key)
async with AsyncSession(request.app[key]) as request[key]:
return await handler(*args, **kwargs)

# Coroutine function decorating
elif iscoroutinefunction(handler):
request = args[0]
if key in request:
raise DuplicatedRequestKeyError(key)
async with AsyncSession(request.app[key]) as request[key]:
return await handler(*args, **kwargs)

Expand All @@ -40,6 +45,8 @@ async def wrapped(*args, **kwargs):
def sa_middleware(key: str = 'sa_main') -> 'Callable':
@middleware
async def sa_middleware_(request: 'Request', handler: 'Callable') -> 'StreamResponse':
if key in request:
raise DuplicatedRequestKeyError(key)
async with AsyncSession(request.app[key]) as request[key]:
return await handler(request)
return sa_middleware_
Expand All @@ -52,9 +59,7 @@ def sa_engine(engine: 'AsyncEngine', key: str = 'sa_main') -> 'Tuple[AsyncEngine
def setup(app: 'Application', engines: 'Iterable[Tuple[AsyncEngine, str]]'):
for engine, key in engines:
if key in app:
raise ValueError(
f'Duplicated app key `{key}`. Check `engines` argument'
f'in `aiohttp_sqlalchemy.setup()` call.')
raise DuplicatedAppKeyError(key)
app[key] = engine


Expand Down
10 changes: 10 additions & 0 deletions aiohttp_sqlalchemy/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class DuplicatedAppKeyError(ValueError):
def __init__(self, key):
self.message = f'Duplicated app key `{key}`. Check `engines` argument in `aiohttp_sqlalchemy.setup()` call.'
super().__init__(self.message)


class DuplicatedRequestKeyError(ValueError):
def __init__(self, key):
self.message = f'Duplicated request key `{key}`. Check middlewares and decorators from `aiohttp_sqlalchemy`.'
super().__init__(self.message)
30 changes: 30 additions & 0 deletions tests/test_aiohttp_sqlalchemy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from aiohttp import web
import aiohttp_sqlalchemy
from aiohttp_sqlalchemy import sa_engine
import pytest
from sqlalchemy.ext.asyncio import create_async_engine
from aiohttp_sqlalchemy.exceptions import DuplicatedAppKeyError, DuplicatedRequestKeyError


def test_aiohttp_sqlalchemy_setup():
engine = create_async_engine('sqlite+aiosqlite:///')

app = web.Application()
with pytest.raises(DuplicatedAppKeyError):
aiohttp_sqlalchemy.setup(app, [
sa_engine(engine),
sa_engine(engine),
])

app = web.Application()
with pytest.raises(DuplicatedAppKeyError):
aiohttp_sqlalchemy.setup(app, [
sa_engine(engine, 'sa_secondary'),
sa_engine(engine, 'sa_secondary'),
])

app = web.Application()
aiohttp_sqlalchemy.setup(app, [
sa_engine(engine),
sa_engine(engine, 'sa_secondary'),
])

0 comments on commit a084021

Please sign in to comment.