ergon-framework-python 0.1.0__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.
- ergon/__init__.py +13 -0
- ergon/bootstrap/src/__project__/__init__.py +0 -0
- ergon/bootstrap/src/__project__/_observability/docker-compose.telemetry.yml +124 -0
- ergon/bootstrap/src/__project__/_observability/grafana.yaml +17 -0
- ergon/bootstrap/src/__project__/_observability/loki.yaml +48 -0
- ergon/bootstrap/src/__project__/_observability/otel-collector-config.yaml +53 -0
- ergon/bootstrap/src/__project__/_observability/prometheus.yaml +11 -0
- ergon/bootstrap/src/__project__/_observability/tempo.yaml +24 -0
- ergon/bootstrap/src/__project__/connectors/__init__.py +0 -0
- ergon/bootstrap/src/__project__/main.py +9 -0
- ergon/bootstrap/src/__project__/tasks/__init__.py +0 -0
- ergon/bootstrap/src/__project__/tasks/constants.py +13 -0
- ergon/bootstrap/src/__project__/tasks/example_task/__init__.py +0 -0
- ergon/bootstrap/src/__project__/tasks/example_task/config.py +4 -0
- ergon/bootstrap/src/__project__/tasks/example_task/exceptions.py +4 -0
- ergon/bootstrap/src/__project__/tasks/example_task/helpers.py +4 -0
- ergon/bootstrap/src/__project__/tasks/example_task/schemas.py +5 -0
- ergon/bootstrap/src/__project__/tasks/example_task/task.py +1 -0
- ergon/bootstrap/src/__project__/tasks/exceptions.py +0 -0
- ergon/bootstrap/src/__project__/tasks/helpers.py +0 -0
- ergon/bootstrap/src/__project__/tasks/schemas.py +0 -0
- ergon/bootstrap/src/__project__/tasks/settings.py +5 -0
- ergon/cli.py +174 -0
- ergon/connector/__init__.py +64 -0
- ergon/connector/connector.py +97 -0
- ergon/connector/excel/__init__.py +18 -0
- ergon/connector/excel/connector.py +175 -0
- ergon/connector/excel/models.py +24 -0
- ergon/connector/excel/service.py +98 -0
- ergon/connector/pipefy/__init__.py +21 -0
- ergon/connector/pipefy/async_connector.py +48 -0
- ergon/connector/pipefy/async_service.py +907 -0
- ergon/connector/pipefy/connector.py +36 -0
- ergon/connector/pipefy/models.py +48 -0
- ergon/connector/pipefy/service.py +1016 -0
- ergon/connector/pipefy/version.py +1 -0
- ergon/connector/postgres/__init__.py +11 -0
- ergon/connector/postgres/async_connector.py +119 -0
- ergon/connector/postgres/async_service.py +116 -0
- ergon/connector/postgres/models.py +34 -0
- ergon/connector/rabbitmq/__init__.py +25 -0
- ergon/connector/rabbitmq/async_connector.py +120 -0
- ergon/connector/rabbitmq/async_service.py +417 -0
- ergon/connector/rabbitmq/connector.py +54 -0
- ergon/connector/rabbitmq/helper.py +14 -0
- ergon/connector/rabbitmq/models.py +92 -0
- ergon/connector/rabbitmq/service.py +199 -0
- ergon/connector/sqs/__init__.py +15 -0
- ergon/connector/sqs/async_connector.py +120 -0
- ergon/connector/sqs/async_service.py +246 -0
- ergon/connector/sqs/connector.py +120 -0
- ergon/connector/sqs/models.py +36 -0
- ergon/connector/sqs/service.py +219 -0
- ergon/connector/transaction.py +14 -0
- ergon/py.typed +0 -0
- ergon/service/__init__.py +5 -0
- ergon/service/service.py +17 -0
- ergon/task/__init__.py +13 -0
- ergon/task/base.py +222 -0
- ergon/task/exceptions.py +217 -0
- ergon/task/helpers.py +691 -0
- ergon/task/manager.py +85 -0
- ergon/task/mixins/__init__.py +13 -0
- ergon/task/mixins/consumer.py +858 -0
- ergon/task/mixins/metrics.py +457 -0
- ergon/task/mixins/producer.py +486 -0
- ergon/task/policies.py +229 -0
- ergon/task/runner.py +386 -0
- ergon/task/utils.py +64 -0
- ergon/telemetry/__init__.py +7 -0
- ergon/telemetry/_resource.py +13 -0
- ergon/telemetry/logging.py +370 -0
- ergon/telemetry/metrics.py +101 -0
- ergon/telemetry/tracing.py +152 -0
- ergon/utils/__init__.py +5 -0
- ergon/utils/env.py +26 -0
- ergon_framework_python-0.1.0.dist-info/METADATA +449 -0
- ergon_framework_python-0.1.0.dist-info/RECORD +82 -0
- ergon_framework_python-0.1.0.dist-info/WHEEL +5 -0
- ergon_framework_python-0.1.0.dist-info/entry_points.txt +2 -0
- ergon_framework_python-0.1.0.dist-info/licenses/LICENSE +21 -0
- ergon_framework_python-0.1.0.dist-info/top_level.txt +1 -0
ergon/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
services:
|
|
2
|
+
|
|
3
|
+
############################################################
|
|
4
|
+
# OpenTelemetry Collector
|
|
5
|
+
############################################################
|
|
6
|
+
otel-collector:
|
|
7
|
+
image: otel/opentelemetry-collector-contrib:0.114.0
|
|
8
|
+
container_name: ergon-otel-collector
|
|
9
|
+
restart: unless-stopped
|
|
10
|
+
command: ["--config=/etc/otelcol/config.yaml"]
|
|
11
|
+
volumes:
|
|
12
|
+
- ./otel-collector-config.yaml:/etc/otelcol/config.yaml:ro
|
|
13
|
+
ports:
|
|
14
|
+
- "4317:4317" # OTLP gRPC
|
|
15
|
+
- "4318:4318" # OTLP HTTP
|
|
16
|
+
- "9464:9464" # Prometheus scrape (metrics)
|
|
17
|
+
depends_on:
|
|
18
|
+
- tempo
|
|
19
|
+
- loki
|
|
20
|
+
healthcheck:
|
|
21
|
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:13133/"]
|
|
22
|
+
interval: 10s
|
|
23
|
+
timeout: 5s
|
|
24
|
+
retries: 5
|
|
25
|
+
networks:
|
|
26
|
+
- ergon-telemetry
|
|
27
|
+
|
|
28
|
+
############################################################
|
|
29
|
+
# Loki (Logs)
|
|
30
|
+
############################################################
|
|
31
|
+
loki:
|
|
32
|
+
image: grafana/loki:3.0.0
|
|
33
|
+
container_name: ergon-loki
|
|
34
|
+
restart: unless-stopped
|
|
35
|
+
volumes:
|
|
36
|
+
- ./loki.yaml:/etc/loki/config.yaml:ro
|
|
37
|
+
- loki-data:/loki
|
|
38
|
+
command: -config.file=/etc/loki/config.yaml
|
|
39
|
+
ports:
|
|
40
|
+
- "3100:3100"
|
|
41
|
+
healthcheck:
|
|
42
|
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3100/ready"]
|
|
43
|
+
interval: 10s
|
|
44
|
+
timeout: 5s
|
|
45
|
+
retries: 5
|
|
46
|
+
networks:
|
|
47
|
+
- ergon-telemetry
|
|
48
|
+
|
|
49
|
+
############################################################
|
|
50
|
+
# Tempo (Traces)
|
|
51
|
+
############################################################
|
|
52
|
+
tempo:
|
|
53
|
+
image: grafana/tempo:2.4.1
|
|
54
|
+
container_name: ergon-tempo
|
|
55
|
+
restart: unless-stopped
|
|
56
|
+
volumes:
|
|
57
|
+
- ./tempo.yaml:/etc/tempo/config.yaml:ro
|
|
58
|
+
- tempo-data:/var/tempo
|
|
59
|
+
command: ["-config.file=/etc/tempo/config.yaml"]
|
|
60
|
+
ports:
|
|
61
|
+
- "3200:3200"
|
|
62
|
+
healthcheck:
|
|
63
|
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3200/ready"]
|
|
64
|
+
interval: 10s
|
|
65
|
+
timeout: 5s
|
|
66
|
+
retries: 5
|
|
67
|
+
networks:
|
|
68
|
+
- ergon-telemetry
|
|
69
|
+
|
|
70
|
+
############################################################
|
|
71
|
+
# Prometheus (Metrics)
|
|
72
|
+
############################################################
|
|
73
|
+
prometheus:
|
|
74
|
+
image: prom/prometheus:latest
|
|
75
|
+
container_name: ergon-prometheus
|
|
76
|
+
restart: unless-stopped
|
|
77
|
+
volumes:
|
|
78
|
+
- ./prometheus.yaml:/etc/prometheus/prometheus.yml:ro
|
|
79
|
+
- prom-data:/prometheus
|
|
80
|
+
command:
|
|
81
|
+
- "--config.file=/etc/prometheus/prometheus.yml"
|
|
82
|
+
ports:
|
|
83
|
+
- "9090:9090"
|
|
84
|
+
depends_on:
|
|
85
|
+
- otel-collector
|
|
86
|
+
healthcheck:
|
|
87
|
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:9090/-/ready"]
|
|
88
|
+
interval: 10s
|
|
89
|
+
timeout: 5s
|
|
90
|
+
retries: 5
|
|
91
|
+
networks:
|
|
92
|
+
- ergon-telemetry
|
|
93
|
+
|
|
94
|
+
############################################################
|
|
95
|
+
# Grafana Dashboard UI
|
|
96
|
+
############################################################
|
|
97
|
+
grafana:
|
|
98
|
+
image: grafana/grafana:10.4.0
|
|
99
|
+
container_name: ergon-grafana
|
|
100
|
+
restart: unless-stopped
|
|
101
|
+
volumes:
|
|
102
|
+
- ./grafana.yaml:/etc/grafana/provisioning/datasources/datasources.yaml:ro
|
|
103
|
+
- grafana-data:/var/lib/grafana
|
|
104
|
+
ports:
|
|
105
|
+
- "3000:3000"
|
|
106
|
+
networks:
|
|
107
|
+
- ergon-telemetry
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
############################################################
|
|
111
|
+
# Volumes
|
|
112
|
+
############################################################
|
|
113
|
+
volumes:
|
|
114
|
+
loki-data:
|
|
115
|
+
tempo-data:
|
|
116
|
+
prom-data:
|
|
117
|
+
grafana-data:
|
|
118
|
+
|
|
119
|
+
############################################################
|
|
120
|
+
# Network
|
|
121
|
+
############################################################
|
|
122
|
+
networks:
|
|
123
|
+
ergon-telemetry:
|
|
124
|
+
driver: bridge
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
apiVersion: 1
|
|
2
|
+
|
|
3
|
+
datasources:
|
|
4
|
+
- name: Loki
|
|
5
|
+
type: loki
|
|
6
|
+
access: proxy
|
|
7
|
+
url: http://loki:3100
|
|
8
|
+
|
|
9
|
+
- name: Tempo
|
|
10
|
+
type: tempo
|
|
11
|
+
access: proxy
|
|
12
|
+
url: http://tempo:3200
|
|
13
|
+
|
|
14
|
+
- name: Prometheus
|
|
15
|
+
type: prometheus
|
|
16
|
+
access: proxy
|
|
17
|
+
url: http://prometheus:9090
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
auth_enabled: false
|
|
2
|
+
|
|
3
|
+
server:
|
|
4
|
+
http_listen_port: 3100
|
|
5
|
+
grpc_listen_port: 9096
|
|
6
|
+
|
|
7
|
+
common:
|
|
8
|
+
instance_addr: 127.0.0.1
|
|
9
|
+
path_prefix: /loki
|
|
10
|
+
storage:
|
|
11
|
+
filesystem:
|
|
12
|
+
chunks_directory: /loki/chunks
|
|
13
|
+
rules_directory: /loki/rules
|
|
14
|
+
replication_factor: 1
|
|
15
|
+
ring:
|
|
16
|
+
kvstore:
|
|
17
|
+
store: inmemory
|
|
18
|
+
|
|
19
|
+
query_range:
|
|
20
|
+
results_cache:
|
|
21
|
+
cache:
|
|
22
|
+
embedded_cache:
|
|
23
|
+
enabled: true
|
|
24
|
+
max_size_mb: 100
|
|
25
|
+
|
|
26
|
+
schema_config:
|
|
27
|
+
configs:
|
|
28
|
+
- from: "2024-01-01"
|
|
29
|
+
store: tsdb
|
|
30
|
+
object_store: filesystem
|
|
31
|
+
schema: v13
|
|
32
|
+
index:
|
|
33
|
+
prefix: index_
|
|
34
|
+
period: 24h
|
|
35
|
+
|
|
36
|
+
pattern_ingester:
|
|
37
|
+
enabled: true
|
|
38
|
+
|
|
39
|
+
compactor:
|
|
40
|
+
working_directory: /loki/boltdb-shipper-compactor
|
|
41
|
+
# shared_store: filesystem <-- REMOVED (Invalid in Loki 3.0)
|
|
42
|
+
delete_request_store: filesystem # <-- ADDED (Required for retention)
|
|
43
|
+
retention_enabled: true
|
|
44
|
+
|
|
45
|
+
limits_config:
|
|
46
|
+
retention_period: 24h
|
|
47
|
+
allow_structured_metadata: true
|
|
48
|
+
max_query_length: 720h
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
receivers:
|
|
2
|
+
otlp:
|
|
3
|
+
protocols:
|
|
4
|
+
http:
|
|
5
|
+
endpoint: 0.0.0.0:4318
|
|
6
|
+
grpc:
|
|
7
|
+
endpoint: 0.0.0.0:4317
|
|
8
|
+
|
|
9
|
+
exporters:
|
|
10
|
+
loki:
|
|
11
|
+
endpoint: http://loki:3100/loki/api/v1/push
|
|
12
|
+
labels:
|
|
13
|
+
resource:
|
|
14
|
+
service.name: "service_name"
|
|
15
|
+
service.version: "service_version"
|
|
16
|
+
ergon.task.name: "task_name"
|
|
17
|
+
ergon.task.execution.host.name: "host_name"
|
|
18
|
+
attributes:
|
|
19
|
+
level: "level"
|
|
20
|
+
|
|
21
|
+
default_labels_enabled:
|
|
22
|
+
exporter: false
|
|
23
|
+
resource: false
|
|
24
|
+
attributes: false
|
|
25
|
+
scope: false
|
|
26
|
+
|
|
27
|
+
otlphttp/tempo:
|
|
28
|
+
endpoint: http://tempo:4318
|
|
29
|
+
tls:
|
|
30
|
+
insecure: true
|
|
31
|
+
|
|
32
|
+
prometheus:
|
|
33
|
+
endpoint: "0.0.0.0:9464"
|
|
34
|
+
|
|
35
|
+
processors:
|
|
36
|
+
batch: {}
|
|
37
|
+
|
|
38
|
+
service:
|
|
39
|
+
pipelines:
|
|
40
|
+
logs:
|
|
41
|
+
receivers: [otlp]
|
|
42
|
+
processors: [batch] # ← Changed: removed "resource"
|
|
43
|
+
exporters: [loki]
|
|
44
|
+
|
|
45
|
+
traces:
|
|
46
|
+
receivers: [otlp]
|
|
47
|
+
processors: [batch] # ← Changed: removed "resource"
|
|
48
|
+
exporters: [otlphttp/tempo]
|
|
49
|
+
|
|
50
|
+
metrics:
|
|
51
|
+
receivers: [otlp]
|
|
52
|
+
processors: [batch]
|
|
53
|
+
exporters: [prometheus]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
server:
|
|
2
|
+
http_listen_port: 3200
|
|
3
|
+
grpc_listen_port: 9095
|
|
4
|
+
|
|
5
|
+
distributor:
|
|
6
|
+
receivers:
|
|
7
|
+
otlp:
|
|
8
|
+
protocols:
|
|
9
|
+
grpc:
|
|
10
|
+
http:
|
|
11
|
+
|
|
12
|
+
ingester:
|
|
13
|
+
max_block_bytes: 100_000_000
|
|
14
|
+
max_block_duration: 5m
|
|
15
|
+
|
|
16
|
+
compactor:
|
|
17
|
+
compaction:
|
|
18
|
+
block_retention: 24h
|
|
19
|
+
|
|
20
|
+
storage:
|
|
21
|
+
trace:
|
|
22
|
+
backend: local
|
|
23
|
+
local:
|
|
24
|
+
path: /var/tempo/traces
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from ergon.task.policies import RetryPolicy
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
# --- RETRY POLICY CONFIGURATION ---
|
|
6
|
+
# ----------------------------------------
|
|
7
|
+
def default_retry_policy():
|
|
8
|
+
return RetryPolicy(
|
|
9
|
+
max_attempts=3,
|
|
10
|
+
backoff=1,
|
|
11
|
+
backoff_multiplier=2,
|
|
12
|
+
backoff_cap=10,
|
|
13
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# from ergon import task, connector
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
ergon/cli.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
import shutil
|
|
4
|
+
import sys
|
|
5
|
+
import uuid
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
from .connector import Transaction
|
|
10
|
+
from .task.base import TaskConfig
|
|
11
|
+
from .task.manager import manager
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# ---------------------------------------------------------------------
|
|
15
|
+
# Utility: bootstrap project
|
|
16
|
+
# ---------------------------------------------------------------------
|
|
17
|
+
def bootstrap_project(project_name: str, target_dir: str):
|
|
18
|
+
root = Path(__file__).resolve().parent
|
|
19
|
+
template_src = root / "bootstrap" / "src" / "__project__"
|
|
20
|
+
|
|
21
|
+
if not template_src.exists():
|
|
22
|
+
raise RuntimeError(f"Template missing: {template_src}")
|
|
23
|
+
|
|
24
|
+
target = Path(target_dir).resolve()
|
|
25
|
+
target_src = target / "src" / project_name
|
|
26
|
+
target_src.mkdir(parents=True, exist_ok=True)
|
|
27
|
+
|
|
28
|
+
for item in template_src.rglob("*"):
|
|
29
|
+
rel = item.relative_to(template_src)
|
|
30
|
+
dest = target_src / rel
|
|
31
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
32
|
+
if item.is_file():
|
|
33
|
+
shutil.copy2(item, dest)
|
|
34
|
+
|
|
35
|
+
print(f"✔ Bootstrapped successfully at src/{project_name}")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ---------------------------------------------------------------------
|
|
39
|
+
# CLI parser
|
|
40
|
+
# ---------------------------------------------------------------------
|
|
41
|
+
def create_parser():
|
|
42
|
+
parser = argparse.ArgumentParser(
|
|
43
|
+
prog="ergon",
|
|
44
|
+
description="Ergon Task Framework CLI",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
48
|
+
|
|
49
|
+
# -------------------------------------------------------------
|
|
50
|
+
# ergon list
|
|
51
|
+
# -------------------------------------------------------------
|
|
52
|
+
subparsers.add_parser("list", help="List all registered tasks")
|
|
53
|
+
|
|
54
|
+
# -------------------------------------------------------------
|
|
55
|
+
# ergon run <task>
|
|
56
|
+
# -------------------------------------------------------------
|
|
57
|
+
run_parser = subparsers.add_parser("run", help="Run a registered task")
|
|
58
|
+
run_parser.add_argument("task_name", type=str)
|
|
59
|
+
|
|
60
|
+
# -------------------------------------------------------------
|
|
61
|
+
# ergon process-transaction
|
|
62
|
+
# -------------------------------------------------------------
|
|
63
|
+
tx_parser = subparsers.add_parser(
|
|
64
|
+
"process-transaction",
|
|
65
|
+
help="Process a single transaction (inline payload)",
|
|
66
|
+
)
|
|
67
|
+
tx_parser.add_argument("task", type=str)
|
|
68
|
+
tx_parser.add_argument("policy", type=str)
|
|
69
|
+
tx_parser.add_argument(
|
|
70
|
+
"--payload-json",
|
|
71
|
+
required=True,
|
|
72
|
+
help="Transaction payload as JSON string",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# -------------------------------------------------------------
|
|
76
|
+
# ergon process-transaction-by-id
|
|
77
|
+
# -------------------------------------------------------------
|
|
78
|
+
tx_id_parser = subparsers.add_parser(
|
|
79
|
+
"process-transaction-by-id",
|
|
80
|
+
help="Process a transaction by ID via connector fetch",
|
|
81
|
+
)
|
|
82
|
+
tx_id_parser.add_argument("task", type=str)
|
|
83
|
+
tx_id_parser.add_argument("policy", type=str)
|
|
84
|
+
tx_id_parser.add_argument("transaction_id", type=str)
|
|
85
|
+
|
|
86
|
+
# -------------------------------------------------------------
|
|
87
|
+
# ergon bootstrap
|
|
88
|
+
# -------------------------------------------------------------
|
|
89
|
+
bootstrap_parser = subparsers.add_parser(
|
|
90
|
+
"bootstrap",
|
|
91
|
+
help="Create a new project using the Ergon template",
|
|
92
|
+
)
|
|
93
|
+
bootstrap_parser.add_argument("project_name", type=str)
|
|
94
|
+
bootstrap_parser.add_argument(
|
|
95
|
+
"target_dir",
|
|
96
|
+
nargs="?",
|
|
97
|
+
default=".",
|
|
98
|
+
help="Target directory (default: current directory)",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
return parser
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ---------------------------------------------------------------------
|
|
105
|
+
# CLI entry point
|
|
106
|
+
# ---------------------------------------------------------------------
|
|
107
|
+
def ergon(tasks: Optional[List[TaskConfig]] = None):
|
|
108
|
+
if tasks:
|
|
109
|
+
for cfg in tasks:
|
|
110
|
+
if not manager.get(cfg.name):
|
|
111
|
+
manager.register(cfg)
|
|
112
|
+
|
|
113
|
+
parser = create_parser()
|
|
114
|
+
args = parser.parse_args()
|
|
115
|
+
|
|
116
|
+
if not args.command:
|
|
117
|
+
parser.print_help()
|
|
118
|
+
sys.exit(1)
|
|
119
|
+
|
|
120
|
+
# -------------------------------------------------------------
|
|
121
|
+
# LIST TASKS
|
|
122
|
+
# -------------------------------------------------------------
|
|
123
|
+
if args.command == "list":
|
|
124
|
+
task_names = manager.list_tasks()
|
|
125
|
+
if not task_names:
|
|
126
|
+
print("No tasks registered. Did you import your config files?")
|
|
127
|
+
else:
|
|
128
|
+
print("Registered tasks:")
|
|
129
|
+
for t in task_names:
|
|
130
|
+
print(f" - {t}")
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
# -------------------------------------------------------------
|
|
134
|
+
# RUN TASK
|
|
135
|
+
# -------------------------------------------------------------
|
|
136
|
+
if args.command == "run":
|
|
137
|
+
manager.run(args.task_name)
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
# -------------------------------------------------------------
|
|
141
|
+
# PROCESS TRANSACTION (INLINE)
|
|
142
|
+
# -------------------------------------------------------------
|
|
143
|
+
if args.command == "process-transaction":
|
|
144
|
+
try:
|
|
145
|
+
payload = json.loads(args.payload_json)
|
|
146
|
+
except json.JSONDecodeError as exc:
|
|
147
|
+
print(f"[ERROR] Invalid JSON payload: {exc}")
|
|
148
|
+
sys.exit(2)
|
|
149
|
+
|
|
150
|
+
transaction = Transaction(id=str(uuid.uuid4()), payload=payload)
|
|
151
|
+
manager.process_transaction(
|
|
152
|
+
task=args.task,
|
|
153
|
+
policy=args.policy,
|
|
154
|
+
transaction=transaction,
|
|
155
|
+
)
|
|
156
|
+
return
|
|
157
|
+
|
|
158
|
+
# -------------------------------------------------------------
|
|
159
|
+
# PROCESS TRANSACTION BY ID
|
|
160
|
+
# -------------------------------------------------------------
|
|
161
|
+
if args.command == "process-transaction-by-id":
|
|
162
|
+
manager.process_transaction_by_id(
|
|
163
|
+
task=args.task,
|
|
164
|
+
policy=args.policy,
|
|
165
|
+
transaction_id=args.transaction_id,
|
|
166
|
+
)
|
|
167
|
+
return
|
|
168
|
+
|
|
169
|
+
# -------------------------------------------------------------
|
|
170
|
+
# BOOTSTRAP
|
|
171
|
+
# -------------------------------------------------------------
|
|
172
|
+
if args.command == "bootstrap":
|
|
173
|
+
bootstrap_project(args.project_name, args.target_dir)
|
|
174
|
+
return
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from .connector import AsyncConnector, Connector, ConnectorConfig
|
|
2
|
+
from .excel import ExcelConnector, ExcelFetchConfig, ExcelRow, ExcelService
|
|
3
|
+
from .postgres import (
|
|
4
|
+
AsyncPostgresConnector,
|
|
5
|
+
AsyncPostgresService,
|
|
6
|
+
PostgresClient,
|
|
7
|
+
PostgresConsumerConfig,
|
|
8
|
+
PostgresProducerConfig,
|
|
9
|
+
)
|
|
10
|
+
from .rabbitmq import (
|
|
11
|
+
AsyncRabbitmqClient,
|
|
12
|
+
AsyncRabbitMQConnector,
|
|
13
|
+
AsyncRabbitmqConsumerConfig,
|
|
14
|
+
AsyncRabbitmqProducerConfig,
|
|
15
|
+
AsyncRabbitMQService,
|
|
16
|
+
RabbitmqClient,
|
|
17
|
+
RabbitMQConnector,
|
|
18
|
+
RabbitmqConsumerMessage,
|
|
19
|
+
RabbitmqProducerMessage,
|
|
20
|
+
RabbitMQService,
|
|
21
|
+
)
|
|
22
|
+
from .sqs import (
|
|
23
|
+
AsyncSQSConnector,
|
|
24
|
+
AsyncSQSService,
|
|
25
|
+
SQSClient,
|
|
26
|
+
SQSConnector,
|
|
27
|
+
SQSConsumerConfig,
|
|
28
|
+
SQSProducerConfig,
|
|
29
|
+
SQSService,
|
|
30
|
+
)
|
|
31
|
+
from .transaction import Transaction
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"AsyncConnector",
|
|
35
|
+
"AsyncPostgresConnector",
|
|
36
|
+
"AsyncPostgresService",
|
|
37
|
+
"AsyncRabbitMQConnector",
|
|
38
|
+
"AsyncRabbitMQService",
|
|
39
|
+
"AsyncRabbitmqClient",
|
|
40
|
+
"AsyncRabbitmqConsumerConfig",
|
|
41
|
+
"AsyncRabbitmqProducerConfig",
|
|
42
|
+
"AsyncSQSConnector",
|
|
43
|
+
"AsyncSQSService",
|
|
44
|
+
"Connector",
|
|
45
|
+
"ConnectorConfig",
|
|
46
|
+
"ExcelConnector",
|
|
47
|
+
"ExcelFetchConfig",
|
|
48
|
+
"ExcelRow",
|
|
49
|
+
"ExcelService",
|
|
50
|
+
"PostgresClient",
|
|
51
|
+
"PostgresConsumerConfig",
|
|
52
|
+
"PostgresProducerConfig",
|
|
53
|
+
"RabbitMQConnector",
|
|
54
|
+
"RabbitMQService",
|
|
55
|
+
"RabbitmqClient",
|
|
56
|
+
"RabbitmqConsumerMessage",
|
|
57
|
+
"RabbitmqProducerMessage",
|
|
58
|
+
"SQSClient",
|
|
59
|
+
"SQSConnector",
|
|
60
|
+
"SQSConsumerConfig",
|
|
61
|
+
"SQSProducerConfig",
|
|
62
|
+
"SQSService",
|
|
63
|
+
"Transaction",
|
|
64
|
+
]
|