async def test_takewhile(assert_run, event_loop):
    with event_loop.assert_cleanup():
        xs = (stream.range(1, 10) | add_resource.pipe(1)
              | pipe.takewhile(lambda x: x < 4))
        await assert_run(xs, [1, 2, 3])

    async def afunc(x):
        await asyncio.sleep(1)
        return x < 4

    with event_loop.assert_cleanup():
        xs = stream.range(1, 10) | add_resource.pipe(1) | pipe.takewhile(afunc)
        await assert_run(xs, [1, 2, 3])
        assert event_loop.steps == [1] * 5
Beispiel #2
0
async def euclidean_norm_handler(reader, writer):

    # Define lambdas
    strip =        lambda x: x.decode().strip()
    nonempty =     lambda x: x != ''
    square =       lambda x: x ** 2
    write_cursor = lambda x: writer.write(b'> ')
    square_root =  lambda x: x ** 0.5

    # Create awaitable
    handle_request = (
        stream.iterate(reader)
        | pipe.print('string: {}')
        | pipe.map(strip)
        | pipe.takewhile(nonempty)
        | pipe.map(float)
        | pipe.map(square)
        | pipe.print('square: {:.2f}')
        | pipe.action(write_cursor)
        | pipe.accumulate(initializer=0)
        | pipe.map(square_root)
        | pipe.print('norm -> {:.2f}')
    )

    # Loop over norm computations
    while not reader.at_eof():
        writer.write(INSTRUCTIONS.encode())
        try:
            result = await handle_request
        except ValueError:
            writer.write(ERROR.encode())
        else:
            writer.write(RESULT.format(result).encode())
Beispiel #3
0
async def euclidean_norm_handler(reader, writer):

    # Define lambdas
    strip = lambda x: x.decode().strip()
    nonempty = lambda x: x != ''
    square = lambda x: x**2
    write_cursor = lambda x: writer.write(b'> ')
    square_root = lambda x: x**0.5

    # Create awaitable
    handle_request = (stream.iterate(reader)
                      | pipe.print('string: {}')
                      | pipe.map(strip)
                      | pipe.takewhile(nonempty)
                      | pipe.map(float)
                      | pipe.map(square)
                      | pipe.print('square: {:.2f}')
                      | pipe.action(write_cursor)
                      | pipe.accumulate(initializer=0)
                      | pipe.map(square_root)
                      | pipe.print('norm -> {:.2f}'))

    # Loop over norm computations
    while not reader.at_eof():
        writer.write(INSTRUCTIONS.encode())
        try:
            result = await handle_request
        except ValueError:
            writer.write(ERROR.encode())
        else:
            writer.write(RESULT.format(result).encode())
    def _stream_config_updates(
            sensor: TinkerforgeSensor) -> AsyncGenerator[dict[str, Any], None]:
        """
        Tries to fetch a config from the database. It also listens to 'nodes/tinkerforge/$UID/update' for new configs
        from the database.
        Parameters
        ----------
        sensor: TinkerforgeSensor
            The brick or bricklet for which to fetch a config from the database

        Returns
        -------
        AsyncGenerator of dict
            A dict containing the configuration of the device
        """
        return stream.chain(
            stream.call(
                call_safely,
                "db_tinkerforge_sensors/get_config",
                "db_tinkerforge_sensors/status_update",
                sensor.device.uid,
            )
            | pipe.takewhile(lambda config: config is not None),
            stream.iterate(
                event_bus.subscribe(
                    f"nodes/tinkerforge/{sensor.device.uid}/update")),
        )
Beispiel #5
0
    def stream_data(self) -> AsyncGenerator[DataEvent, None]:
        """
        Generate the initial configuration of the sensor, configure it, and finally stream the data from the sensor.
        If there is a configuration update, reconfigure the sensor and start streaming again.
        Returns
        -------
        AsyncGenerator of DataEvent
            The data from the device
        """
        # Generates the first configuration
        # Query the database and if it does not have a config for the sensor, wait until there is one

        data_stream = (
            stream.chain(
                stream.call(
                    call_safely, "db_labnode_sensors/get_config", "db_labnode_sensors/status_update", self.__uuid
                )
                | pipe.takewhile(lambda config: config is not None),
                stream.iterate(event_bus.subscribe(f"nodes/by_uuid/{self.__uuid}/update")),
            )
            | pipe.action(
                lambda config: logging.getLogger(__name__).info(
                    "Got new configuration for: %s",
                    self._device,
                )
            )
            | pipe.map(self._create_config)
            | pipe.switchmap(
                lambda config: stream.empty()
                if config is None or not config["enabled"]
                else (self._configure_and_stream(config))
            )
        )

        return data_stream
Beispiel #6
0
async def test_takewhile(assert_run, event_loop):
    with event_loop.assert_cleanup():
        xs = (stream.range(1, 10)
              | add_resource.pipe(1)
              | pipe.takewhile(lambda x: x < 4))
        await assert_run(xs, [1, 2, 3])

    async def afunc(x):
        await asyncio.sleep(1)
        return x < 4

    with event_loop.assert_cleanup():
        xs = (stream.range(1, 10)
              | add_resource.pipe(1)
              | pipe.takewhile(afunc))
        await assert_run(xs, [1, 2, 3])
        assert event_loop.steps == [1]*5
async def run(
    subscription_kinds: List[SubscriptionKind],
    topic: str,
    begin_timestamp=None,
    interval_sec=None,
    num_msgs=10,
    on_message: Optional[Callable[[Any], Any]] = None,
):
    def log_message(msg):
        if not isinstance(msg, list):
            #LOGGER.info("Status: %s", json.dumps(msg))
            pass
        else:
            LOGGER.debug("Received message: %s", json.dumps(msg))

    def maybe_callback(m):
        if on_message:
            on_message(m)

    # the continuous version takes messages up until a time point
    if interval_sec:
        async with KrakenClient() as client:
            for kind in subscription_kinds:
                await subscribe(client, kind, PAIRS, SUBSCRIPTION_DEPTH)
            await (client.stream(reconnect_count=WEBSOCKET_RECONNECT_COUNT)
                   | pipe.action(log_message)
                   | pipe.filter(lambda msg: isinstance(msg, list))
                   | pipe.map(json.dumps)
                   #| pipe.print()
                   | pipe.takewhile(
                       lambda x: time.time() - begin_timestamp < interval_sec)
                   | pipe.action(maybe_callback))
            client.disconnect()

    # the discrete version takes 100 distinct messages
    else:
        async with KrakenClient() as client:
            for kind in subscription_kinds:
                await subscribe(client, kind, PAIRS, SUBSCRIPTION_DEPTH)
            await (client.stream(reconnect_count=WEBSOCKET_RECONNECT_COUNT)
                   | pipe.action(log_message)
                   | pipe.filter(lambda msg: isinstance(msg, list))
                   | pipe.map(json.dumps)
                   #| pipe.print()
                   | pipe.take(num_msgs)
                   | pipe.action(maybe_callback))
            print("disconnecting")
            client.disconnect()