puffinflow 2.dev0__py3-none-any.whl

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.
Files changed (55) hide show
  1. puffinflow/__init__.py +132 -0
  2. puffinflow/core/__init__.py +110 -0
  3. puffinflow/core/agent/__init__.py +320 -0
  4. puffinflow/core/agent/base.py +1635 -0
  5. puffinflow/core/agent/checkpoint.py +50 -0
  6. puffinflow/core/agent/context.py +521 -0
  7. puffinflow/core/agent/decorators/__init__.py +90 -0
  8. puffinflow/core/agent/decorators/builder.py +454 -0
  9. puffinflow/core/agent/decorators/flexible.py +714 -0
  10. puffinflow/core/agent/decorators/inspection.py +144 -0
  11. puffinflow/core/agent/dependencies.py +57 -0
  12. puffinflow/core/agent/scheduling/__init__.py +21 -0
  13. puffinflow/core/agent/scheduling/builder.py +160 -0
  14. puffinflow/core/agent/scheduling/exceptions.py +35 -0
  15. puffinflow/core/agent/scheduling/inputs.py +137 -0
  16. puffinflow/core/agent/scheduling/parser.py +209 -0
  17. puffinflow/core/agent/scheduling/scheduler.py +413 -0
  18. puffinflow/core/agent/state.py +141 -0
  19. puffinflow/core/config.py +62 -0
  20. puffinflow/core/coordination/__init__.py +137 -0
  21. puffinflow/core/coordination/agent_group.py +359 -0
  22. puffinflow/core/coordination/agent_pool.py +629 -0
  23. puffinflow/core/coordination/agent_team.py +577 -0
  24. puffinflow/core/coordination/coordinator.py +720 -0
  25. puffinflow/core/coordination/deadlock.py +1759 -0
  26. puffinflow/core/coordination/fluent_api.py +421 -0
  27. puffinflow/core/coordination/primitives.py +478 -0
  28. puffinflow/core/coordination/rate_limiter.py +520 -0
  29. puffinflow/core/observability/__init__.py +47 -0
  30. puffinflow/core/observability/agent.py +139 -0
  31. puffinflow/core/observability/alerting.py +73 -0
  32. puffinflow/core/observability/config.py +127 -0
  33. puffinflow/core/observability/context.py +88 -0
  34. puffinflow/core/observability/core.py +147 -0
  35. puffinflow/core/observability/decorators.py +105 -0
  36. puffinflow/core/observability/events.py +71 -0
  37. puffinflow/core/observability/interfaces.py +196 -0
  38. puffinflow/core/observability/metrics.py +137 -0
  39. puffinflow/core/observability/tracing.py +209 -0
  40. puffinflow/core/reliability/__init__.py +27 -0
  41. puffinflow/core/reliability/bulkhead.py +96 -0
  42. puffinflow/core/reliability/circuit_breaker.py +149 -0
  43. puffinflow/core/reliability/leak_detector.py +122 -0
  44. puffinflow/core/resources/__init__.py +77 -0
  45. puffinflow/core/resources/allocation.py +790 -0
  46. puffinflow/core/resources/pool.py +645 -0
  47. puffinflow/core/resources/quotas.py +567 -0
  48. puffinflow/core/resources/requirements.py +217 -0
  49. puffinflow/version.py +21 -0
  50. puffinflow-2.dev0.dist-info/METADATA +334 -0
  51. puffinflow-2.dev0.dist-info/RECORD +55 -0
  52. puffinflow-2.dev0.dist-info/WHEEL +5 -0
  53. puffinflow-2.dev0.dist-info/entry_points.txt +3 -0
  54. puffinflow-2.dev0.dist-info/licenses/LICENSE +21 -0
  55. puffinflow-2.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,217 @@
