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

@inject_user() decorator hangs for me #114

Closed
gbnk0 opened this Issue Jun 15, 2018 · 10 comments

Comments

Projects
None yet
3 participants
@gbnk0
Copy link
Contributor

gbnk0 commented Jun 15, 2018

Hi i'm back with another issue, i use @inject_user on a route, it give me this message:

TypeError: object dict can't be used in 'await' expression while handling path /me

Here's my snippet:

@blueprint_me.get("")
@protected()
@inject_user()
async def my_route(request, user):
    return my_func(request, user, es)
@gbnk0

This comment has been minimized.

Copy link
Contributor Author

gbnk0 commented Jun 15, 2018

ok, i've found a solution, my retrieve_user function was not async

@vltr

This comment has been minimized.

Copy link
Collaborator

vltr commented Jun 17, 2018

Hello, @gbnk0 !

Sorry for this late answer, I was not around my computer. AFAIK, there should not be any problems if your retrieve_user function is not async (as you can see here). I don't know if you found a hidden bug or something. Would you mind sharing more code with us or reproduce the error with a small snippet?

I'll leave this issue open for @ahopkins knowledge.

Thanks a lot for your time and patience reporting these "misbehavior" with us 💪 😃

@ahopkins

This comment has been minimized.

Copy link
Owner

ahopkins commented Jun 18, 2018

@gbnk0 and @vltr retrieve_user should be able to be either a regular function:

def my_retrieve_user(...): ...

Or, an awaitable:

async def my_retrieve_user(...): ...

Furthermore, if it is returning an object, the to_dict() method could also be a regular method or an awaitable.

@gbnk0, if you wouldn't mind, can you send me your Initialize snippet, and at least a barebones representation of your retrieve_user definition?

@gbnk0

This comment has been minimized.

Copy link
Contributor Author

gbnk0 commented Jun 18, 2018

Hi,

Here is my (dirty) code snippet:

def retrieve_user(request, payload, *args, **kwargs):
    result = None
    if payload:
        user_id = payload.get('user_id', None)

        if user_id != None:
            user = db.get_user(user_id=user_id)
            # Remove password from returned user
            if type(user) == dict:
                user.pop('password', None)
                result =  user

    return result

and the initialize:

initialize(app,
           authenticate,
           store_refresh_token=store_refresh_token,
           retrieve_refresh_token=retrieve_refresh_token,
           retrieve_user=retrieve_user,
           class_views=custom_views,
           add_scopes_to_payload=scope_extender
        )

Regards,

@gbnk0

This comment has been minimized.

Copy link
Contributor Author

gbnk0 commented Jun 18, 2018

And i have the error when i try a blueprint route:

# Fetch current user details
@blueprint_me.get("")
@inject_user()
@protected()
async def get_user_details_route(request, user):
    return get_my_details(request, user, es)
@ahopkins

This comment has been minimized.

Copy link
Owner

ahopkins commented Jun 18, 2018

@gbnk0 Thank you!

I found the bug.

user = await instance.auth.retrieve_user(request, payload)

This should be executed with utils.call(), which is our under the hood helper method that allows for either def or async def.

The line should be:

user = await utils.call(instance.auth.retrieve_user, request, payload)

My bad. Thanks for pointing it out.

@gbnk0

This comment has been minimized.

Copy link
Contributor Author

gbnk0 commented Jun 25, 2018

Can i inject_user on an entire blueprint?

@ahopkins

This comment has been minimized.

Copy link
Owner

ahopkins commented Jun 25, 2018

The inject_user decorator specifically works on routes. If you want it on an entire Blueprint, then I would suggest making a subclass of HTTPMethodView. Something like this:

from sanic import Sanic
from sanic.response import text
from sanic.views import HTTPMethodView
from sanic_jwt import inject_user
from sanic import Blueprint


app = Sanic('myapp')
bp = Blueprint('mybp')


class MyBaseHTTPView(HTTPMethodView):
    decorators = [inject_user(), ]

class SomeBPView(MyBaseHTTPView):
  async def get(self, request, user):
      return text(f'Hello {user.username}')

bp.add_route(SomeBPView.as_view(), '/')
app.blueprint(bp)

I have not tried this. But, it should look something like this.

@gbnk0

This comment has been minimized.

Copy link
Contributor Author

gbnk0 commented Jun 26, 2018

Ok i'll try this, thanks

@ahopkins ahopkins closed this in 14780ca Aug 5, 2018

@ahopkins

This comment has been minimized.

Copy link
Owner

ahopkins commented Aug 5, 2018

This should be resolved in the latest commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment