Ejemplo n.º 1
0
def test_request(request, dbsession, registry) -> IRequest:
    """Create a dummy HTTP request object which can be used to obtain services and adapters.

    This fixture gives you an instance of :py:class:`pyramid.testing.DummyRequest` object which looks like a request as it would have arrived through HTTP interface. It has request-like properties, namely

    * registry

    * dbsession

    ... and thus can be used to access services, utilies and such which normally would take a request as an argument.

    Example:

    .. code-block:: python

        from websauna.system.user.utils import get_login_service


        def test_order(dbsession, test_request):
            service = get_login_service(test_request)

    The ``request.tm`` is bound to thread-local ``transaction.mananger``.
    """
    request = make_routable_request(dbsession, registry)
    request.tm = transaction.manager
    return request
Ejemplo n.º 2
0
    def on_task_init(self, task_id, task):
        """This method is called before a task is executed.

        Pass our request context to the task.

        http://docs.celeryproject.org/en/latest/userguide/tasks.html#context

        .. note ::

            The same request object is recycled over and over again. Pyramid does not have correctly mechanisms for having retryable request factory.

        """

        # TODO: How Celery handles retries?

        # We must not have on-going transaction when worker spawns a task
        # - otherwise it means init code has left transaction open
        ensure_transactionless(
            "Thread local TX was ongoing when Celery fired up a new task {}: {}"
            .format(task_id, task))

        # When using celery groups, the request is not available, we set it here.
        if not hasattr(self, 'request'):
            self._set_request()

        # Each tasks gets a new request with its own transaction manager and dbsession
        request = make_routable_request(dbsession=None,
                                        registry=self.request.registry)

        task.request.update(request=request)
Ejemplo n.º 3
0
def test_request(request, dbsession, registry) -> IRequest:
    """Create a dummy HTTP request object which can be used to obtain services and adapters.

    This fixture gives you an instance of :py:class:`pyramid.testing.DummyRequest` object which looks like a request as it would have arrived through HTTP interface. It has request-like properties, namely

    * registry

    * dbsession

    ... and thus can be used to access services, utilies and such which normally would take a request as an argument.

    Example:

    .. code-block:: python

        from websauna.system.user.utils import get_login_service


        def test_order(dbsession, test_request):
            service = get_login_service(test_request)

    The ``request.tm`` is bound to thread-local ``transaction.mananger``.
    """
    request = make_routable_request(dbsession, registry)
    request.tm = transaction.manager
    return request
Ejemplo n.º 4
0
    def on_task_init(self, task_id, task):
        """This method is called before a task is executed.

        Pass our request context to the task.

        http://docs.celeryproject.org/en/latest/userguide/tasks.html#context

        .. note ::

            The same request object is recycled over and over again. Pyramid does not have correctly mechanisms for having retryable request factory.

        """

        # TODO: How Celery handles retries?

        # We must not have on-going transaction when worker spawns a task
        # - otherwise it means init code has left transaction open
        ensure_transactionless(
            "Thread local TX was ongoing when Celery fired up a new task {}: {}"
            .format(task_id, task))

        # Kill thread-local transaction manager, so we minimize issues
        # with different Celery threading models.
        # Always use request.tm instead.
        import transaction
        transaction.manager = None

        # Each tasks gets a new request with its own transaction manager and dbsession
        request = make_routable_request(dbsession=None,
                                        registry=self.request.registry)
        task.request.update(request=request)
Ejemplo n.º 5
0
def init_websauna_script_env(config_uri: str) -> dict:
    """Initialize Websauna WSGI application for a IPython notebook.

    :param config_uri: Path to config INI file

    :return: Dictionary of shell variables
    """

    options = {"sanity_check": False}
    app = get_wsgi_app(config_uri, defaults=options)

    initializer = initializer_from_app(app)

    registry = initializer.config.registry
    dbsession = create_dbsession(registry)

    pyramid_env = scripting.prepare(registry=app.initializer.config.registry)
    pyramid_env["app"] = app
    pyramid_env["initializer"] = initializer

    # Websauna specific
    # Set up the request with websauna.site_url setting as the base URL
    request = make_routable_request(dbsession, registry)
    pyramid_env["request"] = request
    pyramid_env["dbsession"] = dbsession

    return pyramid_env
Ejemplo n.º 6
0
    def on_task_init(self, task_id, task):
        """This method is called before a task is executed.

        Pass our request context to the task.

        http://docs.celeryproject.org/en/latest/userguide/tasks.html#context

        .. note ::

            The same request object is recycled over and over again. Pyramid does not have correctly mechanisms for having retryable request factory.

        """

        # TODO: How Celery handles retries?

        # We must not have on-going transaction when worker spawns a task
        # - otherwise it means init code has left transaction open
        ensure_transactionless("Thread local TX was ongoing when Celery fired up a new task {}: {}".format(task_id, task))

        # Kill thread-local transaction manager, so we minimize issues
        # with different Celery threading models.
        # Always use request.tm instead.
        import transaction
        transaction.manager = None

        # Each tasks gets a new request with its own transaction manager and dbsession
        request = make_routable_request(dbsession=None, registry=self.request.registry)
        task.request.update(request=request)