1
+ """
2
+ Resource requirements and types for PuffinFlow resource management.
3
+ """
4
+
5
+ import logging
6
+ from dataclasses import dataclass
7
+ from enum import Flag
8
+ from typing import TYPE_CHECKING, Optional, Union
9
+
10
+ if TYPE_CHECKING:
11
+ from ..agent.state import Priority
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class ResourceType(Flag):
17
+ """Resource type flags for specifying required resources."""
18
+
19
+ NONE = 0
20
+ CPU = 1
21
+ MEMORY = 2
22
+ IO = 4
23
+ NETWORK = 8
24
+ GPU = 16
25
+
26
+ # Convenience combination for all resource types
27
+ ALL = CPU | MEMORY | IO | NETWORK | GPU
28
+
29
+
30
+ @dataclass
31
+ class ResourceRequirements:
32
+ """
33
+ Specifies resource requirements for agent states.
34
+
35
+ This class defines the computational resources needed by an agent state,
36
+ including CPU, memory, I/O, network, and GPU resources, along with
37
+ priority and timeout specifications.
38
+ """
39
+
40
+ cpu_units: float = 1.0
41
+ memory_mb: float = 100.0
42
+ io_weight: float = 1.0
43
+ network_weight: float = 1.0
44
+ gpu_units: float = 0.0
45
+ priority_boost: int = 0
46
+ timeout: Optional[float] = None
47
+ resource_types: ResourceType = ResourceType.ALL
48
+
49
+ def __post_init__(self) -> None:
50
+ """Ensure resource_types is always a valid ResourceType enum."""
51
+ try:
52
+ # Validate that it supports bitwise operations
53
+ try:
54
+ test_result = self.resource_types & ResourceType.CPU
55
+ logger.debug(
56
+ f"Bitwise test successful: {self.resource_types} & CPU = {test_result}"
57
+ )
58
+ except Exception as e:
59
+ logger.warning(f"Bitwise operation failed: {e}")
60
+ self._auto_determine_resource_types()
61
+
62
+ except Exception as e:
63
+ logger.error(f"Error in ResourceRequirements.__post_init__: {e}")
64
+ # Fallback to a safe default
65
+ object.__setattr__(self, "resource_types", ResourceType.ALL)
66
+
67
+ def _auto_determine_resource_types(self) -> None:
68
+ """Auto-determine resource_types from individual resource amounts."""
69
+ resource_types = ResourceType.NONE
70
+
71
+ if getattr(self, "cpu_units", 0) > 0:
72
+ resource_types |= ResourceType.CPU
73
+ if getattr(self, "memory_mb", 0) > 0:
74
+ resource_types |= ResourceType.MEMORY
75
+ if getattr(self, "io_weight", 0) > 0:
76
+ resource_types |= ResourceType.IO
77
+ if getattr(self, "network_weight", 0) > 0:
78
+ resource_types |= ResourceType.NETWORK
79
+ if getattr(self, "gpu_units", 0) > 0:
80
+ resource_types |= ResourceType.GPU
81
+
82
+ # If no specific resources are requested, default to ALL
83
+ if resource_types == ResourceType.NONE:
84
+ resource_types = ResourceType.ALL
85
+
86
+ # Use object.__setattr__ for dataclass
87
+ object.__setattr__(self, "resource_types", resource_types)
88
+ logger.info(f"Auto-determined resource_types: {resource_types}")
89
+
90
+ @property
91
+ def priority(self) -> "Priority":
92
+ """Get priority level based on priority_boost."""
93
+ from ..agent.state import Priority
94
+
95
+ if self.priority_boost <= 0:
96
+ return Priority.LOW
97
+ elif self.priority_boost == 1:
98
+ return Priority.NORMAL
99
+ elif self.priority_boost == 2:
100
+ return Priority.HIGH
101
+ else: # priority_boost >= 3
102
+ return Priority.CRITICAL
103
+
104
+ @priority.setter
105
+ def priority(self, value: Union["Priority", int]) -> None:
106
+ """Set priority level, updating priority_boost accordingly."""
107
+ from ..agent.state import Priority
108
+
109
+ if isinstance(value, Priority):
110
+ self.priority_boost = value.value
111
+ elif isinstance(value, int):
112
+ self.priority_boost = value
113
+ else:
114
+ raise TypeError(f"Priority must be Priority enum or int, got {type(value)}")
115
+
116
+
117
+ # Resource attribute mapping for get_resource_amount function
118
+ RESOURCE_ATTRIBUTE_MAPPING = {
119
+ ResourceType.CPU: "cpu_units",
120
+ ResourceType.MEMORY: "memory_mb",
121
+ ResourceType.IO: "io_weight",
122
+ ResourceType.NETWORK: "network_weight",
123
+ ResourceType.GPU: "gpu_units",
124
+ }
125
+
126
+
127
+ def safe_check_resource_type(
128
+ requirements: ResourceRequirements, resource_type: ResourceType
129
+ ) -> bool:
130
+ """
131
+ Safely check if a resource type is requested in requirements.
132
+
133
+ Args:
134
+ requirements: The ResourceRequirements object
135
+ resource_type: The ResourceType to check
136
+
137
+ Returns:
138
+ True if the resource type is requested, False otherwise
139
+ """
140
+ try:
141
+ # First try the normal bitwise operation
142
+ return bool(requirements.resource_types & resource_type)
143
+ except TypeError as e:
144
+ logger.warning(
145
+ f"Bitwise operation failed: {e}. Falling back to value comparison."
146
+ )
147
+ try:
148
+ # Fallback to value-based comparison
149
+ return bool(requirements.resource_types.value & resource_type.value)
150
+ except Exception as e2:
151
+ logger.error(
152
+ f"Fallback comparison also failed: {e2}. Assuming resource is requested."
153
+ )
154
+ # If all else fails, check if the individual resource amount is > 0
155
+ # Direct attribute access to avoid circular dependency
156
+ if resource_type in RESOURCE_ATTRIBUTE_MAPPING:
157
+ attr_name = RESOURCE_ATTRIBUTE_MAPPING[resource_type]
158
+ return getattr(requirements, attr_name, 0.0) > 0
159
+ return True
160
+
161
+
162
+ def get_resource_amount(
163
+ requirements: ResourceRequirements, resource_type: ResourceType
164
+ ) -> float:
165
+ """
166
+ Get the amount of a specific resource type from requirements.
167
+
168
+ Args:
169
+ requirements: The ResourceRequirements object
170
+ resource_type: The ResourceType to get the amount for
171
+
172
+ Returns:
173
+ The amount of the specified resource type, or 0.0 if the resource type is not enabled
174
+
175
+ Raises:
176
+ ValueError: If resource_type is not a single resource type
177
+ """
178
+ if resource_type == ResourceType.NONE:
179
+ return 0.0
180
+
181
+ # Check if the resource type is enabled in the requirements
182
+ if not safe_check_resource_type(requirements, resource_type):
183
+ return 0.0
184
+
185
+ if resource_type == ResourceType.ALL:
186
+ # Return sum of all resource amounts
187
+ total = 0.0
188
+ for rt, attr in RESOURCE_ATTRIBUTE_MAPPING.items():
189
+ if safe_check_resource_type(requirements, rt):
190
+ total += getattr(requirements, attr, 0.0)
191
+ return total
192
+
193
+ # Check if it's a single resource type (power of 2, excluding NONE)
194
+ if (
195
+ resource_type.value > 0
196
+ and (resource_type.value & (resource_type.value - 1)) == 0
197
+ and resource_type in RESOURCE_ATTRIBUTE_MAPPING
198
+ ):
199
+ attr_name = RESOURCE_ATTRIBUTE_MAPPING[resource_type]
200
+ return getattr(requirements, attr_name, 0.0)
201
+
202
+ # Handle combined resource types by summing individual types
203
+ total = 0.0
204
+ for rt, attr in RESOURCE_ATTRIBUTE_MAPPING.items():
205
+ try:
206
+ if (resource_type.value & rt.value) != 0 and safe_check_resource_type(
207
+ requirements, rt
208
+ ):
209
+ total += getattr(requirements, attr, 0.0)
210
+ except TypeError:
211
+ # Fallback if 'in' operation fails
212
+ if (resource_type.value & rt.value) != 0 and safe_check_resource_type(
213
+ requirements, rt
214
+ ):
215
+ total += getattr(requirements, attr, 0.0)
216
+
217
+ return total
puffinflow/version.py ADDED
@@ -0,0 +1,21 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
6
+ TYPE_CHECKING = False
7
+ if TYPE_CHECKING:
8
+ from typing import Tuple
9
+ from typing import Union
10
+
11
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
12
+ else:
13
+ VERSION_TUPLE = object
14
+
15
+ version: str
16
+ __version__: str
17
+ __version_tuple__: VERSION_TUPLE
18
+ version_tuple: VERSION_TUPLE
19
+
20
+ __version__ = version = '2.dev0'
21
+ __version_tuple__ = version_tuple = (2, 'dev0')
@@ -0,0 +1,334 @@
1
+ Metadata-Version: 2.4
2
+ Name: puffinflow
3
+ Version: 2.dev0
4
+ Summary: A powerful Python workflow orchestration framework with advanced resource management and observability
5
+ Author-email: Mohamed Ahmed <mohamed.ahmed.4894@gmail.com>
6
+ Maintainer-email: Mohamed Ahmed <mohamed.ahmed.4894@gmail.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/m-ahmed-elbeskeri/puffinflow-main
9
+ Project-URL: Documentation, https://puffinflow.readthedocs.io
10
+ Project-URL: Repository, https://github.com/m-ahmed-elbeskeri/puffinflow-main.git
11
+ Project-URL: Bug Tracker, https://github.com/m-ahmed-elbeskeri/puffinflow-main/issues
12
+ Project-URL: Changelog, https://github.com/m-ahmed-elbeskeri/puffinflow-main/blob/main/CHANGELOG.md
13
+ Project-URL: Funding, https://github.com/sponsors/m-ahmed-elbeskeri
14
+ Keywords: workflow,orchestration,async,state-management,resource-allocation,task-execution,distributed-systems,monitoring,observability,tracing,metrics,coordination
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Topic :: System :: Distributed Computing
27
+ Classifier: Topic :: System :: Monitoring
28
+ Classifier: Topic :: System :: Systems Administration
29
+ Classifier: Framework :: AsyncIO
30
+ Classifier: Typing :: Typed
31
+ Requires-Python: >=3.9
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
35
+ Requires-Dist: pydantic-settings<3.0.0,>=2.0.0
36
+ Requires-Dist: structlog>=23.1.0
37
+ Requires-Dist: typing-extensions>=4.8.0; python_version < "3.11"
38
+ Requires-Dist: aiohttp>=3.9.0
39
+ Requires-Dist: prometheus-client>=0.19.0
40
+ Requires-Dist: psutil>=5.9.0
41
+ Provides-Extra: dev
42
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
43
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
44
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
45
+ Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
46
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == "dev"
47
+ Requires-Dist: pytest-timeout>=2.2.0; extra == "dev"
48
+ Requires-Dist: pytest-xdist>=3.5.0; extra == "dev"
49
+ Requires-Dist: black>=23.12.0; extra == "dev"
50
+ Requires-Dist: ruff>=0.1.8; extra == "dev"
51
+ Requires-Dist: mypy>=1.8.0; extra == "dev"
52
+ Requires-Dist: types-psutil>=5.9.0; extra == "dev"
53
+ Requires-Dist: pre-commit>=3.6.0; extra == "dev"
54
+ Requires-Dist: tox>=4.11.0; extra == "dev"
55
+ Requires-Dist: coverage[toml]>=7.3.0; extra == "dev"
56
+ Provides-Extra: docs
57
+ Requires-Dist: sphinx>=7.1.0; extra == "docs"
58
+ Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == "docs"
59
+ Requires-Dist: sphinx-autodoc-typehints>=1.25.0; extra == "docs"
60
+ Requires-Dist: myst-parser>=2.0.0; extra == "docs"
61
+ Requires-Dist: sphinxcontrib-asyncio>=0.3.0; extra == "docs"
62
+ Provides-Extra: cli
63
+ Requires-Dist: typer[all]>=0.9.0; extra == "cli"
64
+ Requires-Dist: rich>=13.7.0; extra == "cli"
65
+ Requires-Dist: click>=8.1.0; extra == "cli"
66
+ Provides-Extra: observability
67
+ Requires-Dist: prometheus-client>=0.19.0; extra == "observability"
68
+ Requires-Dist: psutil>=5.9.0; extra == "observability"
69
+ Requires-Dist: opentelemetry-api<2.0.0,>=1.23.0; extra == "observability"
70
+ Requires-Dist: opentelemetry-sdk<2.0.0,>=1.23.0; extra == "observability"
71
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0.0,>=1.23.0; extra == "observability"
72
+ Requires-Dist: opentelemetry-exporter-jaeger-thrift<2.0.0,>=1.21.0; extra == "observability"
73
+ Requires-Dist: opentelemetry-instrumentation-asyncio<1.0.0,>=0.44b0; extra == "observability"
74
+ Requires-Dist: opentelemetry-instrumentation-logging<1.0.0,>=0.44b0; extra == "observability"
75
+ Requires-Dist: aiohttp>=3.9.0; extra == "observability"
76
+ Requires-Dist: httpx>=0.26.0; extra == "observability"
77
+ Requires-Dist: aiosmtplib>=3.0.0; extra == "observability"
78
+ Requires-Dist: deprecated>=1.2.6; extra == "observability"
79
+ Provides-Extra: monitoring
80
+ Requires-Dist: prometheus-client>=0.19.0; extra == "monitoring"
81
+ Requires-Dist: opentelemetry-api<2.0.0,>=1.23.0; extra == "monitoring"
82
+ Requires-Dist: opentelemetry-sdk<2.0.0,>=1.23.0; extra == "monitoring"
83
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0.0,>=1.23.0; extra == "monitoring"
84
+ Requires-Dist: opentelemetry-instrumentation-asyncio<1.0.0,>=0.44b0; extra == "monitoring"
85
+ Provides-Extra: integrations
86
+ Requires-Dist: fastapi>=0.108.0; extra == "integrations"
87
+ Requires-Dist: celery>=5.3.0; extra == "integrations"
88
+ Requires-Dist: kubernetes>=28.0.0; extra == "integrations"
89
+ Requires-Dist: redis>=5.0.0; extra == "integrations"
90
+ Requires-Dist: httpx>=0.26.0; extra == "integrations"
91
+ Requires-Dist: psutil>=5.9.0; extra == "integrations"
92
+ Provides-Extra: performance
93
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == "performance"
94
+ Requires-Dist: memory-profiler>=0.61.0; extra == "performance"
95
+ Requires-Dist: line-profiler>=4.1.0; extra == "performance"
96
+ Requires-Dist: py-spy>=0.3.14; extra == "performance"
97
+ Provides-Extra: security
98
+ Requires-Dist: bandit>=1.7.5; extra == "security"
99
+ Requires-Dist: safety>=2.3.0; extra == "security"
100
+ Requires-Dist: semgrep>=1.45.0; extra == "security"
101
+ Provides-Extra: all
102
+ Requires-Dist: typer[all]>=0.9.0; extra == "all"
103
+ Requires-Dist: rich>=13.7.0; extra == "all"
104
+ Requires-Dist: click>=8.1.0; extra == "all"
105
+ Requires-Dist: prometheus-client>=0.19.0; extra == "all"
106
+ Requires-Dist: psutil>=5.9.0; extra == "all"
107
+ Requires-Dist: opentelemetry-api<2.0.0,>=1.23.0; extra == "all"
108
+ Requires-Dist: opentelemetry-sdk<2.0.0,>=1.23.0; extra == "all"
109
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0.0,>=1.23.0; extra == "all"
110
+ Requires-Dist: opentelemetry-exporter-jaeger-thrift<2.0.0,>=1.21.0; extra == "all"
111
+ Requires-Dist: opentelemetry-instrumentation-asyncio<1.0.0,>=0.44b0; extra == "all"
112
+ Requires-Dist: opentelemetry-instrumentation-logging<1.0.0,>=0.44b0; extra == "all"
113
+ Requires-Dist: aiohttp>=3.9.0; extra == "all"
114
+ Requires-Dist: httpx>=0.26.0; extra == "all"
115
+ Requires-Dist: aiosmtplib>=3.0.0; extra == "all"
116
+ Requires-Dist: fastapi>=0.108.0; extra == "all"
117
+ Requires-Dist: celery>=5.3.0; extra == "all"
118
+ Requires-Dist: kubernetes>=28.0.0; extra == "all"
119
+ Requires-Dist: redis>=5.0.0; extra == "all"
120
+ Dynamic: license-file
121
+
122
+ # 🐧 PuffinFlow
123
+
124
+ [![PyPI version](https://badge.fury.io/py/puffinflow.svg)](https://badge.fury.io/py/puffinflow)
125
+ [![Python versions](https://img.shields.io/pypi/pyversions/puffinflow.svg)](https://pypi.org/project/puffinflow/)
126
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
127
+
128
+ **PuffinFlow is a powerful Python framework for developers who need to rapidly prototype LLM workflows and seamlessly transition them to production-ready systems.**
129
+
130
+ Perfect for AI engineers, data scientists, and backend developers who want to focus on workflow logic rather than infrastructure complexity.
131
+
132
+ ## Get started
133
+
134
+ Install PuffinFlow:
135
+
136
+ ```bash
137
+ pip install puffinflow
138
+ ```
139
+
140
+ Then, create an agent using the state decorator:
141
+
142
+ ```python
143
+ from puffinflow import Agent, state
144
+
145
+ class DataProcessor(Agent):
146
+ @state(cpu=2.0, memory=1024.0)
147
+ async def fetch_data(self, context):
148
+ """Fetch data from external source."""
149
+ data = await get_external_data()
150
+ context.set_variable("raw_data", data)
151
+ return "validate_data" if data else "error"
152
+
153
+ @state(cpu=1.0, memory=512.0)
154
+ async def validate_data(self, context):
155
+ """Validate the fetched data."""
156
+ data = context.get_variable("raw_data")
157
+ if self.is_valid(data):
158
+ return "process_data"
159
+ return "error"
160
+
161
+ @state(cpu=4.0, memory=2048.0)
162
+ async def process_data(self, context):
163
+ """Process the validated data."""
164
+ data = context.get_variable("raw_data")
165
+ result = await self.transform_data(data)
166
+ context.set_output("processed_data", result)
167
+ return "complete"
168
+
169
+ # Run the agent
170
+ agent = DataProcessor("data-processor")
171
+ result = await agent.run()
172
+ ```
173
+
174
+ For more information, see the [Quickstart](https://puffinflow.readthedocs.io/en/latest/guides/quickstart.html). Or, to learn how to build complex multi-agent workflows with coordination and observability, see the [Advanced Examples](./examples/).
175
+
176
+ ## Core benefits
177
+
178
+ PuffinFlow bridges the gap between quick prototyping and production deployment. Start building your LLM workflow in minutes, then scale to production without rewriting code:
179
+
180
+ **Prototype to Production**: Begin with simple agents and seamlessly add resource management, observability, and coordination as your needs grow.
181
+
182
+ **Intelligent resource management**: Automatically allocate and manage CPU, memory, and other resources based on state requirements with built-in quotas and limits.
183
+
184
+ **Zero-config observability**: Comprehensive monitoring with OpenTelemetry integration, custom metrics, distributed tracing, and real-time alerting that works out of the box.
185
+
186
+ **Built-in reliability**: Circuit breakers, bulkheads, and leak detection ensure robust operation under various failure conditions without additional configuration.
187
+
188
+ **Agent coordination**: Scale from single agents to complex multi-agent workflows with teams, pools, and orchestrators using the same simple API.
189
+
190
+ **Production performance**: Achieve 567,000+ operations/second with sub-millisecond latency, designed for real-world production workloads.
191
+
192
+ ## PuffinFlow's ecosystem
193
+
194
+ While PuffinFlow can be used standalone, it integrates with popular Python frameworks and tools:
195
+
196
+ **FastAPI & Django** — Seamlessly integrate PuffinFlow agents into web applications with built-in async support and resource management.
197
+
198
+ **Celery & Redis** — Enhance existing task queues with stateful workflows, advanced coordination, and comprehensive monitoring.
199
+
200
+ **OpenTelemetry** — Full observability stack with distributed tracing, metrics collection, and integration with monitoring platforms like Prometheus and Jaeger.
201
+
202
+ **Kubernetes** — Production-ready deployment with container orchestration, automatic scaling, and cloud-native observability.
203
+
204
+ ## Additional resources
205
+
206
+ - **[Documentation](https://puffinflow.readthedocs.io/)**: Complete guides and API reference
207
+ - **[Examples](./examples/)**: Ready-to-run code examples for common patterns
208
+ - **[Advanced Guides](./docs/source/guides/)**: Deep dives into resource management, coordination, and observability
209
+ - **[Benchmarks](./benchmarks/)**: Performance metrics and optimization guides
210
+
211
+ ---
212
+
213
+ ## Real-World Examples
214
+
215
+ ### 🔥 Image Processing Pipeline
216
+ ```python
217
+ class ImageProcessor(Agent):
218
+ @state(cpu=2.0, memory=1024.0)
219
+ async def resize_image(self, context):
220
+ image_url = context.get_variable("image_url")
221
+ resized = await resize_image(image_url, size=(800, 600))
222
+ context.set_variable("resized_image", resized)
223
+ return "add_watermark"
224
+
225
+ @state(cpu=1.0, memory=512.0)
226
+ async def add_watermark(self, context):
227
+ image = context.get_variable("resized_image")
228
+ watermarked = await add_watermark(image)
229
+ context.set_variable("final_image", watermarked)
230
+ return "upload_to_storage"
231
+
232
+ @state(cpu=1.0, memory=256.0)
233
+ async def upload_to_storage(self, context):
234
+ image = context.get_variable("final_image")
235
+ url = await upload_to_s3(image)
236
+ context.set_output("result_url", url)
237
+ return "complete"
238
+ ```
239
+
240
+ ### 🤖 ML Model Training
241
+ ```python
242
+ class MLTrainer(Agent):
243
+ @state(cpu=8.0, memory=4096.0)
244
+ async def train_model(self, context):
245
+ dataset = context.get_variable("dataset")
246
+ model = await train_neural_network(dataset)
247
+ context.set_variable("model", model)
248
+ context.set_output("accuracy", model.accuracy)
249
+
250
+ if model.accuracy > 0.9:
251
+ return "deploy_model"
252
+ return "retrain_with_more_data"
253
+
254
+ @state(cpu=2.0, memory=1024.0)
255
+ async def deploy_model(self, context):
256
+ model = context.get_variable("model")
257
+ await deploy_to_production(model)
258
+ context.set_output("deployment_status", "success")
259
+ return "complete"
260
+ ```
261
+
262
+ ### 🔄 Multi-Agent Coordination
263
+ ```python
264
+ from puffinflow import create_team, AgentTeam
265
+
266
+ # Coordinate multiple agents
267
+ email_team = create_team([
268
+ EmailValidator("validator"),
269
+ EmailProcessor("processor"),
270
+ EmailTracker("tracker")
271
+ ])
272
+
273
+ # Execute with built-in coordination
274
+ result = await email_team.execute_parallel()
275
+ ```
276
+
277
+ ---
278
+
279
+ ## 🎯 Use Cases
280
+
281
+ **📊 Data Pipelines** — Build resilient ETL workflows with automatic retries, resource management, and comprehensive monitoring.
282
+
283
+ **🤖 ML Workflows** — Orchestrate training pipelines, model deployment, and inference workflows with checkpointing and observability.
284
+
285
+ **🌐 Microservices** — Coordinate distributed services with circuit breakers, bulkheads, and intelligent load balancing.
286
+
287
+ **⚡ Event Processing** — Handle high-throughput event streams with backpressure control and automatic scaling.
288
+
289
+ ## 📊 Performance
290
+
291
+ PuffinFlow is built for production workloads with excellent performance characteristics:
292
+
293
+ ### Core Performance Metrics
294
+ - **567,000+ operations/second** for basic agent operations
295
+ - **27,000+ operations/second** for complex data processing
296
+ - **1,100+ operations/second** for CPU-intensive tasks
297
+ - **Sub-millisecond** state transition latency (0.00-1.97ms range)
298
+
299
+ ### Benchmark Results (Latest)
300
+ | Operation Type | Avg Latency | Throughput | Use Case |
301
+ |---|---|---|---|
302
+ | Agent State Transitions | 0.00ms | 567,526 ops/s | Basic workflow steps |
303
+ | Data Processing | 0.04ms | 27,974 ops/s | ETL operations |
304
+ | Resource Management | 0.01ms | 104,719 ops/s | Memory/CPU allocation |
305
+ | Async Coordination | 1.23ms | 811 ops/s | Multi-agent workflows |
306
+ | CPU-Intensive Tasks | 0.91ms | 1,100 ops/s | ML training steps |
307
+
308
+ *Benchmarks run on: Linux WSL2, 16 cores, 3.68GB RAM, Python 3.12*
309
+
310
+ [View detailed benchmarks →](./benchmarks/)
311
+
312
+ ## 🤝 Community & Support
313
+
314
+ - **[🐛 Issues](https://github.com/m-ahmed-elbeskeri/puffinflow/issues)** — Bug reports and feature requests
315
+ - **[💬 Discussions](https://github.com/m-ahmed-elbeskeri/puffinflow/discussions)** — Community Q&A
316
+ - **[📧 Email](mailto:mohamed.ahmed.4894@gmail.com)** — Direct contact for support
317
+
318
+ ## Acknowledgements
319
+
320
+ PuffinFlow is inspired by workflow orchestration principles and builds upon the Python async ecosystem. The framework emphasizes practical workflow management with production-ready features. PuffinFlow is built by Mohamed Ahmed, designed for developers who need reliable, observable, and scalable workflow orchestration.
321
+
322
+ ## 📜 License
323
+
324
+ PuffinFlow is released under the [MIT License](LICENSE). Free for commercial and personal use.
325
+
326
+ ---
327
+
328
+ <div align="center">
329
+
330
+ **Ready to build production-ready workflows?**
331
+
332
+ [Get Started →](https://puffinflow.readthedocs.io/en/latest/guides/quickstart.html) | [View Examples →](./examples/) | [Join Community →](https://github.com/m-ahmed-elbeskeri/puffinflow/discussions)
333
+
334
+ </div>
@@ -0,0 +1,55 @@
1
+ puffinflow/__init__.py,sha256=UnuscpJdtuwzB9i9m8zbZ-oQWLJWgM-4_TQeXGCy-b0,2623
2
+ puffinflow/version.py,sha256=h4IuJsX5bQcAuFjGgJgLghhjV7tMYP_AObu5mYfUkFo,514
3
+ puffinflow/core/__init__.py,sha256=ky3V0ulDLGExVSBGtCOSw91ulX3TohSDs1czkYIZHb0,3584
4
+ puffinflow/core/config.py,sha256=00ks86HgALGfBGWKoHarEHd8st1RKn-B3D_L5ilShq8,1952
5
+ puffinflow/core/agent/__init__.py,sha256=AFrdpn1UV6fUh19dRg5IDN555nwk8CVXDf8O1usMRMI,8522
6
+ puffinflow/core/agent/base.py,sha256=uXlEkoRcOYf-xwydu9uWOkv0NSUDZUAcSw_alRNPo-c,62386
7
+ puffinflow/core/agent/checkpoint.py,sha256=E3OZMogJ0omMtZI_coeTjRvu8TmqS8DmUMGpqGUclnY,1492
8
+ puffinflow/core/agent/context.py,sha256=KJnrcePY5HZMQCYTD8wrlKF_uJx6gOorUYMDBZoNcfw,18477
9
+ puffinflow/core/agent/dependencies.py,sha256=6LgR98bFs8BFt6CIRwA_auKm_7deOkGCam6pd3dxJYQ,1978
10
+ puffinflow/core/agent/state.py,sha256=2b7nFTxTM-oEKfNkYhThHF-IKvBc0aNTKnd6hehRK0I,3517
11
+ puffinflow/core/agent/decorators/__init__.py,sha256=zyL2L9TFGukFB3KwaQZNY6DW_PrwssAdIYsW4aZHN9Q,2073
12
+ puffinflow/core/agent/decorators/builder.py,sha256=XZ7D7tYRIVO-qZdY0vS1KXdv6q85Qr4zj23zASfm7Eg,14656
13
+ puffinflow/core/agent/decorators/flexible.py,sha256=nGzMU3la6qnu9ePCXNTm7fu5XL0na_CrHZvQXiFctls,25921
14
+ puffinflow/core/agent/decorators/inspection.py,sha256=4oxEjcanc_wz8bW9O2eBlEACCMviag9r0aqxQD5mRUI,4844
15
+ puffinflow/core/agent/scheduling/__init__.py,sha256=JFJgqhrMa0aid_xHgZkCgoJbPEHL58CVsTugELxZmp4,627
16
+ puffinflow/core/agent/scheduling/builder.py,sha256=gNYDNaqYezb-8NbEbXlFEt_7zFZ_K76MODGZF4_EMeA,5077
17
+ puffinflow/core/agent/scheduling/exceptions.py,sha256=3IAWd3QAJ7uh20xBbmla7QGNVbNXYT2V-BzKbzVbE64,1013
18
+ puffinflow/core/agent/scheduling/inputs.py,sha256=o_CHJchV504fQs3yO1POgMIcRAgeU2-er31M5ba5KpQ,4490
19
+ puffinflow/core/agent/scheduling/parser.py,sha256=wovziX-KqdvhozncJOEw0OfEqIaDsPLvaNdTLsfqXV4,7373
20
+ puffinflow/core/agent/scheduling/scheduler.py,sha256=y-2erkDoguy4Yl87tXG1TaVw6ZhQvrNadrxugiYUWMA,13771
21
+ puffinflow/core/coordination/__init__.py,sha256=pGYDH0QJt9z3YUivhTSKmNCE3QC1XugCoGs1J2OE12A,2921
22
+ puffinflow/core/coordination/agent_group.py,sha256=OtEzLBkGRbV6z9gBbrN6kD58hA6vqYhJ55L5U54iCpU,11962
23
+ puffinflow/core/coordination/agent_pool.py,sha256=x6ldfzvcymIUXavbmLMlfC71_J2h2J36H7_goifpSEA,22772
24
+ puffinflow/core/coordination/agent_team.py,sha256=gQAVTuELq0W3lcwPMKAcyCl5AAySFCE8YUn7WxB-BFk,19516
25
+ puffinflow/core/coordination/coordinator.py,sha256=s2OCb6D1Jv49qghD--lEHupr6fgqTCrSiW7o4WoCf-k,26788
26
+ puffinflow/core/coordination/deadlock.py,sha256=QfOBJzzYoSx7_AIE2Pd_-IUcel6WGnr_n0u-z2Yr43c,64950
27
+ puffinflow/core/coordination/fluent_api.py,sha256=kY8hzY0Mp8qcvO7O7soHTdnEVbMiw09lW8PvGdL2suc,14896
28
+ puffinflow/core/coordination/primitives.py,sha256=nIEJkAp4qRpiQWMUYAfQDu988rcc7q_fidoDWYbMmvk,16634
29
+ puffinflow/core/coordination/rate_limiter.py,sha256=0-xHAl8n2-BdrqRGwRX18dG73faXhqSyrzMuB5FTPaE,17692
30
+ puffinflow/core/observability/__init__.py,sha256=7ldAw323pmhmbv9P4ctYlpETHhniMohv-GD93gbhcSY,1045
31
+ puffinflow/core/observability/agent.py,sha256=bUjGbQmfYaSfFLwQ6zRKG2VceXKxAtQliRG7pGBpH7w,5087
32
+ puffinflow/core/observability/alerting.py,sha256=YtFp5y9LhEHkzkihMPWTb7WFUUf6bvpbMefKmMD4H34,2123
33
+ puffinflow/core/observability/config.py,sha256=EScIvDHJuKiyR0FH11eLXpyND_oyAzG-Kgkx1zJXCEw,4296
34
+ puffinflow/core/observability/context.py,sha256=vRxwyRDDzuW59Bn7RteSltTf-tgaJevwme5qsj-Amks,2932
35
+ puffinflow/core/observability/core.py,sha256=LKo_d8O3G-Nh1RZsjWIN9th7x6bLYQ--icoPWfa19SM,4654
36
+ puffinflow/core/observability/decorators.py,sha256=XOiQgsEfc3HDA8FETR1vq1M_xICs0qLZ41TEBOwOPhU,3820
37
+ puffinflow/core/observability/events.py,sha256=4SWO3DjTjRT4yp3SiDQSPqr5TkDeMxryRiL8ljSkE2A,2525
38
+ puffinflow/core/observability/interfaces.py,sha256=LPofmDp4wUw6-Ls8MgI2SnaQj-FgwCV8GXptw405ep0,4897
39
+ puffinflow/core/observability/metrics.py,sha256=tJnCuREaKwL1wXnpF2qjoAmmJKk4S58pVNR9_QSd620,5139
40
+ puffinflow/core/observability/tracing.py,sha256=xWyTy0uA_CDElORkrdfmBTsDP5EUZmNsehkLjCvz6sY,7403
41
+ puffinflow/core/reliability/__init__.py,sha256=N48Hn2JcJQgM3JzMpBU9bdTWFihH7PU7ZXLCpFx_zvk,684
42
+ puffinflow/core/reliability/bulkhead.py,sha256=JE7G6W2V3gggeZ9pipO_W4h_y4YhYOH23a-uvHAAsbs,2895
43
+ puffinflow/core/reliability/circuit_breaker.py,sha256=jWiWowX08ORoJ7OSgBZuN0BLIgLhthYe_lA2vWUp1rU,4735
44
+ puffinflow/core/reliability/leak_detector.py,sha256=z31u2lvO82EfE6eyzAhFOsFaA6MPctsIhKKT0kEtwuA,4089
45
+ puffinflow/core/resources/__init__.py,sha256=wpq1n83Hjr1Ua1DsSlvaZcZbwLvYmhlrb-phBQ038gU,1722
46
+ puffinflow/core/resources/allocation.py,sha256=mZGBLvk6bmOOU8X_I-U2_6rAS1SrFCYztzx513seZ1E,28851
47
+ puffinflow/core/resources/pool.py,sha256=7KkC66c2Y04yUsq6-1O4dl8MGOdrCUzFyGof9kv61uo,24394
48
+ puffinflow/core/resources/quotas.py,sha256=1377rf00LqIVZuuwq7jxat8aFLwZ8i5WgZSD8766-CA,18159
49
+ puffinflow/core/resources/requirements.py,sha256=7J07JVIqa1sL9v-xCC-aGQjS2Vtk9Fwliajp8fOJNRE,7428
50
+ puffinflow-2.dev0.dist-info/licenses/LICENSE,sha256=_iTSa1NhJHVNdoCwmNMrS3nVUTwnEcflmb8zcplrm_g,1067
51
+ puffinflow-2.dev0.dist-info/METADATA,sha256=v1v_K-GCrqfo06io3jZF3cXPJyj8nNGLUoeOA_3NEIU,15172
52
+ puffinflow-2.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
+ puffinflow-2.dev0.dist-info/entry_points.txt,sha256=kFo-w_DMoIAb-mlBdkE4Rp1sBNQ-rosnI0yFLdTfYaI,113
54
+ puffinflow-2.dev0.dist-info/top_level.txt,sha256=76A_vroRA-4hO5-lugaSXM8BSKuWS5f4uIlqPKohiZs,11
55
+ puffinflow-2.dev0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ puffinflow = puffinflow.cli.main:app
3
+ puffinflow-benchmark = benchmarks.run_all_benchmarks:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 PuffinFlow
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ puffinflow