rucio-clients 35.5.0__tar.gz → 36.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.

Potentially problematic release.


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

Files changed (200) hide show
  1. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/AUTHORS.rst +1 -0
  2. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/PKG-INFO +3 -1
  3. rucio_clients-36.0.0/bin/rucio +118 -0
  4. rucio_clients-36.0.0/bin/rucio-admin +89 -0
  5. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/etc/rucio.cfg.atlas.client.template +3 -2
  6. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/etc/rucio.cfg.template +2 -1
  7. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/baseclient.py +7 -5
  8. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/downloadclient.py +3 -1
  9. rucio_clients-36.0.0/lib/rucio/client/richclient.py +324 -0
  10. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/rseclient.py +4 -4
  11. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/uploadclient.py +4 -1
  12. rucio_clients-36.0.0/lib/rucio/common/bittorrent.py +234 -0
  13. rucio_clients-36.0.0/lib/rucio/common/cache.py +111 -0
  14. rucio_clients-36.0.0/lib/rucio/common/checksum.py +151 -0
  15. rucio_clients-36.0.0/lib/rucio/common/client.py +122 -0
  16. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/config.py +10 -15
  17. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/constants.py +60 -2
  18. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/didtype.py +72 -24
  19. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/exception.py +67 -14
  20. rucio_clients-36.0.0/lib/rucio/common/extra.py +31 -0
  21. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/logging.py +13 -13
  22. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/plugins.py +59 -27
  23. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/schema/__init__.py +53 -11
  24. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/test_rucio_server.py +14 -8
  25. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/types.py +108 -50
  26. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/utils.py +63 -630
  27. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/__init__.py +3 -3
  28. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/bittorrent.py +14 -1
  29. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/gfal.py +1 -1
  30. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/gsiftp.py +15 -0
  31. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/posix.py +1 -1
  32. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/protocol.py +16 -298
  33. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/rclone.py +2 -1
  34. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/rfio.py +9 -0
  35. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/ssh.py +2 -1
  36. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/xrootd.py +2 -1
  37. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/rsemanager.py +11 -8
  38. rucio_clients-36.0.0/lib/rucio/rse/translation.py +273 -0
  39. rucio_clients-36.0.0/lib/rucio/vcsversion.py +11 -0
  40. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/version.py +7 -0
  41. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio_clients.egg-info/SOURCES.txt +7 -7
  42. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/pyproject.toml +21 -1
  43. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/requirements/requirements.client.txt +2 -0
  44. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/setup.py +1 -1
  45. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/setuputil.py +3 -1
  46. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_belleii.py +1 -1
  47. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_bin_rucio.py +103 -102
  48. rucio_clients-36.0.0/tests/test_cli_client_structure.py +673 -0
  49. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_conveyor.py +2 -1
  50. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_download.py +1 -15
  51. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_impl_upload_download.py +30 -30
  52. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_multi_vo.py +0 -2
  53. rucio_clients-36.0.0/tests/test_policy_package.py +60 -0
  54. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_replica_recoverer.py +5 -5
  55. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_replica_sorting.py +22 -1
  56. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse.py +4 -4
  57. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_lfn2path.py +1 -1
  58. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_rclone.py +2 -1
  59. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_rsync.py +2 -1
  60. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_ssh.py +2 -1
  61. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_transfer_plugins.py +88 -75
  62. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_upload.py +6 -1
  63. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_utils.py +2 -24
  64. rucio_clients-35.5.0/bin/rucio +0 -2541
  65. rucio_clients-35.5.0/bin/rucio-admin +0 -2447
  66. rucio_clients-35.5.0/lib/rucio/common/cache.py +0 -74
  67. rucio_clients-35.5.0/lib/rucio/common/extra.py +0 -36
  68. rucio_clients-35.5.0/lib/rucio/common/schema/atlas.py +0 -413
  69. rucio_clients-35.5.0/lib/rucio/common/schema/belleii.py +0 -408
  70. rucio_clients-35.5.0/lib/rucio/common/schema/domatpc.py +0 -401
  71. rucio_clients-35.5.0/lib/rucio/common/schema/escape.py +0 -426
  72. rucio_clients-35.5.0/lib/rucio/common/schema/icecube.py +0 -406
  73. rucio_clients-35.5.0/lib/rucio/vcsversion.py +0 -11
  74. rucio_clients-35.5.0/tests/test_common_types.py +0 -50
  75. rucio_clients-35.5.0/tests/test_didtype.py +0 -96
  76. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/ChangeLog +0 -0
  77. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/LICENSE +0 -0
  78. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/MANIFEST.in +0 -0
  79. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/README.md +0 -0
  80. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/etc/rse-accounts.cfg.template +0 -0
  81. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/__init__.py +0 -0
  82. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/alembicrevision.py +0 -0
  83. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/__init__.py +0 -0
  84. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/accountclient.py +0 -0
  85. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/accountlimitclient.py +0 -0
  86. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/client.py +0 -0
  87. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/configclient.py +0 -0
  88. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/credentialclient.py +0 -0
  89. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/didclient.py +0 -0
  90. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/diracclient.py +0 -0
  91. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/exportclient.py +0 -0
  92. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/fileclient.py +0 -0
  93. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/importclient.py +0 -0
  94. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/lifetimeclient.py +0 -0
  95. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/lockclient.py +0 -0
  96. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/metaconventionsclient.py +0 -0
  97. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/pingclient.py +0 -0
  98. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/replicaclient.py +0 -0
  99. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/requestclient.py +0 -0
  100. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/ruleclient.py +0 -0
  101. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/scopeclient.py +0 -0
  102. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/subscriptionclient.py +0 -0
  103. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/touchclient.py +0 -0
  104. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/__init__.py +0 -0
  105. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/constraints.py +0 -0
  106. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/pcache.py +0 -0
  107. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/policy.py +0 -0
  108. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/schema/generic.py +0 -0
  109. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
  110. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/stomp_utils.py +0 -0
  111. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/stopwatch.py +0 -0
  112. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/__init__.py +0 -0
  113. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/cache.py +0 -0
  114. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/dummy.py +0 -0
  115. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/globus.py +0 -0
  116. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
  117. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/mock.py +0 -0
  118. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
  119. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/srm.py +0 -0
  120. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/storm.py +0 -0
  121. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/webdav.py +0 -0
  122. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/pylintrc +0 -0
  123. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/setup.cfg +0 -0
  124. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_abacus_account.py +0 -0
  125. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_abacus_collection_replica.py +0 -0
  126. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_abacus_rse.py +0 -0
  127. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_account.py +0 -0
  128. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_account_limits.py +0 -0
  129. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_archive.py +0 -0
  130. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_auditor.py +0 -0
  131. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_auditor_hdfs.py +0 -0
  132. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_auditor_srmdumps.py +0 -0
  133. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_authentication.py +0 -0
  134. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_automatix.py +0 -0
  135. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_bad_replica.py +0 -0
  136. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_bb8.py +0 -0
  137. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_boolean.py +0 -0
  138. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_clients.py +0 -0
  139. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_config.py +0 -0
  140. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_conveyor_submitter.py +0 -0
  141. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_counter.py +0 -0
  142. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_credential.py +0 -0
  143. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_curl.py +0 -0
  144. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_daemons.py +0 -0
  145. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dataset_replicas.py +0 -0
  146. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_db.py +0 -0
  147. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_did.py +0 -0
  148. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_did_meta_plugins.py +0 -0
  149. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper.py +0 -0
  150. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper_consistency.py +0 -0
  151. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper_data_model.py +0 -0
  152. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper_path_parsing.py +0 -0
  153. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_filter_engine.py +0 -0
  154. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_gateway_external_representation.py +0 -0
  155. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_heartbeat.py +0 -0
  156. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_hermes.py +0 -0
  157. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_identity.py +0 -0
  158. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_import_export.py +0 -0
  159. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_cleaner.py +0 -0
  160. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_evaluator.py +0 -0
  161. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_injector.py +0 -0
  162. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_repairer.py +0 -0
  163. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_lifetime.py +0 -0
  164. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_message.py +0 -0
  165. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_meta_conventions.py +0 -0
  166. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_meta_did.py +0 -0
  167. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_module_import.py +0 -0
  168. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_monitor.py +0 -0
  169. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_naming_convention.py +0 -0
  170. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_oauthmanager.py +0 -0
  171. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_oidc.py +0 -0
  172. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_permission.py +0 -0
  173. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_pfns.py +0 -0
  174. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_ping.py +0 -0
  175. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_preparer.py +0 -0
  176. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_qos.py +0 -0
  177. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_quarantined_replica.py +0 -0
  178. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_reaper.py +0 -0
  179. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_redirect.py +0 -0
  180. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_replica.py +0 -0
  181. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_request.py +0 -0
  182. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_root_proxy.py +0 -0
  183. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_expression_parser.py +0 -0
  184. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_gfal2.py +0 -0
  185. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
  186. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_posix.py +0 -0
  187. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_srm.py +0 -0
  188. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_webdav.py +0 -0
  189. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_xrootd.py +0 -0
  190. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_selector.py +0 -0
  191. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rucio_server.py +0 -0
  192. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rule.py +0 -0
  193. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_scope.py +0 -0
  194. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_subscription.py +0 -0
  195. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_throttler.py +0 -0
  196. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_tpc.py +0 -0
  197. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_trace.py +0 -0
  198. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_transfer.py +0 -0
  199. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_undertaker.py +0 -0
  200. {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tools/merge_rucio_configs.py +0 -0
@@ -67,6 +67,7 @@ Individual contributors to the source code
67
67
  - Aksel Lunde Aase <aksel.lunde.aase@gmail.com>, 2022
68
68
  - Elena Gazzarrini <gazzarrini.elena@gmail.com>, 2022-2023
69
69
  - Maximilian Linhoff, <maximilian.linhoff@tu-dortmund.de>, 2024
70
+ - Eric Banzuzi, <eric.banzuzi@gmail.com>, 2024
70
71
 
71
72
  Organisations employing contributors
72
73
  ------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rucio-clients
3
- Version: 35.5.0
3
+ Version: 36.0.0
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio
@@ -24,6 +24,8 @@ Requires-Dist: urllib3>=1.26.18
24
24
  Requires-Dist: dogpile-cache>=1.2.2
25
25
  Requires-Dist: tabulate>=0.9.0
26
26
  Requires-Dist: jsonschema>=4.20.0
27
+ Requires-Dist: packaging>=24.1
28
+ Requires-Dist: rich>=13.7.1
27
29
  Provides-Extra: ssh
28
30
  Requires-Dist: paramiko>=3.4.0; extra == "ssh"
29
31
  Provides-Extra: kerberos
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env python
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import argparse
17
+ import sys
18
+ from typing import Optional
19
+
20
+ from rucio.client.commands.bin_legacy.rucio import main as main_legacy
21
+ from rucio.client.commands.command import main
22
+
23
+
24
+ def make_warning():
25
+ base_warning = "\nWARNING: This method is being deprecated."
26
+ new_command = map_legacy_command()
27
+ if new_command is not None:
28
+ warning = f"{base_warning}\nPlease replace your command with `rucio {' '.join(new_command)}`.\n"
29
+ else:
30
+ warning = base_warning + "\nPlease view rucio -h for an updated help menu.\n"
31
+
32
+ return warning
33
+
34
+
35
+ def map_legacy_command() -> Optional[list[str]]:
36
+ try:
37
+ command = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--version")][1]
38
+ except IndexError:
39
+ command = None
40
+
41
+ new_command = None
42
+ if command not in ("-h", "--version", None):
43
+ command_map = {
44
+ "list-file-replicas": ["replica", "list"],
45
+ "list-dataset-replicas": ["replica", "dataset"],
46
+ "add-dataset": ["did", "add", "--type dataset"],
47
+ "add-container": ["did", "add", "--type container"],
48
+ "attach": ["did", "content", "add"],
49
+ "detach": ["did", "content", "remove"],
50
+ "ls": ["did", "list"],
51
+ "list-dids": ["did", "list"],
52
+ "list-parent-dids": ["did", "show", "--parent"],
53
+ "list-scopes": ["scope", "list"],
54
+ "close": ["did", "update", "--close"],
55
+ "reopen": ["did", "update", "--open"],
56
+ "stat": ["did", "show"],
57
+ "erase": ["did", "remove"],
58
+ "list-content": ["did", "content", "list"],
59
+ "list-content-history": ["did", "content", "history"],
60
+ "upload": ["upload"],
61
+ "get": ["download"],
62
+ "download": ["download"],
63
+ "get-metadata": ["did", "metadata", "list"],
64
+ "set-metadata": ["did", "metadata", "add"],
65
+ "delete-metadata": ["did", "metadata", "remove"],
66
+ "list-rse-usage": ["rse", "show"],
67
+ "list-account-usage": ["account", "usage"],
68
+ "list-account-limits": ["account", "limit", "list"],
69
+ "add-rule": ["rule", "add"],
70
+ "delete-rule": ["rule", "remove"],
71
+ "rule-info": ["rule", "info"],
72
+ "list-rules": ["rule", "list"],
73
+ "list-rules-history": ["rule", "history"],
74
+ "update-rule": ["rule", "update"],
75
+ "move-rule": ["rule", "update", "--move"],
76
+ "list-rses": ["rse", "list"],
77
+ "list-suspicious-replicas": ["replica", "state", "suspicious"],
78
+ "list-rse-attributes": ["rse", "attribute", "list"],
79
+ "touch": ["did", "update", "--touch"],
80
+ "add-lifetime-exception": ["lifetime-exception", "add"],
81
+ }
82
+ try:
83
+ new_command = command_map[command]
84
+ except KeyError:
85
+ pass
86
+
87
+ return new_command
88
+
89
+
90
+ if __name__ == "__main__":
91
+ commands = ("-h", "--version", "account", "config", "did", "replica", "rse", "rule", "scope", "subscription", "ping", "whoami", "test-server", "lifetime-exception", "upload", "download")
92
+ first_command = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--help", "--version")][1]
93
+ is_legacy = '--legacy' in sys.argv
94
+
95
+ if (first_command in commands) and not is_legacy:
96
+ main()
97
+
98
+ elif is_legacy:
99
+ warning = make_warning()
100
+ print(warning)
101
+ sys.argv.pop(sys.argv.index('--legacy'))
102
+ main_legacy()
103
+
104
+ else:
105
+ warning = make_warning()
106
+ print(warning)
107
+ try:
108
+ main_legacy()
109
+ # Make a custom warning - show the new help menu when invalid commands are called.
110
+ except argparse.ArgumentError:
111
+ print("Invalid argument(s) - %s " % sys.argv[1:])
112
+ command = map_legacy_command()
113
+ if command is not None:
114
+ sys.argv = ["rucio"] + command + ["-h"]
115
+ else:
116
+ sys.argv = ["rucio", "-h"]
117
+
118
+ main()
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env python
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ import sys
16
+
17
+ from rucio.client.commands.bin_legacy.rucio_admin import main as main_legacy
18
+
19
+
20
+ def make_warning():
21
+ base_warning = "\nWARNING: This method is being deprecated."
22
+ args = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--help", "--version")]
23
+ first_command = args[1]
24
+ try:
25
+ second_command = args[2]
26
+ except IndexError:
27
+ second_command = "-h"
28
+
29
+ if first_command not in ("-h", "--version", "--help"):
30
+ command_map = {
31
+ "data": {"-h": "did -h", "import": "did upload", "export": "did download"},
32
+ "account": {
33
+ "-h": "account -h",
34
+ "add": "account add",
35
+ "delete": "account remove",
36
+ "info": "account show",
37
+ "update": "account update",
38
+ "set-limits": "account limit add",
39
+ "get-limits": "account limit list",
40
+ "delete-limits": "account limit remove",
41
+ "ban": "account update --ban True",
42
+ "unban": "account update --ban False",
43
+ "list-attributes": "account attribute list",
44
+ "add-attribute": "account attribute add",
45
+ "delete-attribute": "account attribute remove",
46
+ },
47
+ "identity": {"-h": "account identity -h", "add": "account identity add", "delete": "account identity remove"},
48
+ "rse": {
49
+ "-h": "rse -h",
50
+ "add": "rse add",
51
+ "list": "rse",
52
+ "update": "rse update",
53
+ "info": "rse info",
54
+ "set-attribute": "rse attribute add",
55
+ "delete-attribute": "rse attribute remove",
56
+ "delete-distance": "rse distance remove",
57
+ "get-distance": "rse distance list",
58
+ "get-attribute": "rse attribute list",
59
+ "add-protocol": "rse protocol add",
60
+ "delete-protocol": "rse protocol remove",
61
+ "delete": "rse remove",
62
+ "add-qos-policy": "rse qos add",
63
+ "add-distance": "rse distance add",
64
+ "delete-qos-policy": "rse qos remove",
65
+ "list-qos-policies": "rse qos list",
66
+ "set-limit": "rse limit add",
67
+ "delete-limit": "rse limit remove",
68
+ },
69
+ "scope": {"-h": "scope -h", "add": "scope add", "list": "scope list"},
70
+ "config": {"-h": "config -h", "get": "config list", "set": "config add", "delete": "config remove"},
71
+ "subscription": {"-h": "subscription -h", "add": "subscription add", "list": "subscription", "update": "subscription update", "reevaluate": "subscription touch"},
72
+ "replicas": {"-h": "replica -h", "quarantine": "replica state quarantine", "declare-bad": "replica state bad", "declare-temporary-unavailable": "replica state temp-unavailable", "list-pfns": "replica pfn", "set-tombstone": "replica tombstone"},
73
+ }
74
+ try:
75
+ new_command = command_map[first_command]
76
+ new_command = new_command[second_command]
77
+ except KeyError:
78
+ new_command = "-h"
79
+
80
+ warning = f"{base_warning}\nPlease replace your command with `rucio {new_command}`.\n"
81
+ else:
82
+ warning = base_warning + "\nPlease view rucio -h for an updated help menu.\n"
83
+
84
+ print(warning)
85
+
86
+
87
+ if __name__ == "__main__":
88
+ make_warning()
89
+ main_legacy()
@@ -29,8 +29,9 @@ request_retries = 3
29
29
  auth_type = x509_proxy
30
30
 
31
31
  [policy]
32
- permission = atlas
33
- schema = atlas
32
+ package = atlas_rucio_policy_package
33
+ #permission = atlas
34
+ #schema = atlas
34
35
  lfn2pfn_algorithm_default = hash
35
36
  support = hn-atlas-dist-analysis-help@cern.ch
36
37
  support_rucio = https://github.com/rucio/rucio/issues/
@@ -229,9 +229,10 @@ panda_url = http://bigpanda.cern.ch/jobs/?category=analysis&jobstatus=running
229
229
  window = 604800
230
230
 
231
231
  [policy]
232
- package = ATLASRucioPolicy
232
+ package = atlas_rucio_policy_package
233
233
  permission = atlas
234
234
  schema = atlas
235
+ extract_scope = atlas
235
236
  lfn2pfn_algorithm_default = hash
236
237
  support = hn-atlas-dist-analysis-help@cern.ch
237
238
  support_rucio = https://github.com/rucio/rucio/issues/
@@ -22,13 +22,11 @@ import os
22
22
  import secrets
23
23
  import sys
24
24
  import time
25
- from collections.abc import Generator
26
25
  from configparser import NoOptionError, NoSectionError
27
- from logging import Logger
28
26
  from os import environ, fdopen, geteuid, makedirs, path
29
27
  from shutil import move
30
28
  from tempfile import mkstemp
31
- from typing import Any, Optional
29
+ from typing import TYPE_CHECKING, Any, Optional
32
30
  from urllib.parse import urlparse
33
31
 
34
32
  import requests
@@ -44,6 +42,10 @@ from rucio.common.exception import CannotAuthenticate, ClientProtocolNotSupporte
44
42
  from rucio.common.extra import import_extras
45
43
  from rucio.common.utils import build_url, get_tmp_dir, my_key_generator, parse_response, setup_logger, ssh_sign
46
44
 
45
+ if TYPE_CHECKING:
46
+ from collections.abc import Generator
47
+ from logging import Logger
48
+
47
49
  EXTRA_MODULES = import_extras(['requests_kerberos'])
48
50
 
49
51
  if EXTRA_MODULES['requests_kerberos']:
@@ -90,7 +92,7 @@ class BaseClient:
90
92
  timeout: Optional[int] = 600,
91
93
  user_agent: Optional[str] = 'rucio-clients',
92
94
  vo: Optional[str] = None,
93
- logger: Logger = LOG) -> None:
95
+ logger: 'Logger' = LOG) -> None:
94
96
  """
95
97
  Constructor of the BaseClient.
96
98
  :param rucio_host: The address of the rucio server, if None it is read from the config file.
@@ -364,7 +366,7 @@ class BaseClient:
364
366
  else:
365
367
  return exception.RucioException, "%s: %s" % (exc_cls, exc_msg)
366
368
 
367
- def _load_json_data(self, response: requests.Response) -> Generator[Any, Any, Any]:
369
+ def _load_json_data(self, response: requests.Response) -> 'Generator[Any, Any, Any]':
368
370
  """
369
371
  Helper method to correctly load json data based on the content type of the http response.
370
372
 
@@ -29,11 +29,13 @@ from typing import TYPE_CHECKING, Any, Optional
29
29
 
30
30
  from rucio import version
31
31
  from rucio.client.client import Client
32
+ from rucio.common.checksum import CHECKSUM_ALGO_DICT, GLOBALLY_SUPPORTED_CHECKSUMS, PREFERRED_CHECKSUM, adler32
33
+ from rucio.common.client import detect_client_location
32
34
  from rucio.common.config import config_get
33
35
  from rucio.common.didtype import DID
34
36
  from rucio.common.exception import InputValidationError, NoFilesDownloaded, NotAllFilesDownloaded, RucioException
35
37
  from rucio.common.pcache import Pcache
36
- from rucio.common.utils import CHECKSUM_ALGO_DICT, GLOBALLY_SUPPORTED_CHECKSUMS, PREFERRED_CHECKSUM, adler32, detect_client_location, execute, extract_scope, generate_uuid, parse_replicas_from_file, parse_replicas_from_string, send_trace, sizefmt
38
+ from rucio.common.utils import execute, extract_scope, generate_uuid, parse_replicas_from_file, parse_replicas_from_string, send_trace, sizefmt
37
39
  from rucio.rse import rsemanager as rsemgr
38
40
 
39
41
  if TYPE_CHECKING:
@@ -0,0 +1,324 @@
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 logging
16
+ import pydoc
17
+ import re
18
+ import subprocess
19
+ import sys
20
+ from datetime import datetime
21
+ from typing import TYPE_CHECKING, Any, Optional, Union
22
+
23
+ from rich import box
24
+ from rich.console import Console, JustifyMethod, RenderableType
25
+ from rich.logging import RichHandler
26
+ from rich.table import Table
27
+ from rich.text import Text
28
+
29
+ from rucio.common.config import config_get
30
+
31
+ if TYPE_CHECKING:
32
+ from collections.abc import Callable, Sequence
33
+
34
+ from rich.style import StyleType
35
+
36
+
37
+ MIN_CONSOLE_WIDTH = 80
38
+ MAX_TRACEBACK_WIDTH = 120 # Slightly higher than default width of rich.traceback (100).
39
+
40
+
41
+ class CLITheme:
42
+ """
43
+ Class to define styles for Rich widgets and prints in the CLI.
44
+ """
45
+ TABLE_FMT = box.SQUARE
46
+
47
+ TEXT_HIGHLIGHT = 'grey50' # Used to highlight prints between tables, e.g. get_metadata or stat.
48
+ SUBHEADER_HIGHLIGHT = 'cyan' # Used to highlight prints between tables for a section, e.g. protocols or usage per account.
49
+ SPINNER = 'dots2'
50
+ SPINNER_STYLE = 'green'
51
+
52
+ JSON_STR = 'green'
53
+ JSON_NUM = 'bold cyan'
54
+
55
+ SUCCESS_ICON = '[bold green]\u2714[/]'
56
+ FAILURE_ICON = '[bold red]\u2717[/]'
57
+
58
+ LOG_THEMES = {
59
+ 'logging.level.info': 'default',
60
+ 'logging.level.warning': 'bold yellow',
61
+ 'logging.level.debug': 'dim',
62
+ 'logging.level.critical': 'default on red',
63
+ 'repr.bool_true': 'green',
64
+ 'repr.bool_false': 'red',
65
+ 'log.time': 'turquoise4'
66
+ }
67
+
68
+ DID_TYPE = {
69
+ 'CONTAINER': 'bold dodger_blue1',
70
+ 'DATASET': 'bold orange3',
71
+ 'FILE': 'bold default',
72
+ 'COLLECTION': 'bold green',
73
+ 'ALL': 'bold magenta',
74
+ 'DERIVED': 'bold magenta'
75
+ }
76
+
77
+ BOOLEAN = {
78
+ 'True': 'green',
79
+ 'False': 'red'
80
+ }
81
+
82
+ RULE_STATE = {
83
+ 'OK': 'bold green',
84
+ 'REPLICATING': 'bold default',
85
+ 'STUCK': 'bold orange3',
86
+ 'WAITING APPROVAL': 'bold dodger_blue1',
87
+ 'INJECT': 'bold medium_purple3',
88
+ 'SUSPENDED': 'bold red'
89
+ }
90
+
91
+ RSE_TYPE = {
92
+ 'DISK': 'bold dodger_blue1',
93
+ 'TAPE': 'bold orange3',
94
+ 'UNKNOWN': 'bold'
95
+ }
96
+
97
+ SUBSCRIPTION_STATE = {
98
+ 'ACTIVE': 'bold green',
99
+ 'INACTIVE': 'bold',
100
+ 'NEW': 'bold dodger_blue1',
101
+ 'UPDATED': 'bold green',
102
+ 'BROKEN': 'bold red',
103
+ 'UNKNOWN': 'bold orange3'
104
+ }
105
+
106
+ AVAILABILITY = {
107
+ 'AVAILABLE': 'bold green',
108
+ 'DELETED': 'bold',
109
+ 'LOST': 'bold red',
110
+ 'UNKNOWN': 'bold orange3'
111
+ }
112
+
113
+ ACCOUNT_STATUS = {
114
+ 'ACTIVE': 'bold green',
115
+ 'SUSPENDED': 'bold red',
116
+ 'DELETED': 'bold'
117
+ }
118
+
119
+ REPLICA_STATE = {
120
+ 'A': 'bold green',
121
+ 'U': 'bold red',
122
+ 'C': 'bold default',
123
+ 'B': 'bold dodger_blue1',
124
+ 'D': 'bold red',
125
+ 'T': 'bold orange3'
126
+ }
127
+
128
+ ACCOUNT_TYPE = {
129
+ 'USER': 'default',
130
+ 'GROUP': 'medium_purple3',
131
+ 'SERVICE': 'yellow'
132
+ }
133
+
134
+
135
+ def setup_rich_logger(
136
+ module_name: Optional[str] = None,
137
+ logger_name: Optional[str] = None,
138
+ logger_level: Optional[int] = None,
139
+ verbose: bool = False,
140
+ console: Optional[Console] = None
141
+ ) -> logging.Logger:
142
+ """
143
+ Factory method to set logger with RichHandler.
144
+
145
+ The function is a copy of the method in rucio.common.utils setup_logger() with minor changes.
146
+
147
+ :param module_name: __name__ of the module that is calling this method
148
+ :param logger_name: name of the logger, typically name of the module.
149
+ :param logger_level: if not given, fetched from config.
150
+ :param verbose: verbose option set in bin/rucio
151
+ :param console: Rich console object
152
+ :returns: logger with RichHandler
153
+ """
154
+ # Helper method for cfg check.
155
+ def _force_cfg_log_level(cfg_option: str) -> bool:
156
+ cfg_forced_modules = config_get('logging', cfg_option, raise_exception=False, default=None, clean_cached=True, check_config_table=False)
157
+ if cfg_forced_modules and module_name is not None:
158
+ if re.match(str(cfg_forced_modules), module_name):
159
+ return True
160
+ return False
161
+
162
+ if not logger_name:
163
+ if not module_name:
164
+ logger_name = 'user'
165
+ else:
166
+ logger_name = module_name.split('.')[-1]
167
+ logger = logging.getLogger(logger_name)
168
+
169
+ # Extracting the log level.
170
+ if not logger_level:
171
+ logger_level = logging.INFO
172
+ if verbose:
173
+ logger_level = logging.DEBUG
174
+
175
+ # Overriding by the config.
176
+ cfg_levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR)
177
+ for level in cfg_levels:
178
+ cfg_opt = 'forceloglevel' + logging.getLevelName(level)
179
+ if _force_cfg_log_level(cfg_opt):
180
+ logger_level = level
181
+
182
+ logger.setLevel(logger_level)
183
+
184
+ def add_handler(logger: logging.Logger,
185
+ console: Optional[Console] = None,
186
+ verbose: bool = False) -> None:
187
+
188
+ def time_formatter(timestamp: datetime) -> Text:
189
+ return Text(f"[{timestamp.isoformat(sep=' ', timespec='milliseconds')}]")
190
+
191
+ console = console or Console()
192
+ handler = RichHandler(rich_tracebacks=True, markup=True, show_path=verbose, show_time=verbose, console=console, tracebacks_width=min(console.width, MAX_TRACEBACK_WIDTH),
193
+ tracebacks_word_wrap=True, log_time_format=time_formatter)
194
+ logger.addHandler(handler)
195
+
196
+ # Setting handler and formatter.
197
+ if not logger.handlers:
198
+ add_handler(logger, console, verbose)
199
+
200
+ return logger
201
+
202
+
203
+ def _format_value(value: Optional[Union[RenderableType, int, float, bool, datetime]] = None) -> RenderableType:
204
+ """
205
+ Formats the value based on its type for Rich Table.
206
+
207
+ A helper function to format the value to Rich RenderableType.
208
+
209
+ :param value: value to format
210
+ :returns: formatted value
211
+ """
212
+ if value is None or str(value) == 'None':
213
+ return ''
214
+ if isinstance(value, bool):
215
+ return CLITheme.BOOLEAN[str(value)]
216
+ if isinstance(value, (int, float, datetime)):
217
+ return str(value)
218
+ return value
219
+
220
+
221
+ def generate_table(
222
+ rows: 'Sequence[Sequence[Union[RenderableType, int, float, bool, datetime]]]',
223
+ headers: Optional['Sequence[RenderableType]'] = None,
224
+ row_styles: Optional['Sequence[StyleType]'] = None,
225
+ col_alignments: Optional[list[JustifyMethod]] = None,
226
+ table_format: box.Box = CLITheme.TABLE_FMT,
227
+ ) -> Table:
228
+ """
229
+ Generates a Rich Table object from given input rows.
230
+
231
+ The elements in each row can be either plain strings or Rich renderable objects.
232
+ Passing strings will display them as simple text, while using Rich objects
233
+ allows you to introduce additional structure, styling, and widgets (e.g. Text, Trees) into
234
+ the table. Strings with style markup will be rendered as styled text.
235
+
236
+ :param table_format: style of the table
237
+ :param headers: list of headers
238
+ :param rows: list of rows
239
+ :param col_alignments: list of column alignments
240
+ :param row_styles: list of row styles
241
+ :returns: a Rich Table object
242
+ """
243
+ table = Table(box=table_format, show_header=headers is not None and len(headers) > 0)
244
+ table.row_styles = row_styles or ['none', 'dim']
245
+
246
+ if len(rows) == 0:
247
+ if headers:
248
+ for header in headers:
249
+ table.add_column(header)
250
+ return table
251
+
252
+ # Auto-detect on first row, numerical values on the right.
253
+ col_alignments = col_alignments or ['right' if str(col).isnumeric() else 'left' for col in rows[0]]
254
+ headers = headers or [''] * len(rows[0])
255
+ while len(headers) > len(col_alignments):
256
+ col_alignments.append('left')
257
+
258
+ for header, alignment in zip(headers, col_alignments):
259
+ table.add_column(header, overflow='fold', justify=alignment)
260
+
261
+ for row in rows:
262
+ row = [_format_value(col) for col in row]
263
+ table.add_row(*row)
264
+ return table
265
+
266
+
267
+ def print_output(
268
+ *output: Any,
269
+ console: Console,
270
+ no_pager: bool = False
271
+ ) -> None:
272
+ """
273
+ Prints the objects using the specified Rich console object. Optionally disables the pager if specified.
274
+
275
+ The function works similarly to Rich's `console.print()` method but provides additional control over the pager feature.
276
+
277
+ :param output: objects to print to the terminal
278
+ :param console: Rich console object
279
+ :param no_pager: flag to disable the pager
280
+ """
281
+ if console.is_terminal:
282
+ if no_pager:
283
+ console.print(*output)
284
+ else:
285
+ console.width = sys.maxsize # Overwrite auto-detected console width.
286
+ console.begin_capture()
287
+ console.print(*output)
288
+ else:
289
+ console.width = sys.maxsize
290
+ console.print(*output)
291
+
292
+
293
+ def get_cli_config() -> str:
294
+ """
295
+ Returns the CLI type from the config file.
296
+
297
+ :returns: CLI type (Rich or tabulate)
298
+ """
299
+ cli_type = config_get('experimental', 'cli', raise_exception=False, default='tabulate').lower()
300
+ if cli_type not in ['rich', 'tabulate']:
301
+ cli_type = 'tabulate'
302
+ return cli_type
303
+
304
+
305
+ def get_pager() -> 'Callable[[str], None]':
306
+ """
307
+ Returns the pager function based on the terminal availability.
308
+
309
+ :returns: pager
310
+ """
311
+ default_pager = 'less'
312
+ try:
313
+ result = subprocess.run([default_pager], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
314
+ less_available = result.returncode == 0
315
+ except Exception:
316
+ less_available = False
317
+
318
+ def less_pager_function(text: str) -> None:
319
+ """Use the 'less' pager with -FRSXKM options."""
320
+ pydoc.pipepager(text, f'{default_pager} -FRSXKM')
321
+
322
+ if less_available:
323
+ return less_pager_function
324
+ return pydoc.pager
@@ -24,7 +24,7 @@ from rucio.common.utils import build_url
24
24
  if TYPE_CHECKING:
25
25
  from collections.abc import Iterable, Iterator
26
26
 
27
- from rucio.common.constants import RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL, RSE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL, SUPPORTED_PROTOCOLS_LITERAL
27
+ from rucio.common.constants import RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL, RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL, SUPPORTED_PROTOCOLS_LITERAL
28
28
 
29
29
 
30
30
  class RSEClient(BaseClient):
@@ -238,7 +238,7 @@ class RSEClient(BaseClient):
238
238
  self,
239
239
  rse: str,
240
240
  protocol_domain: "RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL" = 'ALL',
241
- operation: Optional["RSE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL"] = None,
241
+ operation: Optional["RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL"] = None,
242
242
  default: bool = False,
243
243
  scheme: Optional['SUPPORTED_PROTOCOLS_LITERAL'] = None
244
244
  ) -> Any:
@@ -287,7 +287,7 @@ class RSEClient(BaseClient):
287
287
  rse: str,
288
288
  lfns: 'Iterable[str]',
289
289
  protocol_domain: 'RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL' = 'ALL',
290
- operation: Optional['RSE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL'] = None,
290
+ operation: Optional['RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL'] = None,
291
291
  scheme: Optional['SUPPORTED_PROTOCOLS_LITERAL'] = None
292
292
  ) -> dict[str, str]:
293
293
  """
@@ -409,7 +409,7 @@ class RSEClient(BaseClient):
409
409
  self,
410
410
  rse: str,
411
411
  domain: 'RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL',
412
- operation: 'RSE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL',
412
+ operation: 'RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL',
413
413
  scheme_a: 'SUPPORTED_PROTOCOLS_LITERAL',
414
414
  scheme_b: 'SUPPORTED_PROTOCOLS_LITERAL'
415
415
  ) -> bool: