Separate into 4 modules
authorChristophe de Vienne <christophe@unlish.com>
Thu, 31 Jul 2014 17:48:32 +0200
changeset 11492 b0b8942cdb80
parent 11491 6ba31f0c7d5a
child 11493 00e5cb9771c5
Separate into 4 modules * init_instance: load the cubicweb repository from the `pyramid_cubicweb.instance` configuration key * defaults: provides cw-like defaults for the authentication and session management * core: make cubicweb use the authentication and session management of pyramid. It assumes the application provides the auth policies and session factory, and that the `cubicweb.*` registry entries are correctly initialised. This is this only required module or pyramid_cubicweb, the other ones are optional if the application provides its own versions of what they do. * bwcompat: provides a catchall route that delegate the request handling to an old-fashion cubicweb publisher (ie using url_resolver and controllers). Related to #4291173
pyramid_cubicweb/__init__.py
pyramid_cubicweb/bwcompat.py
pyramid_cubicweb/core.py
pyramid_cubicweb/defaults.py
pyramid_cubicweb/handler.py
pyramid_cubicweb/init_instance.py
sampleapp/development.ini
sampleapp/sampleapp/__init__.py
--- a/pyramid_cubicweb/__init__.py	Tue Jul 22 23:46:09 2014 +0200
+++ b/pyramid_cubicweb/__init__.py	Thu Jul 31 17:48:32 2014 +0200
@@ -1,248 +0,0 @@
-from contextlib import contextmanager
-from warnings import warn
-
-import rql
-
-from cubicweb.web.request import CubicWebRequestBase
-from cubicweb.cwconfig import CubicWebConfiguration
-from cubicweb import repoapi
-
-import cubicweb
-import cubicweb.web
-
-from pyramid import security, httpexceptions
-from pyramid.httpexceptions import HTTPSeeOther
-
-from pyramid_cubicweb import authplugin
-
-import logging
-
-log = logging.getLogger(__name__)
-
-
-@contextmanager
-def cw_to_pyramid(request):
-    """Wrap a call to the cubicweb API.
-
-    All CW exceptions will be transformed into their pyramid equivalent.
-    When needed, some CW reponse bits may be converted too (mainly headers)"""
-    try:
-        yield
-    except cubicweb.web.Redirect as ex:
-        assert 300 <= ex.status < 400
-        raise httpexceptions.status_map[ex.status](ex.location)
-    except cubicweb.web.StatusResponse as ex:
-        warn('[3.16] StatusResponse is deprecated use req.status_out',
-             DeprecationWarning, stacklevel=2)
-        request.body = ex.content
-        request.status_int = ex.status
-    except cubicweb.web.Unauthorized as ex:
-        raise httpexceptions.HTTPForbidden(
-            request.cw_request._(
-                'You\'re not authorized to access this page. '
-                'If you think you should, please contact the site '
-                'administrator.'))
-    except cubicweb.web.Forbidden:
-        raise httpexceptions.HTTPForbidden(
-            request.cw_request._(
-                'This action is forbidden. '
-                'If you think it should be allowed, please contact the site '
-                'administrator.'))
-    except (rql.BadRQLQuery, cubicweb.web.RequestError) as ex:
-        raise
-
-
-class CubicWebPyramidRequest(CubicWebRequestBase):
-    def __init__(self, request):
-        self._request = request
-
-        self.path = request.upath_info
-
-        vreg = request.registry['cubicweb.appli'].vreg
-        https = request.scheme == 'https'
-
-        post = request.params
-        headers_in = request.headers
-
-        super(CubicWebPyramidRequest, self).__init__(vreg, https, post,
-                                                     headers=headers_in)
-
-    def is_secure(self):
-        return self._request.scheme == 'https'
-
-    def relative_path(self, includeparams=True):
-        path = self._request.path[1:]
-        if includeparams and self._request.query_string:
-            return '%s?%s' % (path, self._request.query_string)
-        return path
-
-    def instance_uri(self):
-        return self._request.application_url
-
-    def get_full_path(self):
-        path = self._request.path
-        if self._request.query_string:
-            return '%s?%s' % (path, self._request.query_string)
-        return path
-
-    def http_method(self):
-        return self._request.method
-
-    def _set_status_out(self, value):
-        self._request.response.status_int = value
-
-    def _get_status_out(self):
-        return self._request.response.status_int
-
-    status_out = property(_get_status_out, _set_status_out)
-
-
-def render_view(request, vid, **kwargs):
-    vreg = request.registry['cubicweb.registry']
-    # XXX The select() function could, know how to handle a pyramid
-    # request, and feed it directly to the views that supports it.
-    # On the other hand, we could refine the View concept and decide it works
-    # with a cnx, and never with a WebRequest
-
-    with cw_to_pyramid(request):
-        view = vreg['views'].select(vid, request.cw_request, **kwargs)
-        view.set_stream()
-        view.render()
-        return view._stream.getvalue()
-
-
-def login(request):
-    repo = request.registry['cubicweb.repository']
-
-    response = request.response
-    user_eid = None
-
-    if '__login' in request.params:
-        login = request.params['__login']
-        password = request.params['__password']
-
-        try:
-            with repo.internal_cnx() as cnx:
-                user = repo.authenticate_user(cnx, login, password=password)
-                user_eid = user.eid
-        except cubicweb.AuthenticationError:
-            raise
-
-    if user_eid is not None:
-        headers = security.remember(request, user_eid)
-
-        raise HTTPSeeOther(
-            request.params.get('postlogin_path', '/'),
-            headers=headers)
-
-        response.headerlist.extend(headers)
-
-    response.text = render_view(request, 'login')
-    return response
-
-
-def _cw_cnx(request):
-    cnx = repoapi.ClientConnection(request.cw_session)
-
-    def cleanup(request):
-        if request.exception is not None:
-            cnx.rollback()
-        else:
-            cnx.commit()
-        cnx.__exit__(None, None, None)
-
-    request.add_finished_callback(cleanup)
-    cnx.__enter__()
-    return cnx
-
-
-def _cw_close_session(request):
-    request.cw_session.close()
-
-
-def _cw_session(request):
-    """Obtains a cw session from a pyramid request"""
-    repo = request.registry['cubicweb.repository']
-    config = request.registry['cubicweb.config']
-
-    if not request.authenticated_userid:
-        login, password = config.anonymous_user()
-        sessionid = repo.connect(login, password=password)
-        session = repo._sessions[sessionid]
-        request.add_finished_callback(_cw_close_session)
-    else:
-        session = request._cw_cached_session
-
-    # XXX Ideally we store the cw session data in the pyramid session.
-    # BUT some data in the cw session data dictionnary makes pyramid fail.
-    session.data = request.session
-
-    return session
-
-
-def _cw_request(request):
-    req = CubicWebPyramidRequest(request)
-    req.set_cnx(request.cw_cnx)
-    return req
-
-
-def get_principals(login, request):
-    repo = request.registry['cubicweb.repository']
-
-    try:
-        sessionid = repo.connect(
-            str(login), __pyramid_directauth=authplugin.EXT_TOKEN)
-        session = repo._sessions[sessionid]
-        request._cw_cached_session = session
-        request.add_finished_callback(_cw_close_session)
-    except:
-        log.exception("Failed")
-        raise
-
-    return session.user.groups
-
-
-from pyramid.authentication import SessionAuthenticationPolicy
-from pyramid.authorization import ACLAuthorizationPolicy
-from pyramid.session import SignedCookieSessionFactory
-
-
-def hello_world(request):
-    request.response.text = \
-        u"<html><body>Hello %s</body></html>" % request.cw_cnx.user.login
-    return request.response
-
-
-def includeme(config):
-    appid = config.registry.settings['cubicweb.instance']
-    cwconfig = CubicWebConfiguration.config_for(appid)
-
-    config.set_session_factory(
-        SignedCookieSessionFactory(
-            secret=config.registry.settings['session.secret']
-        ))
-
-    config.set_authentication_policy(
-        SessionAuthenticationPolicy(callback=get_principals))
-    config.set_authorization_policy(ACLAuthorizationPolicy())
-
-    config.registry['cubicweb.config'] = cwconfig
-    config.registry['cubicweb.repository'] = repo = cwconfig.repository()
-    config.registry['cubicweb.registry'] = repo.vreg
-
-    repo.system_source.add_authentifier(authplugin.DirectAuthentifier())
-
-    config.add_request_method(
-        _cw_session, name='cw_session', property=True, reify=True)
-    config.add_request_method(
-        _cw_cnx, name='cw_cnx', property=True, reify=True)
-    config.add_request_method(
-        _cw_request, name='cw_request', property=True, reify=True)
-
-    config.add_route('login', '/login')
-    config.add_view(login, route_name='login')
-
-    config.add_route('hello', '/hello')
-    config.add_view(hello_world, route_name='hello')
-
-    config.include('pyramid_cubicweb.handler')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyramid_cubicweb/bwcompat.py	Thu Jul 31 17:48:32 2014 +0200
@@ -0,0 +1,123 @@
+from pyramid import security
+from pyramid.httpexceptions import HTTPSeeOther
+from pyramid import httpexceptions
+
+import cubicweb
+import cubicweb.web
+
+from cubicweb.web.application import CubicWebPublisher
+
+from cubicweb.web import LogOut, cors
+
+from pyramid_cubicweb.core import cw_to_pyramid
+
+
+class PyramidSessionHandler(object):
+    """A CW Session handler that rely on the pyramid API to fetch the needed
+    informations"""
+
+    def __init__(self, appli):
+        self.appli = appli
+
+    def get_session(self, req):
+        return req._request.cw_session
+
+    def logout(self, req, goto_url):
+        raise LogOut(url=goto_url)
+
+
+class CubicWebPyramidHandler(object):
+    def __init__(self, appli):
+        self.appli = appli
+
+    def __call__(self, request):
+        """
+        Handler that mimics what CubicWebPublisher.main_handle_request and
+        CubicWebPublisher.core_handle do
+        """
+
+        # XXX The main handler of CW forbid anonymous https connections
+        # I guess we can drop this "feature" but in doubt I leave this comment
+        # so we don't forget about it. (cdevienne)
+
+        req = request.cw_request
+        vreg = request.registry['cubicweb.registry']
+
+        try:
+            try:
+                with cw_to_pyramid(request):
+                    cors.process_request(req, vreg.config)
+                    ctrlid, rset = self.appli.url_resolver.process(req, req.path)
+
+                    try:
+                        controller = vreg['controllers'].select(
+                            ctrlid, req, appli=self.appli)
+                    except cubicweb.NoSelectableObject:
+                        raise httpexceptions.HTTPUnauthorized(
+                            req._('not authorized'))
+
+                    req.update_search_state()
+                    content = controller.publish(rset=rset)
+
+                    # XXX this auto-commit should be handled by the cw_request cleanup
+                    # or the pyramid transaction manager.
+                    # It is kept here to have the ValidationError handling bw
+                    # compatible
+                    if req.cnx:
+                        txuuid = req.cnx.commit()
+                        # commited = True
+                        if txuuid is not None:
+                            req.data['last_undoable_transaction'] = txuuid
+            except cors.CORSPreflight:
+                request.response.status_int = 200
+            except cubicweb.web.ValidationError as ex:
+                # XXX The validation_error_handler implementation is light, we
+                # should redo it better in cw_to_pyramid, so it can be properly
+                # handled when raised from a cubicweb view.
+                # BUT the real handling of validation errors should be done
+                # earlier in the controllers, not here. In the end, the
+                # ValidationError should never by handled here.
+                content = self.appli.validation_error_handler(req, ex)
+            except cubicweb.web.RemoteCallFailed as ex:
+                # XXX The default pyramid error handler (or one that we provide
+                # for this exception) should be enough
+                # content = self.appli.ajax_error_handler(req, ex)
+                raise
+
+            if content is not None:
+                request.response.body = content
+
+            # XXX CubicWebPyramidRequest.headers_out should
+            # access directly the pyramid response headers.
+            request.response.headers.clear()
+            for k, v in req.headers_out.getAllRawHeaders():
+                for item in v:
+                    request.response.headers.add(k, item)
+
+        except LogOut as ex:
+            # The actual 'logging out' logic should be in separated function
+            # that is accessible by the pyramid views
+            headers = security.forget(request)
+            raise HTTPSeeOther(ex.url, headers=headers)
+        # except AuthenticationError:
+        # XXX I don't think it makes sens to catch this ex here (cdevienne)
+
+        return request.response
+
+
+def includeme(config):
+    # Set up a defaut route to handle non-catched urls.
+    # This is to keep legacy compatibility for cubes that makes use of the
+    # cubicweb controllers.
+    cwconfig = config.registry['cubicweb.config']
+    repository = config.registry['cubicweb.repository']
+    cwappli = CubicWebPublisher(
+        repository, cwconfig,
+        session_handler_fact=PyramidSessionHandler)
+    handler = CubicWebPyramidHandler(cwappli)
+
+    config.registry['cubicweb.appli'] = cwappli
+    config.registry['cubicweb.handler'] = handler
+
+    config.add_route('catchall', pattern='*path')
+    config.add_view(handler, route_name='catchall')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyramid_cubicweb/core.py	Thu Jul 31 17:48:32 2014 +0200
@@ -0,0 +1,223 @@
+from contextlib import contextmanager
+from warnings import warn
+
+import rql
+
+from cubicweb.web.request import CubicWebRequestBase
+from cubicweb import repoapi
+
+import cubicweb
+import cubicweb.web
+
+from pyramid import security, httpexceptions
+from pyramid.httpexceptions import HTTPSeeOther
+
+from pyramid_cubicweb import authplugin
+
+import logging
+
+log = logging.getLogger(__name__)
+
+
+@contextmanager
+def cw_to_pyramid(request):
+    """Wrap a call to the cubicweb API.
+
+    All CW exceptions will be transformed into their pyramid equivalent.
+    When needed, some CW reponse bits may be converted too (mainly headers)"""
+    try:
+        yield
+    except cubicweb.web.Redirect as ex:
+        assert 300 <= ex.status < 400
+        raise httpexceptions.status_map[ex.status](ex.location)
+    except cubicweb.web.StatusResponse as ex:
+        warn('[3.16] StatusResponse is deprecated use req.status_out',
+             DeprecationWarning, stacklevel=2)
+        request.body = ex.content
+        request.status_int = ex.status
+    except cubicweb.web.Unauthorized as ex:
+        raise httpexceptions.HTTPForbidden(
+            request.cw_request._(
+                'You\'re not authorized to access this page. '
+                'If you think you should, please contact the site '
+                'administrator.'))
+    except cubicweb.web.Forbidden:
+        raise httpexceptions.HTTPForbidden(
+            request.cw_request._(
+                'This action is forbidden. '
+                'If you think it should be allowed, please contact the site '
+                'administrator.'))
+    except (rql.BadRQLQuery, cubicweb.web.RequestError) as ex:
+        raise
+
+
+class CubicWebPyramidRequest(CubicWebRequestBase):
+    def __init__(self, request):
+        self._request = request
+
+        self.path = request.upath_info
+
+        vreg = request.registry['cubicweb.appli'].vreg
+        https = request.scheme == 'https'
+
+        post = request.params
+        headers_in = request.headers
+
+        super(CubicWebPyramidRequest, self).__init__(vreg, https, post,
+                                                     headers=headers_in)
+
+    def is_secure(self):
+        return self._request.scheme == 'https'
+
+    def relative_path(self, includeparams=True):
+        path = self._request.path[1:]
+        if includeparams and self._request.query_string:
+            return '%s?%s' % (path, self._request.query_string)
+        return path
+
+    def instance_uri(self):
+        return self._request.application_url
+
+    def get_full_path(self):
+        path = self._request.path
+        if self._request.query_string:
+            return '%s?%s' % (path, self._request.query_string)
+        return path
+
+    def http_method(self):
+        return self._request.method
+
+    def _set_status_out(self, value):
+        self._request.response.status_int = value
+
+    def _get_status_out(self):
+        return self._request.response.status_int
+
+    status_out = property(_get_status_out, _set_status_out)
+
+
+def render_view(request, vid, **kwargs):
+    vreg = request.registry['cubicweb.registry']
+    # XXX The select() function could, know how to handle a pyramid
+    # request, and feed it directly to the views that supports it.
+    # On the other hand, we could refine the View concept and decide it works
+    # with a cnx, and never with a WebRequest
+
+    with cw_to_pyramid(request):
+        view = vreg['views'].select(vid, request.cw_request, **kwargs)
+        view.set_stream()
+        view.render()
+        return view._stream.getvalue()
+
+
+def login(request):
+    repo = request.registry['cubicweb.repository']
+
+    response = request.response
+    user_eid = None
+
+    if '__login' in request.params:
+        login = request.params['__login']
+        password = request.params['__password']
+
+        try:
+            with repo.internal_cnx() as cnx:
+                user = repo.authenticate_user(cnx, login, password=password)
+                user_eid = user.eid
+        except cubicweb.AuthenticationError:
+            raise
+
+    if user_eid is not None:
+        headers = security.remember(request, user_eid)
+
+        raise HTTPSeeOther(
+            request.params.get('postlogin_path', '/'),
+            headers=headers)
+
+        response.headerlist.extend(headers)
+
+    response.text = render_view(request, 'login')
+    return response
+
+
+def _cw_cnx(request):
+    cnx = repoapi.ClientConnection(request.cw_session)
+
+    def cleanup(request):
+        if request.exception is not None:
+            cnx.rollback()
+        else:
+            cnx.commit()
+        cnx.__exit__(None, None, None)
+
+    request.add_finished_callback(cleanup)
+    cnx.__enter__()
+    return cnx
+
+
+def _cw_close_session(request):
+    request.cw_session.close()
+
+
+def _cw_session(request):
+    """Obtains a cw session from a pyramid request"""
+    repo = request.registry['cubicweb.repository']
+    config = request.registry['cubicweb.config']
+
+    if not request.authenticated_userid:
+        login, password = config.anonymous_user()
+        sessionid = repo.connect(login, password=password)
+        session = repo._sessions[sessionid]
+        request.add_finished_callback(_cw_close_session)
+    else:
+        session = request._cw_cached_session
+
+    # XXX Ideally we store the cw session data in the pyramid session.
+    # BUT some data in the cw session data dictionnary makes pyramid fail.
+    session.data = request.session
+
+    return session
+
+
+def _cw_request(request):
+    req = CubicWebPyramidRequest(request)
+    req.set_cnx(request.cw_cnx)
+    return req
+
+
+def get_principals(login, request):
+    repo = request.registry['cubicweb.repository']
+
+    try:
+        sessionid = repo.connect(
+            str(login), __pyramid_directauth=authplugin.EXT_TOKEN)
+        session = repo._sessions[sessionid]
+        request._cw_cached_session = session
+        request.add_finished_callback(_cw_close_session)
+    except:
+        log.exception("Failed")
+        raise
+
+    return session.user.groups
+
+
+def hello_world(request):
+    request.response.text = \
+        u"<html><body>Hello %s</body></html>" % request.cw_cnx.user.login
+    return request.response
+
+
+def includeme(config):
+    repo = config.registry['cubicweb.repository']
+
+    repo.system_source.add_authentifier(authplugin.DirectAuthentifier())
+
+    config.add_request_method(
+        _cw_session, name='cw_session', property=True, reify=True)
+    config.add_request_method(
+        _cw_cnx, name='cw_cnx', property=True, reify=True)
+    config.add_request_method(
+        _cw_request, name='cw_request', property=True, reify=True)
+
+    config.add_route('login', '/login')
+    config.add_view(login, route_name='login')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyramid_cubicweb/defaults.py	Thu Jul 31 17:48:32 2014 +0200
@@ -0,0 +1,16 @@
+from pyramid.authentication import SessionAuthenticationPolicy
+from pyramid.authorization import ACLAuthorizationPolicy
+from pyramid.session import SignedCookieSessionFactory
+
+from pyramid_cubicweb.core import get_principals
+
+
+def includeme(config):
+    config.set_session_factory(
+        SignedCookieSessionFactory(
+            secret=config.registry.settings['session.secret']
+        ))
+
+    config.set_authentication_policy(
+        SessionAuthenticationPolicy(callback=get_principals))
+    config.set_authorization_policy(ACLAuthorizationPolicy())
--- a/pyramid_cubicweb/handler.py	Tue Jul 22 23:46:09 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-from pyramid import security
-from pyramid.httpexceptions import HTTPSeeOther
-from pyramid import httpexceptions
-
-import cubicweb
-import cubicweb.web
-
-from cubicweb.web.application import CubicWebPublisher
-
-from cubicweb.web import LogOut, cors
-
-from pyramid_cubicweb import cw_to_pyramid
-
-
-class PyramidSessionHandler(object):
-    """A CW Session handler that rely on the pyramid API to fetch the needed
-    informations"""
-
-    def __init__(self, appli):
-        self.appli = appli
-
-    def get_session(self, req):
-        return req._request.cw_session
-
-    def logout(self, req, goto_url):
-        raise LogOut(url=goto_url)
-
-
-class CubicWebPyramidHandler(object):
-    def __init__(self, appli):
-        self.appli = appli
-
-    def __call__(self, request):
-        """
-        Handler that mimics what CubicWebPublisher.main_handle_request and
-        CubicWebPublisher.core_handle do
-        """
-
-        # XXX The main handler of CW forbid anonymous https connections
-        # I guess we can drop this "feature" but in doubt I leave this comment
-        # so we don't forget about it. (cdevienne)
-
-        req = request.cw_request
-        vreg = request.registry['cubicweb.registry']
-
-        try:
-            try:
-                with cw_to_pyramid(request):
-                    cors.process_request(req, vreg.config)
-                    ctrlid, rset = self.appli.url_resolver.process(req, req.path)
-
-                    try:
-                        controller = vreg['controllers'].select(
-                            ctrlid, req, appli=self.appli)
-                    except cubicweb.NoSelectableObject:
-                        raise httpexceptions.HTTPUnauthorized(
-                            req._('not authorized'))
-
-                    req.update_search_state()
-                    content = controller.publish(rset=rset)
-
-                    # XXX this auto-commit should be handled by the cw_request cleanup
-                    # or the pyramid transaction manager.
-                    # It is kept here to have the ValidationError handling bw
-                    # compatible
-                    if req.cnx:
-                        txuuid = req.cnx.commit()
-                        # commited = True
-                        if txuuid is not None:
-                            req.data['last_undoable_transaction'] = txuuid
-            except cors.CORSPreflight:
-                request.response.status_int = 200
-            except cubicweb.web.ValidationError as ex:
-                # XXX The validation_error_handler implementation is light, we
-                # should redo it better in cw_to_pyramid, so it can be properly
-                # handled when raised from a cubicweb view.
-                # BUT the real handling of validation errors should be done
-                # earlier in the controllers, not here. In the end, the
-                # ValidationError should never by handled here.
-                content = self.appli.validation_error_handler(req, ex)
-            except cubicweb.web.RemoteCallFailed as ex:
-                # XXX The default pyramid error handler (or one that we provide
-                # for this exception) should be enough
-                # content = self.appli.ajax_error_handler(req, ex)
-                raise
-
-            if content is not None:
-                request.response.body = content
-
-            # XXX CubicWebPyramidRequest.headers_out should
-            # access directly the pyramid response headers.
-            request.response.headers.clear()
-            for k, v in req.headers_out.getAllRawHeaders():
-                for item in v:
-                    request.response.headers.add(k, item)
-
-        except LogOut as ex:
-            # The actual 'logging out' logic should be in separated function
-            # that is accessible by the pyramid views
-            headers = security.forget(request)
-            raise HTTPSeeOther(ex.url, headers=headers)
-        # except AuthenticationError:
-        # XXX I don't think it makes sens to catch this ex here (cdevienne)
-
-        return request.response
-
-
-def includeme(config):
-    # Set up a defaut route to handle non-catched urls.
-    # This is to keep legacy compatibility for cubes that makes use of the
-    # cubicweb controllers.
-    cwconfig = config.registry['cubicweb.config']
-    repository = config.registry['cubicweb.repository']
-    cwappli = CubicWebPublisher(
-        repository, cwconfig,
-        session_handler_fact=PyramidSessionHandler)
-    handler = CubicWebPyramidHandler(cwappli)
-
-    config.registry['cubicweb.appli'] = cwappli
-    config.registry['cubicweb.handler'] = handler
-
-    config.add_route('catchall', pattern='*path')
-    config.add_view(handler, route_name='catchall')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyramid_cubicweb/init_instance.py	Thu Jul 31 17:48:32 2014 +0200
@@ -0,0 +1,10 @@
+from cubicweb.cwconfig import CubicWebConfiguration
+
+
+def includeme(config):
+    appid = config.registry.settings['cubicweb.instance']
+    cwconfig = CubicWebConfiguration.config_for(appid)
+
+    config.registry['cubicweb.config'] = cwconfig
+    config.registry['cubicweb.repository'] = repo = cwconfig.repository()
+    config.registry['cubicweb.registry'] = repo.vreg
--- a/sampleapp/development.ini	Tue Jul 22 23:46:09 2014 +0200
+++ b/sampleapp/development.ini	Thu Jul 31 17:48:32 2014 +0200
@@ -13,7 +13,6 @@
 pyramid.default_locale_name = en
 pyramid.includes = 
     pyramid_debugtoolbar
-    pyramid_cubicweb
 
 cubicweb.instance = test
 
--- a/sampleapp/sampleapp/__init__.py	Tue Jul 22 23:46:09 2014 +0200
+++ b/sampleapp/sampleapp/__init__.py	Thu Jul 31 17:48:32 2014 +0200
@@ -5,6 +5,10 @@
     """ This function returns a Pyramid WSGI application.
     """
     config = Configurator(settings=settings)
+    config.include('pyramid_cubicweb.init_instance')
+    config.include('pyramid_cubicweb.defaults')
+    config.include('pyramid_cubicweb.core')
+    config.include('pyramid_cubicweb.bwcompat')
 #    config.add_static_view('static', 'static', cache_max_age=3600)
 #    config.add_route('home', '/')
 #    config.scan()