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

Methods of classes cannot be used as blueprint routes #1943

Closed
penn5 opened this issue Oct 1, 2020 · 3 comments
Closed

Methods of classes cannot be used as blueprint routes #1943

penn5 opened this issue Oct 1, 2020 · 3 comments

Comments

@penn5
Copy link

penn5 commented Oct 1, 2020

Describe the bug
Unable to define routes in classes

Code snippet

class MyApp:
    def __init__(self):
        self.bp = Blueprint("app")
        self.bp.add_route(self.route, "/route")

    def route(self, request):
        return text("hi")

Expected behavior
Accessing /route says hi

Actual behavior
Including the blueprint fails with because trying to assign __blueprintname__ on a method, but methods cannot have arbitrary attributes assigned.

Environment (please complete the following information):
19.12.2, and master

Additional context
Introduced in #1445

penn5 added a commit to penn5/sanic that referenced this issue Oct 1, 2020
penn5 added a commit to penn5/sanic that referenced this issue Oct 1, 2020
@ahopkins
Copy link
Member

ahopkins commented Oct 1, 2020

What is the motivation for this style api? Blueprints work really well in modules.

penn5 added a commit to penn5/sanic that referenced this issue Oct 1, 2020
penn5 added a commit to penn5/sanic that referenced this issue Oct 1, 2020
penn5 added a commit to penn5/sanic that referenced this issue Oct 1, 2020
penn5 added a commit to penn5/sanic that referenced this issue Oct 1, 2020
@penn5
Copy link
Author

penn5 commented Oct 1, 2020

What is the motivation for this style api? Blueprints work really well in modules.

I want to pass in some objects, and as we are in the middle of a refactor, I don't want it to be tied to any specific import - I want the database to be injected through the class constructor, rather than an import.

@ashleysommer
Copy link
Member

Hi @penn5
There is a workaround which doesn't involve hacking the sanic route mechanism.
You can turn the method into a function using functools.partial and functools.wraps like this:

from functools import partial, wraps
class MyApp:
    def __init__(self):
        self.bp = Blueprint("app")
        handler = wraps(self.route)(partial(self.route))
        self.bp.add_route(handler, "/route")

    def route(self, request):
        return text("hi")

I've tested this, and it works exactly as expected. (And actually I will keep this in mind to implement in one of my applications in the future.)

@ahopkins ahopkins closed this as completed Oct 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants