rucio-clients 36.0.0__tar.gz → 36.0.0.post1__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 (205) hide show
  1. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/PKG-INFO +1 -1
  2. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/bin/rucio +1 -1
  3. rucio_clients-36.0.0.post1/lib/rucio/client/commands/__init__.py +25 -0
  4. rucio_clients-36.0.0.post1/lib/rucio/client/commands/account.py +219 -0
  5. rucio_clients-36.0.0.post1/lib/rucio/client/commands/command.py +258 -0
  6. rucio_clients-36.0.0.post1/lib/rucio/client/commands/command_base.py +193 -0
  7. rucio_clients-36.0.0.post1/lib/rucio/client/commands/config.py +58 -0
  8. rucio_clients-36.0.0.post1/lib/rucio/client/commands/did.py +202 -0
  9. rucio_clients-36.0.0.post1/lib/rucio/client/commands/download.py +92 -0
  10. rucio_clients-36.0.0.post1/lib/rucio/client/commands/lifetime_exception.py +53 -0
  11. rucio_clients-36.0.0.post1/lib/rucio/client/commands/replica.py +166 -0
  12. rucio_clients-36.0.0.post1/lib/rucio/client/commands/rse.py +268 -0
  13. rucio_clients-36.0.0.post1/lib/rucio/client/commands/rule.py +123 -0
  14. rucio_clients-36.0.0.post1/lib/rucio/client/commands/scope.py +51 -0
  15. rucio_clients-36.0.0.post1/lib/rucio/client/commands/subscription.py +72 -0
  16. rucio_clients-36.0.0.post1/lib/rucio/client/commands/upload.py +62 -0
  17. rucio_clients-36.0.0.post1/lib/rucio/client/commands/utils.py +226 -0
  18. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/test_rucio_server.py +4 -4
  19. rucio_clients-36.0.0.post1/lib/rucio/vcsversion.py +11 -0
  20. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio_clients.egg-info/SOURCES.txt +15 -0
  21. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/requirements/requirements.client.txt +1 -0
  22. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/setup.py +1 -1
  23. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_impl_upload_download.py +0 -16
  24. rucio_clients-36.0.0.post1/tests/test_rucio_server.py +124 -0
  25. rucio_clients-36.0.0/lib/rucio/vcsversion.py +0 -11
  26. rucio_clients-36.0.0/tests/test_rucio_server.py +0 -23
  27. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/AUTHORS.rst +0 -0
  28. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/ChangeLog +0 -0
  29. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/LICENSE +0 -0
  30. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/MANIFEST.in +0 -0
  31. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/README.md +0 -0
  32. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/bin/rucio-admin +0 -0
  33. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/etc/rse-accounts.cfg.template +0 -0
  34. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/etc/rucio.cfg.atlas.client.template +0 -0
  35. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/etc/rucio.cfg.template +0 -0
  36. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/__init__.py +0 -0
  37. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/alembicrevision.py +0 -0
  38. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/__init__.py +0 -0
  39. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/accountclient.py +0 -0
  40. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/accountlimitclient.py +0 -0
  41. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/baseclient.py +0 -0
  42. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/client.py +0 -0
  43. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/configclient.py +0 -0
  44. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/credentialclient.py +0 -0
  45. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/didclient.py +0 -0
  46. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/diracclient.py +0 -0
  47. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/downloadclient.py +0 -0
  48. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/exportclient.py +0 -0
  49. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/fileclient.py +0 -0
  50. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/importclient.py +0 -0
  51. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/lifetimeclient.py +0 -0
  52. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/lockclient.py +0 -0
  53. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/metaconventionsclient.py +0 -0
  54. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/pingclient.py +0 -0
  55. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/replicaclient.py +0 -0
  56. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/requestclient.py +0 -0
  57. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/richclient.py +0 -0
  58. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/rseclient.py +0 -0
  59. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/ruleclient.py +0 -0
  60. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/scopeclient.py +0 -0
  61. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/subscriptionclient.py +0 -0
  62. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/touchclient.py +0 -0
  63. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/client/uploadclient.py +0 -0
  64. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/__init__.py +0 -0
  65. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/bittorrent.py +0 -0
  66. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/cache.py +0 -0
  67. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/checksum.py +0 -0
  68. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/client.py +0 -0
  69. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/config.py +0 -0
  70. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/constants.py +0 -0
  71. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/constraints.py +0 -0
  72. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/didtype.py +0 -0
  73. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/exception.py +0 -0
  74. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/extra.py +0 -0
  75. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/logging.py +0 -0
  76. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/pcache.py +0 -0
  77. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/plugins.py +0 -0
  78. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/policy.py +0 -0
  79. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/schema/__init__.py +0 -0
  80. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/schema/generic.py +0 -0
  81. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
  82. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/stomp_utils.py +0 -0
  83. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/stopwatch.py +0 -0
  84. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/types.py +0 -0
  85. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/common/utils.py +0 -0
  86. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/__init__.py +0 -0
  87. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/__init__.py +0 -0
  88. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/bittorrent.py +0 -0
  89. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/cache.py +0 -0
  90. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/dummy.py +0 -0
  91. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/gfal.py +0 -0
  92. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/globus.py +0 -0
  93. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/gsiftp.py +0 -0
  94. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/http_cache.py +0 -0
  95. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/mock.py +0 -0
  96. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/ngarc.py +0 -0
  97. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/posix.py +0 -0
  98. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/protocol.py +0 -0
  99. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/rclone.py +0 -0
  100. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/rfio.py +0 -0
  101. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/srm.py +0 -0
  102. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/ssh.py +0 -0
  103. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/storm.py +0 -0
  104. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/webdav.py +0 -0
  105. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/protocols/xrootd.py +0 -0
  106. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/rsemanager.py +0 -0
  107. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/rse/translation.py +0 -0
  108. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/lib/rucio/version.py +0 -0
  109. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/pylintrc +0 -0
  110. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/pyproject.toml +0 -0
  111. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/setup.cfg +0 -0
  112. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/setuputil.py +0 -0
  113. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_abacus_account.py +0 -0
  114. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_abacus_collection_replica.py +0 -0
  115. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_abacus_rse.py +0 -0
  116. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_account.py +0 -0
  117. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_account_limits.py +0 -0
  118. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_archive.py +0 -0
  119. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_auditor.py +0 -0
  120. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_auditor_hdfs.py +0 -0
  121. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_auditor_srmdumps.py +0 -0
  122. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_authentication.py +0 -0
  123. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_automatix.py +0 -0
  124. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_bad_replica.py +0 -0
  125. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_bb8.py +0 -0
  126. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_belleii.py +0 -0
  127. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_bin_rucio.py +0 -0
  128. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_boolean.py +0 -0
  129. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_cli_client_structure.py +0 -0
  130. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_clients.py +0 -0
  131. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_config.py +0 -0
  132. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_conveyor.py +0 -0
  133. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_conveyor_submitter.py +0 -0
  134. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_counter.py +0 -0
  135. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_credential.py +0 -0
  136. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_curl.py +0 -0
  137. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_daemons.py +0 -0
  138. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_dataset_replicas.py +0 -0
  139. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_db.py +0 -0
  140. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_did.py +0 -0
  141. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_did_meta_plugins.py +0 -0
  142. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_download.py +0 -0
  143. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_dumper.py +0 -0
  144. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_dumper_consistency.py +0 -0
  145. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_dumper_data_model.py +0 -0
  146. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_dumper_path_parsing.py +0 -0
  147. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_filter_engine.py +0 -0
  148. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_gateway_external_representation.py +0 -0
  149. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_heartbeat.py +0 -0
  150. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_hermes.py +0 -0
  151. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_identity.py +0 -0
  152. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_import_export.py +0 -0
  153. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_judge_cleaner.py +0 -0
  154. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_judge_evaluator.py +0 -0
  155. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_judge_injector.py +0 -0
  156. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_judge_repairer.py +0 -0
  157. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_lifetime.py +0 -0
  158. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_message.py +0 -0
  159. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_meta_conventions.py +0 -0
  160. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_meta_did.py +0 -0
  161. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_module_import.py +0 -0
  162. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_monitor.py +0 -0
  163. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_multi_vo.py +0 -0
  164. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_naming_convention.py +0 -0
  165. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_oauthmanager.py +0 -0
  166. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_oidc.py +0 -0
  167. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_permission.py +0 -0
  168. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_pfns.py +0 -0
  169. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_ping.py +0 -0
  170. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_policy_package.py +0 -0
  171. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_preparer.py +0 -0
  172. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_qos.py +0 -0
  173. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_quarantined_replica.py +0 -0
  174. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_reaper.py +0 -0
  175. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_redirect.py +0 -0
  176. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_replica.py +0 -0
  177. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_replica_recoverer.py +0 -0
  178. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_replica_sorting.py +0 -0
  179. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_request.py +0 -0
  180. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_root_proxy.py +0 -0
  181. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse.py +0 -0
  182. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_expression_parser.py +0 -0
  183. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_lfn2path.py +0 -0
  184. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_gfal2.py +0 -0
  185. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_gfal2_impl.py +0 -0
  186. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_posix.py +0 -0
  187. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_rclone.py +0 -0
  188. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_rsync.py +0 -0
  189. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_srm.py +0 -0
  190. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_ssh.py +0 -0
  191. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_webdav.py +0 -0
  192. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_protocol_xrootd.py +0 -0
  193. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rse_selector.py +0 -0
  194. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_rule.py +0 -0
  195. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_scope.py +0 -0
  196. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_subscription.py +0 -0
  197. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_throttler.py +0 -0
  198. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_tpc.py +0 -0
  199. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_trace.py +0 -0
  200. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_transfer.py +0 -0
  201. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_transfer_plugins.py +0 -0
  202. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_undertaker.py +0 -0
  203. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_upload.py +0 -0
  204. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tests/test_utils.py +0 -0
  205. {rucio_clients-36.0.0 → rucio_clients-36.0.0.post1}/tools/merge_rucio_configs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rucio-clients
3
- Version: 36.0.0
3
+ Version: 36.0.0.post1
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio
@@ -88,7 +88,7 @@ def map_legacy_command() -> Optional[list[str]]:
88
88
 
89
89
 
90
90
  if __name__ == "__main__":
91
- commands = ("-h", "--version", "account", "config", "did", "replica", "rse", "rule", "scope", "subscription", "ping", "whoami", "test-server", "lifetime-exception", "upload", "download")
91
+ commands = ("-h", "--help", "--version", "account", "config", "did", "replica", "rse", "rule", "scope", "subscription", "ping", "whoami", "test-server", "lifetime-exception", "upload", "download")
92
92
  first_command = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--help", "--version")][1]
93
93
  is_legacy = '--legacy' in sys.argv
94
94
 
@@ -0,0 +1,25 @@
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
+ from rucio.client.commands.account import Account # noqa: F401
15
+ from rucio.client.commands.command_base import CommandBase # noqa: F401
16
+ from rucio.client.commands.config import Config # noqa: F401
17
+ from rucio.client.commands.did import DID # noqa: F401
18
+ from rucio.client.commands.download import Download # noqa: F401
19
+ from rucio.client.commands.lifetime_exception import LifetimeException # noqa: F401
20
+ from rucio.client.commands.replica import Replica # noqa: F401
21
+ from rucio.client.commands.rse import RSE # noqa: F401
22
+ from rucio.client.commands.rule import Rule # noqa: F401
23
+ from rucio.client.commands.scope import Scope # noqa: F401
24
+ from rucio.client.commands.subscription import Subscription # noqa: F401
25
+ from rucio.client.commands.upload import Upload # noqa: F401
@@ -0,0 +1,219 @@
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
+ from argparse import SUPPRESS
15
+ from typing import TYPE_CHECKING
16
+
17
+ from rucio.client.commands.bin_legacy.rucio import list_account_usage
18
+ from rucio.client.commands.bin_legacy.rucio_admin import (
19
+ add_account,
20
+ add_account_attribute,
21
+ ban_account,
22
+ delete_account,
23
+ delete_account_attribute,
24
+ delete_limits,
25
+ identity_add,
26
+ identity_delete,
27
+ info_account,
28
+ list_account_attributes,
29
+ list_accounts,
30
+ list_identities,
31
+ set_limits,
32
+ unban_account,
33
+ update_account,
34
+ )
35
+ from rucio.client.commands.command_base import CommandBase
36
+
37
+ if TYPE_CHECKING:
38
+ from argparse import ArgumentParser
39
+
40
+ from rucio.client.commands.utils import OperationDict
41
+
42
+
43
+ class Account(CommandBase):
44
+ def module_help(self) -> str:
45
+ return "Methods to add or change accounts for users, groups, and services. Used to assign privileges."
46
+
47
+ def usage_example(self) -> list[str]:
48
+ return [
49
+ "$ rucio account list # List all accounts on the instance",
50
+ "$ rucio account add --account user_jdoe --type USER # Create a new user account",
51
+ "$ rucio account update --account user_jdoe --email jdoe@cern.ch # Update jdoe's email",
52
+ "$ rucio account update --account jdoe --ban True # Ban jdoe",
53
+ "$ rucio account history --account root # Show all the usage history for the account root",
54
+ ]
55
+
56
+ def list_namespace(self, parser: "ArgumentParser") -> None:
57
+ parser.add_argument("--type", dest="account_type", help="Account Type", choices={"USER", "GROUP", "SERVICE"})
58
+ parser.add_argument("-a", "--account", dest="account", help="Account name")
59
+ parser.add_argument("--id", dest="identity", action="store", help="Identity (e.g. DN)")
60
+ parser.add_argument("--filters", dest="filters", action="store", help="Filter arguments in form `key=value,another_key=next_value`")
61
+
62
+ def add_namespace(self, parser: "ArgumentParser") -> None:
63
+ parser.add_argument("--type", dest="accounttype", help="Account Type (USER, GROUP, SERVICE)", required=True)
64
+ parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
65
+ parser.add_argument("--email", dest="accountemail", help="Add an email address associated with the account")
66
+
67
+ def show_namespace(self, parser: "ArgumentParser") -> None:
68
+ parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
69
+
70
+ def update_namespace(self, parser: "ArgumentParser") -> None:
71
+ parser.add_argument("-a", "--account", help="Account name", required=True)
72
+ parser.add_argument("--email", help="Account email")
73
+ parser.add_argument("--ban", type=bool, choices=(True, False), help='Ban the account, to disable it. Use --ban False to unban.', default=None)
74
+
75
+ def remove_namespace(self, parser: "ArgumentParser") -> None:
76
+ parser.add_argument("-a", "--account", dest="acnt", action="store", help="Account name", required=True)
77
+
78
+ def _operations(self) -> dict[str, "OperationDict"]:
79
+ return {
80
+ "list": {"call": self.list_, "docs": "List accounts", "namespace": self.list_namespace},
81
+ "add": {"call": self.add, "docs": "Add a new account", "namespace": self.add_namespace},
82
+ "show": {"call": self.show, "docs": "Get all stats on an account, including status, account type, and dates of creation and updates", "namespace": self.show_namespace},
83
+ "remove": {"call": self.remove, "docs": "Delete an account", "namespace": self.remove_namespace},
84
+ "update": {"call": self.update, "docs": "Change the basic account settings", "namespace": self.update_namespace},
85
+ }
86
+
87
+ def implemented_subcommands(self) -> dict[str, type[CommandBase]]:
88
+ return {"attribute": Attribute, "limit": Limit, "identity": Identity}
89
+
90
+ def list_(self):
91
+ list_accounts(self.args, self.client, self.logger, self.console, self.spinner)
92
+
93
+ def add(self):
94
+ add_account(self.args, self.client, self.logger, self.console, self.spinner)
95
+
96
+ def remove(self):
97
+ delete_account(self.args, self.client, self.logger, self.console, self.spinner)
98
+
99
+ def show(self):
100
+ info_account(self.args, self.client, self.logger, self.console, self.spinner)
101
+
102
+ def update(self):
103
+ if self.args.ban is not None:
104
+ if self.args.ban:
105
+ ban_account(self.args, self.client, self.logger, self.console, self.spinner)
106
+ else:
107
+ unban_account(self.args, self.client, self.logger, self.console, self.spinner)
108
+ else:
109
+ # Temp fix to allow specific kwargs
110
+ self.args.key = "email"
111
+ self.args.value = self.args.email
112
+ update_account(self.args, self.client, self.logger, self.console, self.spinner)
113
+
114
+
115
+ class Attribute(Account):
116
+ def module_help(self) -> str:
117
+ return "Add additional key/value pairs associated with an account."
118
+
119
+ def implemented_subcommands(self) -> dict[str, type[CommandBase]]:
120
+ return {}
121
+
122
+ def namespace(self, subparser):
123
+ subparser.add_argument("-a", "--account", help="Account name")
124
+ subparser.add_argument("--key", dest="key", action="store", help="Attribute key")
125
+ subparser.add_argument("--value", dest="value", action="store", help="Attribute value")
126
+
127
+ def usage_example(self) -> list[str]:
128
+ return ["$ rucio account attribute list --account jdoe # Show all attributes for jdoe",
129
+ "$ rucio -v account attribute add --account jdoe --key test_key --value true # Set test_key = true for jdoe"]
130
+
131
+ def _operations(self) -> dict[str, "OperationDict"]:
132
+ return {
133
+ "list": {"call": self.list_, "docs": "List all account attributes"},
134
+ "add": {"call": self.add, "docs": "Add a new attribute to an account or update an existing one"},
135
+ "remove": {"call": self.remove, "docs": "Remove an existing account attribute"},
136
+ }
137
+
138
+ def list_(self):
139
+ list_account_attributes(self.args, self.client, self.logger, self.console, self.spinner)
140
+
141
+ def add(self):
142
+ add_account_attribute(self.args, self.client, self.logger, self.console, self.spinner)
143
+
144
+ def remove(self):
145
+ delete_account_attribute(self.args, self.client, self.logger, self.console, self.spinner)
146
+
147
+
148
+ class Limit(Account):
149
+ def module_help(self) -> str:
150
+ return "Manage storage limits for an account at a given RSE."
151
+
152
+ def namespace(self, parser: "ArgumentParser") -> None:
153
+ parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
154
+ parser.add_argument("--rses", "--rse-exp", dest='rse', action="store", help="RSE expression")
155
+ parser.add_argument("--bytes", action="store", help='Value can be specified in bytes ("10000"), with a storage unit ("10GB"), or "infinity"')
156
+ parser.add_argument("--locality", nargs="?", default="local", choices=["local", "global"], help="Global or local limit scope")
157
+ parser.add_argument("--human", default=True, help=SUPPRESS)
158
+
159
+ def _operations(self) -> dict[str, "OperationDict"]:
160
+ return {
161
+ "list": {"call": self.list_, "docs": "Show limits and current utilization for an account at a given RSE", "namespace": self.namespace},
162
+ "add": {"call": self.add, "docs": "Add or update limits for an account", "namespace": self.namespace}, # TODO Add and update should become different operations
163
+ "remove": {"call": self.remove, "docs": "Remove all limits for given account/rse/locality", "namespace": self.namespace},
164
+ }
165
+
166
+ def implemented_subcommands(self) -> dict[str, type[CommandBase]]:
167
+ return {}
168
+
169
+ def usage_example(self) -> list[str]:
170
+ return super().usage_example()
171
+
172
+ def list_(self):
173
+ self.args.usage_account = self.args.account
174
+ list_account_usage(self.args, self.client, self.logger, self.console, self.spinner)
175
+
176
+ def add(self):
177
+ set_limits(self.args, self.client, self.logger, self.console, self.spinner)
178
+
179
+ def remove(self):
180
+ delete_limits(self.args, self.client, self.logger, self.console, self.spinner)
181
+
182
+
183
+ class Identity(Account):
184
+ def module_help(self) -> str:
185
+ return "Manage identities on an account."
186
+
187
+ def namespace(self, parser: "ArgumentParser") -> None:
188
+ parser.add_argument("--account", dest="account", action="store", help="Account name", required=True)
189
+ parser.add_argument("--type", dest="authtype", action="store", choices=["X509", "GSS", "USERPASS", "SSH", "SAML", "OIDC"], help="Authentication type")
190
+ parser.add_argument("--id", dest="identity", action="store", help="Identity as a DNs for X509 IDs.")
191
+ parser.add_argument("--email", dest="email", action="store", help="Email address associated with the identity")
192
+ parser.add_argument("--password", dest="password", action="store", help="Password if authtype is USERPASS")
193
+ parser.add_argument("--human", default=True, help=SUPPRESS)
194
+
195
+ def _operations(self) -> dict[str, "OperationDict"]:
196
+ return {
197
+ "list": {"call": self.list_, "docs": "Display existing identities for an account", "namespace": self.namespace},
198
+ "add": {"call": self.add, "docs": "Grant identity access to an account", "namespace": self.namespace},
199
+ "remove": {"call": self.remove, "docs": "Revoke identity access for an account", "namespace": self.namespace},
200
+ }
201
+
202
+ def usage_example(self) -> list[str]:
203
+ return [
204
+ "$ rucio account identity list --account jdoe # List all auth identities for jdoe",
205
+ "$ rucio account identity add --account jdoe --type GSS --email jdoe@cern.ch --id jdoe@fnal.ch # Add a new GSS auth",
206
+ "$ rucio account identity add --account jdoe --type X509 --id 'CN=Joe Doe,CN=707658,CN=jdoe,OU=Users,OU=Organic Units,DC=cern,DC=ch' --email jdoe@cern.ch # Add a new X509 auth",
207
+ ]
208
+
209
+ def implemented_subcommands(self) -> dict[str, type[CommandBase]]:
210
+ return {}
211
+
212
+ def list_(self):
213
+ list_identities(self.args, self.client, self.logger, self.console, self.spinner)
214
+
215
+ def add(self):
216
+ identity_add(self.args, self.client, self.logger, self.console, self.spinner)
217
+
218
+ def remove(self):
219
+ identity_delete(self.args, self.client, self.logger, self.console, self.spinner)
@@ -0,0 +1,258 @@
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
+ import argparse
15
+ import os
16
+ import signal
17
+ import sys
18
+ import time
19
+ from typing import TYPE_CHECKING, Optional
20
+
21
+ from rich.console import Console
22
+ from rich.status import Status
23
+ from rich.theme import Theme
24
+ from rich.traceback import install
25
+
26
+ import rucio.client.commands as commands
27
+ from rucio import version
28
+ from rucio.client.commands.bin_legacy.rucio import get_client, ping, test_server, whoami_account
29
+ from rucio.client.commands.command_base import CommandBase
30
+ from rucio.client.commands.utils import exception_handler, setup_gfal2_logger, signal_handler
31
+ from rucio.client.richclient import MAX_TRACEBACK_WIDTH, MIN_CONSOLE_WIDTH, CLITheme, get_cli_config, get_pager, setup_rich_logger
32
+ from rucio.common.extra import import_extras
33
+ from rucio.common.utils import setup_logger
34
+
35
+ if TYPE_CHECKING:
36
+ from argparse import Namespace
37
+ from logging import Logger
38
+
39
+ from rucio.client.client import Client
40
+
41
+ EXTRA_MODULES = import_extras(["argcomplete"])
42
+
43
+ if EXTRA_MODULES["argcomplete"]:
44
+ import argcomplete # pylint: disable=E0401
45
+
46
+ SUCCESS, FAILURE = 0, 1
47
+
48
+
49
+ class Commands:
50
+ def __init__(self, logger: "Logger", client: "Client", args: "Namespace", console: Console, spinner: Status) -> None:
51
+ self.logger = logger
52
+ self.args = args
53
+ self.client = client
54
+ self.console = console
55
+ self.spinner = spinner
56
+
57
+ @staticmethod
58
+ def _all_commands() -> dict[str, type[commands.CommandBase]]:
59
+ # Look for all the CommandBase'd child classes in this folder and add their parsers and child parsers
60
+ command_map = {child.__name__.lower(): child for child in commands.CommandBase.__subclasses__() if child.__name__ != "LifetimeException"}
61
+ command_map["lifetime-exception"] = commands.LifetimeException
62
+ command_map["ping"] = Ping
63
+ command_map["whoami"] = Whoami
64
+ command_map["test-server"] = TestServer
65
+ return command_map
66
+
67
+ @staticmethod
68
+ def _add_parsers() -> argparse.ArgumentParser:
69
+ parser = argparse.ArgumentParser(description='CLI Rucio Client. (Use --legacy to view CLI from <36.0)')
70
+ Commands._main_parser(parser)
71
+
72
+ subparsers = parser.add_subparsers(dest="command", help="Command to execute, see `{command} -h` for more details and subcommands.")
73
+ for command in Commands._all_commands().values():
74
+ command(None, None, None, None, None).parser(subparsers) # type: ignore
75
+
76
+ return parser
77
+
78
+ @staticmethod
79
+ def _main_parser(parser: argparse.ArgumentParser) -> None:
80
+ main_args = parser.add_argument_group("Main Arguments")
81
+
82
+ main_args.add_argument("--version", action="version", version="%(prog)s " + version.version_string())
83
+
84
+ main_args.add_argument("--config", help="The Rucio configuration file to use.")
85
+ main_args.add_argument("--verbose", "-v", default=False, action="store_true", help="Print more verbose output.")
86
+ main_args.add_argument("-H", "--host", metavar="ADDRESS", help="The Rucio API host.")
87
+ main_args.add_argument("--auth-host", metavar="ADDRESS", help="The Rucio Authentication host.")
88
+ main_args.add_argument("-a", "--account", dest="issuer", help="Rucio account to use.")
89
+ main_args.add_argument("-S", "--auth-strategy", help="Authentication strategy (userpass, x509...)")
90
+ main_args.add_argument("-T", "--timeout", type=float, help="Set all timeout values to seconds.")
91
+ main_args.add_argument("--user-agent", "-U", dest="user_agent", default="rucio-clients", help="Rucio User Agent")
92
+ main_args.add_argument("--vo", metavar="VO", help="VO to authenticate at. Only used in multi-VO mode.")
93
+ main_args.add_argument("--no-pager", dest="no_pager", default=False, action='store_true', help=argparse.SUPPRESS)
94
+
95
+ auth_args = parser.add_argument_group("Authentication Settings")
96
+
97
+ auth_args.add_argument("-u", "--user", dest="username", help="username")
98
+ auth_args.add_argument("-pwd", "--password", help="password")
99
+ # Options for defining remaining OIDC parameters
100
+ auth_args.add_argument("--oidc-user", dest="oidc_username", help="OIDC username")
101
+ auth_args.add_argument("--oidc-password", help="OIDC password")
102
+ auth_args.add_argument(
103
+ "--oidc-scope",
104
+ default="openid profile",
105
+ help="""
106
+ Defines which (OIDC) information user will share with Rucio. Rucio requires at least -sc='openid profile'.
107
+ To request refresh token for Rucio, scope must include 'openid offline_access' and there must be no active
108
+ access token saved on the side of the currently used Rucio Client.
109
+ """
110
+ )
111
+ auth_args.add_argument("--oidc-audience", help="Defines which audience are tokens requested for.")
112
+ auth_args.add_argument(
113
+ "--oidc-auto",
114
+ default=False,
115
+ action="store_true",
116
+ help="""
117
+ If not specified, username and password credentials are not required and users will be given a URL to use in their browser.
118
+ If specified, the users explicitly trust Rucio with their IdP credentials.
119
+ """
120
+ )
121
+ auth_args.add_argument(
122
+ "--oidc-polling",
123
+ default=False,
124
+ action="store_true",
125
+ help="""
126
+ If not specified, user will be asked to enter a code returned by the browser to the command line.
127
+ If --polling is set, Rucio Client should get the token without any further interaction of the user.
128
+ This option is active only if --auto is *not* specified.
129
+ """
130
+ )
131
+ auth_args.add_argument(
132
+ "--oidc-refresh-lifetime",
133
+ help="""
134
+ Max lifetime in hours for this access token; the token will be refreshed by an asynchronous Rucio daemon.
135
+ If not specified, refresh will be stopped after 4 days.
136
+ This option is effective only if --oidc-scope includes offline_access scope for a refresh token to be granted to Rucio.
137
+ """
138
+ )
139
+ auth_args.add_argument("--oidc-issuer", help="Defines which Identity Provider is going to be used. The issuer string must correspond to the keys configured in the /etc/idpsecrets.json auth server configuration file.") # NOQA: W503
140
+
141
+ # Options for the x509 auth_strategy
142
+ auth_args.add_argument("--certificate", help="Client certificate file.")
143
+ auth_args.add_argument('--client-key', dest='client_key', default=None, help='Client key for x509 Authentication.')
144
+ auth_args.add_argument("--ca-certificate", help="CA certificate to verify peer against (SSL).")
145
+
146
+ def _run_command(self) -> Optional[int]:
147
+ try:
148
+ command_class = Commands._all_commands()[self.args.command]
149
+ except KeyError as e:
150
+ if self.args.command is not None:
151
+ self.logger.error(f"Cannot find command {self.args.command}: {e}")
152
+ sys.exit(FAILURE)
153
+
154
+ return exception_handler(command_class(self.client, self.args, self.logger, self.console, self.spinner))()
155
+
156
+ def __call__(self) -> None:
157
+ self.logger.debug("Running a command with the following arguments: %s" % vars(self.args))
158
+ start_time = time.time()
159
+ self._run_command()
160
+ end_time = time.time()
161
+
162
+ self.logger.debug("Completed in %-0.4f sec." % (end_time - start_time))
163
+
164
+
165
+ class Ping(CommandBase):
166
+ def _operations(self):
167
+ return {}
168
+
169
+ def module_help(self) -> str:
170
+ return ""
171
+
172
+ def usage_example(self) -> list[str]:
173
+ return []
174
+
175
+ def parser(self, subparser):
176
+ command_parser = subparser.add_parser("ping", description="Ping the server", formatter_class=argparse.RawDescriptionHelpFormatter)
177
+ return command_parser
178
+
179
+ def __call__(self):
180
+ ping(self.args, self.client, self.logger, self.console, self.spinner)
181
+
182
+
183
+ class Whoami(CommandBase):
184
+ def _operations(self):
185
+ return {}
186
+
187
+ def module_help(self) -> str:
188
+ return ""
189
+
190
+ def usage_example(self) -> list[str]:
191
+ return []
192
+
193
+ def parser(self, subparser):
194
+ command_parser = subparser.add_parser("whoami", description="See login information, test credentials", formatter_class=argparse.RawDescriptionHelpFormatter)
195
+ return command_parser
196
+
197
+ def __call__(self):
198
+ whoami_account(self.args, self.client, self.logger, self.console, self.spinner)
199
+
200
+
201
+ class TestServer(CommandBase):
202
+ def _operations(self):
203
+ return {}
204
+
205
+ def module_help(self) -> str:
206
+ return ""
207
+
208
+ def usage_example(self) -> list[str]:
209
+ return []
210
+
211
+ def parser(self, subparser):
212
+ command_parser = subparser.add_parser("test-server", description="Test client against the server", formatter_class=argparse.RawDescriptionHelpFormatter)
213
+ return command_parser
214
+
215
+ def __call__(self):
216
+ test_server(self.args, self.client, self.logger, self.console, self.spinner)
217
+
218
+
219
+ def main():
220
+ cli_config = get_cli_config()
221
+ console = Console(theme=Theme(CLITheme.LOG_THEMES), soft_wrap=True)
222
+ console.width = max(MIN_CONSOLE_WIDTH, console.width)
223
+
224
+ spinner = Status('Initializing spinner', spinner=CLITheme.SPINNER, spinner_style=CLITheme.SPINNER_STYLE, console=console)
225
+ pager = get_pager()
226
+
227
+ parser_object = Commands._add_parsers()
228
+ if EXTRA_MODULES["argcomplete"]:
229
+ argcomplete.autocomplete(parser_object)
230
+ args = parser_object.parse_args()
231
+ if args.config is not None:
232
+ os.environ["RUCIO_CONFIG"] = args.config
233
+ if args.command is None:
234
+ parser_object.print_help()
235
+ sys.exit(FAILURE)
236
+
237
+ setup_gfal2_logger()
238
+
239
+ if cli_config == 'rich':
240
+ install(console=console, word_wrap=True, width=min(console.width, MAX_TRACEBACK_WIDTH)) # Make rich exception tracebacks the default.
241
+ logger = setup_rich_logger(module_name=__name__, logger_name='user', verbose=args.verbose, console=console)
242
+
243
+ else:
244
+ logger = setup_logger(module_name=__name__, logger_name="user", verbose=args.verbose)
245
+
246
+ client = get_client(args, logger)
247
+ signal.signal(signal.SIGINT, lambda sig, frame: signal_handler(sig, frame, logger))
248
+
249
+ Commands(logger, client, args, console, spinner)()
250
+
251
+ if cli_config == 'rich':
252
+ spinner.stop()
253
+
254
+ if console.is_terminal and not args.no_pager:
255
+ command_output = console.end_capture()
256
+ if command_output != '':
257
+ signal.signal(signal.SIGINT, signal.SIG_IGN) # Do not allow the user to stop the program while sending to pager
258
+ pager(command_output)