fluidattacks_zoho_sdk 2.10.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.
Files changed (53) hide show
  1. fluidattacks_zoho_sdk-2.10.0/.envrc +3 -0
  2. fluidattacks_zoho_sdk-2.10.0/PKG-INFO +9 -0
  3. fluidattacks_zoho_sdk-2.10.0/build/default.nix +13 -0
  4. fluidattacks_zoho_sdk-2.10.0/build/filter.nix +12 -0
  5. fluidattacks_zoho_sdk-2.10.0/flake.lock +353 -0
  6. fluidattacks_zoho_sdk-2.10.0/flake.nix +29 -0
  7. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/__init__.py +6 -0
  8. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/_decoders.py +268 -0
  9. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/_http_client/__init__.py +23 -0
  10. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/_http_client/_client.py +363 -0
  11. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/_http_client/_core.py +153 -0
  12. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/_http_client/paginate.py +35 -0
  13. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/auth/__init__.py +51 -0
  14. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/auth/_access.py +86 -0
  15. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/auth/_core.py +39 -0
  16. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/auth/_decode.py +62 -0
  17. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/auth/_refresh.py +123 -0
  18. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/auth/_revoke.py +98 -0
  19. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/bulk_export/__init__.py +31 -0
  20. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/bulk_export/_client.py +190 -0
  21. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/bulk_export/_decode.py +41 -0
  22. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/bulk_export/core.py +97 -0
  23. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/bulk_export/utils.py +71 -0
  24. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/ids.py +68 -0
  25. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/py.typed +0 -0
  26. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_desk/__init__.py +57 -0
  27. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_desk/_client.py +88 -0
  28. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_desk/_decode.py +316 -0
  29. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_desk/core.py +143 -0
  30. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_people/__init__.py +3 -0
  31. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_people/_client.py +95 -0
  32. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_people/_decode.py +147 -0
  33. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_people/core.py +46 -0
  34. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_people/decoders_ids.py +30 -0
  35. fluidattacks_zoho_sdk-2.10.0/fluidattacks_zoho_sdk/zoho_people/ids.py +25 -0
  36. fluidattacks_zoho_sdk-2.10.0/mypy.ini +30 -0
  37. fluidattacks_zoho_sdk-2.10.0/pyproject.toml +25 -0
  38. fluidattacks_zoho_sdk-2.10.0/ruff.toml +37 -0
  39. fluidattacks_zoho_sdk-2.10.0/tests/__init__.py +0 -0
  40. fluidattacks_zoho_sdk-2.10.0/tests/arch/__init__.py +0 -0
  41. fluidattacks_zoho_sdk-2.10.0/tests/arch/arch.py +70 -0
  42. fluidattacks_zoho_sdk-2.10.0/tests/arch/test_arch.py +43 -0
  43. fluidattacks_zoho_sdk-2.10.0/tests/desk/__init__.py +0 -0
  44. fluidattacks_zoho_sdk-2.10.0/tests/desk/data_agent.json +25 -0
  45. fluidattacks_zoho_sdk-2.10.0/tests/desk/data_contact.json +43 -0
  46. fluidattacks_zoho_sdk-2.10.0/tests/desk/data_team.json +16 -0
  47. fluidattacks_zoho_sdk-2.10.0/tests/desk/data_ticket.json +102 -0
  48. fluidattacks_zoho_sdk-2.10.0/tests/desk/test_decode.py +178 -0
  49. fluidattacks_zoho_sdk-2.10.0/tests/people/__init__.py +0 -0
  50. fluidattacks_zoho_sdk-2.10.0/tests/people/data_leaves.json +60 -0
  51. fluidattacks_zoho_sdk-2.10.0/tests/people/test_decode.py +96 -0
  52. fluidattacks_zoho_sdk-2.10.0/tests/py.typed +0 -0
  53. fluidattacks_zoho_sdk-2.10.0/uv.lock +943 -0
@@ -0,0 +1,3 @@
1
+ # use https://github.com/nix-community/nix-direnv
2
+ ln -f ../../common/mypy.ini ./mypy.ini
3
+ use_flake ".#python311.devShell"
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: fluidattacks_zoho_sdk
3
+ Version: 2.10.0
4
+ Summary: zoho SDK
5
+ Author-email: Product Team <development@fluidattacks.com>
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: fa-purity >=2.5.0, <3.0.0
8
+ Requires-Dist: fluidattacks-etl-utils >=2.0.0, <3.0.0
9
+ Requires-Dist: pure-requests >=3.0.0, <4.0.0
@@ -0,0 +1,13 @@
1
+ {
2
+ nixpkgs,
3
+ builders,
4
+ scripts,
5
+ src,
6
+ }:
7
+ {
8
+ inherit src;
9
+ root_path = "observes/sdk/zoho";
10
+ module_name = "fluidattacks_zoho_sdk";
11
+ pypi_token_var = "ZOHO_SDK_TOKEN";
12
+ override = b: b;
13
+ }
@@ -0,0 +1,12 @@
1
+ path_filter: src:
2
+ path_filter {
3
+ root = src;
4
+ include = [
5
+ "fluidattacks_zoho_sdk"
6
+ "tests"
7
+ "pyproject.toml"
8
+ "mypy.ini"
9
+ "ruff.toml"
10
+ "uv.lock"
11
+ ];
12
+ }
@@ -0,0 +1,353 @@
1
+ {
2
+ "nodes": {
3
+ "flake-parts": {
4
+ "inputs": {
5
+ "nixpkgs-lib": "nixpkgs-lib"
6
+ },
7
+ "locked": {
8
+ "lastModified": 1762810396,
9
+ "narHash": "sha256-dxFVgQPG+R72dkhXTtqUm7KpxElw3u6E+YlQ2WaDgt8=",
10
+ "owner": "hercules-ci",
11
+ "repo": "flake-parts",
12
+ "rev": "0bdadb1b265fb4143a75bd1ec7d8c915898a9923",
13
+ "type": "github"
14
+ },
15
+ "original": {
16
+ "owner": "hercules-ci",
17
+ "repo": "flake-parts",
18
+ "type": "github"
19
+ }
20
+ },
21
+ "nix_filter": {
22
+ "locked": {
23
+ "lastModified": 1757882181,
24
+ "narHash": "sha256-+cCxYIh2UNalTz364p+QYmWHs0P+6wDhiWR4jDIKQIU=",
25
+ "owner": "numtide",
26
+ "repo": "nix-filter",
27
+ "rev": "59c44d1909c72441144b93cf0f054be7fe764de5",
28
+ "type": "github"
29
+ },
30
+ "original": {
31
+ "owner": "numtide",
32
+ "repo": "nix-filter",
33
+ "type": "github"
34
+ }
35
+ },
36
+ "nix_filter_2": {
37
+ "locked": {
38
+ "lastModified": 1731533336,
39
+ "narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
40
+ "owner": "numtide",
41
+ "repo": "nix-filter",
42
+ "rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
43
+ "type": "github"
44
+ },
45
+ "original": {
46
+ "owner": "numtide",
47
+ "repo": "nix-filter",
48
+ "type": "github"
49
+ }
50
+ },
51
+ "nixpkgs": {
52
+ "locked": {
53
+ "lastModified": 1736441877,
54
+ "narHash": "sha256-m3+PhBFkDwqo9lBplG4AyMW8P4/KcioJRS1UG8N7okM=",
55
+ "owner": "nixos",
56
+ "repo": "nixpkgs",
57
+ "rev": "ce3899414dab3297cf025bfa356dc2da426feefd",
58
+ "type": "github"
59
+ },
60
+ "original": {
61
+ "owner": "nixos",
62
+ "repo": "nixpkgs",
63
+ "type": "github"
64
+ }
65
+ },
66
+ "nixpkgs-lib": {
67
+ "locked": {
68
+ "lastModified": 1761765539,
69
+ "narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
70
+ "owner": "nix-community",
71
+ "repo": "nixpkgs.lib",
72
+ "rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
73
+ "type": "github"
74
+ },
75
+ "original": {
76
+ "owner": "nix-community",
77
+ "repo": "nixpkgs.lib",
78
+ "type": "github"
79
+ }
80
+ },
81
+ "nixpkgs_2": {
82
+ "locked": {
83
+ "lastModified": 1758690382,
84
+ "narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=",
85
+ "owner": "nixos",
86
+ "repo": "nixpkgs",
87
+ "rev": "e643668fd71b949c53f8626614b21ff71a07379d",
88
+ "type": "github"
89
+ },
90
+ "original": {
91
+ "owner": "nixos",
92
+ "ref": "nixos-unstable",
93
+ "repo": "nixpkgs",
94
+ "type": "github"
95
+ }
96
+ },
97
+ "nixpkgs_3": {
98
+ "locked": {
99
+ "lastModified": 1758690382,
100
+ "narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=",
101
+ "owner": "nixos",
102
+ "repo": "nixpkgs",
103
+ "rev": "e643668fd71b949c53f8626614b21ff71a07379d",
104
+ "type": "github"
105
+ },
106
+ "original": {
107
+ "owner": "nixos",
108
+ "ref": "nixos-unstable",
109
+ "repo": "nixpkgs",
110
+ "type": "github"
111
+ }
112
+ },
113
+ "nixpkgs_4": {
114
+ "locked": {
115
+ "lastModified": 1761373498,
116
+ "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=",
117
+ "owner": "nixos",
118
+ "repo": "nixpkgs",
119
+ "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce",
120
+ "type": "github"
121
+ },
122
+ "original": {
123
+ "owner": "nixos",
124
+ "ref": "nixos-unstable",
125
+ "repo": "nixpkgs",
126
+ "type": "github"
127
+ }
128
+ },
129
+ "nixpkgs_flake": {
130
+ "locked": {
131
+ "lastModified": 1762812764,
132
+ "narHash": "sha256-MNqrovkO8AEQeYQK7e3X2GDx2H8vfDIxV4K/VEaIjjo=",
133
+ "owner": "nixos",
134
+ "repo": "nixpkgs",
135
+ "rev": "400156fe527ab6b54cf6f70cca2c8385548a29c4",
136
+ "type": "github"
137
+ },
138
+ "original": {
139
+ "owner": "nixos",
140
+ "repo": "nixpkgs",
141
+ "type": "github"
142
+ }
143
+ },
144
+ "observes_flake_builder": {
145
+ "inputs": {
146
+ "nix_filter": "nix_filter",
147
+ "nixpkgs_flake": "nixpkgs_flake",
148
+ "pynix_flake": "pynix_flake",
149
+ "pyproject-build-systems": "pyproject-build-systems",
150
+ "pyproject-nix": "pyproject-nix_2",
151
+ "shell-helpers": "shell-helpers",
152
+ "uv2nix": "uv2nix_2"
153
+ },
154
+ "locked": {
155
+ "dir": "observes/common/std_flake_2",
156
+ "lastModified": 1764767408,
157
+ "narHash": "sha256-CYGyCtQuboXbHQ0OUXNNdXXIcPOM1ZhOM94LUNjEQig=",
158
+ "ref": "refs/heads/trunk",
159
+ "rev": "28bda83eeda56c9c4016f43c86aaf93a366446c3",
160
+ "shallow": true,
161
+ "type": "git",
162
+ "url": "ssh://git@gitlab.com/fluidattacks/universe"
163
+ },
164
+ "original": {
165
+ "dir": "observes/common/std_flake_2",
166
+ "rev": "28bda83eeda56c9c4016f43c86aaf93a366446c3",
167
+ "shallow": true,
168
+ "type": "git",
169
+ "url": "ssh://git@gitlab.com/fluidattacks/universe"
170
+ }
171
+ },
172
+ "pynix_flake": {
173
+ "inputs": {
174
+ "nix_filter": "nix_filter_2",
175
+ "nixpkgs": "nixpkgs"
176
+ },
177
+ "locked": {
178
+ "lastModified": 1758642502,
179
+ "narHash": "sha256-PD/bQMz2dqZSkydHyvRh+jS/0qoV8SdcIVs6sassteQ=",
180
+ "owner": "dmurciaatfluid",
181
+ "repo": "python_nix_builder",
182
+ "rev": "809aafe2e1995e72c15378d099bf251b78f04a20",
183
+ "type": "gitlab"
184
+ },
185
+ "original": {
186
+ "owner": "dmurciaatfluid",
187
+ "repo": "python_nix_builder",
188
+ "type": "gitlab"
189
+ }
190
+ },
191
+ "pyproject-build-systems": {
192
+ "inputs": {
193
+ "nixpkgs": "nixpkgs_2",
194
+ "pyproject-nix": "pyproject-nix",
195
+ "uv2nix": "uv2nix"
196
+ },
197
+ "locked": {
198
+ "lastModified": 1761781027,
199
+ "narHash": "sha256-YDvxPAm2WnxrznRqWwHLjryBGG5Ey1ATEJXrON+TWt8=",
200
+ "owner": "pyproject-nix",
201
+ "repo": "build-system-pkgs",
202
+ "rev": "795a980d25301e5133eca37adae37283ec3c8e66",
203
+ "type": "github"
204
+ },
205
+ "original": {
206
+ "owner": "pyproject-nix",
207
+ "repo": "build-system-pkgs",
208
+ "type": "github"
209
+ }
210
+ },
211
+ "pyproject-nix": {
212
+ "inputs": {
213
+ "nixpkgs": [
214
+ "observes_flake_builder",
215
+ "pyproject-build-systems",
216
+ "nixpkgs"
217
+ ]
218
+ },
219
+ "locked": {
220
+ "lastModified": 1758265079,
221
+ "narHash": "sha256-amLaLNwKSZPShQHzfgmc/9o76dU8xzN0743dWgvYlr8=",
222
+ "owner": "nix-community",
223
+ "repo": "pyproject.nix",
224
+ "rev": "02e9418fd4af638447dca4b17b1280da95527fc9",
225
+ "type": "github"
226
+ },
227
+ "original": {
228
+ "owner": "nix-community",
229
+ "repo": "pyproject.nix",
230
+ "type": "github"
231
+ }
232
+ },
233
+ "pyproject-nix_2": {
234
+ "inputs": {
235
+ "nixpkgs": "nixpkgs_3"
236
+ },
237
+ "locked": {
238
+ "lastModified": 1762427963,
239
+ "narHash": "sha256-CkPlAbIQ87wmjy5qHibfzk4DmMGBNqFer+lLfXjpP5M=",
240
+ "owner": "pyproject-nix",
241
+ "repo": "pyproject.nix",
242
+ "rev": "4540ea004e04fcd12dd2738d51383d10f956f7b9",
243
+ "type": "github"
244
+ },
245
+ "original": {
246
+ "owner": "pyproject-nix",
247
+ "repo": "pyproject.nix",
248
+ "type": "github"
249
+ }
250
+ },
251
+ "pyproject-nix_3": {
252
+ "inputs": {
253
+ "nixpkgs": [
254
+ "observes_flake_builder",
255
+ "uv2nix",
256
+ "nixpkgs"
257
+ ]
258
+ },
259
+ "locked": {
260
+ "lastModified": 1760402624,
261
+ "narHash": "sha256-jF6UKLs2uGc2rtved8Vrt58oTWjTQoAssuYs/0578Z4=",
262
+ "owner": "pyproject-nix",
263
+ "repo": "pyproject.nix",
264
+ "rev": "84c4ea102127c77058ea1ed7be7300261fafc7d2",
265
+ "type": "github"
266
+ },
267
+ "original": {
268
+ "owner": "pyproject-nix",
269
+ "repo": "pyproject.nix",
270
+ "type": "github"
271
+ }
272
+ },
273
+ "root": {
274
+ "inputs": {
275
+ "observes_flake_builder": "observes_flake_builder"
276
+ }
277
+ },
278
+ "shell-helpers": {
279
+ "inputs": {
280
+ "flake-parts": "flake-parts",
281
+ "nixpkgs": [
282
+ "observes_flake_builder",
283
+ "nixpkgs_flake"
284
+ ]
285
+ },
286
+ "locked": {
287
+ "dir": "common/utils/shell-helpers",
288
+ "lastModified": 1762806066,
289
+ "narHash": "sha256-Wz99Fl7SpPU1NkTHJ36XOo6DjOEAMXCw3ThRABOS2Hs=",
290
+ "ref": "refs/heads/trunk",
291
+ "rev": "d73cfdc7ae9e7f547e22a4481d4c2ccce38b26a8",
292
+ "shallow": true,
293
+ "type": "git",
294
+ "url": "ssh://git@gitlab.com/fluidattacks/universe"
295
+ },
296
+ "original": {
297
+ "dir": "common/utils/shell-helpers",
298
+ "rev": "d73cfdc7ae9e7f547e22a4481d4c2ccce38b26a8",
299
+ "shallow": true,
300
+ "type": "git",
301
+ "url": "ssh://git@gitlab.com/fluidattacks/universe"
302
+ }
303
+ },
304
+ "uv2nix": {
305
+ "inputs": {
306
+ "nixpkgs": [
307
+ "observes_flake_builder",
308
+ "pyproject-build-systems",
309
+ "nixpkgs"
310
+ ],
311
+ "pyproject-nix": [
312
+ "observes_flake_builder",
313
+ "pyproject-build-systems",
314
+ "pyproject-nix"
315
+ ]
316
+ },
317
+ "locked": {
318
+ "lastModified": 1758933732,
319
+ "narHash": "sha256-HAmm1GBS1myZCFuog0DC2ZLaynvZtiUI2Crmo+cdQI0=",
320
+ "owner": "pyproject-nix",
321
+ "repo": "uv2nix",
322
+ "rev": "273ce18f913d8559e0d04f820d724308966d7c4d",
323
+ "type": "github"
324
+ },
325
+ "original": {
326
+ "owner": "pyproject-nix",
327
+ "repo": "uv2nix",
328
+ "type": "github"
329
+ }
330
+ },
331
+ "uv2nix_2": {
332
+ "inputs": {
333
+ "nixpkgs": "nixpkgs_4",
334
+ "pyproject-nix": "pyproject-nix_3"
335
+ },
336
+ "locked": {
337
+ "lastModified": 1761872265,
338
+ "narHash": "sha256-i25GRgp2vUOebY70L3NTAgkd+Pr1hnn5xM3qHxH0ONU=",
339
+ "owner": "pyproject-nix",
340
+ "repo": "uv2nix",
341
+ "rev": "74dfb62871be152ad3673b143b0cc56105a4f3c5",
342
+ "type": "github"
343
+ },
344
+ "original": {
345
+ "owner": "pyproject-nix",
346
+ "repo": "uv2nix",
347
+ "type": "github"
348
+ }
349
+ }
350
+ },
351
+ "root": "root",
352
+ "version": 7
353
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ description = "Zoho API auth SDK";
3
+
4
+ inputs = {
5
+ observes_flake_builder = {
6
+ url = "git+ssh://git@gitlab.com/fluidattacks/universe?shallow=1&rev=28bda83eeda56c9c4016f43c86aaf93a366446c3&dir=observes/common/std_flake_2";
7
+ };
8
+ };
9
+
10
+ outputs =
11
+ { self, ... }@inputs:
12
+ let
13
+ build_args =
14
+ {
15
+ system,
16
+ python_version,
17
+ nixpkgs,
18
+ builders,
19
+ scripts,
20
+ }:
21
+ import ./build {
22
+ inherit nixpkgs builders scripts;
23
+ src = import ./build/filter.nix nixpkgs.nix-filter self;
24
+ };
25
+ in
26
+ {
27
+ packages = inputs.observes_flake_builder.outputs.build build_args;
28
+ };
29
+ }
@@ -0,0 +1,6 @@
1
+ from fluidattacks_zoho_sdk._http_client import TokenManager
2
+ from fluidattacks_zoho_sdk.auth import AuthApiFactory, Credentials
3
+
4
+ __version__ = "2.10.0"
5
+
6
+ __all__ = ["AuthApiFactory", "Credentials", "TokenManager"]
@@ -0,0 +1,268 @@
1
+ from collections.abc import Callable
2
+ from datetime import UTC, datetime
3
+ from typing import (
4
+ IO,
5
+ TypeVar,
6
+ )
7
+
8
+ from fa_purity import (
9
+ Coproduct,
10
+ FrozenList,
11
+ Maybe,
12
+ PureIterFactory,
13
+ Result,
14
+ ResultE,
15
+ ResultTransform,
16
+ Unsafe,
17
+ )
18
+ from fa_purity.date_time import DatetimeUTC
19
+ from fa_purity.json import (
20
+ JsonObj,
21
+ JsonPrimitiveUnfolder,
22
+ JsonUnfolder,
23
+ JsonValueFactory,
24
+ UnfoldedFactory,
25
+ Unfolder,
26
+ )
27
+ from fluidattacks_etl_utils.decode import DecodeUtils
28
+ from fluidattacks_etl_utils.natural import Natural
29
+
30
+ from fluidattacks_zoho_sdk.auth import Credentials
31
+ from fluidattacks_zoho_sdk.ids import (
32
+ AccountId,
33
+ ContactId,
34
+ CrmId,
35
+ DeparmentId,
36
+ NumberId,
37
+ ProductId,
38
+ ProfileId,
39
+ RoleId,
40
+ TeamId,
41
+ TicketId,
42
+ UserId,
43
+ )
44
+ from fluidattacks_zoho_sdk.zoho_desk.core import OptionalId
45
+
46
+ _T = TypeVar("_T")
47
+
48
+
49
+ def decode_list_objs(
50
+ items: FrozenList[JsonObj],
51
+ transaform: Callable[[JsonObj], ResultE[_T]],
52
+ ) -> ResultE[FrozenList[_T]]:
53
+ if not items:
54
+ return Result.failure(ValueError("Expected a list"))
55
+
56
+ return ResultTransform.all_ok(
57
+ PureIterFactory.from_list(items).map(lambda v: transaform(v)).to_list(),
58
+ )
59
+
60
+
61
+ def _decode_zoho_creds(raw: JsonObj) -> ResultE[Credentials]:
62
+ client_id = JsonUnfolder.require(raw, "client_id", Unfolder.to_primitive).bind(
63
+ JsonPrimitiveUnfolder.to_str,
64
+ )
65
+ client_secret = JsonUnfolder.require(raw, "client_secret", Unfolder.to_primitive).bind(
66
+ JsonPrimitiveUnfolder.to_str,
67
+ )
68
+ refresh_token = JsonUnfolder.require(raw, "refresh_token", Unfolder.to_primitive).bind(
69
+ JsonPrimitiveUnfolder.to_str,
70
+ )
71
+ scopes_result = JsonUnfolder.require(
72
+ raw,
73
+ "scopes",
74
+ lambda i: Unfolder.to_list_of(
75
+ i,
76
+ lambda x: Unfolder.to_primitive(x).bind(JsonPrimitiveUnfolder.to_str),
77
+ ),
78
+ )
79
+ return client_id.bind(
80
+ lambda cid: client_secret.bind(
81
+ lambda secret: refresh_token.bind(
82
+ lambda token: scopes_result.map(
83
+ lambda scopes: Credentials(cid, secret, token, frozenset(scopes)),
84
+ ),
85
+ ),
86
+ ),
87
+ )
88
+
89
+
90
+ def get_sub_json(raw: JsonObj, key: str) -> JsonObj:
91
+ return (
92
+ JsonUnfolder.require(raw, key, lambda v: Unfolder.to_json(v))
93
+ .alt(Unsafe.raise_exception)
94
+ .to_union()
95
+ )
96
+
97
+
98
+ def decode_optional_date(raw: JsonObj, key: str) -> ResultE[Maybe[DatetimeUTC]]:
99
+ return JsonUnfolder.optional(raw, key, DecodeUtils.to_opt_date_time).map(
100
+ lambda v: v.bind(lambda j: j),
101
+ )
102
+
103
+
104
+ def decode_datetime_assume_utc(s: str) -> ResultE[Maybe[DatetimeUTC]]:
105
+ try:
106
+ if not s or not s.strip():
107
+ return Result.success(Maybe.empty())
108
+
109
+ dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S").replace(tzinfo=UTC)
110
+ return DecodeUtils.to_opt_date_time(JsonValueFactory.from_unfolded(str(dt)))
111
+
112
+ except ValueError as e:
113
+ return Result.failure(e)
114
+
115
+
116
+ def flatten_decoder_date(
117
+ y: Result[Maybe[ResultE[Maybe[DatetimeUTC]]], Exception],
118
+ ) -> ResultE[Maybe[DatetimeUTC]]:
119
+ return y.bind(lambda maybe_inner: maybe_inner.value_or(Result.success(Maybe.empty())))
120
+
121
+
122
+ def decode_opt_date_to_utc(raw: JsonObj, key: str) -> ResultE[Maybe[DatetimeUTC]]:
123
+ date = JsonUnfolder.optional(raw, key, DecodeUtils.to_opt_str).map(
124
+ lambda maybe_str: maybe_str.bind(lambda j: j).map(lambda v: decode_datetime_assume_utc(v)),
125
+ )
126
+ return flatten_decoder_date(date)
127
+
128
+
129
+ def decode_require_date(raw: JsonObj, key: str) -> ResultE[DatetimeUTC]:
130
+ return JsonUnfolder.require(raw, key, DecodeUtils.to_date_time)
131
+
132
+
133
+ def decode_maybe_str(raw: JsonObj, key: str) -> ResultE[Maybe[str]]:
134
+ return JsonUnfolder.optional(raw, key, DecodeUtils.to_opt_str).map(
135
+ lambda v: v.bind(lambda j: j),
136
+ )
137
+
138
+
139
+ def decode_zoho_creds(auth_file: IO[str]) -> ResultE[Credentials]:
140
+ return UnfoldedFactory.load(auth_file).bind(_decode_zoho_creds)
141
+
142
+
143
+ def decode_user_id(raw: JsonObj) -> ResultE[UserId]:
144
+ return (
145
+ JsonUnfolder.require(raw, "id", DecodeUtils.to_str)
146
+ .bind(lambda v: Natural.from_int(int(v)))
147
+ .map(UserId)
148
+ )
149
+
150
+
151
+ def decode_rol_id(raw: JsonObj) -> ResultE[RoleId]:
152
+ return (
153
+ JsonUnfolder.require(raw, "roleId", DecodeUtils.to_str)
154
+ .bind(lambda v: Natural.from_int(int(v)))
155
+ .map(RoleId)
156
+ )
157
+
158
+
159
+ def decode_profile_id(raw: JsonObj) -> ResultE[ProfileId]:
160
+ return (
161
+ JsonUnfolder.require(raw, "profileId", DecodeUtils.to_str)
162
+ .bind(lambda v: Natural.from_int(int(v)))
163
+ .map(ProfileId)
164
+ )
165
+
166
+
167
+ def decode_account_id_bulk(raw: JsonObj) -> ResultE[AccountId]:
168
+ return JsonUnfolder.require(raw, "Account ID", DecodeUtils.to_str).bind(
169
+ lambda v: Natural.from_int(int(v)).map(AccountId),
170
+ )
171
+
172
+
173
+ def decode_account_id(raw: JsonObj) -> ResultE[AccountId]:
174
+ return (
175
+ JsonUnfolder.require(raw, "Account ID", DecodeUtils.to_str)
176
+ .bind(lambda v: Natural.from_int(int(v)))
177
+ .map(AccountId)
178
+ )
179
+
180
+
181
+ def decode_crm_id(raw: JsonObj) -> ResultE[CrmId]:
182
+ return JsonUnfolder.require(raw, "CRM ID", DecodeUtils.to_str).bind(
183
+ lambda v: Natural.from_int(int(v)).map(CrmId),
184
+ )
185
+
186
+
187
+ def decode_department_id(raw: JsonObj) -> ResultE[DeparmentId]:
188
+ return (
189
+ JsonUnfolder.require(raw, "Department", DecodeUtils.to_str)
190
+ .bind(lambda v: Natural.from_int(int(v)))
191
+ .map(DeparmentId)
192
+ )
193
+
194
+
195
+ def decode_department_id_team(raw: JsonObj) -> ResultE[DeparmentId]:
196
+ return (
197
+ JsonUnfolder.require(raw, "departmentId", DecodeUtils.to_str)
198
+ .bind(lambda v: Natural.from_int(int(v)))
199
+ .map(DeparmentId)
200
+ )
201
+
202
+
203
+ def decode_require_product_id(raw: JsonObj) -> ResultE[ProductId]:
204
+ return JsonUnfolder.require(raw, "Product ID", DecodeUtils.to_str).bind(
205
+ lambda v: Natural.from_int(int(v)).map(lambda obj: ProductId(obj)),
206
+ )
207
+
208
+
209
+ def decode_team_id(raw: JsonObj) -> ResultE[TeamId]:
210
+ return JsonUnfolder.require(raw, "Team Id", DecodeUtils.to_str).bind(
211
+ lambda v: Natural.from_int(int(v)).map(lambda obj: TeamId(obj)),
212
+ )
213
+
214
+
215
+ def decode_ticket_id(raw: JsonObj) -> ResultE[TicketId]:
216
+ return JsonUnfolder.require(raw, "ID", DecodeUtils.to_str).bind(
217
+ lambda v: Natural.from_int(int(v)).map(lambda obj: TicketId(obj)),
218
+ )
219
+
220
+
221
+ def decode_contact_id(raw: JsonObj) -> ResultE[ContactId]:
222
+ return JsonUnfolder.require(raw, "Contact ID", DecodeUtils.to_str).bind(
223
+ lambda v: Natural.from_int(int(v)).map(lambda obj: ContactId(obj)),
224
+ )
225
+
226
+
227
+ def decode_contact_id_bulk(raw: JsonObj) -> ResultE[ContactId]:
228
+ return JsonUnfolder.require(raw, "ID", DecodeUtils.to_str).bind(
229
+ lambda v: Natural.from_int(int(v)).map(lambda obj: ContactId(obj)),
230
+ )
231
+
232
+
233
+ def decode_id_team(raw: JsonObj) -> ResultE[TeamId]:
234
+ return JsonUnfolder.require(raw, "id", DecodeUtils.to_str).bind(
235
+ lambda v: Natural.from_int(int(v)).map(lambda obj: TeamId(obj)),
236
+ )
237
+
238
+
239
+ def decode_user_id_bulk(raw: JsonObj) -> ResultE[UserId]:
240
+ return JsonUnfolder.require(raw, "ID", DecodeUtils.to_str).bind(
241
+ lambda v: Natural.from_int(int(v)).map(UserId),
242
+ )
243
+
244
+
245
+ def decode_number_id(raw: JsonObj) -> ResultE[NumberId]:
246
+ return JsonUnfolder.require(raw, "Request Id", DecodeUtils.to_str).bind(
247
+ lambda v: Natural.from_int(int(v)).map(NumberId),
248
+ )
249
+
250
+
251
+ def decode_optional_id(raw: JsonObj, key: str) -> ResultE[Maybe[OptionalId]]:
252
+ return JsonUnfolder.optional(raw, key, DecodeUtils.to_opt_str).map(
253
+ lambda v: v.bind(lambda x: x).map(lambda j: OptionalId(j)),
254
+ )
255
+
256
+
257
+ def assert_single(item: Coproduct[JsonObj, FrozenList[JsonObj]]) -> ResultE[JsonObj]:
258
+ return item.map(
259
+ Result.success,
260
+ lambda _: Result.failure(ValueError("Expected a json not a list")),
261
+ )
262
+
263
+
264
+ def assert_multiple(item: Coproduct[JsonObj, FrozenList[JsonObj]]) -> ResultE[FrozenList[JsonObj]]:
265
+ return item.map(
266
+ lambda _: Result.failure(ValueError("Expected a json list not a single json")),
267
+ Result.success,
268
+ )