rucio-clients 37.0.0rc1__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.

Potentially problematic release.


This version of rucio-clients might be problematic. Click here for more details.

Files changed (104) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/cli/__init__.py +14 -0
  4. rucio/cli/account.py +216 -0
  5. rucio/cli/bin_legacy/__init__.py +13 -0
  6. rucio/cli/bin_legacy/rucio.py +2825 -0
  7. rucio/cli/bin_legacy/rucio_admin.py +2500 -0
  8. rucio/cli/command.py +272 -0
  9. rucio/cli/config.py +72 -0
  10. rucio/cli/did.py +191 -0
  11. rucio/cli/download.py +128 -0
  12. rucio/cli/lifetime_exception.py +33 -0
  13. rucio/cli/replica.py +162 -0
  14. rucio/cli/rse.py +293 -0
  15. rucio/cli/rule.py +158 -0
  16. rucio/cli/scope.py +40 -0
  17. rucio/cli/subscription.py +73 -0
  18. rucio/cli/upload.py +60 -0
  19. rucio/cli/utils.py +226 -0
  20. rucio/client/__init__.py +15 -0
  21. rucio/client/accountclient.py +432 -0
  22. rucio/client/accountlimitclient.py +183 -0
  23. rucio/client/baseclient.py +983 -0
  24. rucio/client/client.py +120 -0
  25. rucio/client/configclient.py +126 -0
  26. rucio/client/credentialclient.py +59 -0
  27. rucio/client/didclient.py +868 -0
  28. rucio/client/diracclient.py +56 -0
  29. rucio/client/downloadclient.py +1783 -0
  30. rucio/client/exportclient.py +44 -0
  31. rucio/client/fileclient.py +50 -0
  32. rucio/client/importclient.py +42 -0
  33. rucio/client/lifetimeclient.py +90 -0
  34. rucio/client/lockclient.py +109 -0
  35. rucio/client/metaconventionsclient.py +140 -0
  36. rucio/client/pingclient.py +44 -0
  37. rucio/client/replicaclient.py +452 -0
  38. rucio/client/requestclient.py +125 -0
  39. rucio/client/richclient.py +317 -0
  40. rucio/client/rseclient.py +746 -0
  41. rucio/client/ruleclient.py +294 -0
  42. rucio/client/scopeclient.py +90 -0
  43. rucio/client/subscriptionclient.py +173 -0
  44. rucio/client/touchclient.py +82 -0
  45. rucio/client/uploadclient.py +969 -0
  46. rucio/common/__init__.py +13 -0
  47. rucio/common/bittorrent.py +234 -0
  48. rucio/common/cache.py +111 -0
  49. rucio/common/checksum.py +168 -0
  50. rucio/common/client.py +122 -0
  51. rucio/common/config.py +788 -0
  52. rucio/common/constants.py +217 -0
  53. rucio/common/constraints.py +17 -0
  54. rucio/common/didtype.py +237 -0
  55. rucio/common/exception.py +1208 -0
  56. rucio/common/extra.py +31 -0
  57. rucio/common/logging.py +420 -0
  58. rucio/common/pcache.py +1409 -0
  59. rucio/common/plugins.py +185 -0
  60. rucio/common/policy.py +93 -0
  61. rucio/common/schema/__init__.py +200 -0
  62. rucio/common/schema/generic.py +416 -0
  63. rucio/common/schema/generic_multi_vo.py +395 -0
  64. rucio/common/stomp_utils.py +423 -0
  65. rucio/common/stopwatch.py +55 -0
  66. rucio/common/test_rucio_server.py +154 -0
  67. rucio/common/types.py +483 -0
  68. rucio/common/utils.py +1688 -0
  69. rucio/rse/__init__.py +96 -0
  70. rucio/rse/protocols/__init__.py +13 -0
  71. rucio/rse/protocols/bittorrent.py +194 -0
  72. rucio/rse/protocols/cache.py +111 -0
  73. rucio/rse/protocols/dummy.py +100 -0
  74. rucio/rse/protocols/gfal.py +708 -0
  75. rucio/rse/protocols/globus.py +243 -0
  76. rucio/rse/protocols/http_cache.py +82 -0
  77. rucio/rse/protocols/mock.py +123 -0
  78. rucio/rse/protocols/ngarc.py +209 -0
  79. rucio/rse/protocols/posix.py +250 -0
  80. rucio/rse/protocols/protocol.py +361 -0
  81. rucio/rse/protocols/rclone.py +365 -0
  82. rucio/rse/protocols/rfio.py +145 -0
  83. rucio/rse/protocols/srm.py +338 -0
  84. rucio/rse/protocols/ssh.py +414 -0
  85. rucio/rse/protocols/storm.py +195 -0
  86. rucio/rse/protocols/webdav.py +594 -0
  87. rucio/rse/protocols/xrootd.py +302 -0
  88. rucio/rse/rsemanager.py +881 -0
  89. rucio/rse/translation.py +260 -0
  90. rucio/vcsversion.py +11 -0
  91. rucio/version.py +45 -0
  92. rucio_clients-37.0.0rc1.data/data/etc/rse-accounts.cfg.template +25 -0
  93. rucio_clients-37.0.0rc1.data/data/etc/rucio.cfg.atlas.client.template +43 -0
  94. rucio_clients-37.0.0rc1.data/data/etc/rucio.cfg.template +241 -0
  95. rucio_clients-37.0.0rc1.data/data/requirements.client.txt +19 -0
  96. rucio_clients-37.0.0rc1.data/data/rucio_client/merge_rucio_configs.py +144 -0
  97. rucio_clients-37.0.0rc1.data/scripts/rucio +133 -0
  98. rucio_clients-37.0.0rc1.data/scripts/rucio-admin +97 -0
  99. rucio_clients-37.0.0rc1.dist-info/METADATA +54 -0
  100. rucio_clients-37.0.0rc1.dist-info/RECORD +104 -0
  101. rucio_clients-37.0.0rc1.dist-info/WHEEL +5 -0
  102. rucio_clients-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
  103. rucio_clients-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
  104. rucio_clients-37.0.0rc1.dist-info/top_level.txt +1 -0
rucio/common/types.py ADDED
@@ -0,0 +1,483 @@
1
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import sys
16
+ from collections.abc import Callable
17
+ from os import PathLike
18
+
19
+ if sys.version_info < (3, 11): # pragma: no cover
20
+ from typing_extensions import TYPE_CHECKING, Any, Literal, NotRequired, Optional, TypedDict, TypeGuard, Union # noqa: UP035
21
+ PathTypeAlias = Union[PathLike, str]
22
+ else:
23
+ from typing import TYPE_CHECKING, Any, Literal, NotRequired, Optional, TypedDict, TypeGuard, Union
24
+ PathTypeAlias = PathLike
25
+
26
+
27
+ if TYPE_CHECKING:
28
+ from datetime import datetime
29
+
30
+ from rucio.common.constants import SUPPORTED_PROTOCOLS_LITERAL
31
+ from rucio.db.sqla.constants import AccountType, IdentityType, ReplicaState, RequestState, RequestType, RSEType
32
+
33
+
34
+ class InternalType:
35
+ '''
36
+ Base for Internal representations of string types
37
+ '''
38
+ def __init__(self, value: Optional[str], vo: str = 'def', from_external: bool = True):
39
+ if value is None:
40
+ self.external = None
41
+ self.internal = None
42
+ self.vo = vo
43
+ elif from_external:
44
+ self.external = value
45
+ self.vo = vo
46
+ self.internal = _RepresentationCalculator.calc_internal(self.external, self.vo)
47
+ else:
48
+ self.internal = value
49
+ vo, external = _RepresentationCalculator.calc_external(self.internal)
50
+ self.external = external
51
+ self.vo = vo
52
+
53
+ def __repr__(self):
54
+ return self.internal
55
+
56
+ def __str__(self):
57
+ return self.external
58
+
59
+ def __eq__(self, other):
60
+ if type(self) is type(other):
61
+ return self.internal == other.internal
62
+ return NotImplemented
63
+
64
+ def __le__(self, other):
65
+ if type(self) is type(other) and self.external is not None and other.external is not None:
66
+ return self.external <= other.external
67
+ return NotImplemented
68
+
69
+ def __lt__(self, other):
70
+ if type(self) is type(other) and self.external is not None and other.external is not None:
71
+ return self.external < other.external
72
+ return NotImplemented
73
+
74
+ def __hash__(self):
75
+ return hash(self.internal)
76
+
77
+
78
+ class _RepresentationCalculator:
79
+ @staticmethod
80
+ def calc_external(internal: str) -> tuple[str, str]:
81
+ """
82
+ Calculate external representation from internal representation
83
+
84
+ :param internal: internal representation
85
+
86
+ :returns: tuple of VO and external representation
87
+ """
88
+ split = internal.split('@', 1)
89
+ if len(split) == 1: # if cannot convert, vo is '' and this is single vo
90
+ vo = 'def'
91
+ external = split[0]
92
+ else:
93
+ vo = split[1]
94
+ external = split[0]
95
+ return vo, external
96
+
97
+ @staticmethod
98
+ def calc_internal(external: str, vo: str) -> str:
99
+ """
100
+ Calculate internal representation from external representation and VO
101
+
102
+ :param external: external representation
103
+ :param vo: VO name
104
+
105
+ :returns: internal representation
106
+ """
107
+ if vo == 'def':
108
+ return external
109
+ internal = '{}@{}'.format(external, vo)
110
+ return internal
111
+
112
+
113
+ class InternalAccount(InternalType):
114
+ '''
115
+ Internal representation of an account
116
+ '''
117
+ def __init__(self, account: Optional[str], vo: str = 'def', from_external: bool = True):
118
+ super(InternalAccount, self).__init__(value=account, vo=vo, from_external=from_external)
119
+
120
+
121
+ class InternalScope(InternalType):
122
+ '''
123
+ Internal representation of a scope
124
+ '''
125
+ def __init__(self, scope: Optional[str], vo: str = 'def', from_external: bool = True):
126
+ super(InternalScope, self).__init__(value=scope, vo=vo, from_external=from_external)
127
+
128
+
129
+ LoggerFunction = Callable[..., Any]
130
+
131
+
132
+ class RSEDomainLANDict(TypedDict):
133
+ read: Optional[int]
134
+ write: Optional[int]
135
+ delete: Optional[int]
136
+
137
+
138
+ class RSEDomainWANDict(TypedDict):
139
+ read: Optional[int]
140
+ write: Optional[int]
141
+ delete: Optional[int]
142
+ third_party_copy_read: Optional[int]
143
+ third_party_copy_write: Optional[int]
144
+
145
+
146
+ class RSEDomainsDict(TypedDict):
147
+ lan: RSEDomainLANDict
148
+ wan: RSEDomainWANDict
149
+
150
+
151
+ class RSEProtocolDict(TypedDict):
152
+ auth_token: Optional[str] # FIXME: typing.NotRequired
153
+ hostname: str
154
+ scheme: str
155
+ port: int
156
+ prefix: str
157
+ impl: str
158
+ domains: RSEDomainsDict
159
+ extended_attributes: Optional[Union[str, dict[str, Any]]]
160
+
161
+
162
+ class RSESettingsDict(TypedDict):
163
+ availability_delete: bool
164
+ availability_read: bool
165
+ availability_write: bool
166
+ credentials: Optional[dict[str, Any]]
167
+ lfn2pfn_algorithm: str
168
+ qos_class: Optional[str]
169
+ staging_area: bool
170
+ rse_type: str
171
+ sign_url: Optional[str]
172
+ read_protocol: int
173
+ write_protocol: int
174
+ delete_protocol: int
175
+ third_party_copy_read_protocol: int
176
+ third_party_copy_write_protocol: int
177
+ id: str
178
+ rse: str
179
+ volatile: bool
180
+ verify_checksum: bool
181
+ deterministic: bool
182
+ domain: list[str]
183
+ protocols: list[RSEProtocolDict]
184
+
185
+ # Compatibility with protocols that access protocol-specific data from rse_settings (e.g. RFIO)
186
+ protocol: RSEProtocolDict
187
+ prefix: str
188
+ scheme: str
189
+ hostname: str
190
+
191
+
192
+ class RSEAccountCounterDict(TypedDict):
193
+ account: InternalAccount
194
+ rse_id: str
195
+
196
+
197
+ class RSEAccountUsageDict(TypedDict):
198
+ rse_id: str
199
+ rse: str
200
+ account: InternalAccount
201
+ used_files: int
202
+ used_bytes: int
203
+ quota_bytes: int
204
+
205
+
206
+ class RSEGlobalAccountUsageDict(TypedDict):
207
+ rse_expression: str
208
+ bytes: int
209
+ files: int
210
+ bytes_limit: int
211
+ bytes_remaining: int
212
+
213
+
214
+ class RSELocalAccountUsageDict(TypedDict):
215
+ rse_id: str
216
+ rse: str
217
+ bytes: int
218
+ files: int
219
+ bytes_limit: int
220
+ bytes_remaining: int
221
+
222
+
223
+ class RSEResolvedGlobalAccountLimitDict(TypedDict):
224
+ resolved_rses: str
225
+ resolved_rse_ids: list[str]
226
+ limit: float
227
+
228
+
229
+ class RuleDict(TypedDict):
230
+ account: InternalAccount
231
+ copies: int
232
+ rse_expression: str
233
+ grouping: Literal['ALL', 'DATASET', 'NONE']
234
+ weight: Optional[str]
235
+ lifetime: Optional[int]
236
+ locked: bool
237
+ subscription_id: Optional[str]
238
+ source_replica_expression: Optional[str]
239
+ activity: str
240
+ notify: Optional[Literal['Y', 'N', 'C', 'P']]
241
+ purge_replicas: bool
242
+
243
+
244
+ class ReplicaDict(TypedDict):
245
+ scope: InternalScope
246
+ name: str
247
+ path: Optional[str]
248
+ state: "ReplicaState"
249
+ bytes: int
250
+ md5: Optional[str]
251
+ adler32: Optional[str]
252
+ rse_id: str
253
+ rse_name: str
254
+ rse_type: "RSEType"
255
+ volatile: bool
256
+
257
+
258
+ class DIDDict(TypedDict):
259
+ name: str
260
+ scope: InternalScope
261
+
262
+
263
+ class DIDStringDict(TypedDict):
264
+ name: str
265
+ scope: str
266
+
267
+
268
+ class LFNDict(TypedDict):
269
+ name: str
270
+ scope: str
271
+ path: NotRequired[str]
272
+ filesize: NotRequired[int]
273
+ adler32: NotRequired[str]
274
+ md5: NotRequired[str]
275
+ filename: NotRequired[str]
276
+
277
+
278
+ class DatasetDict(DIDStringDict):
279
+ rse: str
280
+
281
+
282
+ class AttachDict(DatasetDict):
283
+ did: DIDStringDict
284
+
285
+
286
+ class HopDict(TypedDict):
287
+ source_rse_id: str
288
+ source_scheme: "SUPPORTED_PROTOCOLS_LITERAL"
289
+ source_scheme_priority: int
290
+ dest_rse_id: str
291
+ dest_scheme: "SUPPORTED_PROTOCOLS_LITERAL"
292
+ dest_scheme_priority: int
293
+
294
+
295
+ class TokenDict(TypedDict):
296
+ token: str
297
+ expires_at: 'datetime'
298
+
299
+
300
+ class TokenValidationDict(TypedDict):
301
+ account: Optional[InternalAccount]
302
+ identity: Optional[str]
303
+ lifetime: 'datetime'
304
+ audience: Optional[str]
305
+ authz_scope: Optional[str]
306
+
307
+
308
+ class IPDict(TypedDict):
309
+ ip: Optional[str]
310
+ fqdn: Optional[str]
311
+ site: Optional[str]
312
+
313
+
314
+ class IPWithLocationDict(TypedDict):
315
+ ip: str
316
+ fqdn: str
317
+ site: str
318
+ latitude: Optional[float]
319
+ longitude: Optional[float]
320
+
321
+
322
+ class AccountDict(TypedDict):
323
+ account: InternalAccount
324
+ type: "AccountType"
325
+ email: str
326
+
327
+
328
+ class AccountAttributesDict(TypedDict):
329
+ key: str
330
+ value: Union[bool, str]
331
+
332
+
333
+ class IdentityDict(TypedDict):
334
+ type: "IdentityType"
335
+ identity: str
336
+ email: str
337
+
338
+
339
+ class UsageDict(TypedDict):
340
+ bytes: int
341
+ files: int
342
+ updated_at: Optional['datetime']
343
+
344
+
345
+ class AccountUsageModelDict(TypedDict):
346
+ account: InternalAccount
347
+ rse_id: str
348
+ files: int
349
+ bytes: int
350
+
351
+
352
+ class TraceBaseDict(TypedDict):
353
+ hostname: str
354
+ account: str
355
+ eventType: str
356
+ eventVersion: str
357
+ vo: Optional[str]
358
+ uuid: NotRequired[str]
359
+ scope: NotRequired[str]
360
+ datasetScope: NotRequired[str]
361
+ dataset: NotRequired[str]
362
+ remoteSite: NotRequired[str]
363
+ filesize: NotRequired[int]
364
+ stateReason: NotRequired[str]
365
+ protocol: NotRequired[str]
366
+ clientState: NotRequired[str]
367
+ transferStart: NotRequired[float]
368
+ transferEnd: NotRequired[float]
369
+
370
+
371
+ class TraceDict(TraceBaseDict):
372
+ uuid: str
373
+ scope: str
374
+ datasetScope: str
375
+ dataset: str
376
+ remoteSite: str
377
+ filesize: int
378
+ stateReason: str
379
+ protocol: str
380
+ clientState: str
381
+ transferStart: float
382
+ transferEnd: float
383
+
384
+
385
+ class TraceSchemaDict(TypedDict):
386
+ eventType: str
387
+
388
+
389
+ class FileToUploadDict(TypedDict):
390
+ path: PathTypeAlias
391
+ rse: str
392
+ did_scope: str
393
+ did_name: str
394
+ dataset_scope: NotRequired[str]
395
+ dataset_name: NotRequired[str]
396
+ dataset_meta: NotRequired[str]
397
+ impl: NotRequired[str]
398
+ force_scheme: NotRequired[str]
399
+ pfn: NotRequired[str]
400
+ no_register: NotRequired[bool]
401
+ register_after_upload: NotRequired[bool]
402
+ lifetime: NotRequired[int]
403
+ transfer_timeout: NotRequired[int]
404
+ guid: NotRequired[str]
405
+ recursive: NotRequired[bool]
406
+
407
+
408
+ class FileToUploadWithCollectedInfoDict(FileToUploadDict):
409
+ basename: str
410
+ adler32: str
411
+ md5: str
412
+ meta: dict[str, str]
413
+ state: str
414
+ dataset_did_str: NotRequired[str]
415
+ dirname: str
416
+ upload_result: dict
417
+ bytes: int
418
+ basename: str
419
+
420
+
421
+ class FileToUploadWithCollectedAndDatasetInfoDict(FileToUploadWithCollectedInfoDict):
422
+ dataset_scope: str
423
+ dataset_name: str
424
+
425
+
426
+ class RequestGatewayDict(TypedDict):
427
+ """
428
+ Request dict expected as input to gateway
429
+ """
430
+ scope: str
431
+ name: str
432
+ account: Optional[str]
433
+ dest_rse_id: str
434
+ request_type: "RequestType"
435
+ attributes: "RequestAttributesDict"
436
+
437
+
438
+ class RequestDict(TypedDict):
439
+ """
440
+ Requested dict used in core
441
+ """
442
+ id: str
443
+ request_id: str
444
+ scope: InternalScope
445
+ name: str
446
+ source_rse_id: str
447
+ dest_rse_id: str
448
+ dest_url: str
449
+ state: "RequestState"
450
+ account: NotRequired[InternalAccount]
451
+ rule_id: str
452
+ adler32: str
453
+ bytes: int
454
+ err_msg: str
455
+ sources: list[dict[str, Any]]
456
+ request_type: "RequestType"
457
+ retry_count: Optional[int]
458
+ previous_attempt_id: str
459
+ external_host: str
460
+ external_id: str
461
+ transfertool: str
462
+ attributes: "RequestAttributesDict"
463
+
464
+
465
+ class RequestAttributesDict(TypedDict):
466
+ activity: str
467
+ bytes: int
468
+ md5: str
469
+ adler32: str
470
+ is_intermediate_hop: bool
471
+
472
+
473
+ class FilterDict(TypedDict):
474
+ rule_id: str
475
+ request_id: str
476
+ older_than: 'datetime'
477
+ activities: Union[list[str], str]
478
+
479
+
480
+ def is_str_list(in_list: list[Any]) -> TypeGuard[list[str]]:
481
+ """Typeguard to narrow type of list to list[str].
482
+ For speed, assumes that all elements are str if the first element is str."""
483
+ return isinstance(next(iter(in_list), None), str)