fluidattacks_integrates_dal 2.3.1__tar.gz → 3.0.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.
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/PKG-INFO +4 -3
- fluidattacks_integrates_dal-3.0.0/build/default.nix +13 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/flake.lock +47 -81
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/flake.nix +5 -4
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/__init__.py +1 -1
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/_cli.py +4 -4
- fluidattacks_integrates_dal-3.0.0/fluidattacks_integrates_dal/_typing.py +11 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/clients/group/__init__.py +2 -2
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/clients/organization/__init__.py +27 -18
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/clients/out_of_scope/__init__.py +2 -2
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/core.py +9 -7
- fluidattacks_integrates_dal-3.0.0/fluidattacks_integrates_dal/utils.py +38 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/pyproject.toml +5 -4
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/ruff.toml +1 -1
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/arch/arch.py +3 -8
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/arch/test_arch.py +2 -2
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/test_list_groups.py +6 -2
- fluidattacks_integrates_dal-3.0.0/uv.lock +756 -0
- fluidattacks_integrates_dal-2.3.1/build/default.nix +0 -13
- fluidattacks_integrates_dal-2.3.1/fluidattacks_integrates_dal/_typing.py +0 -17
- fluidattacks_integrates_dal-2.3.1/fluidattacks_integrates_dal/utils.py +0 -32
- fluidattacks_integrates_dal-2.3.1/uv.lock +0 -1082
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/.envrc +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/build/filter.nix +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/_logger.py +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/client.py +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/clients/__init__.py +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/list_groups.py +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/fluidattacks_integrates_dal/py.typed +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/mypy.ini +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/__init__.py +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/arch/__init__.py +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/py.typed +0 -0
- {fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/test_core.py +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fluidattacks_integrates_dal
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: ASM Synchronous Data Access Layer
|
|
5
5
|
Author-email: Engineering Team <development@fluidattacks.com>
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.13.14, <3.14
|
|
7
7
|
Classifier: License :: OSI Approved :: MIT License
|
|
8
8
|
Requires-Dist: boto3 >=1.40.53, <2.0.0
|
|
9
9
|
Requires-Dist: click >=8.1.7, <9.0.0
|
|
10
10
|
Requires-Dist: fa-purity >=2.5.2, <3.0.0
|
|
11
11
|
Requires-Dist: fluidattacks-etl-utils >=5.1.0, <6.0.0
|
|
12
|
-
Requires-Dist: fluidattacks-utils-logger >=3.0.
|
|
12
|
+
Requires-Dist: fluidattacks-utils-logger >=3.0.5, <4.0.0
|
|
13
|
+
Requires-Dist: mypy-boto3-dynamodb >=1.40.40, <2.0.0
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"nixpkgs-lib": "nixpkgs-lib"
|
|
6
6
|
},
|
|
7
7
|
"locked": {
|
|
8
|
-
"lastModified":
|
|
9
|
-
"narHash": "sha256-
|
|
8
|
+
"lastModified": 1768135262,
|
|
9
|
+
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
|
|
10
10
|
"owner": "hercules-ci",
|
|
11
11
|
"repo": "flake-parts",
|
|
12
|
-
"rev": "
|
|
12
|
+
"rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
|
|
13
13
|
"type": "github"
|
|
14
14
|
},
|
|
15
15
|
"original": {
|
|
@@ -35,27 +35,27 @@
|
|
|
35
35
|
},
|
|
36
36
|
"nixpkgs": {
|
|
37
37
|
"locked": {
|
|
38
|
-
"lastModified":
|
|
39
|
-
"narHash": "sha256-
|
|
38
|
+
"lastModified": 1785133411,
|
|
39
|
+
"narHash": "sha256-Yjv0WEg39KRYS0rBdTbu6Fc/or/ihAKk13W9sQ6VWd0=",
|
|
40
40
|
"owner": "nixos",
|
|
41
41
|
"repo": "nixpkgs",
|
|
42
|
-
"rev": "
|
|
42
|
+
"rev": "2f5a153c270b70cb0f8c11f46d96d6d3bc39f4e3",
|
|
43
43
|
"type": "github"
|
|
44
44
|
},
|
|
45
45
|
"original": {
|
|
46
46
|
"owner": "nixos",
|
|
47
|
-
"ref": "nixos-unstable",
|
|
48
47
|
"repo": "nixpkgs",
|
|
48
|
+
"rev": "2f5a153c270b70cb0f8c11f46d96d6d3bc39f4e3",
|
|
49
49
|
"type": "github"
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"nixpkgs-lib": {
|
|
53
53
|
"locked": {
|
|
54
|
-
"lastModified":
|
|
55
|
-
"narHash": "sha256-
|
|
54
|
+
"lastModified": 1765674936,
|
|
55
|
+
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
|
56
56
|
"owner": "nix-community",
|
|
57
57
|
"repo": "nixpkgs.lib",
|
|
58
|
-
"rev": "
|
|
58
|
+
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
|
59
59
|
"type": "github"
|
|
60
60
|
},
|
|
61
61
|
"original": {
|
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
},
|
|
83
83
|
"nixpkgs_3": {
|
|
84
84
|
"locked": {
|
|
85
|
-
"lastModified":
|
|
86
|
-
"narHash": "sha256-
|
|
85
|
+
"lastModified": 1758690382,
|
|
86
|
+
"narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=",
|
|
87
87
|
"owner": "nixos",
|
|
88
88
|
"repo": "nixpkgs",
|
|
89
|
-
"rev": "
|
|
89
|
+
"rev": "e643668fd71b949c53f8626614b21ff71a07379d",
|
|
90
90
|
"type": "github"
|
|
91
91
|
},
|
|
92
92
|
"original": {
|
|
@@ -96,67 +96,25 @@
|
|
|
96
96
|
"type": "github"
|
|
97
97
|
}
|
|
98
98
|
},
|
|
99
|
-
"
|
|
99
|
+
"nixpkgs_4": {
|
|
100
100
|
"locked": {
|
|
101
|
-
"lastModified":
|
|
102
|
-
"narHash": "sha256-
|
|
103
|
-
"owner": "nixos",
|
|
104
|
-
"repo": "nixpkgs",
|
|
105
|
-
"rev": "400156fe527ab6b54cf6f70cca2c8385548a29c4",
|
|
106
|
-
"type": "github"
|
|
107
|
-
},
|
|
108
|
-
"original": {
|
|
109
|
-
"owner": "nixos",
|
|
110
|
-
"repo": "nixpkgs",
|
|
111
|
-
"type": "github"
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
"nixpkgs_flake_2": {
|
|
115
|
-
"locked": {
|
|
116
|
-
"lastModified": 1761668286,
|
|
117
|
-
"narHash": "sha256-YN/cm/hbm7pi7lMZCsNhu6jlBUi4wUirrIlyOMpbjKU=",
|
|
101
|
+
"lastModified": 1761373498,
|
|
102
|
+
"narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=",
|
|
118
103
|
"owner": "nixos",
|
|
119
104
|
"repo": "nixpkgs",
|
|
120
|
-
"rev": "
|
|
105
|
+
"rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce",
|
|
121
106
|
"type": "github"
|
|
122
107
|
},
|
|
123
108
|
"original": {
|
|
124
109
|
"owner": "nixos",
|
|
110
|
+
"ref": "nixos-unstable",
|
|
125
111
|
"repo": "nixpkgs",
|
|
126
112
|
"type": "github"
|
|
127
113
|
}
|
|
128
114
|
},
|
|
129
|
-
"observes_flake_builder": {
|
|
130
|
-
"inputs": {
|
|
131
|
-
"nix_filter": "nix_filter",
|
|
132
|
-
"nixpkgs_flake": "nixpkgs_flake",
|
|
133
|
-
"pyproject-build-systems": "pyproject-build-systems",
|
|
134
|
-
"pyproject-nix": "pyproject-nix_2",
|
|
135
|
-
"pythonix_flake": "pythonix_flake",
|
|
136
|
-
"shell-helpers": "shell-helpers",
|
|
137
|
-
"uv2nix": "uv2nix_2"
|
|
138
|
-
},
|
|
139
|
-
"locked": {
|
|
140
|
-
"dir": "observes/common/std_flake_2",
|
|
141
|
-
"lastModified": 1770672786,
|
|
142
|
-
"narHash": "sha256-W4qMpuS/Zg9P/PooFDsqW7EzjF3A+ITsxKbp1SWdARI=",
|
|
143
|
-
"ref": "refs/heads/trunk",
|
|
144
|
-
"rev": "ad927cc6545df64a7d622696a43bcee225b9867b",
|
|
145
|
-
"shallow": true,
|
|
146
|
-
"type": "git",
|
|
147
|
-
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
148
|
-
},
|
|
149
|
-
"original": {
|
|
150
|
-
"dir": "observes/common/std_flake_2",
|
|
151
|
-
"rev": "ad927cc6545df64a7d622696a43bcee225b9867b",
|
|
152
|
-
"shallow": true,
|
|
153
|
-
"type": "git",
|
|
154
|
-
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
115
|
"pyproject-build-systems": {
|
|
158
116
|
"inputs": {
|
|
159
|
-
"nixpkgs": "
|
|
117
|
+
"nixpkgs": "nixpkgs_2",
|
|
160
118
|
"pyproject-nix": "pyproject-nix",
|
|
161
119
|
"uv2nix": "uv2nix"
|
|
162
120
|
},
|
|
@@ -177,7 +135,7 @@
|
|
|
177
135
|
"pyproject-nix": {
|
|
178
136
|
"inputs": {
|
|
179
137
|
"nixpkgs": [
|
|
180
|
-
"
|
|
138
|
+
"python_builder",
|
|
181
139
|
"pyproject-build-systems",
|
|
182
140
|
"nixpkgs"
|
|
183
141
|
]
|
|
@@ -198,7 +156,7 @@
|
|
|
198
156
|
},
|
|
199
157
|
"pyproject-nix_2": {
|
|
200
158
|
"inputs": {
|
|
201
|
-
"nixpkgs": "
|
|
159
|
+
"nixpkgs": "nixpkgs_3"
|
|
202
160
|
},
|
|
203
161
|
"locked": {
|
|
204
162
|
"lastModified": 1762427963,
|
|
@@ -217,7 +175,7 @@
|
|
|
217
175
|
"pyproject-nix_3": {
|
|
218
176
|
"inputs": {
|
|
219
177
|
"nixpkgs": [
|
|
220
|
-
"
|
|
178
|
+
"python_builder",
|
|
221
179
|
"uv2nix",
|
|
222
180
|
"nixpkgs"
|
|
223
181
|
]
|
|
@@ -236,23 +194,30 @@
|
|
|
236
194
|
"type": "github"
|
|
237
195
|
}
|
|
238
196
|
},
|
|
239
|
-
"
|
|
197
|
+
"python_builder": {
|
|
240
198
|
"inputs": {
|
|
241
|
-
"
|
|
199
|
+
"nix_filter": "nix_filter",
|
|
200
|
+
"nixpkgs_flake": [
|
|
201
|
+
"nixpkgs"
|
|
202
|
+
],
|
|
203
|
+
"pyproject-build-systems": "pyproject-build-systems",
|
|
204
|
+
"pyproject-nix": "pyproject-nix_2",
|
|
205
|
+
"shell-helpers": "shell-helpers",
|
|
206
|
+
"uv2nix": "uv2nix_2"
|
|
242
207
|
},
|
|
243
208
|
"locked": {
|
|
244
|
-
"dir": "
|
|
245
|
-
"lastModified":
|
|
246
|
-
"narHash": "sha256-
|
|
209
|
+
"dir": "common/utils/python-builder",
|
|
210
|
+
"lastModified": 1787753967,
|
|
211
|
+
"narHash": "sha256-1kWAiANGMA4B9flxHFj73EwvOpF8r0nXGg1RVXNKPK8=",
|
|
247
212
|
"ref": "refs/heads/trunk",
|
|
248
|
-
"rev": "
|
|
213
|
+
"rev": "2490a24f91f075f7580cd0b9df5bc01dbc467a50",
|
|
249
214
|
"shallow": true,
|
|
250
215
|
"type": "git",
|
|
251
216
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
252
217
|
},
|
|
253
218
|
"original": {
|
|
254
|
-
"dir": "
|
|
255
|
-
"rev": "
|
|
219
|
+
"dir": "common/utils/python-builder",
|
|
220
|
+
"rev": "2490a24f91f075f7580cd0b9df5bc01dbc467a50",
|
|
256
221
|
"shallow": true,
|
|
257
222
|
"type": "git",
|
|
258
223
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
@@ -260,30 +225,31 @@
|
|
|
260
225
|
},
|
|
261
226
|
"root": {
|
|
262
227
|
"inputs": {
|
|
263
|
-
"
|
|
228
|
+
"nixpkgs": "nixpkgs",
|
|
229
|
+
"python_builder": "python_builder"
|
|
264
230
|
}
|
|
265
231
|
},
|
|
266
232
|
"shell-helpers": {
|
|
267
233
|
"inputs": {
|
|
268
234
|
"flake-parts": "flake-parts",
|
|
269
235
|
"nixpkgs": [
|
|
270
|
-
"
|
|
236
|
+
"python_builder",
|
|
271
237
|
"nixpkgs_flake"
|
|
272
238
|
]
|
|
273
239
|
},
|
|
274
240
|
"locked": {
|
|
275
241
|
"dir": "common/utils/shell-helpers",
|
|
276
|
-
"lastModified":
|
|
277
|
-
"narHash": "sha256-
|
|
242
|
+
"lastModified": 1787145059,
|
|
243
|
+
"narHash": "sha256-i5i+qLR9JhcNasrQvzG4S/0AotpZAqTHXa4/68MmvwA=",
|
|
278
244
|
"ref": "refs/heads/trunk",
|
|
279
|
-
"rev": "
|
|
245
|
+
"rev": "e0d58302690af6f38b7544265e59c625b63df76f",
|
|
280
246
|
"shallow": true,
|
|
281
247
|
"type": "git",
|
|
282
248
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
283
249
|
},
|
|
284
250
|
"original": {
|
|
285
251
|
"dir": "common/utils/shell-helpers",
|
|
286
|
-
"rev": "
|
|
252
|
+
"rev": "e0d58302690af6f38b7544265e59c625b63df76f",
|
|
287
253
|
"shallow": true,
|
|
288
254
|
"type": "git",
|
|
289
255
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
@@ -292,12 +258,12 @@
|
|
|
292
258
|
"uv2nix": {
|
|
293
259
|
"inputs": {
|
|
294
260
|
"nixpkgs": [
|
|
295
|
-
"
|
|
261
|
+
"python_builder",
|
|
296
262
|
"pyproject-build-systems",
|
|
297
263
|
"nixpkgs"
|
|
298
264
|
],
|
|
299
265
|
"pyproject-nix": [
|
|
300
|
-
"
|
|
266
|
+
"python_builder",
|
|
301
267
|
"pyproject-build-systems",
|
|
302
268
|
"pyproject-nix"
|
|
303
269
|
]
|
|
@@ -318,7 +284,7 @@
|
|
|
318
284
|
},
|
|
319
285
|
"uv2nix_2": {
|
|
320
286
|
"inputs": {
|
|
321
|
-
"nixpkgs": "
|
|
287
|
+
"nixpkgs": "nixpkgs_4",
|
|
322
288
|
"pyproject-nix": "pyproject-nix_3"
|
|
323
289
|
},
|
|
324
290
|
"locked": {
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
description = "Common Integrates-dal";
|
|
3
3
|
|
|
4
4
|
inputs = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
nixpkgs.url = "github:nixos/nixpkgs/2f5a153c270b70cb0f8c11f46d96d6d3bc39f4e3";
|
|
6
|
+
python_builder = {
|
|
7
|
+
url = "git+ssh://git@gitlab.com/fluidattacks/universe?shallow=1&rev=2490a24f91f075f7580cd0b9df5bc01dbc467a50&dir=common/utils/python-builder";
|
|
8
|
+
inputs.nixpkgs_flake.follows = "nixpkgs";
|
|
7
9
|
};
|
|
8
10
|
};
|
|
9
11
|
|
|
@@ -19,11 +21,10 @@
|
|
|
19
21
|
scripts,
|
|
20
22
|
}:
|
|
21
23
|
import ./build {
|
|
22
|
-
inherit nixpkgs builders scripts;
|
|
23
24
|
src = import ./build/filter.nix nixpkgs.nix-filter self;
|
|
24
25
|
};
|
|
25
26
|
in
|
|
26
27
|
{
|
|
27
|
-
packages = inputs.
|
|
28
|
+
packages = inputs.python_builder.outputs.build build_args;
|
|
28
29
|
};
|
|
29
30
|
}
|
|
@@ -42,10 +42,10 @@ def list_all_groups() -> NoReturn:
|
|
|
42
42
|
list_groups.list_all_groups(t[0], t[1])
|
|
43
43
|
.map(lambda gs: "\n".join(g.name for g in gs))
|
|
44
44
|
.bind(
|
|
45
|
-
lambda s:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
lambda _: None
|
|
45
|
+
lambda s: (
|
|
46
|
+
Cmd[int]
|
|
47
|
+
.wrap_impure(lambda: sys.stdout.write(s + "\n")) # type: ignore[misc]
|
|
48
|
+
.map(lambda _: None)
|
|
49
49
|
),
|
|
50
50
|
)
|
|
51
51
|
),
|
|
@@ -125,7 +125,7 @@ def _get_groups_page(
|
|
|
125
125
|
LOG.debug(page)
|
|
126
126
|
return page
|
|
127
127
|
|
|
128
|
-
return Cmd.wrap_impure(_action)
|
|
128
|
+
return Cmd[_Page].wrap_impure(_action)
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
def _get_groups(table: Table, org: OrganizationId) -> Stream[GroupId]:
|
|
@@ -137,7 +137,7 @@ def _get_groups(table: Table, org: OrganizationId) -> Stream[GroupId]:
|
|
|
137
137
|
lambda p: (
|
|
138
138
|
_get_groups_page(table, org, p.last_index).map(_union.inl)
|
|
139
139
|
if p and p.last_index
|
|
140
|
-
else Cmd.wrap_value(None).map(_union.inr)
|
|
140
|
+
else Cmd[None].wrap_value(None).map(_union.inr)
|
|
141
141
|
),
|
|
142
142
|
),
|
|
143
143
|
init.map(_union.inl),
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import (
|
|
5
|
+
TYPE_CHECKING,
|
|
6
|
+
)
|
|
5
7
|
|
|
6
8
|
from fa_purity import (
|
|
7
9
|
Cmd,
|
|
@@ -20,9 +22,11 @@ from fa_purity.json import (
|
|
|
20
22
|
JsonPrimitiveFactory,
|
|
21
23
|
JsonPrimitiveUnfolder,
|
|
22
24
|
)
|
|
25
|
+
from mypy_boto3_dynamodb.type_defs import (
|
|
26
|
+
QueryOutputTypeDef,
|
|
27
|
+
)
|
|
23
28
|
|
|
24
29
|
from fluidattacks_integrates_dal._typing import (
|
|
25
|
-
Dict,
|
|
26
30
|
Iterable,
|
|
27
31
|
TypeVar,
|
|
28
32
|
)
|
|
@@ -37,37 +41,40 @@ if TYPE_CHECKING:
|
|
|
37
41
|
from mypy_boto3_dynamodb import (
|
|
38
42
|
DynamoDBClient,
|
|
39
43
|
)
|
|
40
|
-
from mypy_boto3_dynamodb.type_defs import (
|
|
41
|
-
QueryOutputTypeDef,
|
|
42
|
-
)
|
|
43
44
|
LOG = logging.getLogger(__name__)
|
|
44
45
|
_T = TypeVar("_T")
|
|
45
46
|
_K = TypeVar("_K")
|
|
46
47
|
_DB_TABLE = "integrates_vms"
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
def _require_key(item:
|
|
50
|
+
def _require_key(item: dict[_K, _T], key: _K) -> ResultE[_T]:
|
|
50
51
|
try:
|
|
51
|
-
return Result.success(item[key])
|
|
52
|
+
return Result[_T, Exception].success(item[key])
|
|
52
53
|
except KeyError as err:
|
|
53
|
-
return Result.failure(err).alt(cast_exception)
|
|
54
|
+
return Result[_T, KeyError].failure(err).alt(cast_exception)
|
|
54
55
|
|
|
55
56
|
|
|
56
|
-
def _decode_dynamo_str(item:
|
|
57
|
+
def _decode_dynamo_str(item: object) -> ResultE[JsonPrimitive]:
|
|
57
58
|
if isinstance(item, dict):
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
# isinstance narrows to dict[Unknown, Unknown]; the actual key/value
|
|
60
|
+
# types are only known by convention (DynamoDB's typed-attribute maps).
|
|
61
|
+
s_value: ResultE[str] = _require_key(
|
|
62
|
+
item, # pyright: ignore[reportUnknownArgumentType]
|
|
63
|
+
"S",
|
|
60
64
|
)
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
return s_value.bind(JsonPrimitiveFactory.from_any)
|
|
66
|
+
return (
|
|
67
|
+
Result[JsonPrimitive, TypeError]
|
|
68
|
+
.failure(TypeError(f"Expected `dict` instance; got `{type(item)}`"))
|
|
69
|
+
.alt(cast_exception)
|
|
63
70
|
)
|
|
64
71
|
|
|
65
72
|
|
|
66
|
-
def _decode_dynamo_key_str(item:
|
|
73
|
+
def _decode_dynamo_key_str(item: dict[str, _T], key: str) -> ResultE[JsonPrimitive]:
|
|
67
74
|
return _require_key(item, key).bind(_decode_dynamo_str)
|
|
68
75
|
|
|
69
76
|
|
|
70
|
-
def _decode_org_id(raw:
|
|
77
|
+
def _decode_org_id(raw: dict[str, _T]) -> ResultE[OrganizationId]:
|
|
71
78
|
_pk = _decode_dynamo_key_str(raw, "pk").bind(JsonPrimitiveUnfolder.to_str)
|
|
72
79
|
_sk = _decode_dynamo_key_str(raw, "sk").bind(JsonPrimitiveUnfolder.to_str)
|
|
73
80
|
return _pk.bind(lambda pk: _sk.bind(lambda sk: OrganizationId.new(pk, sk)))
|
|
@@ -85,7 +92,7 @@ def _to_items(page: QueryOutputTypeDef) -> FrozenList[OrganizationId]:
|
|
|
85
92
|
def _all_orgs(client: DynamoDBClient) -> Stream[OrganizationId]:
|
|
86
93
|
def _new_iter() -> Iterable[Cmd[QueryOutputTypeDef]]:
|
|
87
94
|
LOG.debug("Getting all orgs")
|
|
88
|
-
exp_attrs_values:
|
|
95
|
+
exp_attrs_values: dict[str, dict[str, str]] = {
|
|
89
96
|
":pk": {"S": "ORG#all"},
|
|
90
97
|
":sk": {"S": "ORG#"},
|
|
91
98
|
}
|
|
@@ -100,10 +107,12 @@ def _all_orgs(client: DynamoDBClient) -> Stream[OrganizationId]:
|
|
|
100
107
|
IndexName="gsi_2",
|
|
101
108
|
)
|
|
102
109
|
LOG.debug("all orgs retrieved!")
|
|
103
|
-
return
|
|
110
|
+
return (Cmd[QueryOutputTypeDef].wrap_value(v) for v in response) # type: ignore[misc]
|
|
104
111
|
|
|
105
112
|
data = StreamFactory.from_commands( # type: ignore[misc]
|
|
106
|
-
Unsafe.pure_iter_from_cmd(
|
|
113
|
+
Unsafe.pure_iter_from_cmd(
|
|
114
|
+
Cmd[Iterable[Cmd[QueryOutputTypeDef]]].wrap_impure(_new_iter), # type: ignore[misc]
|
|
115
|
+
),
|
|
107
116
|
)
|
|
108
117
|
return (
|
|
109
118
|
data.map(_to_items) # type: ignore[misc]
|
|
@@ -113,9 +113,9 @@ def _get_page(
|
|
|
113
113
|
.transform(PureIterTransform.filter_maybe)
|
|
114
114
|
.to_list()
|
|
115
115
|
)
|
|
116
|
-
return (roots, Maybe.from_optional(response.get("LastEvaluatedKey")))
|
|
116
|
+
return (roots, Maybe[_Cursor].from_optional(response.get("LastEvaluatedKey")))
|
|
117
117
|
|
|
118
|
-
return Cmd.wrap_impure(_action)
|
|
118
|
+
return Cmd[tuple[FrozenList[OutOfScopeRoot], Maybe[_Cursor]]].wrap_impure(_action)
|
|
119
119
|
|
|
120
120
|
|
|
121
121
|
def _get_roots(table: Table, org: OrganizationId) -> Stream[FrozenList[OutOfScopeRoot]]:
|
|
@@ -31,8 +31,8 @@ class GroupId:
|
|
|
31
31
|
pattern = r"^[\w\s-]+$"
|
|
32
32
|
if not re.match(pattern, _name):
|
|
33
33
|
err = ValueError(rf"Group name is not `^[\w- ]+$` i.e. {_name}")
|
|
34
|
-
return Result.failure(err
|
|
35
|
-
return Result.success(GroupId(_Private(), _name)
|
|
34
|
+
return Result[GroupId, ValueError].failure(err).alt(cast_exception)
|
|
35
|
+
return Result[GroupId, Exception].success(GroupId(_Private(), _name))
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
@dataclass(frozen=True)
|
|
@@ -47,13 +47,13 @@ class OrganizationId:
|
|
|
47
47
|
_uuid = uuid.removeprefix("ORG#")
|
|
48
48
|
if not _name.isalnum():
|
|
49
49
|
err = ValueError(f"Org name is not alphanum i.e. {_name}")
|
|
50
|
-
return Result.failure(err
|
|
50
|
+
return Result[OrganizationId, ValueError].failure(err).alt(cast_exception)
|
|
51
51
|
uuidv4 = "^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$"
|
|
52
52
|
if re.match(uuidv4, _uuid, re.IGNORECASE) is None:
|
|
53
53
|
err = ValueError(f"Org id is not an UUIDv4 i.e. {_uuid}")
|
|
54
|
-
return Result.failure(err
|
|
54
|
+
return Result[OrganizationId, ValueError].failure(err).alt(cast_exception)
|
|
55
55
|
|
|
56
|
-
return Result.success(OrganizationId(_Private(), _name, _uuid)
|
|
56
|
+
return Result[OrganizationId, Exception].success(OrganizationId(_Private(), _name, _uuid))
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
@dataclass(frozen=True)
|
|
@@ -66,5 +66,7 @@ class OutOfScopeRoot:
|
|
|
66
66
|
def new(nickname: str, status: str) -> ResultE[OutOfScopeRoot]:
|
|
67
67
|
if not nickname:
|
|
68
68
|
err = ValueError("Out-of-scope root nickname is empty")
|
|
69
|
-
return Result.failure(err
|
|
70
|
-
return Result
|
|
69
|
+
return Result[OutOfScopeRoot, ValueError].failure(err).alt(cast_exception)
|
|
70
|
+
return Result[OutOfScopeRoot, Exception].success(
|
|
71
|
+
OutOfScopeRoot(_Private(), nickname, status),
|
|
72
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from boto3 import (
|
|
4
|
+
Session,
|
|
5
|
+
)
|
|
6
|
+
from fa_purity import (
|
|
7
|
+
Cmd,
|
|
8
|
+
)
|
|
9
|
+
from mypy_boto3_dynamodb import (
|
|
10
|
+
DynamoDBClient,
|
|
11
|
+
DynamoDBServiceResource,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def new_session() -> Cmd[Session]:
|
|
16
|
+
# This impure procedure gets inputs (credentials) through the environment
|
|
17
|
+
# e.g. AWS_DEFAULT_REGION
|
|
18
|
+
return Cmd[Session].wrap_impure(Session)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def new_resource(session: Session) -> Cmd[DynamoDBServiceResource]:
|
|
22
|
+
# boto3-stubs' resource() overload set is partially unknown because
|
|
23
|
+
# only mypy_boto3_dynamodb is installed.
|
|
24
|
+
return Cmd[DynamoDBServiceResource].wrap_impure(
|
|
25
|
+
lambda: session.resource( # pyright: ignore[reportUnknownMemberType]
|
|
26
|
+
service_name="dynamodb",
|
|
27
|
+
use_ssl=True,
|
|
28
|
+
verify=True,
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def new_client(session: Session) -> Cmd[DynamoDBClient]:
|
|
34
|
+
# boto3-stubs' client() overload set is partially unknown because
|
|
35
|
+
# only mypy_boto3_dynamodb is installed.
|
|
36
|
+
return Cmd[DynamoDBClient].wrap_impure(
|
|
37
|
+
lambda: session.client("dynamodb"), # pyright: ignore[reportUnknownMemberType]
|
|
38
|
+
)
|
|
@@ -6,13 +6,14 @@ authors = [
|
|
|
6
6
|
classifiers = [
|
|
7
7
|
"License :: OSI Approved :: MIT License",
|
|
8
8
|
]
|
|
9
|
-
requires-python = ">=3.
|
|
9
|
+
requires-python = ">=3.13.14, <3.14"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"boto3 >=1.40.53, <2.0.0",
|
|
12
12
|
"click >=8.1.7, <9.0.0",
|
|
13
13
|
"fa-purity >=2.5.2, <3.0.0",
|
|
14
14
|
"fluidattacks-etl-utils >=5.1.0, <6.0.0",
|
|
15
|
-
"fluidattacks-utils-logger >=3.0.
|
|
15
|
+
"fluidattacks-utils-logger >=3.0.5, <4.0.0",
|
|
16
|
+
"mypy-boto3-dynamodb >=1.40.40, <2.0.0",
|
|
16
17
|
]
|
|
17
18
|
description = "ASM Synchronous Data Access Layer"
|
|
18
19
|
dynamic = ["version"]
|
|
@@ -33,9 +34,9 @@ dev = [
|
|
|
33
34
|
"ruff >=0.14.1, <1.0.0",
|
|
34
35
|
"botocore-stubs >=1.40.53, <2.0.0",
|
|
35
36
|
"boto3-stubs >=1.40.53, <2.0.0",
|
|
36
|
-
"
|
|
37
|
+
"basedpyright >=1.39.8, <2.0.0",
|
|
37
38
|
]
|
|
38
39
|
|
|
39
40
|
[tool.uv]
|
|
40
41
|
exclude-newer = "7 days"
|
|
41
|
-
exclude-newer-package = { fluidattacks-core = "2099-01-
|
|
42
|
+
exclude-newer-package = { fluidattacks-core = "2099-01-02T00:00:00Z", fluid-blends = "2099-01-02T00:00:00Z" , fluidattacks-utils-logger = "2099-01-02T00:00:00Z" }
|
|
@@ -8,13 +8,8 @@ from fa_purity import (
|
|
|
8
8
|
FrozenList,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
|
-
from fluidattacks_integrates_dal._typing import (
|
|
12
|
-
Dict,
|
|
13
|
-
FrozenSet,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
11
|
root = FullPathModule.assert_module("fluidattacks_integrates_dal")
|
|
17
|
-
_dag:
|
|
12
|
+
_dag: dict[str, FrozenList[FrozenList[str] | str]] = {
|
|
18
13
|
"fluidattacks_integrates_dal": (
|
|
19
14
|
"_cli",
|
|
20
15
|
"list_groups",
|
|
@@ -35,8 +30,8 @@ def project_dag() -> DagMap:
|
|
|
35
30
|
return item
|
|
36
31
|
|
|
37
32
|
|
|
38
|
-
def forbidden_allowlist() ->
|
|
39
|
-
_raw:
|
|
33
|
+
def forbidden_allowlist() -> dict[FullPathModule, frozenset[FullPathModule]]:
|
|
34
|
+
_raw: dict[str, frozenset[str]] = {}
|
|
40
35
|
return {
|
|
41
36
|
FullPathModule.assert_module(k): frozenset(FullPathModule.assert_module(i) for i in v)
|
|
42
37
|
for k, v in _raw.items()
|
{fluidattacks_integrates_dal-2.3.1 → fluidattacks_integrates_dal-3.0.0}/tests/arch/test_arch.py
RENAMED
|
@@ -20,7 +20,7 @@ from .arch import (
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def test_dag_creation() -> None:
|
|
23
|
-
project_dag()
|
|
23
|
+
_ = project_dag()
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def test_dag() -> None:
|
|
@@ -34,7 +34,7 @@ def test_dag_completeness() -> None:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def test_forbidden_creation() -> None:
|
|
37
|
-
forbidden_allowlist()
|
|
37
|
+
_ = forbidden_allowlist()
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def test_forbidden() -> None:
|