Skip to main content

Observable operations for async generators

Project description

RxIter

RxIter brings observables to python in a bare bones way by using async generators and the async await syntax. In this paradigm observables are analogous to async iterables, and observers analogous to async iterators.

It implements 2 fundamental observable operations, which may be familar to those who know rxpy.

Operations

Share

share allows multiple "observers" to subscribe the same observable

import asyncio
from rxiter import share

async def main():

    @share
    async def count():   # a counting "observable"
        v = 0
        while True:
            print(f"returning value {v}")
            yield v
            await asyncio.sleep(1)
            v += 1

    async def count_squared(obs):  # a counting "observer"
        async for v in obs: 
            print(f"{v} squared is {v**2}")

    square_task_subscription = asyncio.Task(count_squared(count()))  # subscribe

    async def count_cubed(obs):  # another counting "observer
        async for v in obs:
            print(f"{v} cubed is {v**3}")

    cube_task_subscription = asyncio.Task(count_cubed(count())) # subscribe

    await asyncio.gather(square_task_subscription, cube_task_subscription)

asyncio.run(main())

The output on this code would be:

returning value 0
0 squared is 0
0 cubed is 0
returning value 1
1 squared is 1
1 cubed is 1
returning value 2
2 squared is 4
2 cubed is 8
etc...

Repeat

repeat takes a iterator, and "records" it's outputed values so that it is turned into an iterable, and can be "listened" back multiple times.

Example

Polling an API

Suppose we have a API endpoint that we would like to poll to get the most up to date weather in Toronto. We could set up an observable as follows:

async get_toronto_weather():
  while True:
    yield await poll_my_api("api_enpoint")
    await asyncio.sleep(60 * 30)  # wait 30 minutes

If you want to "pipe" this to do further operations, like extract some specific content from the dict returned by get_toronto_weather()

async get_temperature():
  async for v in poll_api():
    yield v["temperature"]

Now if we want to have multiple listeners, that is where the share comes into the picture. We can do

@share
async get_toronto_weather():
  while True:
    yield await poll_my_api("api_enpoint")
    await asyncio.sleep(60 * 30)  # wait 30 minutes

async get_temperature():
  async for v in get_toronto_weather():
    yield v["temperature"]

async get_humidity():
  async for v in get_toronto_weather():
    yield v["humidity"]

asyncio.Task(get_temperature())
asyncio.Task(get_humidity())

and get_toronto_weather() will only run once for both get_temperature() and get_humidity()

Realtime stdout on python subprocess

Installation

pip install rxiter

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rxiter-0.0.7.tar.gz (3.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rxiter-0.0.7-py3-none-any.whl (3.9 kB view details)

Uploaded Python 3

File details

Details for the file rxiter-0.0.7.tar.gz.

File metadata

  • Download URL: rxiter-0.0.7.tar.gz
  • Upload date:
  • Size: 3.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.13

File hashes

Hashes for rxiter-0.0.7.tar.gz
Algorithm Hash digest
SHA256 bb1aecd0f6c32c4d86425a5c2c0a362adc65d7da0a270a21b67e3adef7688107
MD5 6be0c125c42e6e1ac415b206c4b11558
BLAKE2b-256 47c9f1ed2c90623cf98716b7f9542bcfc7a0c2be4843c072d3fe90b42f8a3f5f

See more details on using hashes here.

File details

Details for the file rxiter-0.0.7-py3-none-any.whl.

File metadata

  • Download URL: rxiter-0.0.7-py3-none-any.whl
  • Upload date:
  • Size: 3.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.13

File hashes

Hashes for rxiter-0.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 49bc9b72db9eeb73f379daedd29ab82058bf3e27ab6584bdb8862d6cc5d47be3
MD5 5ad7f469e147d2f0d7cb2aa5c12e6c0e
BLAKE2b-256 83cd4251ad849d0628241610d3be26797ea3cec40d5f026aabeb434c1abb6b09

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page