From d3b047263d3748250b3dfe4f460833f5ea8d5053 Mon Sep 17 00:00:00 2001 From: CoprDistGit Date: Fri, 5 May 2023 09:00:10 +0000 Subject: automatic import of python-aiocells --- .gitignore | 1 + python-aiocells.spec | 839 +++++++++++++++++++++++++++++++++++++++++++++++++++ sources | 1 + 3 files changed, 841 insertions(+) create mode 100644 python-aiocells.spec create mode 100644 sources diff --git a/.gitignore b/.gitignore index e69de29..9196678 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/aiocells-1.0.4.tar.gz diff --git a/python-aiocells.spec b/python-aiocells.spec new file mode 100644 index 0000000..6c4146d --- /dev/null +++ b/python-aiocells.spec @@ -0,0 +1,839 @@ +%global _empty_manifest_terminate_build 0 +Name: python-aiocells +Version: 1.0.4 +Release: 1 +Summary: A package for synchronous and asynchronous dependency graph computation +License: MIT +URL: https://github.com/isbjorntrading/aiocells +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/3a/d6/1062f97a9140c040f128f391138b2da94d7d681433713bf4b26b7e0e17d1/aiocells-1.0.4.tar.gz +BuildArch: noarch + +Requires: python3-click +Requires: python3-klogs + +%description +`aiocells` is a package that provides tools for synchronous and asynchronous +execution of nodes in a dependency graph. + +Contents: + + 1. [Examples](#examples) + 1. [Development Installation](#development-installation) + +## Examples + +### Hello world + +Here is the code for the [first demo](src/aiocells/demo_1.py). + +```python +#!/usr/bin/env python3 + +import aiocells + + +def hello_world(): + print("Hello, world!") + + +def main(): + graph = aiocells.DependencyGraph() + + # The node can be any callable, in this case a function. + graph.add_node(hello_world) + aiocells.compute_sequential(graph) +``` + +This is _synchronous_ graph computation. There is only one node in the graph. +It is a function that prints a message. Synchronous nodes must be `callable`. + +### Defining ordering constraints + +Here is [demo 4](src/aiocells/demo_4.py). It shows how edges between nodes +are defined: + + +```python +#!/usr/bin/env python3 + +import time + +import aiocells + + +def main(): + graph = aiocells.DependencyGraph() + + # 'add_node' always returns the node that has just been added, in this + # case the lambda functions. We will use this below to define precedence + # relationships + print_sleeping = graph.add_node(lambda: print("Sleeping...")) + sleep = graph.add_node(lambda: time.sleep(2)) + print_woke_up = graph.add_node(lambda: print("Woke up!")) + + print("Define the precedence relationships...") + graph.add_precedence(print_sleeping, sleep) + graph.add_precedence(sleep, print_woke_up) + + # Now, after we've defined the precedence relationships, we use the + # simplest computer to compute the graph. The nodes will be called in + # an order that is consistent with the precedence relationships. + # Specifically, the nodes are executed in topological order. + aiocells.compute_sequential(graph) +``` + +In this case, there are three nodes. After the nodes are added, we define +precedence relationships between them. When the graph is computed, it is +done so in a way that honours the precedence relationships. + +### Asynchronous nodes + +Below is the code for [demo_5](src/aiocells/demo_5.py). Note the use of +`asyncio.sleep`, `functools.partial` and `aiocells.async_compute_sequential`. + +```python +#!/usr/bin/env python3 + +import asyncio +from functools import partial + +import aiocells + +# This example demonstrates graph nodes that are coroutines. We use +# a different computer; one that know how to deal with coroutines. + + +def main(): + graph = aiocells.DependencyGraph() + + # First, we add a lambda function + before_sleep = graph.add_node(lambda: print("Sleeping...")) + + # Second, we create a coroutine function using functools.partial. This + # is the closest we can get to a lambda for an async function + sleep_2 = partial(asyncio.sleep, 2) + + # Finally, another lambda function + wake_up = graph.add_node(lambda: print("Woke up!")) + + # Here, 'sleep' will implicitly be added to the graph because it is + # part of the precedence relationship + graph.add_precedence(before_sleep, sleep_2) + graph.add_precedence(sleep_2, wake_up) + + # Here, we use the `async_compute_sequential`, which, like + # `compute_sequential`, call the nodes in a topologically correct sequence. + # However, whereas `compute_sequential` only supports vanilla callables, + # `async_compute_sequential` additionally supports coroutine functions, + # as defined by `inspect.iscoroutinefunction`. However, the execution is + # still sequential. Each coroutine function is executed using 'await' and + # must complete before the next node is executed. The function + # `async_compute_sequential` is a coroutine and must be awaited. Here, + # we simply pass it to `asyncio.run`. + asyncio.run(aiocells.async_compute_sequential(graph)) +``` + +### Concurrent computation + +[demo 6](src/aiocells/demo_6.py) is a an example of graph that _could_ be +computed concurrently but is not due to the use if `async_compute_sequential`. + +```python +import asyncio +from functools import partial + +import aiocells + + +def create_graph(stopwatch): + + graph = aiocells.DependencyGraph() + + # The method to start the stopwatch + start_stopwatch = stopwatch.start + + # Two sleeps. Note that they are asyncio.sleep + sleep_1 = partial(asyncio.sleep, 1) + sleep_2 = partial(asyncio.sleep, 2) + + # The method to stop the stopwatch + stop_stopwatch = stopwatch.stop + + # Start the stopwatch before the first sleep + graph.add_precedence(start_stopwatch, sleep_1) + # Stop the stopwatch after the first sleep + graph.add_precedence(sleep_1, stop_stopwatch) + + # Start the stopwatch before the second sleep + graph.add_precedence(start_stopwatch, sleep_2) + # Stop the stopwatch after the second sleep + graph.add_precedence(sleep_2, stop_stopwatch) + + # Note that there is no precedence relationship between the two + # sleeps. + return graph + + +def main(): + + stopwatch = aiocells.Stopwatch() + graph = create_graph(stopwatch) + # Even though the graph is a diamond (the sleeps do no depend on each + # other and _could_ be executed concurrenty, `async_compute_sequential` + # does not support concurrent execution. Thus, the execution time is + # about 3 seconds, the sum of the two sleeps. + print("Two async sleeps computed sequentially.") + print("Total time should take about 3 seconds...") + asyncio.run(aiocells.async_compute_sequential(graph)) + print("Computation with `async_compute_sequential` took" + f" {stopwatch.elapsed_time()}") +``` + +[demo_7](src/aiocells/demo_7.py) is the same graph as above but computed +concurrently with `async_compute_concurrent`. + +```python +#!/usr/bin/env python3 + +import asyncio + +import aiocells +import aiocells.demo_6 as demo_6 + + +def main(): + stopwatch = aiocells.Stopwatch() + graph = demo_6.create_graph(stopwatch) + + # Here, we run the same graph as the previous demo but we use + # 'async_compute_concurrent' which will run the two sleeps concurrently. + # Thus, the execution time will be around 2 seconds, the maximum of + # the two sleeps. + + print("Running previous demo's graph concurrently.") + print("Total execution time should be about 2 seconds...") + asyncio.run(aiocells.async_compute_concurrent(graph)) + print("Computation with `async_compute_concurrent` took" + f" {stopwatch.elapsed_time()}") + +``` + +## Development Installation + +There is a `Makefile` in the repository. The default target will initialise +a virtual environment, install dependencies into that environment and then +test the code. It requires `Python 3.8`, `virtualenv` and `pip` to be +installed. If those are missing, it will print suggestions on how to address +the problem. + +```bash +$ make +``` + +### Activating the virtual environment and running the demos + +The default make target will generate a file called `activate_aiocells`. To +activate the virtual environment: + +```bash +$ source activate_aiocells +``` + +Once you've done that, you should have the following command available: + +```bash +$ aiocells demo-1 +``` + +### Tab completion + +`activate_aiocells` will enable tab completion for `aiocells`: + +```bash +$ aiocells +``` + +### Editable installation + +The package will be installed in the virutal environment using +`pip --editable`. This means that modifications to the code will be immediately +available. + +To test this, try modifying `src/aiocells/demo_1.py` to print a different +message. You should be able to immediately run the demo and see the new +message: +```bash +$ aiocells demo-1 +``` + + + + +%package -n python3-aiocells +Summary: A package for synchronous and asynchronous dependency graph computation +Provides: python-aiocells +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-aiocells +`aiocells` is a package that provides tools for synchronous and asynchronous +execution of nodes in a dependency graph. + +Contents: + + 1. [Examples](#examples) + 1. [Development Installation](#development-installation) + +## Examples + +### Hello world + +Here is the code for the [first demo](src/aiocells/demo_1.py). + +```python +#!/usr/bin/env python3 + +import aiocells + + +def hello_world(): + print("Hello, world!") + + +def main(): + graph = aiocells.DependencyGraph() + + # The node can be any callable, in this case a function. + graph.add_node(hello_world) + aiocells.compute_sequential(graph) +``` + +This is _synchronous_ graph computation. There is only one node in the graph. +It is a function that prints a message. Synchronous nodes must be `callable`. + +### Defining ordering constraints + +Here is [demo 4](src/aiocells/demo_4.py). It shows how edges between nodes +are defined: + + +```python +#!/usr/bin/env python3 + +import time + +import aiocells + + +def main(): + graph = aiocells.DependencyGraph() + + # 'add_node' always returns the node that has just been added, in this + # case the lambda functions. We will use this below to define precedence + # relationships + print_sleeping = graph.add_node(lambda: print("Sleeping...")) + sleep = graph.add_node(lambda: time.sleep(2)) + print_woke_up = graph.add_node(lambda: print("Woke up!")) + + print("Define the precedence relationships...") + graph.add_precedence(print_sleeping, sleep) + graph.add_precedence(sleep, print_woke_up) + + # Now, after we've defined the precedence relationships, we use the + # simplest computer to compute the graph. The nodes will be called in + # an order that is consistent with the precedence relationships. + # Specifically, the nodes are executed in topological order. + aiocells.compute_sequential(graph) +``` + +In this case, there are three nodes. After the nodes are added, we define +precedence relationships between them. When the graph is computed, it is +done so in a way that honours the precedence relationships. + +### Asynchronous nodes + +Below is the code for [demo_5](src/aiocells/demo_5.py). Note the use of +`asyncio.sleep`, `functools.partial` and `aiocells.async_compute_sequential`. + +```python +#!/usr/bin/env python3 + +import asyncio +from functools import partial + +import aiocells + +# This example demonstrates graph nodes that are coroutines. We use +# a different computer; one that know how to deal with coroutines. + + +def main(): + graph = aiocells.DependencyGraph() + + # First, we add a lambda function + before_sleep = graph.add_node(lambda: print("Sleeping...")) + + # Second, we create a coroutine function using functools.partial. This + # is the closest we can get to a lambda for an async function + sleep_2 = partial(asyncio.sleep, 2) + + # Finally, another lambda function + wake_up = graph.add_node(lambda: print("Woke up!")) + + # Here, 'sleep' will implicitly be added to the graph because it is + # part of the precedence relationship + graph.add_precedence(before_sleep, sleep_2) + graph.add_precedence(sleep_2, wake_up) + + # Here, we use the `async_compute_sequential`, which, like + # `compute_sequential`, call the nodes in a topologically correct sequence. + # However, whereas `compute_sequential` only supports vanilla callables, + # `async_compute_sequential` additionally supports coroutine functions, + # as defined by `inspect.iscoroutinefunction`. However, the execution is + # still sequential. Each coroutine function is executed using 'await' and + # must complete before the next node is executed. The function + # `async_compute_sequential` is a coroutine and must be awaited. Here, + # we simply pass it to `asyncio.run`. + asyncio.run(aiocells.async_compute_sequential(graph)) +``` + +### Concurrent computation + +[demo 6](src/aiocells/demo_6.py) is a an example of graph that _could_ be +computed concurrently but is not due to the use if `async_compute_sequential`. + +```python +import asyncio +from functools import partial + +import aiocells + + +def create_graph(stopwatch): + + graph = aiocells.DependencyGraph() + + # The method to start the stopwatch + start_stopwatch = stopwatch.start + + # Two sleeps. Note that they are asyncio.sleep + sleep_1 = partial(asyncio.sleep, 1) + sleep_2 = partial(asyncio.sleep, 2) + + # The method to stop the stopwatch + stop_stopwatch = stopwatch.stop + + # Start the stopwatch before the first sleep + graph.add_precedence(start_stopwatch, sleep_1) + # Stop the stopwatch after the first sleep + graph.add_precedence(sleep_1, stop_stopwatch) + + # Start the stopwatch before the second sleep + graph.add_precedence(start_stopwatch, sleep_2) + # Stop the stopwatch after the second sleep + graph.add_precedence(sleep_2, stop_stopwatch) + + # Note that there is no precedence relationship between the two + # sleeps. + return graph + + +def main(): + + stopwatch = aiocells.Stopwatch() + graph = create_graph(stopwatch) + # Even though the graph is a diamond (the sleeps do no depend on each + # other and _could_ be executed concurrenty, `async_compute_sequential` + # does not support concurrent execution. Thus, the execution time is + # about 3 seconds, the sum of the two sleeps. + print("Two async sleeps computed sequentially.") + print("Total time should take about 3 seconds...") + asyncio.run(aiocells.async_compute_sequential(graph)) + print("Computation with `async_compute_sequential` took" + f" {stopwatch.elapsed_time()}") +``` + +[demo_7](src/aiocells/demo_7.py) is the same graph as above but computed +concurrently with `async_compute_concurrent`. + +```python +#!/usr/bin/env python3 + +import asyncio + +import aiocells +import aiocells.demo_6 as demo_6 + + +def main(): + stopwatch = aiocells.Stopwatch() + graph = demo_6.create_graph(stopwatch) + + # Here, we run the same graph as the previous demo but we use + # 'async_compute_concurrent' which will run the two sleeps concurrently. + # Thus, the execution time will be around 2 seconds, the maximum of + # the two sleeps. + + print("Running previous demo's graph concurrently.") + print("Total execution time should be about 2 seconds...") + asyncio.run(aiocells.async_compute_concurrent(graph)) + print("Computation with `async_compute_concurrent` took" + f" {stopwatch.elapsed_time()}") + +``` + +## Development Installation + +There is a `Makefile` in the repository. The default target will initialise +a virtual environment, install dependencies into that environment and then +test the code. It requires `Python 3.8`, `virtualenv` and `pip` to be +installed. If those are missing, it will print suggestions on how to address +the problem. + +```bash +$ make +``` + +### Activating the virtual environment and running the demos + +The default make target will generate a file called `activate_aiocells`. To +activate the virtual environment: + +```bash +$ source activate_aiocells +``` + +Once you've done that, you should have the following command available: + +```bash +$ aiocells demo-1 +``` + +### Tab completion + +`activate_aiocells` will enable tab completion for `aiocells`: + +```bash +$ aiocells +``` + +### Editable installation + +The package will be installed in the virutal environment using +`pip --editable`. This means that modifications to the code will be immediately +available. + +To test this, try modifying `src/aiocells/demo_1.py` to print a different +message. You should be able to immediately run the demo and see the new +message: +```bash +$ aiocells demo-1 +``` + + + + +%package help +Summary: Development documents and examples for aiocells +Provides: python3-aiocells-doc +%description help +`aiocells` is a package that provides tools for synchronous and asynchronous +execution of nodes in a dependency graph. + +Contents: + + 1. [Examples](#examples) + 1. [Development Installation](#development-installation) + +## Examples + +### Hello world + +Here is the code for the [first demo](src/aiocells/demo_1.py). + +```python +#!/usr/bin/env python3 + +import aiocells + + +def hello_world(): + print("Hello, world!") + + +def main(): + graph = aiocells.DependencyGraph() + + # The node can be any callable, in this case a function. + graph.add_node(hello_world) + aiocells.compute_sequential(graph) +``` + +This is _synchronous_ graph computation. There is only one node in the graph. +It is a function that prints a message. Synchronous nodes must be `callable`. + +### Defining ordering constraints + +Here is [demo 4](src/aiocells/demo_4.py). It shows how edges between nodes +are defined: + + +```python +#!/usr/bin/env python3 + +import time + +import aiocells + + +def main(): + graph = aiocells.DependencyGraph() + + # 'add_node' always returns the node that has just been added, in this + # case the lambda functions. We will use this below to define precedence + # relationships + print_sleeping = graph.add_node(lambda: print("Sleeping...")) + sleep = graph.add_node(lambda: time.sleep(2)) + print_woke_up = graph.add_node(lambda: print("Woke up!")) + + print("Define the precedence relationships...") + graph.add_precedence(print_sleeping, sleep) + graph.add_precedence(sleep, print_woke_up) + + # Now, after we've defined the precedence relationships, we use the + # simplest computer to compute the graph. The nodes will be called in + # an order that is consistent with the precedence relationships. + # Specifically, the nodes are executed in topological order. + aiocells.compute_sequential(graph) +``` + +In this case, there are three nodes. After the nodes are added, we define +precedence relationships between them. When the graph is computed, it is +done so in a way that honours the precedence relationships. + +### Asynchronous nodes + +Below is the code for [demo_5](src/aiocells/demo_5.py). Note the use of +`asyncio.sleep`, `functools.partial` and `aiocells.async_compute_sequential`. + +```python +#!/usr/bin/env python3 + +import asyncio +from functools import partial + +import aiocells + +# This example demonstrates graph nodes that are coroutines. We use +# a different computer; one that know how to deal with coroutines. + + +def main(): + graph = aiocells.DependencyGraph() + + # First, we add a lambda function + before_sleep = graph.add_node(lambda: print("Sleeping...")) + + # Second, we create a coroutine function using functools.partial. This + # is the closest we can get to a lambda for an async function + sleep_2 = partial(asyncio.sleep, 2) + + # Finally, another lambda function + wake_up = graph.add_node(lambda: print("Woke up!")) + + # Here, 'sleep' will implicitly be added to the graph because it is + # part of the precedence relationship + graph.add_precedence(before_sleep, sleep_2) + graph.add_precedence(sleep_2, wake_up) + + # Here, we use the `async_compute_sequential`, which, like + # `compute_sequential`, call the nodes in a topologically correct sequence. + # However, whereas `compute_sequential` only supports vanilla callables, + # `async_compute_sequential` additionally supports coroutine functions, + # as defined by `inspect.iscoroutinefunction`. However, the execution is + # still sequential. Each coroutine function is executed using 'await' and + # must complete before the next node is executed. The function + # `async_compute_sequential` is a coroutine and must be awaited. Here, + # we simply pass it to `asyncio.run`. + asyncio.run(aiocells.async_compute_sequential(graph)) +``` + +### Concurrent computation + +[demo 6](src/aiocells/demo_6.py) is a an example of graph that _could_ be +computed concurrently but is not due to the use if `async_compute_sequential`. + +```python +import asyncio +from functools import partial + +import aiocells + + +def create_graph(stopwatch): + + graph = aiocells.DependencyGraph() + + # The method to start the stopwatch + start_stopwatch = stopwatch.start + + # Two sleeps. Note that they are asyncio.sleep + sleep_1 = partial(asyncio.sleep, 1) + sleep_2 = partial(asyncio.sleep, 2) + + # The method to stop the stopwatch + stop_stopwatch = stopwatch.stop + + # Start the stopwatch before the first sleep + graph.add_precedence(start_stopwatch, sleep_1) + # Stop the stopwatch after the first sleep + graph.add_precedence(sleep_1, stop_stopwatch) + + # Start the stopwatch before the second sleep + graph.add_precedence(start_stopwatch, sleep_2) + # Stop the stopwatch after the second sleep + graph.add_precedence(sleep_2, stop_stopwatch) + + # Note that there is no precedence relationship between the two + # sleeps. + return graph + + +def main(): + + stopwatch = aiocells.Stopwatch() + graph = create_graph(stopwatch) + # Even though the graph is a diamond (the sleeps do no depend on each + # other and _could_ be executed concurrenty, `async_compute_sequential` + # does not support concurrent execution. Thus, the execution time is + # about 3 seconds, the sum of the two sleeps. + print("Two async sleeps computed sequentially.") + print("Total time should take about 3 seconds...") + asyncio.run(aiocells.async_compute_sequential(graph)) + print("Computation with `async_compute_sequential` took" + f" {stopwatch.elapsed_time()}") +``` + +[demo_7](src/aiocells/demo_7.py) is the same graph as above but computed +concurrently with `async_compute_concurrent`. + +```python +#!/usr/bin/env python3 + +import asyncio + +import aiocells +import aiocells.demo_6 as demo_6 + + +def main(): + stopwatch = aiocells.Stopwatch() + graph = demo_6.create_graph(stopwatch) + + # Here, we run the same graph as the previous demo but we use + # 'async_compute_concurrent' which will run the two sleeps concurrently. + # Thus, the execution time will be around 2 seconds, the maximum of + # the two sleeps. + + print("Running previous demo's graph concurrently.") + print("Total execution time should be about 2 seconds...") + asyncio.run(aiocells.async_compute_concurrent(graph)) + print("Computation with `async_compute_concurrent` took" + f" {stopwatch.elapsed_time()}") + +``` + +## Development Installation + +There is a `Makefile` in the repository. The default target will initialise +a virtual environment, install dependencies into that environment and then +test the code. It requires `Python 3.8`, `virtualenv` and `pip` to be +installed. If those are missing, it will print suggestions on how to address +the problem. + +```bash +$ make +``` + +### Activating the virtual environment and running the demos + +The default make target will generate a file called `activate_aiocells`. To +activate the virtual environment: + +```bash +$ source activate_aiocells +``` + +Once you've done that, you should have the following command available: + +```bash +$ aiocells demo-1 +``` + +### Tab completion + +`activate_aiocells` will enable tab completion for `aiocells`: + +```bash +$ aiocells +``` + +### Editable installation + +The package will be installed in the virutal environment using +`pip --editable`. This means that modifications to the code will be immediately +available. + +To test this, try modifying `src/aiocells/demo_1.py` to print a different +message. You should be able to immediately run the demo and see the new +message: +```bash +$ aiocells demo-1 +``` + + + + +%prep +%autosetup -n aiocells-1.0.4 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-aiocells -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Fri May 05 2023 Python_Bot - 1.0.4-1 +- Package Spec generated diff --git a/sources b/sources new file mode 100644 index 0000000..9da96d7 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +ff14e43a019b7a0f2dc4d25281365ddd aiocells-1.0.4.tar.gz -- cgit v1.2.3