Ejemplo n.º 7
0
    def get_traverse_endpoint_context(self, router: Router,
                                      route: Route) -> Resource:
        """Get root object for a traversable route.

        E.g. resolve /container/* to a SampleContainer context.
        """

        # chop off last part /container/*traverse'
        start_path = "/".join(route.pattern.split("/")[0:-2]) + "/"

        # create a new request to traverse based on detected route pattern
        # dbsession must be passed here to prevent creating new dbsession
        sample_request = make_routable_request(
            dbsession=self.request.dbsession,
            registry=self.request.registry,
            path=start_path)

        root = route.factory(sample_request)

        traverser = self.request.registry.queryAdapter(root, ITraverser)
        # We are about to traverse and find a context
        if traverser is None:
            traverser = ResourceTreeTraverser(root)

        # {'virtual_root': <websauna.tests.sitemapsamples.SampleContainer object at 0x104656f98>, 'traversed': (), 'root': <websauna.tests.sitemapsamples.SampleContainer object at 0x104656f98>, 'virtual_root_path': (), 'view_name': 'container', 'subpath': (), 'context': <websauna.tests.sitemapsamples.SampleContainer object at 0x104656f98>}
        tdict = traverser(sample_request)
        context = tdict["context"]
        return context
Ejemplo n.º 8
0
def test_push_render_email(dbsession: Session, registry, user_id):
    """Create a new activity and generates rendered email notification.."""

    # Create a request with route_url()
    request = make_routable_request(dbsession, registry)

    # Reset test mailer at the beginnign of the test
    mailer = get_mailer(registry)

    # Check we got a right type of mailer for our unit test
    assert isinstance(mailer, DummyMailer)
    assert len(mailer.outbox) == 0

    with transaction.manager:
        u = dbsession.query(User).get(user_id)

        # Create an activity
        a = create_activity(request, "demo_msg", {"text": "foobar"}, uuid4(), u)

        # Push it through notification channel
        channel = Email(request)
        channel.push_notification(a)

        # DummyMailer updates it outbox immediately, no need to wait transaction.commit
        assert len(mailer.outbox) == 1
Ejemplo n.º 9
0
def init_websauna_script_env(config_uri: str) -> dict:
    """Initialize Websauna WSGI application for a IPython notebook.

    :param config_uri: Path to config INI file

    :return: Dictionary of shell variables
    """

    monkey_patch_paster_config_parser()

    setup_logging(config_uri)

    bootstrap_env = bootstrap(config_uri, options=dict(sanity_check=False))
    app = bootstrap_env["app"]
    initializer = getattr(app, "initializer", None)
    assert initializer is not None, "Configuration did not yield to Websauna application with Initializer set up"

    registry = initializer.config.registry
    dbsession = create_dbsession(registry)

    pyramid_env = scripting.prepare(registry=app.initializer.config.registry)
    pyramid_env["app"] = app
    pyramid_env["initializer"] = initializer

    # Websauna specific
    # Set up the request with websauna.site_url setting as the base URL
    request = make_routable_request(dbsession, registry)
    pyramid_env["request"] = request
    pyramid_env["dbsession"] = dbsession

    return pyramid_env
Ejemplo n.º 10
0
def init_websauna(config_uri: str,
                  sanity_check: bool = False,
                  console_app: bool = False,
                  extra_options: dict = None) -> Request:
    """Initialize Websauna WSGI application for a command line oriented script.

    Example:

    .. code-block:: python

        import sys
        from websauna.system.devop.cmdline import init_websauna

        config_uri = sys.argv[1]
        request = init_websauna(config_uri)

    :param config_uri: Path to config INI file

    :param sanity_check: Perform database sanity check on start

    :param console_app: Set true to setup console-mode logging. See :func:`setup_console_logging`

    :param extra_options: Passed through bootstrap() and is available as :attr:`websauna.system.Initializer.global_options`.

    :return: Faux Request object pointing to a site root, having registry and every configured.
    """

    # Paster thinks we are a string
    if sanity_check:
        sanity_check = "true"
    else:
        sanity_check = "false"

    options = {"sanity_check": sanity_check}

    if extra_options:
        options.update(extra_options)

    app = get_wsgi_app(config_uri, defaults=options)
    initializer = initializer_from_app(app)

    registry = initializer.config.registry
    dbsession = create_dbsession(registry)

    # Set up the request with websauna.site_url setting as the base URL
    request = make_routable_request(dbsession, registry)

    # This exposes the app object for the integration tests e.g test_static_asset
    # TODO: Find a cleaner way to do this
    request.app = app

    return request
Ejemplo n.º 11
0
    def get_traverse_endpoint_context(self, router: Router, route: Route) -> Resource:
        """Get root object for a traversable route.

        E.g. resolve /container/* to a SampleContainer context.
        """

        # chop off last part /container/*traverse'
        start_path = "/".join(route.pattern.split("/")[0:-2]) + "/"
        sample_request = make_routable_request(path=start_path, registry=self.request.registry)

        root = route.factory(sample_request)

        traverser = self.request.registry.queryAdapter(root, ITraverser)
        # We are about to traverse and find a context
        if traverser is None:
            traverser = ResourceTreeTraverser(root)

        # {'virtual_root': <websauna.tests.sitemapsamples.SampleContainer object at 0x104656f98>, 'traversed': (), 'root': <websauna.tests.sitemapsamples.SampleContainer object at 0x104656f98>, 'virtual_root_path': (), 'view_name': 'container', 'subpath': (), 'context': <websauna.tests.sitemapsamples.SampleContainer object at 0x104656f98>}
        tdict = traverser(sample_request)
        context = tdict["context"]
        return context
Ejemplo n.º 12
0
def sitemap_request(sitemap_app):
    """Create a dummy request object useable for sitemap building tests."""
    return make_routable_request(dbsession=None, registry=sitemap_app.init.config.registry)