async-graph-data-flow 1.4.0__tar.gz → 1.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- async_graph_data_flow-1.5.1/CHANGELOG.md +68 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/LICENSE.txt +1 -1
- async_graph_data_flow-1.5.1/MANIFEST.in +1 -0
- {async-graph-data-flow-1.4.0/src/async_graph_data_flow.egg-info → async_graph_data_flow-1.5.1}/PKG-INFO +28 -23
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/README.md +13 -12
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/pyproject.toml +17 -14
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow/executor.py +35 -29
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow/graph.py +0 -3
- async_graph_data_flow-1.5.1/src/async_graph_data_flow/py.typed +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1/src/async_graph_data_flow.egg-info}/PKG-INFO +28 -23
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow.egg-info/SOURCES.txt +3 -0
- async_graph_data_flow-1.5.1/src/async_graph_data_flow.egg-info/requires.txt +15 -0
- async-graph-data-flow-1.4.0/src/async_graph_data_flow.egg-info/requires.txt +0 -12
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/setup.cfg +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow/__init__.py +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow.egg-info/dependency_links.txt +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow.egg-info/not-zip-safe +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow.egg-info/top_level.txt +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/tests/test_executor.py +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/tests/test_graph.py +0 -0
- {async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/tests/test_version_number.py +0 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased] - YYYY-MM-DD
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
### Deprecated
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
|
|
22
|
+
## [1.5.1] - 2024-11-07
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Added static type checking using mypy. (#12)
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- Fixed documentation to actually show example code. (#12)
|
|
29
|
+
|
|
30
|
+
## [1.5.0] - 2024-10-30
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- Python 3.13 is officially supported and tested on CI. (#11)
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- Migrated the docs to the Read The Docs site. (#11)
|
|
37
|
+
|
|
38
|
+
## [1.4.0] - 2023-11-30
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- Python 3.12 is officially supported and tested on CI.
|
|
42
|
+
- Added a technical notes page to the Sphinx documentation.
|
|
43
|
+
|
|
44
|
+
## [1.3.0] - 2023-06-20
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- `AsyncGraph.add_node` has the new keyword argument `check_async_gen`
|
|
48
|
+
to optionally disable the async generator function check for advanced usage.
|
|
49
|
+
|
|
50
|
+
## [1.2.0] - 2023-04-25
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- An `AsyncExecutor` instance now has the `start_nodes` property.
|
|
54
|
+
It maps start nodes to their arguments passed in at the beginning of graph execution.
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
- Before a graph executes, the `exceptions` property of an `AsyncExecutor` instance
|
|
58
|
+
now returns `None`. Previously, accessing this property before graph execute
|
|
59
|
+
would raise an exception.
|
|
60
|
+
|
|
61
|
+
## [1.1.0] - 2023-03-02
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
- Keep track of and expose exceptions. (#6)
|
|
65
|
+
|
|
66
|
+
## [1.0.0] - 2023-01-05
|
|
67
|
+
|
|
68
|
+
First release!
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include CHANGELOG.md
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: async-graph-data-flow
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.1
|
|
4
4
|
Summary: Asynchronous functions that pass data along a directed acyclic graph
|
|
5
5
|
Author-email: Civis Analytics <opensource@civisanalytics.com>
|
|
6
6
|
License: BSD 3-Clause
|
|
7
|
+
Project-URL: Documentation, https://async-graph-data-flow.readthedocs.io
|
|
7
8
|
Project-URL: Source, https://github.com/civisanalytics/async-graph-data-flow
|
|
8
9
|
Keywords: async,asynchronous,asyncio,data flow,graph
|
|
9
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -17,21 +18,24 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
22
|
Classifier: Framework :: AsyncIO
|
|
21
23
|
Requires-Python: >=3.10
|
|
22
24
|
Description-Content-Type: text/markdown
|
|
23
25
|
License-File: LICENSE.txt
|
|
24
26
|
Provides-Extra: dev
|
|
25
|
-
Requires-Dist: black==
|
|
26
|
-
Requires-Dist: flake8==
|
|
27
|
-
Requires-Dist: pytest==
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
27
|
+
Requires-Dist: black==24.10.0; extra == "dev"
|
|
28
|
+
Requires-Dist: flake8==7.1.1; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest==8.3.3; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy==1.13.0; extra == "dev"
|
|
31
|
+
Requires-Dist: build==1.2.2; extra == "dev"
|
|
32
|
+
Requires-Dist: twine==5.1.1; extra == "dev"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: Sphinx==8.1.3; extra == "docs"
|
|
35
|
+
Requires-Dist: furo==2024.8.6; extra == "docs"
|
|
36
|
+
Requires-Dist: numpydoc==1.8.0; extra == "docs"
|
|
37
|
+
Requires-Dist: sphinx-copybutton==0.5.2; extra == "docs"
|
|
38
|
+
Requires-Dist: sphinxcontrib-mermaid==1.0.0; extra == "docs"
|
|
35
39
|
|
|
36
40
|
# async-graph-data-flow
|
|
37
41
|
|
|
@@ -41,7 +45,7 @@ Requires-Dist: sphinxcontrib-mermaid==0.9.2; extra == "dev"
|
|
|
41
45
|
|
|
42
46
|
## Full Documentation
|
|
43
47
|
|
|
44
|
-
Please visit https://
|
|
48
|
+
Please visit https://async-graph-data-flow.readthedocs.io
|
|
45
49
|
|
|
46
50
|
Please also check out this
|
|
47
51
|
[blog post](https://www.civisanalytics.com/blog/open-source-software-release-introducing-async-graph-data-flow-a-python-library-for-efficient-data-pipelines/)
|
|
@@ -71,17 +75,18 @@ flake8 src tests examples
|
|
|
71
75
|
black --check src tests examples
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
##
|
|
78
|
+
## Building Documentation
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
everything else under `docs/` is auto-generated.
|
|
79
|
-
After the manual updates under `docs/source/` are ready,
|
|
80
|
-
the HTML pages are updated as follows:
|
|
80
|
+
We use the Sphinx framework. The documentation source files are in `docs/source/`.
|
|
81
|
+
These files can be updated as necessary.
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
The public documentation is accessible at https://async-graph-data-flow.readthedocs.io.
|
|
84
|
+
The doc build is configured by `.readthedocs.yaml`.
|
|
85
|
+
Normally, even when we need to update the documentation or make a new release of async-graph-data-flow,
|
|
86
|
+
neither this configuration YAML file nor Civis's account on the Read the Docs site need any updates.
|
|
87
|
+
The builds by the Read The Docs site generate the necessary files (the HTML pages and other things)
|
|
88
|
+
for the public documentation. All these auto-generated files are explicitly not versioned (see `.gitignore`).
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
To build the documentation locally (for testing and development),
|
|
91
|
+
install the full doc-related dependencies: `pip install -r docs/requirements.txt`,
|
|
92
|
+
then run `sphinx-build -b html docs/ docs/build/`.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Full Documentation
|
|
8
8
|
|
|
9
|
-
Please visit https://
|
|
9
|
+
Please visit https://async-graph-data-flow.readthedocs.io
|
|
10
10
|
|
|
11
11
|
Please also check out this
|
|
12
12
|
[blog post](https://www.civisanalytics.com/blog/open-source-software-release-introducing-async-graph-data-flow-a-python-library-for-efficient-data-pipelines/)
|
|
@@ -36,17 +36,18 @@ flake8 src tests examples
|
|
|
36
36
|
black --check src tests examples
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
##
|
|
39
|
+
## Building Documentation
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
everything else under `docs/` is auto-generated.
|
|
44
|
-
After the manual updates under `docs/source/` are ready,
|
|
45
|
-
the HTML pages are updated as follows:
|
|
41
|
+
We use the Sphinx framework. The documentation source files are in `docs/source/`.
|
|
42
|
+
These files can be updated as necessary.
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
The public documentation is accessible at https://async-graph-data-flow.readthedocs.io.
|
|
45
|
+
The doc build is configured by `.readthedocs.yaml`.
|
|
46
|
+
Normally, even when we need to update the documentation or make a new release of async-graph-data-flow,
|
|
47
|
+
neither this configuration YAML file nor Civis's account on the Read the Docs site need any updates.
|
|
48
|
+
The builds by the Read The Docs site generate the necessary files (the HTML pages and other things)
|
|
49
|
+
for the public documentation. All these auto-generated files are explicitly not versioned (see `.gitignore`).
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
To build the documentation locally (for testing and development),
|
|
52
|
+
install the full doc-related dependencies: `pip install -r docs/requirements.txt`,
|
|
53
|
+
then run `sphinx-build -b html docs/ docs/build/`.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools >=
|
|
2
|
+
requires = ["setuptools >= 69.0.0", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "async-graph-data-flow"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.5.1"
|
|
8
8
|
description = "Asynchronous functions that pass data along a directed acyclic graph"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">= 3.10"
|
|
@@ -29,29 +29,32 @@ classifiers = [
|
|
|
29
29
|
"Programming Language :: Python :: 3.10",
|
|
30
30
|
"Programming Language :: Python :: 3.11",
|
|
31
31
|
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
32
33
|
"Framework :: AsyncIO",
|
|
33
34
|
]
|
|
34
35
|
|
|
35
36
|
[project.urls]
|
|
37
|
+
Documentation = "https://async-graph-data-flow.readthedocs.io"
|
|
36
38
|
Source = "https://github.com/civisanalytics/async-graph-data-flow"
|
|
37
39
|
|
|
38
40
|
[project.optional-dependencies]
|
|
39
41
|
dev = [
|
|
40
42
|
# Running tests and linters
|
|
41
|
-
"black ==
|
|
42
|
-
"flake8 ==
|
|
43
|
-
"pytest ==
|
|
43
|
+
"black == 24.10.0",
|
|
44
|
+
"flake8 == 7.1.1",
|
|
45
|
+
"pytest == 8.3.3",
|
|
46
|
+
"mypy == 1.13.0",
|
|
44
47
|
|
|
45
48
|
# Managing source distributions
|
|
46
|
-
"build == 1.
|
|
47
|
-
"twine ==
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"Sphinx ==
|
|
51
|
-
"furo ==
|
|
52
|
-
"numpydoc == 1.
|
|
49
|
+
"build == 1.2.2",
|
|
50
|
+
"twine == 5.1.1",
|
|
51
|
+
]
|
|
52
|
+
docs = [
|
|
53
|
+
"Sphinx == 8.1.3",
|
|
54
|
+
"furo == 2024.8.6",
|
|
55
|
+
"numpydoc == 1.8.0",
|
|
53
56
|
"sphinx-copybutton == 0.5.2",
|
|
54
|
-
"sphinxcontrib-mermaid == 0.
|
|
57
|
+
"sphinxcontrib-mermaid == 1.0.0",
|
|
55
58
|
]
|
|
56
59
|
|
|
57
60
|
[tool.setuptools.packages.find]
|
|
@@ -62,5 +65,5 @@ zip-safe = false
|
|
|
62
65
|
package-dir = { "" = "src" }
|
|
63
66
|
|
|
64
67
|
[tool.pytest.ini_options]
|
|
65
|
-
addopts = "-vv --durations=0"
|
|
68
|
+
addopts = "-vv --durations=0 --strict-markers"
|
|
66
69
|
testpaths = ["tests"]
|
{async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow/executor.py
RENAMED
|
@@ -20,7 +20,7 @@ class AsyncExecutor:
|
|
|
20
20
|
self,
|
|
21
21
|
graph: AsyncGraph,
|
|
22
22
|
*,
|
|
23
|
-
logger: logging.Logger = None,
|
|
23
|
+
logger: logging.Logger | None = None,
|
|
24
24
|
max_exceptions: int = 1_000,
|
|
25
25
|
):
|
|
26
26
|
"""Initialize an executor.
|
|
@@ -41,23 +41,23 @@ class AsyncExecutor:
|
|
|
41
41
|
if not isinstance(self._graph, AsyncGraph):
|
|
42
42
|
raise TypeError(f"{self._graph} must be an AsyncGraph instance")
|
|
43
43
|
|
|
44
|
-
self._node_queues = {}
|
|
45
|
-
self._consumer_tasks = {}
|
|
44
|
+
self._node_queues: dict[str, asyncio.Queue] = {}
|
|
45
|
+
self._consumer_tasks: dict[str, asyncio.Task] = {}
|
|
46
46
|
self._halt_pipeline_execution = False
|
|
47
47
|
self._logger = logger if logger else _LOG
|
|
48
48
|
self._max_exceptions = max_exceptions
|
|
49
49
|
|
|
50
|
-
self._data_flow_stats = None
|
|
50
|
+
self._data_flow_stats: dict[str, dict[str, int]] | None = None
|
|
51
51
|
self._data_flow_logging_lock = asyncio.Lock()
|
|
52
52
|
self._data_flow_logging = False
|
|
53
53
|
self._data_flow_logging_node_format = _DEFAULT_DATA_FLOW_LOGGING_NODE_FORMAT
|
|
54
54
|
self._data_flow_logging_time_interval = _DEFAULT_DATA_FLOW_LOGGING_TIME_INTERVAL
|
|
55
|
-
self._data_flow_logging_node_filter = self._graph._nodes.keys()
|
|
56
|
-
self._data_flow_logging_last_timestamp = 0
|
|
55
|
+
self._data_flow_logging_node_filter: Iterable[str] = self._graph._nodes.keys()
|
|
56
|
+
self._data_flow_logging_last_timestamp = 0.0
|
|
57
57
|
|
|
58
|
-
self._start_node_args = None
|
|
58
|
+
self._start_node_args: dict[str, tuple] | None = None
|
|
59
59
|
|
|
60
|
-
self._exceptions = None
|
|
60
|
+
self._exceptions: dict[str, deque[Exception]] | None = None
|
|
61
61
|
|
|
62
62
|
@property
|
|
63
63
|
def graph(self) -> AsyncGraph:
|
|
@@ -72,7 +72,7 @@ class AsyncExecutor:
|
|
|
72
72
|
raised from the node.
|
|
73
73
|
"""
|
|
74
74
|
if self._exceptions is None:
|
|
75
|
-
return
|
|
75
|
+
return None
|
|
76
76
|
from_deque_to_list = {}
|
|
77
77
|
for node_name, excs in self._exceptions.items():
|
|
78
78
|
# `excs` is a deque. Turning it into a list for user-friendliness.
|
|
@@ -106,7 +106,7 @@ class AsyncExecutor:
|
|
|
106
106
|
node_filter: Iterable[str] | None = None,
|
|
107
107
|
time_interval: int | None = None,
|
|
108
108
|
logger: logging.Logger | None = None,
|
|
109
|
-
):
|
|
109
|
+
) -> None:
|
|
110
110
|
"""Turn on and configure data flow logging.
|
|
111
111
|
|
|
112
112
|
For a long-running graph execution,
|
|
@@ -148,11 +148,11 @@ class AsyncExecutor:
|
|
|
148
148
|
if logger and isinstance(logger, logging.Logger):
|
|
149
149
|
self._logger = logger
|
|
150
150
|
|
|
151
|
-
def turn_off_data_flow_logging(self):
|
|
151
|
+
def turn_off_data_flow_logging(self) -> None:
|
|
152
152
|
"""Turn off data flow logging."""
|
|
153
153
|
self._data_flow_logging = False
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
def _log_data_flow_nodes(self):
|
|
156
156
|
for node, flow in self._data_flow_stats.items():
|
|
157
157
|
if (
|
|
158
158
|
self._data_flow_logging_node_filter
|
|
@@ -186,7 +186,7 @@ class AsyncExecutor:
|
|
|
186
186
|
current_timestamp - self._data_flow_logging_last_timestamp
|
|
187
187
|
> self._data_flow_logging_time_interval
|
|
188
188
|
):
|
|
189
|
-
|
|
189
|
+
self._log_data_flow_nodes()
|
|
190
190
|
self._data_flow_logging_last_timestamp = current_timestamp
|
|
191
191
|
|
|
192
192
|
queue = self._node_queues[node_name]
|
|
@@ -202,17 +202,17 @@ class AsyncExecutor:
|
|
|
202
202
|
try:
|
|
203
203
|
if len(params) == 0:
|
|
204
204
|
coro = node.func()
|
|
205
|
-
elif node.unpack_input and (
|
|
206
|
-
|
|
207
|
-
):
|
|
208
|
-
coro = node.func(
|
|
205
|
+
elif node.unpack_input and isinstance(data, tuple):
|
|
206
|
+
coro = node.func(*data)
|
|
207
|
+
elif node.unpack_input and isinstance(data, dict):
|
|
208
|
+
coro = node.func(**data)
|
|
209
209
|
else:
|
|
210
210
|
coro = node.func(data)
|
|
211
211
|
except asyncio.CancelledError:
|
|
212
212
|
continue
|
|
213
213
|
except Exception as exc:
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
self._update_data_flow_error_stats(node_name)
|
|
215
|
+
self._update_exceptions(node_name, exc)
|
|
216
216
|
self._logger.error(traceback.format_exc())
|
|
217
217
|
if self._graph.halt_on_exception or node.halt_on_exception:
|
|
218
218
|
self._logger.error(
|
|
@@ -238,8 +238,8 @@ class AsyncExecutor:
|
|
|
238
238
|
except asyncio.CancelledError:
|
|
239
239
|
break
|
|
240
240
|
except Exception as exc:
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
self._update_data_flow_error_stats(node_name)
|
|
242
|
+
self._update_exceptions(node_name, exc)
|
|
243
243
|
self._logger.error(traceback.format_exc())
|
|
244
244
|
if self._graph.halt_on_exception or node.halt_on_exception:
|
|
245
245
|
# close current agen
|
|
@@ -255,27 +255,33 @@ class AsyncExecutor:
|
|
|
255
255
|
continue
|
|
256
256
|
else:
|
|
257
257
|
node_edges = self._graph._nodes_to_edges[node_name]
|
|
258
|
-
|
|
258
|
+
self._update_data_flow_in_out_stats(node_name, node_edges)
|
|
259
259
|
await self._add_to_node_queue(node_edges, next_data_item)
|
|
260
260
|
|
|
261
261
|
queue.task_done()
|
|
262
262
|
except asyncio.CancelledError:
|
|
263
263
|
break
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
def _update_data_flow_in_out_stats(self, in_node: str, out_nodes: set[str]):
|
|
266
|
+
if self._data_flow_stats is None:
|
|
267
|
+
return None
|
|
266
268
|
self._data_flow_stats[in_node]["out"] += 1
|
|
267
269
|
for node in out_nodes:
|
|
268
270
|
self._data_flow_stats[node]["in"] += 1
|
|
269
271
|
|
|
270
|
-
|
|
272
|
+
def _update_data_flow_error_stats(self, node: str):
|
|
273
|
+
if self._data_flow_stats is None:
|
|
274
|
+
return None
|
|
271
275
|
self._data_flow_stats[node]["err"] += 1
|
|
272
276
|
|
|
273
|
-
|
|
277
|
+
def _update_exceptions(self, node: str, exc: Exception):
|
|
278
|
+
if self._exceptions is None:
|
|
279
|
+
return None
|
|
274
280
|
self._exceptions[node].append(exc)
|
|
275
281
|
|
|
276
282
|
async def _pipeline_execution(self):
|
|
277
|
-
self._data_flow_stats
|
|
278
|
-
self._exceptions
|
|
283
|
+
self._data_flow_stats = {}
|
|
284
|
+
self._exceptions = {}
|
|
279
285
|
|
|
280
286
|
for node_name, node in self._graph._nodes.items():
|
|
281
287
|
queue = asyncio.Queue(maxsize=node.queue_size)
|
|
@@ -299,7 +305,7 @@ class AsyncExecutor:
|
|
|
299
305
|
await asyncio.gather(*self._consumer_tasks.values())
|
|
300
306
|
|
|
301
307
|
if self._data_flow_logging:
|
|
302
|
-
|
|
308
|
+
self._log_data_flow_nodes()
|
|
303
309
|
|
|
304
310
|
def _get_start_node_args(self, start_node_args) -> dict[str, tuple]:
|
|
305
311
|
if start_node_args is None:
|
|
@@ -313,7 +319,7 @@ class AsyncExecutor:
|
|
|
313
319
|
raise TypeError(f"args for the node '{node}' isn't a tuple: {args}")
|
|
314
320
|
return start_node_args
|
|
315
321
|
|
|
316
|
-
def execute(self, start_nodes: dict[str, tuple] = None) -> None:
|
|
322
|
+
def execute(self, start_nodes: dict[str, tuple] | None = None) -> None:
|
|
317
323
|
"""Start executing the functions along the graph.
|
|
318
324
|
|
|
319
325
|
Parameters
|
|
File without changes
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: async-graph-data-flow
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.1
|
|
4
4
|
Summary: Asynchronous functions that pass data along a directed acyclic graph
|
|
5
5
|
Author-email: Civis Analytics <opensource@civisanalytics.com>
|
|
6
6
|
License: BSD 3-Clause
|
|
7
|
+
Project-URL: Documentation, https://async-graph-data-flow.readthedocs.io
|
|
7
8
|
Project-URL: Source, https://github.com/civisanalytics/async-graph-data-flow
|
|
8
9
|
Keywords: async,asynchronous,asyncio,data flow,graph
|
|
9
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -17,21 +18,24 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
22
|
Classifier: Framework :: AsyncIO
|
|
21
23
|
Requires-Python: >=3.10
|
|
22
24
|
Description-Content-Type: text/markdown
|
|
23
25
|
License-File: LICENSE.txt
|
|
24
26
|
Provides-Extra: dev
|
|
25
|
-
Requires-Dist: black==
|
|
26
|
-
Requires-Dist: flake8==
|
|
27
|
-
Requires-Dist: pytest==
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
27
|
+
Requires-Dist: black==24.10.0; extra == "dev"
|
|
28
|
+
Requires-Dist: flake8==7.1.1; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest==8.3.3; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy==1.13.0; extra == "dev"
|
|
31
|
+
Requires-Dist: build==1.2.2; extra == "dev"
|
|
32
|
+
Requires-Dist: twine==5.1.1; extra == "dev"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: Sphinx==8.1.3; extra == "docs"
|
|
35
|
+
Requires-Dist: furo==2024.8.6; extra == "docs"
|
|
36
|
+
Requires-Dist: numpydoc==1.8.0; extra == "docs"
|
|
37
|
+
Requires-Dist: sphinx-copybutton==0.5.2; extra == "docs"
|
|
38
|
+
Requires-Dist: sphinxcontrib-mermaid==1.0.0; extra == "docs"
|
|
35
39
|
|
|
36
40
|
# async-graph-data-flow
|
|
37
41
|
|
|
@@ -41,7 +45,7 @@ Requires-Dist: sphinxcontrib-mermaid==0.9.2; extra == "dev"
|
|
|
41
45
|
|
|
42
46
|
## Full Documentation
|
|
43
47
|
|
|
44
|
-
Please visit https://
|
|
48
|
+
Please visit https://async-graph-data-flow.readthedocs.io
|
|
45
49
|
|
|
46
50
|
Please also check out this
|
|
47
51
|
[blog post](https://www.civisanalytics.com/blog/open-source-software-release-introducing-async-graph-data-flow-a-python-library-for-efficient-data-pipelines/)
|
|
@@ -71,17 +75,18 @@ flake8 src tests examples
|
|
|
71
75
|
black --check src tests examples
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
##
|
|
78
|
+
## Building Documentation
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
everything else under `docs/` is auto-generated.
|
|
79
|
-
After the manual updates under `docs/source/` are ready,
|
|
80
|
-
the HTML pages are updated as follows:
|
|
80
|
+
We use the Sphinx framework. The documentation source files are in `docs/source/`.
|
|
81
|
+
These files can be updated as necessary.
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
The public documentation is accessible at https://async-graph-data-flow.readthedocs.io.
|
|
84
|
+
The doc build is configured by `.readthedocs.yaml`.
|
|
85
|
+
Normally, even when we need to update the documentation or make a new release of async-graph-data-flow,
|
|
86
|
+
neither this configuration YAML file nor Civis's account on the Read the Docs site need any updates.
|
|
87
|
+
The builds by the Read The Docs site generate the necessary files (the HTML pages and other things)
|
|
88
|
+
for the public documentation. All these auto-generated files are explicitly not versioned (see `.gitignore`).
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
To build the documentation locally (for testing and development),
|
|
91
|
+
install the full doc-related dependencies: `pip install -r docs/requirements.txt`,
|
|
92
|
+
then run `sphinx-build -b html docs/ docs/build/`.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
CHANGELOG.md
|
|
1
2
|
LICENSE.txt
|
|
3
|
+
MANIFEST.in
|
|
2
4
|
README.md
|
|
3
5
|
pyproject.toml
|
|
4
6
|
src/async_graph_data_flow/__init__.py
|
|
5
7
|
src/async_graph_data_flow/executor.py
|
|
6
8
|
src/async_graph_data_flow/graph.py
|
|
9
|
+
src/async_graph_data_flow/py.typed
|
|
7
10
|
src/async_graph_data_flow.egg-info/PKG-INFO
|
|
8
11
|
src/async_graph_data_flow.egg-info/SOURCES.txt
|
|
9
12
|
src/async_graph_data_flow.egg-info/dependency_links.txt
|
|
File without changes
|
{async-graph-data-flow-1.4.0 → async_graph_data_flow-1.5.1}/src/async_graph_data_flow/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|