simplibs-actions 0.1.0__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.
- simplibs_actions-0.1.0/LICENSE +21 -0
- simplibs_actions-0.1.0/PKG-INFO +374 -0
- simplibs_actions-0.1.0/README.md +344 -0
- simplibs_actions-0.1.0/pyproject.toml +61 -0
- simplibs_actions-0.1.0/setup.cfg +4 -0
- simplibs_actions-0.1.0/src/simplibs/actions/__init__.py +103 -0
- simplibs_actions-0.1.0/src/simplibs/actions/base_class/Action.py +188 -0
- simplibs_actions-0.1.0/src/simplibs/actions/base_class/__init__.py +17 -0
- simplibs_actions-0.1.0/src/simplibs/actions/base_class/_validations/__init__.py +16 -0
- simplibs_actions-0.1.0/src/simplibs/actions/base_class/_validations/raise_invalid_action_target.py +54 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/__init__.py +88 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/_helpers/__init__.py +18 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/_helpers/as_action.py +31 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/_helpers/as_predicate.py +58 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/_helpers/validations/__init__.py +16 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/_helpers/validations/raise_invalid_predicate.py +42 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/__init__.py +21 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/_validations/__init__.py +18 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/_validations/raise_guard_failed.py +42 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/_validations/raise_not_iterable.py +39 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/aliases/__init__.py +24 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/aliases/apply_to_each.py +19 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/aliases/conditional_action.py +24 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/aliases/guarded_action.py +20 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/branch.py +77 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/for_each.py +58 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/flow_control/guard.py +96 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/__init__.py +22 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/aliases/__init__.py +24 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/aliases/run_in_parallel.py +20 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/aliases/run_in_sequence.py +20 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/aliases/try_or_fallback.py +27 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/compose_class/ParallelCompose.py +53 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/compose_class/SequenceCompose.py +59 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/compose_class/__init__.py +23 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/fallback.py +88 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/parallel.py +66 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/operators/sequence.py +74 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/primitives/__init__.py +19 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/primitives/aliases/__init__.py +22 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/primitives/aliases/pass_through.py +19 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/primitives/aliases/replace_with.py +19 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/primitives/constant.py +46 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/primitives/identity.py +53 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/__init__.py +23 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/_validations/__init__.py +16 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/_validations/raise_invalid_attempts.py +40 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/aliases/__init__.py +26 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/aliases/callable_action.py +21 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/aliases/log_step.py +21 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/aliases/retry_on_failure.py +23 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/aliases/run_side_effect.py +21 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/lambda_action.py +55 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/log_action.py +58 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/retry.py +82 -0
- simplibs_actions-0.1.0/src/simplibs/actions/containers/wrappers/tap.py +55 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/__init__.py +26 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/__init__.py +16 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/constants/EMPTY.py +42 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/constants/__init__.py +16 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/__init__.py +20 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/_helpers/__init__.py +24 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/_helpers/_describe_annotation.py +53 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/_helpers/build_call_docstring.py +68 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/_helpers/build_init_docstring.py +56 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/create_act.py +145 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/create_call.py +102 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/creators/create_init_and_slots.py +103 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/__init__.py +23 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/resolve_class_name.py +54 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/resolve_param.py +77 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/unwrap_log_this_and_validate_call.py +72 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/validations/__init__.py +18 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/validations/raise_main_param_not_found.py +39 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/resolvers/validations/raise_no_parameters.py +37 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/validations/__init__.py +23 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/validations/_verify_type_is_validatable.py +48 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/validations/raise_action_instance_error.py +32 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/validations/validate_param_kinds.py +46 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/validations/validate_params_annotations.py +45 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/_helpers/validations/validate_return_annotations.py +42 -0
- simplibs_actions-0.1.0/src/simplibs/actions/creator/create_action.py +229 -0
- simplibs_actions-0.1.0/src/simplibs/actions/decorator/__init__.py +26 -0
- simplibs_actions-0.1.0/src/simplibs/actions/decorator/to_action.py +109 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/__init__.py +50 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/assert_action.py +195 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/assert_action_alias.py +102 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/asserts/__init__.py +31 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/asserts/assert_action_construction.py +105 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/asserts/assert_action_io_types.py +80 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/asserts/assert_action_output.py +74 -0
- simplibs_actions-0.1.0/src/simplibs/actions/testing/asserts/assert_action_raises.py +80 -0
- simplibs_actions-0.1.0/src/simplibs_actions.egg-info/PKG-INFO +374 -0
- simplibs_actions-0.1.0/src/simplibs_actions.egg-info/SOURCES.txt +95 -0
- simplibs_actions-0.1.0/src/simplibs_actions.egg-info/dependency_links.txt +1 -0
- simplibs_actions-0.1.0/src/simplibs_actions.egg-info/requires.txt +7 -0
- simplibs_actions-0.1.0/src/simplibs_actions.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dalibor Sova (Sudip2708)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: simplibs-actions
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A composable Action pipeline system — chainable via >>, &, and if_matches, built on simplibs-rules.
|
|
5
|
+
Author-email: "Dalibor Sova (Sudip2708)" <daliborsova@seznam.cz>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/simplibs/simplibs-actions
|
|
8
|
+
Project-URL: Repository, https://github.com/simplibs/simplibs-actions
|
|
9
|
+
Project-URL: Issues, https://github.com/simplibs/simplibs-actions/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/simplibs/simplibs-actions/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: actions,pipeline,composition,functional,validation,data-validation,simplibs,simplibs-actions,developer-tools
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Software Development :: Testing
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: simplibs-rules>=0.2.2
|
|
24
|
+
Requires-Dist: simplibs-exception>=1.1.3
|
|
25
|
+
Requires-Dist: simplibs-validate>=0.2.1
|
|
26
|
+
Requires-Dist: simplibs-types>=0.2.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# 🔗 `simplibs-actions`
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/simplibs-actions/)
|
|
34
|
+
[](https://www.python.org/downloads/)
|
|
35
|
+
[](https://github.com/simplibs/simplibs-actions/blob/main/LICENSE)
|
|
36
|
+
|
|
37
|
+
**Turn ordinary functions into composable pipeline steps — chain them with `>>`, `&`, and `|`.**
|
|
38
|
+
|
|
39
|
+
A lightweight Python library for building `Action` objects: single-purpose pipeline steps
|
|
40
|
+
that chain into sequences, run in parallel, and fall back on failure using plain Python
|
|
41
|
+
operators — no pipeline framework, no DSL, no boilerplate. Any function becomes an `Action`
|
|
42
|
+
with one decorator, complete with type-checked construction and calls, structured
|
|
43
|
+
diagnostics on failure, and its own dedicated testing toolkit.
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from simplibs.actions import to_action
|
|
47
|
+
|
|
48
|
+
@to_action
|
|
49
|
+
def strip(data: str) -> str:
|
|
50
|
+
return data.strip()
|
|
51
|
+
|
|
52
|
+
@to_action
|
|
53
|
+
def shout(data: str) -> str:
|
|
54
|
+
return data.upper() + "!"
|
|
55
|
+
|
|
56
|
+
pipeline = strip() >> shout()
|
|
57
|
+
pipeline(" hello ") # -> "HELLO!"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
> `simplibs-actions` is the pipeline layer of the ecosystem, built directly on
|
|
61
|
+
> [`simplibs-rules`](https://pypi.org/project/simplibs-rules/) (conditions),
|
|
62
|
+
> [`simplibs-validate`](https://pypi.org/project/simplibs-validate/) (`validate_call`,
|
|
63
|
+
> `log_this`), and [`simplibs-exception`](https://pypi.org/project/simplibs-exception/)
|
|
64
|
+
> (structured diagnostics) — see [Related libraries](#-related-libraries) below.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 🧭 The Core Philosophy
|
|
69
|
+
|
|
70
|
+
Most pipeline/workflow tooling forces a choice: write ad-hoc chains of `if`/`try` calls
|
|
71
|
+
scattered through your codebase, or adopt a heavy orchestration framework with its own
|
|
72
|
+
configuration language. `simplibs-actions` takes neither route. An `Action` is nothing
|
|
73
|
+
more than a plain function with a real signature — `create_action`/`@to_action` wraps it
|
|
74
|
+
once, and from then on it composes with the same three operators every function in this
|
|
75
|
+
library composes with:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
step_a >> step_b >> step_c # sequence — thread output into the next input
|
|
79
|
+
step_a & step_b & step_c # parallel — same input, every branch, one flat tuple out
|
|
80
|
+
step_a | step_b # fallback — try step_a; on failure, run step_b instead
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Every generated `Action` keeps the function's own signature intact — its parameters are
|
|
84
|
+
still individually annotated, still individually type-checked at call time (via
|
|
85
|
+
`simplibs-validate`'s `validate_call`), and still individually documented, rather than
|
|
86
|
+
being flattened into an opaque `(*args, **kwargs)` wrapper. Because that generation is
|
|
87
|
+
itself a well-defined, mechanical process, the library ships its own testing tool
|
|
88
|
+
(`assert_action`) that audits the *entire* contract of any `Action` — this library's own
|
|
89
|
+
containers, or any `Action` a downstream library builds — with one function call.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 📦 Installation
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pip install simplibs-actions
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 🚀 Quick Start in 60 Seconds
|
|
102
|
+
|
|
103
|
+
### Level 1: Turning a function into an Action
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from simplibs.actions import to_action
|
|
107
|
+
|
|
108
|
+
@to_action
|
|
109
|
+
def double(data: int) -> int:
|
|
110
|
+
return data * 2
|
|
111
|
+
|
|
112
|
+
action = double()
|
|
113
|
+
action(21) # -> 42
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Level 2: Composing Actions
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from simplibs.actions import to_action
|
|
120
|
+
|
|
121
|
+
@to_action
|
|
122
|
+
def strip(data: str) -> str:
|
|
123
|
+
return data.strip()
|
|
124
|
+
|
|
125
|
+
@to_action
|
|
126
|
+
def upper(data: str) -> str:
|
|
127
|
+
return data.upper()
|
|
128
|
+
|
|
129
|
+
@to_action
|
|
130
|
+
def lower(data: str) -> str:
|
|
131
|
+
return data.lower()
|
|
132
|
+
|
|
133
|
+
# Sequence: thread output into the next input
|
|
134
|
+
pipeline = strip() >> upper()
|
|
135
|
+
pipeline(" hi ") # -> "HI"
|
|
136
|
+
|
|
137
|
+
# Parallel: same input, every branch, one flat tuple out
|
|
138
|
+
both = upper() & lower()
|
|
139
|
+
both("Hi") # -> ("HI", "hi")
|
|
140
|
+
|
|
141
|
+
# Fallback: try the left side; on failure, run the right side instead
|
|
142
|
+
safe = risky_parse() | default_value(value=None)
|
|
143
|
+
safe(raw_input)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`Rule` instances from `simplibs-rules` compose the same way — `is_integer >> add_one`
|
|
147
|
+
verifies the rule first, then continues with the action.
|
|
148
|
+
|
|
149
|
+
### Level 3: Testing an Action
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from simplibs.actions.testing import assert_action
|
|
153
|
+
|
|
154
|
+
def test_double_contract(subtests):
|
|
155
|
+
assert_action(
|
|
156
|
+
subtests,
|
|
157
|
+
double(),
|
|
158
|
+
valid_values=[21],
|
|
159
|
+
expected_outputs=[42],
|
|
160
|
+
invalid_values=["not-a-number"],
|
|
161
|
+
expected_exception_type=ValidationError,
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
One call audits the full deterministic contract: valid inputs produce the right output,
|
|
166
|
+
invalid inputs raise the right exception, and (by default) the generated class carries
|
|
167
|
+
correct `_input_type`/`_output_type` introspection.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 🛠️ Architecture & Package Structure
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
src/simplibs/actions/
|
|
175
|
+
├── base_class/ ◄── Abstract base class Action — __call__, operators, resolve_action
|
|
176
|
+
├── containers/ ◄── Every built-in Action
|
|
177
|
+
│ ├── flow_control/ ◄── guard, branch, for_each
|
|
178
|
+
│ ├── operators/ ◄── sequence, parallel, fallback, compose_class/ (self-flattening)
|
|
179
|
+
│ ├── primitives/ ◄── identity, constant
|
|
180
|
+
│ └── wrappers/ ◄── lambda_action, tap, retry, log_action
|
|
181
|
+
├── creator/ ◄── create_action — dynamically builds Action classes from functions
|
|
182
|
+
├── decorator/ ◄── to_action — the decorator interface for create_action
|
|
183
|
+
└── testing/ ◄── assert_action, assert_action_alias
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 🧩 The `Action` Class
|
|
189
|
+
|
|
190
|
+
Every action in this library — hand-written or generated — is an `Action`. It defines
|
|
191
|
+
the one mandatory contract (`__call__`) and provides full operator-based composition out
|
|
192
|
+
of the box.
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
class Action(ABC):
|
|
196
|
+
|
|
197
|
+
@abstractmethod
|
|
198
|
+
def __call__(self, data: Any, /) -> Any:
|
|
199
|
+
"""Run this action over `data` and return the result."""
|
|
200
|
+
raise NotImplementedError
|
|
201
|
+
|
|
202
|
+
def then(self, next_step: Any) -> "Action":
|
|
203
|
+
"""Chains this action with a subsequent action, rule, or callable."""
|
|
204
|
+
...
|
|
205
|
+
|
|
206
|
+
def __and__(self, other: Any) -> "Action":
|
|
207
|
+
"""Executes actions in parallel over identical input data."""
|
|
208
|
+
...
|
|
209
|
+
|
|
210
|
+
def __or__(self, other: Any) -> "Action":
|
|
211
|
+
"""Fallback handling: executes `other` if this action fails."""
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
@staticmethod
|
|
215
|
+
def resolve_action(obj: Any) -> "Action":
|
|
216
|
+
"""Convert an Action, a Rule, or a plain callable into an Action instance."""
|
|
217
|
+
...
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
➡️ Full method-by-method reference: [README_ACTION](https://github.com/simplibs/simplibs-actions/blob/main/docs/README_ACTION.md)
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 📖 Built-in Containers
|
|
225
|
+
|
|
226
|
+
Every built-in `Action` is exposed as a `@to_action`-generated class, constructed with
|
|
227
|
+
its own configuration parameters and called with one main input value.
|
|
228
|
+
|
|
229
|
+
| Container | Package | Description |
|
|
230
|
+
|-----------------|----------------|--------------------------------------------------------------------------------------------------------------------|
|
|
231
|
+
| `guard` | `flow_control` | Hard gate — passes data through, or raises, based on a `Rule`/condition. |
|
|
232
|
+
| `branch` | `flow_control` | Soft conditional — runs one of two actions based on a condition, no error either way. |
|
|
233
|
+
| `for_each` | `flow_control` | Applies an action to every item of an iterable, collecting the results. |
|
|
234
|
+
| `sequence` | `operators` | Chains any number of steps left to right. Self-flattening variant: `SequenceCompose`. |
|
|
235
|
+
| `parallel` | `operators` | Runs N actions over the same input, returning a flat tuple of results. Self-flattening variant: `ParallelCompose`. |
|
|
236
|
+
| `fallback` | `operators` | Tries one action; on failure, runs another or returns the original data. |
|
|
237
|
+
| `identity` | `primitives` | No-op — returns data unchanged. |
|
|
238
|
+
| `constant` | `primitives` | Ignores data, always returns a fixed value. |
|
|
239
|
+
| `lambda_action` | `wrappers` | Adapts a raw callable into an Action. |
|
|
240
|
+
| `tap` | `wrappers` | Runs an action for its side effect; always returns the original data. |
|
|
241
|
+
| `retry` | `wrappers` | Retries an action up to N times on failure. |
|
|
242
|
+
| `log_action` | `wrappers` | Logs the data flowing through one pipeline point, unchanged. |
|
|
243
|
+
|
|
244
|
+
Every container above also ships under a more descriptive alias (`guarded_action`,
|
|
245
|
+
`run_in_sequence`, `pass_through`, ...) — see the full list in the containers reference.
|
|
246
|
+
|
|
247
|
+
➡️ [README_CONTAINERS](https://github.com/simplibs/simplibs-actions/blob/main/docs/README_CONTAINERS.md)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 🏗️ Creating Actions
|
|
252
|
+
|
|
253
|
+
Any function becomes an `Action` two ways: the decorator (everyday use), or the
|
|
254
|
+
function it wraps (when you need to build one dynamically):
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from simplibs.actions import to_action, create_action
|
|
258
|
+
|
|
259
|
+
@to_action
|
|
260
|
+
def greet(data: dict, prefix: str = "Hi") -> str:
|
|
261
|
+
return f"{prefix}, {data['name']}!"
|
|
262
|
+
|
|
263
|
+
# Equivalent, without the decorator:
|
|
264
|
+
Greet = create_action(greet)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
`create_action` fully annotates, validates, and documents the generated class's
|
|
268
|
+
`__init__`/`__call__`/`act` — nothing about the source function's own signature is lost
|
|
269
|
+
or flattened into `(*args, **kwargs)`.
|
|
270
|
+
|
|
271
|
+
➡️ [README_CREATOR](https://github.com/simplibs/simplibs-actions/blob/main/docs/README_CREATOR.md) — `create_action` and every internal resolver/generator it's built from
|
|
272
|
+
➡️ [README_DECOTATOR](https://github.com/simplibs/simplibs-actions/blob/main/docs/README_DECOTATOR.md) — `to_action`, the decorator interface
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 🧪 Testing Utilities
|
|
277
|
+
|
|
278
|
+
`simplibs-actions` includes its own contract-testing tools, so this library's containers
|
|
279
|
+
— and any `Action` a downstream library builds on top of it — can be audited with one
|
|
280
|
+
function call instead of a hand-written test module per action:
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
from simplibs.actions.testing import assert_action
|
|
284
|
+
|
|
285
|
+
# Full deterministic contract: valid/invalid execution, type introspection, construction guard
|
|
286
|
+
assert_action(
|
|
287
|
+
subtests,
|
|
288
|
+
my_action,
|
|
289
|
+
valid_values=[...], expected_outputs=[...],
|
|
290
|
+
invalid_values=[...], expected_exception_type=SomeError,
|
|
291
|
+
)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
➡️ [README_TESTING_ASSERT_ACTION](https://github.com/simplibs/simplibs-actions/blob/main/docs/README_TESTING_ASSERT_ACTION.md)
|
|
295
|
+
➡️ [README_TESTING_ASSERT_ACTION_ALIAS](https://github.com/simplibs/simplibs-actions/blob/main/docs/README_TESTING_ASSERT_ACTION_ALIAS.md) — identity + smoke-test verification for alias objects
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## ⚠️ Exceptions
|
|
300
|
+
|
|
301
|
+
Every diagnostic this library raises — a rejected constructor argument, a type
|
|
302
|
+
mismatch on call, an unsupported source-function signature — is a structured
|
|
303
|
+
[`simplibs.exception`](https://pypi.org/project/simplibs-exception/) card
|
|
304
|
+
(`ParamError`, `ValidationError`, ...), not a bare `TypeError`/`ValueError` traceback.
|
|
305
|
+
Validation failures on a generated `Action`'s own parameters (constructor or call) go
|
|
306
|
+
through [`simplibs-validate`](https://pypi.org/project/simplibs-validate/)'s
|
|
307
|
+
`validate_call`, using the same annotation-decomposition engine as
|
|
308
|
+
[`simplibs-rules`](https://pypi.org/project/simplibs-rules/).
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## 🔗 Related libraries
|
|
313
|
+
|
|
314
|
+
* **[`simplibs-rules`](https://pypi.org/project/simplibs-rules/)** — the `Rule`
|
|
315
|
+
abstraction actions compose with directly (`rule >> action`, `rule & action`, ...)
|
|
316
|
+
and the engine behind `guard`'s condition checking.
|
|
317
|
+
* **[`simplibs-validate`](https://pypi.org/project/simplibs-validate/)** —
|
|
318
|
+
`validate_call`/`log_this`, applied to every generated `Action`'s `__init__`/
|
|
319
|
+
`__call__`/`act`.
|
|
320
|
+
* **[`simplibs-exception`](https://pypi.org/project/simplibs-exception/)** — the
|
|
321
|
+
structured diagnostic cards every failure in this library raises, and the testing
|
|
322
|
+
primitives (`assert_function_raises`, `assert_exception_function`) `assert_action`
|
|
323
|
+
is built on.
|
|
324
|
+
* **[`simplibs-types`](https://pypi.org/project/simplibs-types/)** — reusable
|
|
325
|
+
validated types (like `tuple_not_empty`) used as annotations on several built-in
|
|
326
|
+
containers (`sequence`'s `steps`, `parallel`'s `branches`).
|
|
327
|
+
|
|
328
|
+
`simplibs-actions` is, in turn, the foundation other `simplibs` libraries build their
|
|
329
|
+
own domain-specific actions on top of — each ships ready-made `Action`s for its own
|
|
330
|
+
area alongside its standalone functions.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## ☯️ About simplibs
|
|
335
|
+
|
|
336
|
+
All libraries in the **simplibs** (Simple Libraries) ecosystem share a common engineering philosophy:
|
|
337
|
+
|
|
338
|
+
* **Dyslexia-friendly:**
|
|
339
|
+
We actively minimize cognitive load. Code is atomized into small, self-contained units,
|
|
340
|
+
files are named directly after the logical task they perform,
|
|
341
|
+
and explanations describe *why* something is designed, not just *what* it is.
|
|
342
|
+
* **Programmer's Zen:**
|
|
343
|
+
Nothing should be missing, and nothing should be superfluous.
|
|
344
|
+
We value clean execution paths and robust, understandable code architectures over rushed, messy feature sets.
|
|
345
|
+
* **Defensive Style:**
|
|
346
|
+
We actively anticipate edge cases and failure modes so that only safe operational paths remain.
|
|
347
|
+
Our code is built to degrade gracefully rather than crash unexpectedly.
|
|
348
|
+
* **Minimalism:**
|
|
349
|
+
Find the most direct path to the goal in as few operational steps as possible
|
|
350
|
+
without taking shortcuts on safety, readability, or completeness.
|
|
351
|
+
* **Code as Craft:**
|
|
352
|
+
Code should be pleasant to look at, readable at a glance, and evoke structural harmony.
|
|
353
|
+
We treat software engineering as a precision trade.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### 🤝 Contributing & Community
|
|
358
|
+
|
|
359
|
+
This is an **open-source project** built with love and care.
|
|
360
|
+
We strongly believe in community collaboration and welcome any feedback, bug reports, or feature ideas!
|
|
361
|
+
|
|
362
|
+
* **Want to contribute?** Feel free to open an Issue or submit a Pull Request.
|
|
363
|
+
* **Want to get in touch?** If you'd like to discuss the project further, collaborate,
|
|
364
|
+
or just say hello, feel free to open a GitHub Issue or start a Discussion.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
### 📝 License
|
|
369
|
+
|
|
370
|
+
This library is released under the **MIT License**. Build great things!
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
[▲ Back to Top](#-simplibs-actions)
|