fluidattacks_batch_client 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.
- fluidattacks_batch_client/__init__.py +9 -0
- fluidattacks_batch_client/_cli.py +171 -0
- fluidattacks_batch_client/_logger.py +17 -0
- fluidattacks_batch_client/_utils.py +102 -0
- fluidattacks_batch_client/api/__init__.py +11 -0
- fluidattacks_batch_client/api/_client_1/__init__.py +36 -0
- fluidattacks_batch_client/api/_client_1/_get_command.py +68 -0
- fluidattacks_batch_client/api/_client_1/_list_jobs.py +123 -0
- fluidattacks_batch_client/api/_client_1/_send_job.py +189 -0
- fluidattacks_batch_client/api/_core.py +33 -0
- fluidattacks_batch_client/core.py +310 -0
- fluidattacks_batch_client/decode.py +175 -0
- fluidattacks_batch_client/py.typed +0 -0
- fluidattacks_batch_client/sender/__init__.py +15 -0
- fluidattacks_batch_client/sender/_core.py +26 -0
- fluidattacks_batch_client/sender/_send.py +87 -0
- fluidattacks_batch_client-0.1.0.dist-info/METADATA +9 -0
- fluidattacks_batch_client-0.1.0.dist-info/RECORD +20 -0
- fluidattacks_batch_client-0.1.0.dist-info/WHEEL +4 -0
- fluidattacks_batch_client-0.1.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from fluidattacks_batch_client.api import ApiClient
|
|
2
|
+
from ._send import send_pipeline, send_single_job
|
|
3
|
+
from ._core import BatchJobSender
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def new_sender(client: ApiClient) -> BatchJobSender:
|
|
7
|
+
return BatchJobSender(
|
|
8
|
+
lambda j, d: send_single_job(client, j, d),
|
|
9
|
+
lambda p: send_pipeline(client, p),
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"BatchJobSender",
|
|
15
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from fluidattacks_batch_client.core import (
|
|
2
|
+
AllowDuplicates,
|
|
3
|
+
JobArn,
|
|
4
|
+
JobId,
|
|
5
|
+
JobRequest,
|
|
6
|
+
)
|
|
7
|
+
from collections.abc import (
|
|
8
|
+
Callable,
|
|
9
|
+
)
|
|
10
|
+
from dataclasses import (
|
|
11
|
+
dataclass,
|
|
12
|
+
)
|
|
13
|
+
from fa_purity import (
|
|
14
|
+
Cmd,
|
|
15
|
+
Maybe,
|
|
16
|
+
PureIter,
|
|
17
|
+
UnitType,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class BatchJobSender:
|
|
23
|
+
send_single_job: Callable[
|
|
24
|
+
[JobRequest, AllowDuplicates], Cmd[Maybe[tuple[JobId, JobArn]]]
|
|
25
|
+
]
|
|
26
|
+
send_pipeline: Callable[[PureIter[JobRequest]], Cmd[UnitType]]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from fluidattacks_batch_client.api import (
|
|
2
|
+
ApiClient,
|
|
3
|
+
)
|
|
4
|
+
from fluidattacks_batch_client.core import (
|
|
5
|
+
AllowDuplicates,
|
|
6
|
+
DependentJobRequest,
|
|
7
|
+
JobArn,
|
|
8
|
+
JobDependencies,
|
|
9
|
+
JobRequest,
|
|
10
|
+
JobId,
|
|
11
|
+
JobStatus,
|
|
12
|
+
)
|
|
13
|
+
from fa_purity import (
|
|
14
|
+
Bool,
|
|
15
|
+
Cmd,
|
|
16
|
+
Maybe,
|
|
17
|
+
PureIter,
|
|
18
|
+
CmdUnwrapper,
|
|
19
|
+
UnitType,
|
|
20
|
+
Unsafe,
|
|
21
|
+
unit,
|
|
22
|
+
)
|
|
23
|
+
import logging
|
|
24
|
+
|
|
25
|
+
LOG = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def send_single_job(
|
|
29
|
+
client: ApiClient,
|
|
30
|
+
job: JobRequest,
|
|
31
|
+
allow_duplicates: AllowDuplicates,
|
|
32
|
+
) -> Cmd[Maybe[tuple[JobId, JobArn]]]:
|
|
33
|
+
dup_msg = Cmd.wrap_impure(lambda: LOG.info("Detecting duplicates..."))
|
|
34
|
+
skipped_msg = Cmd[None].wrap_impure(
|
|
35
|
+
lambda: LOG.warning("Duplicated job detected. Skipping job submission")
|
|
36
|
+
)
|
|
37
|
+
allow_send = Bool.from_primitive(allow_duplicates.value).map(
|
|
38
|
+
lambda _: Cmd.wrap_impure(
|
|
39
|
+
lambda: LOG.warning("Duplicated jobs are allowed")
|
|
40
|
+
).map(lambda _: Bool.true_value()),
|
|
41
|
+
lambda _: dup_msg
|
|
42
|
+
+ client.list_jobs(
|
|
43
|
+
job.name,
|
|
44
|
+
job.queue,
|
|
45
|
+
frozenset(
|
|
46
|
+
[
|
|
47
|
+
JobStatus.PENDING,
|
|
48
|
+
JobStatus.RUNNABLE,
|
|
49
|
+
JobStatus.RUNNING,
|
|
50
|
+
JobStatus.STARTING,
|
|
51
|
+
JobStatus.SUBMITTED,
|
|
52
|
+
]
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
.find_first(lambda _: True)
|
|
56
|
+
.map(lambda m: m.map(lambda _: Bool.false_value()).value_or(Bool.true_value())),
|
|
57
|
+
)
|
|
58
|
+
return allow_send.bind(
|
|
59
|
+
lambda b: b.map(
|
|
60
|
+
lambda _: client.send_job(DependentJobRequest(job, Maybe.empty())).map(
|
|
61
|
+
Maybe.some
|
|
62
|
+
),
|
|
63
|
+
lambda _: skipped_msg.map(lambda _: Maybe.empty()),
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def send_pipeline(client: ApiClient, pipeline: PureIter[JobRequest]) -> Cmd[UnitType]:
|
|
69
|
+
def _action(unwrapper: CmdUnwrapper) -> UnitType:
|
|
70
|
+
prev: Maybe[JobId] = Maybe.empty()
|
|
71
|
+
LOG.info("Submiting jobs pipeline...")
|
|
72
|
+
for draft in pipeline:
|
|
73
|
+
send = client.send_job(
|
|
74
|
+
DependentJobRequest(
|
|
75
|
+
draft,
|
|
76
|
+
prev.map(
|
|
77
|
+
lambda j: JobDependencies.new(frozenset([j]))
|
|
78
|
+
.alt(Unsafe.raise_exception)
|
|
79
|
+
.to_union()
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
sent_id = unwrapper.act(send)
|
|
84
|
+
prev = Maybe.some(sent_id[0])
|
|
85
|
+
return unit
|
|
86
|
+
|
|
87
|
+
return Cmd.new_cmd(_action)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fluidattacks_batch_client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AWS batch python client
|
|
5
|
+
Author-email: Engineering Team <development@fluidattacks.com>
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: click >=8.1.8, <9.0.0
|
|
8
|
+
Requires-Dist: boto3 >=1.42.32, <2.0.0
|
|
9
|
+
Requires-Dist: fa_purity >=2.5.0, <3.0.0
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
fluidattacks_batch_client/__init__.py,sha256=d6jwGZ5P-0Spje-ZkWPK1QjwC8nn8rb4HmDR55dtNQU,143
|
|
2
|
+
fluidattacks_batch_client/_cli.py,sha256=GjukpB3Vn9fK-h9iiUeImUtR7ZhmUWRfsNJ5K5Qjxec,4618
|
|
3
|
+
fluidattacks_batch_client/_logger.py,sha256=Mv8zUo3-8BPtWJ_JadFhyTdfRSWg9dfwdQGoZ0S2pws,435
|
|
4
|
+
fluidattacks_batch_client/_utils.py,sha256=XiAdyjlDrH2lbt_wclMZp9ObU7kVf6yAqY5jfVC3cRk,2353
|
|
5
|
+
fluidattacks_batch_client/core.py,sha256=RNNx-BxhgBUv03hpbtIARaSx5kuYJcET6p6cQYjQVaU,7146
|
|
6
|
+
fluidattacks_batch_client/decode.py,sha256=Y6ji_6BOpAVDEaAGNANztdUbGybnP7jTs2G0xUSbQCQ,5492
|
|
7
|
+
fluidattacks_batch_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
fluidattacks_batch_client/api/__init__.py,sha256=co3NbLVD0pwxUDD3lRMree4jARZ_MDYfH0Gdgxq-FbI,131
|
|
9
|
+
fluidattacks_batch_client/api/_core.py,sha256=dVgvZcpxFBmSenxU38n7VKEksvljB7Zq55zPRGmcYLI,675
|
|
10
|
+
fluidattacks_batch_client/api/_client_1/__init__.py,sha256=XQB85CaDEkjBQS3PLgZHX2QkL3Hhoc65tVOnJOneAHg,796
|
|
11
|
+
fluidattacks_batch_client/api/_client_1/_get_command.py,sha256=XHXOpIH8dmxLmmb_5vAtJMided7tZRqNwcALWoAZnE8,1796
|
|
12
|
+
fluidattacks_batch_client/api/_client_1/_list_jobs.py,sha256=IhLJbVoo7pnaQx3XGi04isrIivLC56wEnQ2bOOZgVvE,3413
|
|
13
|
+
fluidattacks_batch_client/api/_client_1/_send_job.py,sha256=F6eZGvJ-5JD8I4qOTEnxmSJMyDIN-jPIvpU6Mph8e5k,5661
|
|
14
|
+
fluidattacks_batch_client/sender/__init__.py,sha256=yRDNy6JEoK2EFDlvUynWdP4yVQXeDmv4OSP9RGCSKv8,358
|
|
15
|
+
fluidattacks_batch_client/sender/_core.py,sha256=ktMFG65D1Xy_fUTc3cF3asBzcB1D-4bi6btUKOx5V2Q,494
|
|
16
|
+
fluidattacks_batch_client/sender/_send.py,sha256=TtF9dk8UIH_eSXUM1TS43GVtoElCQL8ouDcDuec_-CY,2475
|
|
17
|
+
fluidattacks_batch_client-0.1.0.dist-info/entry_points.txt,sha256=RbvCGvjFtF7qynSr5itc1ENJt-BsDEv-pOc7CweQaUs,68
|
|
18
|
+
fluidattacks_batch_client-0.1.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
19
|
+
fluidattacks_batch_client-0.1.0.dist-info/METADATA,sha256=xNCT0VhHHwOkeLXk1Vxc3TpDu6LHlnmwv2PxTj5KvCA,305
|
|
20
|
+
fluidattacks_batch_client-0.1.0.dist-info/RECORD,,
|