avtomatika 1.0b6__tar.gz → 1.0b8__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.
- {avtomatika-1.0b6/src/avtomatika.egg-info → avtomatika-1.0b8}/PKG-INFO +91 -3
- {avtomatika-1.0b6 → avtomatika-1.0b8}/README.md +84 -1
- {avtomatika-1.0b6 → avtomatika-1.0b8}/pyproject.toml +5 -2
- avtomatika-1.0b8/src/avtomatika/api/handlers.py +549 -0
- avtomatika-1.0b8/src/avtomatika/api/routes.py +118 -0
- avtomatika-1.0b8/src/avtomatika/app_keys.py +33 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/blueprint.py +125 -54
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/config.py +10 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/context.py +2 -2
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/data_types.py +4 -2
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/dispatcher.py +9 -27
- avtomatika-1.0b8/src/avtomatika/engine.py +398 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/executor.py +55 -22
- avtomatika-1.0b8/src/avtomatika/health_checker.py +57 -0
- avtomatika-1.0b8/src/avtomatika/history/base.py +105 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/history/noop.py +18 -7
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/history/postgres.py +8 -6
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/history/sqlite.py +7 -5
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/metrics.py +1 -1
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/reputation.py +46 -40
- avtomatika-1.0b8/src/avtomatika/s3.py +323 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/scheduler.py +8 -8
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/storage/base.py +45 -4
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/storage/memory.py +56 -13
- avtomatika-1.0b8/src/avtomatika/storage/redis.py +443 -0
- avtomatika-1.0b8/src/avtomatika/utils/__init__.py +0 -0
- avtomatika-1.0b8/src/avtomatika/utils/webhook_sender.py +96 -0
- avtomatika-1.0b8/src/avtomatika/watcher.py +78 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/ws_manager.py +7 -6
- {avtomatika-1.0b6 → avtomatika-1.0b8/src/avtomatika.egg-info}/PKG-INFO +91 -3
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika.egg-info/SOURCES.txt +11 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika.egg-info/requires.txt +7 -1
- avtomatika-1.0b8/tests/test_blueprint_integrity.py +100 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_dispatcher.py +31 -44
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_dispatcher_extended.py +7 -3
- avtomatika-1.0b8/tests/test_engine.py +293 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_error_handling.py +21 -13
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_executor.py +71 -0
- avtomatika-1.0b8/tests/test_handlers.py +459 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_history.py +15 -7
- avtomatika-1.0b8/tests/test_optimization.py +83 -0
- avtomatika-1.0b8/tests/test_postgres_history.py +84 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_reputation.py +2 -2
- avtomatika-1.0b8/tests/test_s3.py +265 -0
- avtomatika-1.0b8/tests/test_webhook_sender.py +74 -0
- avtomatika-1.0b6/src/avtomatika/engine.py +0 -929
- avtomatika-1.0b6/src/avtomatika/health_checker.py +0 -39
- avtomatika-1.0b6/src/avtomatika/history/base.py +0 -51
- avtomatika-1.0b6/src/avtomatika/storage/redis.py +0 -510
- avtomatika-1.0b6/src/avtomatika/watcher.py +0 -82
- avtomatika-1.0b6/tests/test_engine.py +0 -678
- avtomatika-1.0b6/tests/test_postgres_history.py +0 -107
- {avtomatika-1.0b6 → avtomatika-1.0b8}/LICENSE +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/setup.cfg +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/__init__.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/api.html +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/client_config_loader.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/compression.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/constants.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/datastore.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/logging_config.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/py.typed +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/quota.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/ratelimit.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/scheduler_config_loader.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/security.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/storage/__init__.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/telemetry.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika/worker_config_loader.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika.egg-info/dependency_links.txt +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/src/avtomatika.egg-info/top_level.txt +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_blueprint_conditions.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_blueprints.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_client_config_loader.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_compression.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_config_validation.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_context.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_health_checker.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_integration.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_logging_config.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_memory_locking.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_memory_storage.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_metrics.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_noop_history.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_ratelimit.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_redis_locking.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_redis_storage.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_scheduler.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_telemetry.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_watcher.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_worker_config_loader.py +0 -0
- {avtomatika-1.0b6 → avtomatika-1.0b8}/tests/test_ws_manager.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: avtomatika
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.0b8
|
|
4
4
|
Summary: A state-machine based orchestrator for long-running AI and other jobs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/avtomatika-ai/avtomatika
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/avtomatika-ai/avtomatika/issues
|
|
@@ -12,7 +12,6 @@ Requires-Python: >=3.11
|
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: aiohttp~=3.12
|
|
15
|
-
Requires-Dist: aiocache~=0.12
|
|
16
15
|
Requires-Dist: python-json-logger~=4.0
|
|
17
16
|
Requires-Dist: graphviz~=0.21
|
|
18
17
|
Requires-Dist: zstandard~=0.24
|
|
@@ -21,6 +20,9 @@ Requires-Dist: msgpack~=1.1
|
|
|
21
20
|
Requires-Dist: orjson~=3.11
|
|
22
21
|
Provides-Extra: redis
|
|
23
22
|
Requires-Dist: redis~=7.1; extra == "redis"
|
|
23
|
+
Provides-Extra: s3
|
|
24
|
+
Requires-Dist: obstore>=0.2; extra == "s3"
|
|
25
|
+
Requires-Dist: aiofiles~=23.2; extra == "s3"
|
|
24
26
|
Provides-Extra: history
|
|
25
27
|
Requires-Dist: aiosqlite~=0.22; extra == "history"
|
|
26
28
|
Requires-Dist: asyncpg~=0.30; extra == "history"
|
|
@@ -38,10 +40,13 @@ Requires-Dist: pytest-mock~=3.14; extra == "test"
|
|
|
38
40
|
Requires-Dist: aioresponses~=0.7; extra == "test"
|
|
39
41
|
Requires-Dist: backports.zstd~=1.2; extra == "test"
|
|
40
42
|
Requires-Dist: opentelemetry-instrumentation-aiohttp-client; extra == "test"
|
|
43
|
+
Requires-Dist: obstore>=0.2; extra == "test"
|
|
44
|
+
Requires-Dist: aiofiles~=23.2; extra == "test"
|
|
41
45
|
Provides-Extra: all
|
|
42
46
|
Requires-Dist: avtomatika[redis]; extra == "all"
|
|
43
47
|
Requires-Dist: avtomatika[history]; extra == "all"
|
|
44
48
|
Requires-Dist: avtomatika[telemetry]; extra == "all"
|
|
49
|
+
Requires-Dist: avtomatika[s3]; extra == "all"
|
|
45
50
|
Dynamic: license-file
|
|
46
51
|
|
|
47
52
|
# Avtomatika Orchestrator
|
|
@@ -61,6 +66,8 @@ This document serves as a comprehensive guide for developers looking to build pi
|
|
|
61
66
|
- [Parallel Execution and Aggregation (Fan-out/Fan-in)](#parallel-execution-and-aggregation-fan-outfan-in)
|
|
62
67
|
- [Dependency Injection (DataStore)](#dependency-injection-datastore)
|
|
63
68
|
- [Native Scheduler](#native-scheduler)
|
|
69
|
+
- [S3 Payload Offloading](#s3-payload-offloading)
|
|
70
|
+
- [Webhook Notifications](#webhook-notifications)
|
|
64
71
|
- [Production Configuration](#production-configuration)
|
|
65
72
|
- [Fault Tolerance](#fault-tolerance)
|
|
66
73
|
- [Storage Backend](#storage-backend)
|
|
@@ -107,6 +114,11 @@ Avtomatika is part of a larger ecosystem:
|
|
|
107
114
|
pip install "avtomatika[telemetry]"
|
|
108
115
|
```
|
|
109
116
|
|
|
117
|
+
* **Install with S3 support (Payload Offloading):**
|
|
118
|
+
```bash
|
|
119
|
+
pip install "avtomatika[s3]"
|
|
120
|
+
```
|
|
121
|
+
|
|
110
122
|
* **Install all dependencies, including for testing:**
|
|
111
123
|
```bash
|
|
112
124
|
pip install "avtomatika[all,test]"
|
|
@@ -157,7 +169,13 @@ async def end_handler(context):
|
|
|
157
169
|
engine = OrchestratorEngine(storage, config)
|
|
158
170
|
engine.register_blueprint(my_blueprint)
|
|
159
171
|
|
|
160
|
-
# 4.
|
|
172
|
+
# 4. Accessing Components (Optional)
|
|
173
|
+
# You can access the internal aiohttp app and core components using AppKeys
|
|
174
|
+
# from avtomatika.app_keys import ENGINE_KEY, DISPATCHER_KEY
|
|
175
|
+
# app = engine.app
|
|
176
|
+
# dispatcher = app[DISPATCHER_KEY]
|
|
177
|
+
|
|
178
|
+
# 5. Define the main entrypoint to run the server
|
|
161
179
|
async def main():
|
|
162
180
|
await engine.start()
|
|
163
181
|
|
|
@@ -244,6 +262,19 @@ async def publish_handler_old_style(context):
|
|
|
244
262
|
print(f"Job {context.job_id}: Publishing video at {output_path} ({duration}s).")
|
|
245
263
|
context.actions.transition_to("complete")
|
|
246
264
|
```
|
|
265
|
+
## Key Concepts: JobContext and Actions
|
|
266
|
+
|
|
267
|
+
### High Performance Architecture
|
|
268
|
+
|
|
269
|
+
Avtomatika is engineered for high-load environments with thousands of concurrent workers.
|
|
270
|
+
|
|
271
|
+
* **O(1) Dispatcher**: Uses advanced Redis Set intersections to find suitable workers instantly, regardless of the cluster size. No O(N) scanning.
|
|
272
|
+
* **Non-Blocking I/O**:
|
|
273
|
+
* **Webhooks**: Sent via a bounded background queue to prevent backpressure.
|
|
274
|
+
* **History Logging**: Writes to SQL databases are buffered and asynchronous, ensuring the main execution loop never blocks.
|
|
275
|
+
* **Redis Streams**: Uses blocking reads to eliminate busy-waiting and reduce CPU usage.
|
|
276
|
+
* **Memory Safety**: S3 file transfers use streaming to handle multi-gigabyte files with constant, low RAM usage.
|
|
277
|
+
|
|
247
278
|
## Blueprint Cookbook: Key Features
|
|
248
279
|
|
|
249
280
|
### 1. Conditional Transitions (`.when()`)
|
|
@@ -355,6 +386,63 @@ blueprint = "backup_flow"
|
|
|
355
386
|
daily_at = "02:00"
|
|
356
387
|
```
|
|
357
388
|
|
|
389
|
+
### 6. Webhook Notifications
|
|
390
|
+
|
|
391
|
+
The orchestrator can send asynchronous notifications to an external system when a job completes, fails, or is quarantined. This eliminates the need for clients to constantly poll the API for status updates.
|
|
392
|
+
|
|
393
|
+
### 7. S3 Payload Offloading
|
|
394
|
+
|
|
395
|
+
Orchestrator provides first-class support for handling large files via S3-compatible storage, powered by the high-performance `obstore` library (Rust bindings).
|
|
396
|
+
|
|
397
|
+
* **Memory Safe (Streaming)**: Uses streaming for uploads and downloads, allowing processing of files larger than available RAM without OOM errors.
|
|
398
|
+
* **Managed Mode**: The Orchestrator manages file lifecycle (automatic cleanup of S3 objects and local temporary files on job completion).
|
|
399
|
+
* **Dependency Injection**: Use the `task_files` argument in your handlers to easily read/write data.
|
|
400
|
+
* **Directory Support**: Supports recursive download and upload of entire directories.
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
@bp.handler_for("process_data")
|
|
404
|
+
async def process_data(task_files, actions):
|
|
405
|
+
# Streaming download of a large file
|
|
406
|
+
local_path = await task_files.download("large_dataset.csv")
|
|
407
|
+
|
|
408
|
+
# ... process data ...
|
|
409
|
+
|
|
410
|
+
# Upload results
|
|
411
|
+
await task_files.write_json("results.json", {"status": "done"})
|
|
412
|
+
|
|
413
|
+
actions.transition_to("finished")
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Production Configuration
|
|
417
|
+
* **Events:**
|
|
418
|
+
* `job_finished`: The job reached a final success state.
|
|
419
|
+
* `job_failed`: The job failed (e.g., due to an error or invalid input).
|
|
420
|
+
* `job_quarantined`: The job was moved to quarantine after repeated failures.
|
|
421
|
+
|
|
422
|
+
**Example Request:**
|
|
423
|
+
```json
|
|
424
|
+
POST /api/v1/jobs/my_flow
|
|
425
|
+
{
|
|
426
|
+
"initial_data": {
|
|
427
|
+
"video_url": "..."
|
|
428
|
+
},
|
|
429
|
+
"webhook_url": "https://my-app.com/webhooks/avtomatika"
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**Example Webhook Payload:**
|
|
434
|
+
```json
|
|
435
|
+
{
|
|
436
|
+
"event": "job_finished",
|
|
437
|
+
"job_id": "123e4567-e89b-12d3-a456-426614174000",
|
|
438
|
+
"status": "finished",
|
|
439
|
+
"result": {
|
|
440
|
+
"output_path": "/videos/result.mp4"
|
|
441
|
+
},
|
|
442
|
+
"error": null
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
358
446
|
## Production Configuration
|
|
359
447
|
|
|
360
448
|
The orchestrator's behavior can be configured through environment variables. Additionally, any configuration parameter loaded from environment variables can be programmatically overridden in your application code after the `Config` object has been initialized. This provides flexibility for different deployment and testing scenarios.
|
|
@@ -15,6 +15,8 @@ This document serves as a comprehensive guide for developers looking to build pi
|
|
|
15
15
|
- [Parallel Execution and Aggregation (Fan-out/Fan-in)](#parallel-execution-and-aggregation-fan-outfan-in)
|
|
16
16
|
- [Dependency Injection (DataStore)](#dependency-injection-datastore)
|
|
17
17
|
- [Native Scheduler](#native-scheduler)
|
|
18
|
+
- [S3 Payload Offloading](#s3-payload-offloading)
|
|
19
|
+
- [Webhook Notifications](#webhook-notifications)
|
|
18
20
|
- [Production Configuration](#production-configuration)
|
|
19
21
|
- [Fault Tolerance](#fault-tolerance)
|
|
20
22
|
- [Storage Backend](#storage-backend)
|
|
@@ -61,6 +63,11 @@ Avtomatika is part of a larger ecosystem:
|
|
|
61
63
|
pip install "avtomatika[telemetry]"
|
|
62
64
|
```
|
|
63
65
|
|
|
66
|
+
* **Install with S3 support (Payload Offloading):**
|
|
67
|
+
```bash
|
|
68
|
+
pip install "avtomatika[s3]"
|
|
69
|
+
```
|
|
70
|
+
|
|
64
71
|
* **Install all dependencies, including for testing:**
|
|
65
72
|
```bash
|
|
66
73
|
pip install "avtomatika[all,test]"
|
|
@@ -111,7 +118,13 @@ async def end_handler(context):
|
|
|
111
118
|
engine = OrchestratorEngine(storage, config)
|
|
112
119
|
engine.register_blueprint(my_blueprint)
|
|
113
120
|
|
|
114
|
-
# 4.
|
|
121
|
+
# 4. Accessing Components (Optional)
|
|
122
|
+
# You can access the internal aiohttp app and core components using AppKeys
|
|
123
|
+
# from avtomatika.app_keys import ENGINE_KEY, DISPATCHER_KEY
|
|
124
|
+
# app = engine.app
|
|
125
|
+
# dispatcher = app[DISPATCHER_KEY]
|
|
126
|
+
|
|
127
|
+
# 5. Define the main entrypoint to run the server
|
|
115
128
|
async def main():
|
|
116
129
|
await engine.start()
|
|
117
130
|
|
|
@@ -198,6 +211,19 @@ async def publish_handler_old_style(context):
|
|
|
198
211
|
print(f"Job {context.job_id}: Publishing video at {output_path} ({duration}s).")
|
|
199
212
|
context.actions.transition_to("complete")
|
|
200
213
|
```
|
|
214
|
+
## Key Concepts: JobContext and Actions
|
|
215
|
+
|
|
216
|
+
### High Performance Architecture
|
|
217
|
+
|
|
218
|
+
Avtomatika is engineered for high-load environments with thousands of concurrent workers.
|
|
219
|
+
|
|
220
|
+
* **O(1) Dispatcher**: Uses advanced Redis Set intersections to find suitable workers instantly, regardless of the cluster size. No O(N) scanning.
|
|
221
|
+
* **Non-Blocking I/O**:
|
|
222
|
+
* **Webhooks**: Sent via a bounded background queue to prevent backpressure.
|
|
223
|
+
* **History Logging**: Writes to SQL databases are buffered and asynchronous, ensuring the main execution loop never blocks.
|
|
224
|
+
* **Redis Streams**: Uses blocking reads to eliminate busy-waiting and reduce CPU usage.
|
|
225
|
+
* **Memory Safety**: S3 file transfers use streaming to handle multi-gigabyte files with constant, low RAM usage.
|
|
226
|
+
|
|
201
227
|
## Blueprint Cookbook: Key Features
|
|
202
228
|
|
|
203
229
|
### 1. Conditional Transitions (`.when()`)
|
|
@@ -309,6 +335,63 @@ blueprint = "backup_flow"
|
|
|
309
335
|
daily_at = "02:00"
|
|
310
336
|
```
|
|
311
337
|
|
|
338
|
+
### 6. Webhook Notifications
|
|
339
|
+
|
|
340
|
+
The orchestrator can send asynchronous notifications to an external system when a job completes, fails, or is quarantined. This eliminates the need for clients to constantly poll the API for status updates.
|
|
341
|
+
|
|
342
|
+
### 7. S3 Payload Offloading
|
|
343
|
+
|
|
344
|
+
Orchestrator provides first-class support for handling large files via S3-compatible storage, powered by the high-performance `obstore` library (Rust bindings).
|
|
345
|
+
|
|
346
|
+
* **Memory Safe (Streaming)**: Uses streaming for uploads and downloads, allowing processing of files larger than available RAM without OOM errors.
|
|
347
|
+
* **Managed Mode**: The Orchestrator manages file lifecycle (automatic cleanup of S3 objects and local temporary files on job completion).
|
|
348
|
+
* **Dependency Injection**: Use the `task_files` argument in your handlers to easily read/write data.
|
|
349
|
+
* **Directory Support**: Supports recursive download and upload of entire directories.
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
@bp.handler_for("process_data")
|
|
353
|
+
async def process_data(task_files, actions):
|
|
354
|
+
# Streaming download of a large file
|
|
355
|
+
local_path = await task_files.download("large_dataset.csv")
|
|
356
|
+
|
|
357
|
+
# ... process data ...
|
|
358
|
+
|
|
359
|
+
# Upload results
|
|
360
|
+
await task_files.write_json("results.json", {"status": "done"})
|
|
361
|
+
|
|
362
|
+
actions.transition_to("finished")
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Production Configuration
|
|
366
|
+
* **Events:**
|
|
367
|
+
* `job_finished`: The job reached a final success state.
|
|
368
|
+
* `job_failed`: The job failed (e.g., due to an error or invalid input).
|
|
369
|
+
* `job_quarantined`: The job was moved to quarantine after repeated failures.
|
|
370
|
+
|
|
371
|
+
**Example Request:**
|
|
372
|
+
```json
|
|
373
|
+
POST /api/v1/jobs/my_flow
|
|
374
|
+
{
|
|
375
|
+
"initial_data": {
|
|
376
|
+
"video_url": "..."
|
|
377
|
+
},
|
|
378
|
+
"webhook_url": "https://my-app.com/webhooks/avtomatika"
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Example Webhook Payload:**
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"event": "job_finished",
|
|
386
|
+
"job_id": "123e4567-e89b-12d3-a456-426614174000",
|
|
387
|
+
"status": "finished",
|
|
388
|
+
"result": {
|
|
389
|
+
"output_path": "/videos/result.mp4"
|
|
390
|
+
},
|
|
391
|
+
"error": null
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
312
395
|
## Production Configuration
|
|
313
396
|
|
|
314
397
|
The orchestrator's behavior can be configured through environment variables. Additionally, any configuration parameter loaded from environment variables can be programmatically overridden in your application code after the `Config` object has been initialized. This provides flexibility for different deployment and testing scenarios.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "avtomatika"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.0b8"
|
|
8
8
|
description = "A state-machine based orchestrator for long-running AI and other jobs."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -16,7 +16,6 @@ classifiers = [
|
|
|
16
16
|
]
|
|
17
17
|
dependencies = [
|
|
18
18
|
"aiohttp~=3.12",
|
|
19
|
-
"aiocache~=0.12",
|
|
20
19
|
"python-json-logger~=4.0",
|
|
21
20
|
"graphviz~=0.21",
|
|
22
21
|
"zstandard~=0.24",
|
|
@@ -27,6 +26,7 @@ dependencies = [
|
|
|
27
26
|
|
|
28
27
|
[project.optional-dependencies]
|
|
29
28
|
redis = ["redis~=7.1"]
|
|
29
|
+
s3 = ["obstore>=0.2", "aiofiles~=23.2"]
|
|
30
30
|
history = ["aiosqlite~=0.22", "asyncpg~=0.30"]
|
|
31
31
|
telemetry = [
|
|
32
32
|
"opentelemetry-api~=1.39",
|
|
@@ -43,11 +43,14 @@ test = [
|
|
|
43
43
|
"aioresponses~=0.7",
|
|
44
44
|
"backports.zstd~=1.2",
|
|
45
45
|
"opentelemetry-instrumentation-aiohttp-client",
|
|
46
|
+
"obstore>=0.2",
|
|
47
|
+
"aiofiles~=23.2",
|
|
46
48
|
]
|
|
47
49
|
all = [
|
|
48
50
|
"avtomatika[redis]",
|
|
49
51
|
"avtomatika[history]",
|
|
50
52
|
"avtomatika[telemetry]",
|
|
53
|
+
"avtomatika[s3]",
|
|
51
54
|
]
|
|
52
55
|
|
|
53
56
|
[project.urls]
|