Skip to content

AttributeError: '_AsyncGeneratorContextManager' object has no attribute 'execute' #94

@aryaniyaps

Description

@aryaniyaps

These are my dependencies:

from contextlib import asynccontextmanager, contextmanager
from typing import AsyncIterator, Iterator

import inject
from argon2 import PasswordHasher
from redis.asyncio import Redis, from_url
from sqlalchemy.ext.asyncio import AsyncConnection

from app.config import settings
from app.core.database import engine
from app.core.emails import EmailSender


@asynccontextmanager
async def get_database_connection() -> AsyncIterator[AsyncConnection]:
    """Get a database connection."""
    async with engine.begin() as connection:
        yield connection


@asynccontextmanager
async def get_redis_client() -> AsyncIterator[Redis]:
    """Get the redis client."""
    redis_client = from_url(
        url=str(settings.redis_url),
    )
    yield redis_client

    await redis_client.aclose()


@contextmanager
def get_email_sender() -> Iterator[EmailSender]:
    """Get the email sender."""
    email_sender = EmailSender(
        email_server=settings.email_server,
        email_from=settings.email_from,
    )
    yield email_sender
    email_sender.close_connection()


def app_config(binder: inject.Binder) -> None:
    """Configure dependencies for the binder."""
    binder.bind_to_constructor(
        EmailSender,
        get_email_sender,
    )
    binder.bind_to_constructor(
        Redis,
        get_redis_client,
    )
    binder.bind_to_provider(
        AsyncConnection,
        get_database_connection,
    )
    binder.bind(
        PasswordHasher,
        PasswordHasher(),
    )


inject.configure(app_config)

This is my UserRepo:

class UserRepo:
    _connection = inject.attr(AsyncConnection)
    _password_hasher = inject.attr(PasswordHasher)

    async def create_user(
        self,
        username: str,
        email: str,
        password: str,
    ) -> User:
        """Create a new user."""
        result = await self._connection.execute(
            insert(users_table)
            .values(
                username=username,
                email=email,
                # hash the password before storing
                password_hash=self.hash_password(
                    password=password,
                ),
            )
            .returning(*users_table.c),
        )
        user_row = result.one()
        return User.model_validate(user_row)

    def hash_password(self, password: str) -> str:
        """Hash the given password."""
        return self._password_hasher.hash(
            password=password,
        )

I am getting this error while accessing the UserRepo:

self = <app.users.repos.UserRepo object at 0x0000016D0F176810>, username = 'new_user', email = 'new@example.com', password = 'password'

    async def create_user(
        self,
        username: str,
        email: str,
        password: str,
    ) -> User:
        """Create a new user."""
>       result = await self._connection.execute(
            insert(users_table)
            .values(
                username=username,
                email=email,
                # hash the password before storing
                password_hash=self.hash_password(
                    password=password,
                ),
            )
            .returning(*users_table.c),
        )
E       AttributeError: '_AsyncGeneratorContextManager' object has no attribute 'execute'

app\users\repos.py:24: AttributeError

This UserRepo is used by a AuthService:

class AuthService:
    _auth_repo = inject.attr(AuthRepo)
    _user_repo = inject.attr(UserRepo)
    _password_hasher = inject.attr(PasswordHasher)

Which is accessed by my falcon resources like this:

class AuthResource:
    @inject.autoparams("auth_service")
    async def on_post_register(
        self,
        req: Request,
        resp: Response,
        auth_service: AuthService,
    ) -> None:
        """Register a new user."""
        data = await req.media
        result = await auth_service.register_user(
            data=RegisterUserInput.model_validate(data),
        )
        resp.media = result.model_dump(mode="json")
        resp.status = HTTP_201
        

How to fix this error? Im stuck as the documentation doesn't seem that clear!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions