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

Make Service decorators work with Class Based Views #479

Open
ergo opened this issue Mar 29, 2018 · 2 comments
Open

Make Service decorators work with Class Based Views #479

ergo opened this issue Mar 29, 2018 · 2 comments

Comments

@ergo
Copy link
Collaborator

ergo commented Mar 29, 2018

Currently it is impossible to use Cornice decorators on CBV's (except @resource decorator),

This is the feedback I got from pyramid developers on what we can do to improve the situation, leaving here for reference.

yeah if I had to guess cornice is only registering a venusian scan for the service                                                                                                           
then cornice itself calls config.add_route and config.add_view directly                                                                                                                      
the decorator is just handled in the service directly                                                                                                                                        
that is my impression... so then it's up to cornice to deal with it itself                                                                                                                   
if you want to keep things structured that way at least internally... 
instead of making them venusian decorators on the methods                                                              
for example @foo.get() could be a venusian decorator that under the hood calls 
config.add_resource(foo, type='get', ...)                                                                     
which would be an action that executes before add_view/add_route                                                                                                                             
this is how you'd restructure the config into pyramid actions at least                                                                                                                       
but atm cornice does all the config itself at import-time and then just 
registers with pyramid at scan-time... cornice doesn't register its own 
fine-grained actions that to all the work on the service                                                                                                                                                                                  
@wrkhenddher
Copy link

wrkhenddher commented May 11, 2018

Side note: BIG GOTCHA to be aware of:
Pyramid IRC folks confirmed it.

I added the auto-wiring of factory instance to support pyramidic ACL to @resource decorated classes and came to discover something interesting about that (#456)

The following construct will cause BaseResource.__init__(self, request) to be called "twice". Once for the instance of the factory and the other for the instance of the view. Pyramid won't care but the unaware coder (me) of a Resource would be very confused especially if __init__ does some setup that's meant to happen only once.

@resource(collection_path='/items', path='/items/{uuid}')
class Items(BaseResource):
    @view(permission='edit')
    def get(self):
        logging.error("GET")
        ...
 
class BaseResource:
def __acl__(self, context=None):
    ...
def __init__(self, request):
    logging.error("BaseResource %r %r ", self, request)  # TWO CALLS => 2 INSTANCES!!!
    self.request = request 
    ...

Output will be the following:

default.py  54 ERROR  BaseResource <xserver.views.default.Items object at 0x1116a8d68> <Request at 0x1116a8278 GET http://localhost/items/0D057D01-B3DE-450A-9A68-9BB8AC3E4DC3>
default.py  46 ERROR  __acl__ <xserver.views.default.Items object at 0x1116a8d68> <Request at 0x1116a8278 GET http://localhost/items/0D057D01-B3DE-450A-9A68-9BB8AC3E4DC3>
default.py  54 ERROR  BaseResource <xserver.views.default.Items object at 0x11168db70> <Request at 0x1116a8278 GET http://localhost/items/0D057D01-B3DE-450A-9A68-9BB8AC3E4DC3>
default.py 183 ERROR  GET <Request at 0x1116a8278 GET http://localhost/items/0D057D01-B3DE-450A-9A68-9BB8AC3E4DC3>

@mangroovie
Copy link

can confirm with pattern like:

class Root(object):
    __name__ = 'Root'
    __parent__ = None

    def __acl__(self):
        return [
            (Allow, Authenticated, MINIMAL),
           ...
        ]


@resource(collection_path='/items',  path='/items/{id}',
          factory=Root)
class ItemView(object):

    def __init__(self, request, context=None):
        self.request = request

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