datatrail-cli 0.13.0__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. datatrail_cli-1.0.1/.github/workflows/codeql.yml +101 -0
  2. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/workflows/continuous-deployment.yml +4 -0
  3. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/workflows/continuous-integration.yml +4 -1
  4. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/workflows/docs.yml +3 -0
  5. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/workflows/stale.yml +5 -0
  6. datatrail_cli-1.0.1/.release-please-manifest.json +3 -0
  7. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/CHANGELOG.md +63 -0
  8. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/PKG-INFO +10 -3
  9. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/README.md +2 -0
  10. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/commands.md +3 -0
  11. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/install.md +2 -0
  12. datatrail_cli-1.0.1/docs/inventory.md +80 -0
  13. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/list.md +105 -0
  14. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/ps.md +24 -0
  15. datatrail_cli-1.0.1/docs/pull-manifest.md +69 -0
  16. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/clear.py +2 -2
  17. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/cli.py +18 -2
  18. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/config.py +48 -8
  19. datatrail_cli-1.0.1/dtcli/doctor.py +169 -0
  20. datatrail_cli-1.0.1/dtcli/inventory.py +423 -0
  21. datatrail_cli-1.0.1/dtcli/locking.py +42 -0
  22. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/ls.py +135 -1
  23. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/ps.py +40 -10
  24. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/pull.py +34 -5
  25. datatrail_cli-1.0.1/dtcli/pull_manifest.py +445 -0
  26. datatrail_cli-1.0.1/dtcli/scout.py +323 -0
  27. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/src/functions.py +274 -23
  28. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/unregistered.py +2 -2
  29. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/utilities/cadcclient.py +188 -62
  30. datatrail_cli-1.0.1/dtcli/utilities/results.py +12 -0
  31. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/utilities/utilities.py +35 -0
  32. datatrail_cli-1.0.1/dtcli/verify.py +326 -0
  33. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/mkdocs.yml +2 -0
  34. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/pyproject.toml +17 -4
  35. datatrail_cli-1.0.1/tests/conftest.py +105 -0
  36. datatrail_cli-1.0.1/tests/test_cadc_summary.py +41 -0
  37. datatrail_cli-1.0.1/tests/test_canfar_permissions.py +206 -0
  38. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/tests/test_cli.py +184 -1
  39. datatrail_cli-1.0.1/tests/test_config.py +159 -0
  40. datatrail_cli-1.0.1/tests/test_doctor.py +336 -0
  41. datatrail_cli-1.0.1/tests/test_functions.py +443 -0
  42. datatrail_cli-1.0.1/tests/test_inventory.py +406 -0
  43. datatrail_cli-1.0.1/tests/test_locking.py +62 -0
  44. datatrail_cli-1.0.1/tests/test_pull_manifest.py +462 -0
  45. datatrail_cli-1.0.1/tests/test_pull_reliability.py +355 -0
  46. datatrail_cli-1.0.1/tests/test_pull_size.py +164 -0
  47. datatrail_cli-1.0.1/tests/test_scout.py +419 -0
  48. datatrail_cli-1.0.1/tests/test_utils.py +96 -0
  49. datatrail_cli-1.0.1/tests/test_verify.py +223 -0
  50. datatrail_cli-1.0.1/uv.lock +1702 -0
  51. datatrail_cli-0.13.0/.release-please-manifest.json +0 -3
  52. datatrail_cli-0.13.0/dtcli/scout.py +0 -233
  53. datatrail_cli-0.13.0/tests/test_functions.py +0 -114
  54. datatrail_cli-0.13.0/tests/test_utils.py +0 -43
  55. datatrail_cli-0.13.0/uv.lock +0 -3431
  56. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  57. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  58. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  59. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.gitignore +0 -0
  60. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/.pre-commit-config.yaml +0 -0
  61. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/LICENSE +0 -0
  62. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/clear.md +0 -0
  63. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/cli.md +0 -0
  64. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/images/Datatrail-logo.png +0 -0
  65. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/index.md +0 -0
  66. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/initialising.md +0 -0
  67. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/pull.md +0 -0
  68. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/scout.md +0 -0
  69. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/unregistered.md +0 -0
  70. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/docs/user_guide.md +0 -0
  71. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/__init__.py +0 -0
  72. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/dtcli/config.yaml +0 -0
  73. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/release-please-config.json +0 -0
  74. {datatrail_cli-0.13.0 → datatrail_cli-1.0.1}/tox.ini +0 -0
@@ -0,0 +1,101 @@
1
+ # For most projects, this workflow file will not need changing; you simply need
2
+ # to commit it to your repository.
3
+ #
4
+ # You may wish to alter this file to override the set of languages analyzed,
5
+ # or to provide custom queries or build logic.
6
+ #
7
+ # ******** NOTE ********
8
+ # We have attempted to detect the languages in your repository. Please check
9
+ # the `language` matrix defined below to confirm you have the correct set of
10
+ # supported CodeQL languages.
11
+ #
12
+ name: "CodeQL Advanced"
13
+
14
+ on:
15
+ push:
16
+ branches: [ "main" ]
17
+ pull_request:
18
+ branches: [ "main" ]
19
+ schedule:
20
+ - cron: '24 11 * * 2'
21
+
22
+ jobs:
23
+ analyze:
24
+ name: Analyze (${{ matrix.language }})
25
+ # Runner size impacts CodeQL analysis time. To learn more, please see:
26
+ # - https://gh.io/recommended-hardware-resources-for-running-codeql
27
+ # - https://gh.io/supported-runners-and-hardware-resources
28
+ # - https://gh.io/using-larger-runners (GitHub.com only)
29
+ # Consider using larger runners or machines with greater resources for possible analysis time improvements.
30
+ runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
31
+ permissions:
32
+ # required for all workflows
33
+ security-events: write
34
+
35
+ # required to fetch internal or private CodeQL packs
36
+ packages: read
37
+
38
+ # only required for workflows in private repositories
39
+ actions: read
40
+ contents: read
41
+
42
+ strategy:
43
+ fail-fast: false
44
+ matrix:
45
+ include:
46
+ - language: actions
47
+ build-mode: none
48
+ - language: python
49
+ build-mode: none
50
+ # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
51
+ # Use `c-cpp` to analyze code written in C, C++ or both
52
+ # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
53
+ # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
54
+ # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
55
+ # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
56
+ # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
57
+ # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
58
+ steps:
59
+ - name: Checkout repository
60
+ uses: actions/checkout@v7
61
+
62
+ # Add any setup steps before running the `github/codeql-action/init` action.
63
+ # This includes steps like installing compilers or runtimes (`actions/setup-node`
64
+ # or others). This is typically only required for manual builds.
65
+ # - name: Setup runtime (example)
66
+ # uses: actions/setup-example@v1
67
+
68
+ # Initializes the CodeQL tools for scanning.
69
+ - name: Initialize CodeQL
70
+ uses: github/codeql-action/init@v4
71
+ with:
72
+ languages: ${{ matrix.language }}
73
+ build-mode: ${{ matrix.build-mode }}
74
+ # If you wish to specify custom queries, you can do so here or in a config file.
75
+ # By default, queries listed here will override any specified in a config file.
76
+ # Prefix the list here with "+" to use these queries and those in the config file.
77
+
78
+ # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
79
+ # queries: security-extended,security-and-quality
80
+
81
+ # If the analyze step fails for one of the languages you are analyzing with
82
+ # "We were unable to automatically build your code", modify the matrix above
83
+ # to set the build mode to "manual" for that language. Then modify this step
84
+ # to build your code.
85
+ # ℹ️ Command-line programs to run using the OS shell.
86
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
87
+ - name: Run manual build steps
88
+ if: matrix.build-mode == 'manual'
89
+ shell: bash
90
+ run: |
91
+ echo 'If you are using a "manual" build mode for one or more of the' \
92
+ 'languages you are analyzing, replace this with the commands to build' \
93
+ 'your code, for example:'
94
+ echo ' make bootstrap'
95
+ echo ' make release'
96
+ exit 1
97
+
98
+ - name: Perform CodeQL Analysis
99
+ uses: github/codeql-action/analyze@v4
100
+ with:
101
+ category: "/language:${{matrix.language}}"
@@ -3,6 +3,10 @@ on:
3
3
  branches:
4
4
  - main
5
5
  name: Continuous Deployment
6
+ permissions:
7
+ contents: write
8
+ issues: write
9
+ pull-requests: write
6
10
  jobs:
7
11
  release-please:
8
12
  runs-on: ubuntu-latest
@@ -1,5 +1,8 @@
1
1
  name: Continuous Integration
2
2
 
3
+ permissions:
4
+ contents: read
5
+
3
6
  on:
4
7
  push:
5
8
  paths-ignore:
@@ -37,7 +40,7 @@ jobs:
37
40
  matrix:
38
41
  os: [ubuntu-latest]
39
42
  python-version:
40
- - "3.9"
43
+ - "3.10"
41
44
  - "3.11"
42
45
  - "3.12"
43
46
  - "3.13"
@@ -7,6 +7,9 @@ on:
7
7
  - "docs/**"
8
8
  - ".github/workflows/docs.yml"
9
9
 
10
+ permissions:
11
+ contents: read
12
+
10
13
  jobs:
11
14
  mkdocs:
12
15
  runs-on: ubuntu-latest
@@ -4,6 +4,11 @@ on:
4
4
  schedule:
5
5
  - cron: "0 0 * * *" # Run every day at midnight
6
6
 
7
+ permissions:
8
+ contents: read
9
+ issues: write
10
+ pull-requests: write
11
+
7
12
  jobs:
8
13
  close_stale_prs:
9
14
  runs-on: ubuntu-latest
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "1.0.1"
3
+ }
@@ -1,5 +1,68 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.1](https://github.com/CHIMEFRB/datatrail-cli/compare/datatrail-cli-v1.0.0...datatrail-cli-v1.0.1) (2026-09-29)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **pull:** continue when optional size query is unavailable ([#195](https://github.com/CHIMEFRB/datatrail-cli/issues/195)) ([b36bbbf](https://github.com/CHIMEFRB/datatrail-cli/commit/b36bbbf90d47eb22f20eaa7a12cfea8f4ae703bb))
9
+ * **scout:** restore discrepancy detection and confirmed repairs ([#197](https://github.com/CHIMEFRB/datatrail-cli/issues/197)) ([54dfbf4](https://github.com/CHIMEFRB/datatrail-cli/commit/54dfbf4b3abf8ff0f7f9db13e5eb7ccdb28ccce1))
10
+
11
+
12
+ ### Performance Improvements
13
+
14
+ * **pull:** apply CANFAR permissions without subprocesses ([#157](https://github.com/CHIMEFRB/datatrail-cli/issues/157)) ([b8c2230](https://github.com/CHIMEFRB/datatrail-cli/commit/b8c22306432a6b24b435b5ddb421ac5cdcd9e1eb))
15
+
16
+ ## [1.0.0](https://github.com/CHIMEFRB/datatrail-cli/compare/datatrail-cli-v0.13.0...datatrail-cli-v1.0.0) (2026-09-28)
17
+
18
+
19
+ ### ⚠ BREAKING CHANGES
20
+
21
+ * require Python 3.10 for patched dependencies
22
+
23
+ ### Features
24
+
25
+ * **doctor:** add readiness checks ([ae0565c](https://github.com/CHIMEFRB/datatrail-cli/commit/ae0565cd7963758e465889f312f0fac2d0418c3d))
26
+ * **doctor:** add readiness checks ([6691c31](https://github.com/CHIMEFRB/datatrail-cli/commit/6691c31cb20e5419588af7a21f62810aee1fbc02))
27
+ * **inventory:** add resumable manifests ([c7c4df5](https://github.com/CHIMEFRB/datatrail-cli/commit/c7c4df5d1634e8573f700ba2b1368105f4f67fb7))
28
+ * **inventory:** add resumable manifests ([343a28a](https://github.com/CHIMEFRB/datatrail-cli/commit/343a28a74366f91b8a0bd428250f1576cd4a752f))
29
+ * **ls:** add --match and --expand for dataset discovery ([bf08635](https://github.com/CHIMEFRB/datatrail-cli/commit/bf08635a75f6ec3b1415541ff1b9a1f31e9d443b))
30
+ * **ls:** add match and expand for dataset discovery ([31cccde](https://github.com/CHIMEFRB/datatrail-cli/commit/31cccde47ee8827aec17df7ce13ba5a7ac7b13d3))
31
+ * **ls:** add recursive dataset discovery ([8ea3bc4](https://github.com/CHIMEFRB/datatrail-cli/commit/8ea3bc4e5026fbb9fedb231a0bdb7b78a8f90bdf))
32
+ * **ls:** add recursive dataset discovery ([6f9a85e](https://github.com/CHIMEFRB/datatrail-cli/commit/6f9a85e608eea73a5b3e8b30331203a09908c71c))
33
+ * **ps:** expose common paths in JSON output ([3ee4238](https://github.com/CHIMEFRB/datatrail-cli/commit/3ee423828ee81fca7c9a661051975920e71e17bf))
34
+ * **ps:** expose per-storage-element common paths in --json output ([b748fb4](https://github.com/CHIMEFRB/datatrail-cli/commit/b748fb442589a0259b483774ed6fcf391a8eb391))
35
+ * **pull:** add resumable manifest transfers ([9017c11](https://github.com/CHIMEFRB/datatrail-cli/commit/9017c118450ee98082f72b4142b2c76d77c94f28))
36
+ * **pull:** add resumable manifest transfers ([7272daa](https://github.com/CHIMEFRB/datatrail-cli/commit/7272daa58fc76b3130181fdc1171da7453b01f82))
37
+ * **verify:** verify registered dataset files ([cef2ab7](https://github.com/CHIMEFRB/datatrail-cli/commit/cef2ab708b2d4f26bae4131d18f5613ba86ec0e3))
38
+ * **verify:** verify registered dataset files ([27f3810](https://github.com/CHIMEFRB/datatrail-cli/commit/27f3810dfe78c1f889cb94abae3836a7058ebfd5))
39
+
40
+
41
+ ### Bug Fixes
42
+
43
+ * add stable command error metadata ([d1096ff](https://github.com/CHIMEFRB/datatrail-cli/commit/d1096ffb850b6bd1a690370318dcec5be97ce4f3))
44
+ * **deps:** require patched Requests on Python 3.10 and newer ([e0fb559](https://github.com/CHIMEFRB/datatrail-cli/commit/e0fb55951975d60c202181644c703f280602fa5f))
45
+ * **deps:** require patched Requests on Python 3.10+ ([7d1c4ba](https://github.com/CHIMEFRB/datatrail-cli/commit/7d1c4ba3ead33b46cc6c042e554464fca4e78438))
46
+ * **deps:** require patched urllib3 on Python 3.10+ ([5a4ad0b](https://github.com/CHIMEFRB/datatrail-cli/commit/5a4ad0bc1a29dcad305cad8ec739dd47e703ef6a))
47
+ * **deps:** use patched dependencies on Python 3.10 and newer ([69f0806](https://github.com/CHIMEFRB/datatrail-cli/commit/69f080682a6fa11f18c4acbc890b3c043bc22393))
48
+ * **doctor:** handle certificate and authentication failures ([3584b7b](https://github.com/CHIMEFRB/datatrail-cli/commit/3584b7b0d71ee9bc18479bba75e5b10b96ac8ac2))
49
+ * **encoding:** use ASCII status output ([a0646d7](https://github.com/CHIMEFRB/datatrail-cli/commit/a0646d7d17e66b7507a7f6019e1cd48c3faf2f9d))
50
+ * enforce patched urllib3 on Python 3.10 and newer ([ab12a03](https://github.com/CHIMEFRB/datatrail-cli/commit/ab12a03402cb0ecfec471b2c1941bc3513101762))
51
+ * **failure:** add stable command error metadata ([f52a917](https://github.com/CHIMEFRB/datatrail-cli/commit/f52a917acc05a88b4cbe1364ce3d41af8e1af4ae))
52
+ * **inventory:** reconcile recovered discovery checkpoints ([2a0bda5](https://github.com/CHIMEFRB/datatrail-cli/commit/2a0bda5751e849503903c96bba65fe530bb016d2))
53
+ * **ls:** validate discovery filters and response names ([af2de4f](https://github.com/CHIMEFRB/datatrail-cli/commit/af2de4f3526da507e54dc30f68cc139227f3381b))
54
+ * **ps:** preserve paths for duplicate and invalid replicas ([2dae57d](https://github.com/CHIMEFRB/datatrail-cli/commit/2dae57d4654c4a22c81aea17827a5d0f041b977c))
55
+ * **pull:** clean up CADC SDK partial downloads ([1b15bff](https://github.com/CHIMEFRB/datatrail-cli/commit/1b15bffaa32b2685669a74f4d18f9d6bb73ee1ef))
56
+ * **pull:** protect aliased directory ownership paths ([c03f284](https://github.com/CHIMEFRB/datatrail-cli/commit/c03f284d730fdf1dd9bf2f8dbe5ddda8780324ac))
57
+ * **pull:** publish downloads atomically ([b512e5f](https://github.com/CHIMEFRB/datatrail-cli/commit/b512e5f8ba5b6acd3a5a09c68440eb914d9e8d8e))
58
+ * **pull:** publish downloads atomically ([bf7846f](https://github.com/CHIMEFRB/datatrail-cli/commit/bf7846f4efb41ea55d3edd3961b19c5da7d79eb3))
59
+ * **pull:** report lost workers and clean up failed starts ([bfe5d91](https://github.com/CHIMEFRB/datatrail-cli/commit/bfe5d91d71d130230f5a6b232953e09e34fc8219))
60
+ * **pull:** validate manifest paths before creating state ([b0dc320](https://github.com/CHIMEFRB/datatrail-cli/commit/b0dc32064e1859fc90466da5ed2b4a7f62aa8ccd))
61
+ * require Python 3.10 for patched dependencies ([07de5af](https://github.com/CHIMEFRB/datatrail-cli/commit/07de5af18da463d514ca4b05da06a749c5c2b0dd))
62
+ * update TLS dependencies without raising Python minimum ([8658c58](https://github.com/CHIMEFRB/datatrail-cli/commit/8658c5828ce63772ba229ffa6f4ff93b5c9575fe))
63
+ * update TLS dependencies without raising Python minimum ([ec11019](https://github.com/CHIMEFRB/datatrail-cli/commit/ec110197e2f5281cd22261b605de1d1ad47405e3))
64
+ * **verify:** preserve reports when metadata services fail ([8dbeea3](https://github.com/CHIMEFRB/datatrail-cli/commit/8dbeea34caa8a87d94f4f4d0e3418f3bcfb2df9f))
65
+
3
66
  ## [0.13.0](https://github.com/CHIMEFRB/datatrail-cli/compare/datatrail-cli-v0.12.0...datatrail-cli-v0.13.0) (2026-08-25)
4
67
 
5
68
 
@@ -1,24 +1,29 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: datatrail-cli
3
- Version: 0.13.0
3
+ Version: 1.0.1
4
4
  Summary: CHIME/FRB Datatrail CLI
5
5
  Author: CHIME FRB Project Office
6
6
  Author-email: Tarik Zegmott <tarik.zegmott@mcgill.ca>
7
7
  License-Expression: MIT
8
8
  License-File: LICENSE
9
- Requires-Python: !=3.9.0,!=3.9.1,<4.0,>=3.8.1
9
+ Requires-Python: <4.0,>=3.10
10
10
  Requires-Dist: cadcdata>=2.5.0
11
11
  Requires-Dist: cadctap>=0.9.11
12
12
  Requires-Dist: cadcutils>=1.5.1.1
13
13
  Requires-Dist: click-aliasing>=1.0.0
14
14
  Requires-Dist: click>=8.1.3
15
+ Requires-Dist: cryptography>=50.0.0
15
16
  Requires-Dist: dill>=0.3.6
16
17
  Requires-Dist: lxml>=6.1.0
17
18
  Requires-Dist: mergedeep>=1.3.4
18
19
  Requires-Dist: pyaml>=21.10.1
19
- Requires-Dist: requests>=2.29.0
20
+ Requires-Dist: pygments>=2.20.0
21
+ Requires-Dist: pyopenssl>=26.4.0
22
+ Requires-Dist: requests>=2.33.0
20
23
  Requires-Dist: rich>=13.3.5
24
+ Requires-Dist: setuptools>=83.0.0
21
25
  Requires-Dist: tenacity>=8.0.0
26
+ Requires-Dist: urllib3>=2.7.0
22
27
  Description-Content-Type: text/markdown
23
28
 
24
29
  <div align="center">
@@ -56,6 +61,8 @@ Description-Content-Type: text/markdown
56
61
 
57
62
  ## 🛠️ Installation
58
63
 
64
+ Python 3.10 or newer is required for the supported dependency versions.
65
+
59
66
  ### Install from PYPI
60
67
 
61
68
  ```shell
@@ -33,6 +33,8 @@
33
33
 
34
34
  ## 🛠️ Installation
35
35
 
36
+ Python 3.10 or newer is required for the supported dependency versions.
37
+
36
38
  ### Install from PYPI
37
39
 
38
40
  ```shell
@@ -9,11 +9,14 @@ The commands available to you are:
9
9
  - `clear`: This removes all files belonging to the 'scope' and 'dataset', only
10
10
  available for the local and canfar sites.
11
11
  - `config`: Edit the `.datatrail/config.yaml` configuration file.
12
+ - `inventory`: Recursively discover datasets and write their file replica URIs
13
+ to a resumable JSON manifest.
12
14
  - `list`: This list either the 'scopes' available or all of the datasets
13
15
  belonging to the given dataset.
14
16
  - `ps`: This provides detailed information for the given 'scope' and 'dataset' combination.
15
17
  - `pull`: This allows you to download all files belonging to the 'scope' and
16
18
  'dataset' provided.
19
+ - `pull-manifest`: Download Minoc files from a resumable inventory manifest.
17
20
  - `scout`: This command provides an overview of what the Datatrail database
18
21
  thinks is the current number of files for a given dataset at each storage
19
22
  element, compared to what is observed. If a discrepancy is found at Minoc,
@@ -1,5 +1,7 @@
1
1
  # 🛠️ Installation
2
2
 
3
+ Python 3.10 or newer is required.
4
+
3
5
  There are two ways to install the Datatrail CLI:
4
6
 
5
7
  === "PYPI"
@@ -0,0 +1,80 @@
1
+ # Building a durable inventory
2
+
3
+ `datatrail inventory` recursively discovers terminal datasets and records each
4
+ file replica URI in a versioned JSON manifest. The manifest can later drive a
5
+ batch download without repeating the archive crawl.
6
+
7
+ Every run must be bounded in one of these ways:
8
+
9
+ ```shell
10
+ $> datatrail inventory chime.event.baseband.raw
11
+ $> datatrail inventory --match classified,baseband
12
+ $> datatrail inventory gbo.acquisition.processed --parent complex_gains
13
+ ```
14
+
15
+ A scope limits traversal to that scope. `--match` may search across scopes but
16
+ only opens matching larger datasets. `--parent` requires a scope and starts at
17
+ one known dataset. It cannot be combined with `--match`.
18
+
19
+ Use `--output` to choose the manifest path:
20
+
21
+ ```shell
22
+ $> datatrail inventory chime.event.baseband.raw --match classified \
23
+ --output baseband-inventory.json
24
+ ```
25
+
26
+ The command writes the manifest atomically after discovery and after every
27
+ dataset query. A rerun with the same selection reuses `ready` and `empty`
28
+ entries, then retries `pending` and `failed` entries. A different selection is
29
+ refused so unrelated inventories cannot be mixed.
30
+
31
+ Successful discovery replaces obsolete entries with the current terminal
32
+ datasets. If a failed parent lookup recovers, its placeholder is replaced by
33
+ the discovered descendants. A discovery outage preserves earlier checkpoints.
34
+
35
+ Only one inventory command may own an output at a time. A competing run exits
36
+ with an error before reading or changing the manifest, including when a symlink
37
+ refers to the same output. Ownership is released when the process exits. Leave
38
+ the hidden `.lock` file in place; its presence does not mean a run is active.
39
+
40
+ An inventory with any failed discovery branch or file query exits nonzero.
41
+ `--allow-incomplete` keeps the incomplete manifest but exits zero when a caller
42
+ wants to inspect or process the available subset.
43
+
44
+ ## Manifest format
45
+
46
+ The first format is `datatrail.inventory/v1`:
47
+
48
+ ```json
49
+ {
50
+ "schema": "datatrail.inventory/v1",
51
+ "selection": {
52
+ "scope": "gbo.acquisition.processed",
53
+ "match": [],
54
+ "parent": "complex_gains"
55
+ },
56
+ "complete": true,
57
+ "discovery_failures": [],
58
+ "datasets": [
59
+ {
60
+ "scope": "gbo.acquisition.processed",
61
+ "dataset": "20230525",
62
+ "parent": "complex_gains",
63
+ "path": ["complex_gains", "20230525"],
64
+ "status": "ready",
65
+ "replicas": [
66
+ {
67
+ "storage_element": "minoc",
68
+ "uri": "cadc:CHIMEFRB/example/file.h5"
69
+ }
70
+ ]
71
+ }
72
+ ]
73
+ }
74
+ ```
75
+
76
+ Replica rows contain only Datatrail information. Size and checksum fields may
77
+ be added in a later schema when they can be obtained without requiring a CADC
78
+ credential during inventory creation. A valid dataset with no replica URIs has
79
+ status `empty`; an unavailable or invalid file response has status `failed`
80
+ and an `error` field.
@@ -12,6 +12,12 @@ Options:
12
12
  -q, --quiet Only errors shown in logs.
13
13
  --write Write the events to file.
14
14
  --json Output as JSON.
15
+ --match TEXT Comma-separated, case-insensitive terms a larger dataset must
16
+ all contain.
17
+ --expand Open each matched larger dataset one level and list its
18
+ children.
19
+ --recursive Open each matched larger dataset through all descendant
20
+ levels.
15
21
  --help Show this message and exit.
16
22
 
17
23
  ```
@@ -102,6 +108,105 @@ Within Datatrail, there are two types of datasets:
102
108
  Please see the CLI reference page for more information on the `list` command:
103
109
  [datatrail list](../cli/#datatrail-list)
104
110
 
111
+ ## Finding datasets with `--match` and `--expand`
112
+
113
+ Navigating the hierarchy one name at a time gets slow when you do not know
114
+ where a dataset lives. `--match` filters the larger datasets of a scope, or
115
+ of **every** scope when no scope is given, by one or more comma-separated,
116
+ case-insensitive terms, which must all appear in the combined
117
+ `scope dataset` text. At least one nonempty term is required; whitespace and
118
+ commas alone are rejected:
119
+
120
+ ```shell
121
+ $> datatrail ls chime.acquisition.processed --match gains
122
+ Datatrail: Dataset Map
123
+ +-----------------------------+---------------+
124
+ | Scope | Dataset |
125
+ +-----------------------------+---------------+
126
+ | chime.acquisition.processed | complex_gains |
127
+ +-----------------------------+---------------+
128
+ ```
129
+
130
+ A hit may be a container whose children are the datasets you actually want.
131
+ `--expand` opens each matched larger dataset one level and lists the children
132
+ it finds, recording the parent; a match whose children cannot be listed keeps
133
+ its own row:
134
+
135
+ ```shell
136
+ $> datatrail ls --match gain --expand
137
+ Datatrail: Dataset Map
138
+ +-----------------------------+---------------+---------------+
139
+ | Scope | Dataset | Parent |
140
+ +-----------------------------+---------------+---------------+
141
+ | chime.acquisition.processed | complex_gains | |
142
+ +-----------------------------+---------------+---------------+
143
+ | gbo.acquisition.processed | 20230716 | complex_gains |
144
+ | gbo.acquisition.processed | 20230715 | complex_gains |
145
+ | ... | ... | ... |
146
+ +-----------------------------+---------------+---------------+
147
+ ```
148
+
149
+ Rows reached through a parent resolve directly with
150
+ `datatrail ps <scope> <dataset>`; a row kept for a matched dataset whose
151
+ children could not be listed (or that has none) may still be a container.
152
+
153
+ !!! warning "Incomplete maps"
154
+
155
+ If Datatrail does not answer for a scope or dataset during the walk, the
156
+ map is reported as **incomplete** and the unanswered queries are listed,
157
+ rather than silently showing them as empty. With `--json`, those queries
158
+ appear in the `failed` list. A partial map still exits 0; a map with **no**
159
+ rows and unanswered queries exits 1, since nothing was determined.
160
+
161
+ `--recursive` follows every descendant of each matched larger dataset instead
162
+ of stopping after one level. It emits terminal datasets and records the full
163
+ path used to reach each one:
164
+
165
+ ```shell
166
+ $> datatrail ls gbo.acquisition.processed --match gains --recursive
167
+ ```
168
+
169
+ The walk visits each dataset once, so shared descendants are not duplicated
170
+ and hierarchy cycles cannot loop forever. The first path found in sorted order
171
+ is retained. An answered empty child list is a terminal dataset. A branch that
172
+ does not answer is retained as a partial row and also listed under `failed`.
173
+ Like `--expand`, a recursive walk across all scopes requires `--match` to keep
174
+ the request bounded.
175
+
176
+ With `--json`, the map is emitted as structured rows for scripting; `parent`
177
+ is `null` for rows that were not reached through expansion. Recursive rows
178
+ also include `path`, from the matched larger dataset through the terminal row:
179
+
180
+ ```bash
181
+ $ datatrail ls --match gain --expand --json
182
+ {
183
+ "results": [
184
+ {
185
+ "scope": "gbo.acquisition.processed",
186
+ "dataset": "20230525",
187
+ "parent": "complex_gains"
188
+ },
189
+ ...
190
+ ],
191
+ "failed": []
192
+ }
193
+ ```
194
+
195
+ ```bash
196
+ $ datatrail ls gbo.acquisition.processed --match gains --recursive --json
197
+ {
198
+ "results": [
199
+ {
200
+ "scope": "gbo.acquisition.processed",
201
+ "dataset": "20230525",
202
+ "parent": "complex_gains",
203
+ "path": ["complex_gains", "20230525"]
204
+ }
205
+ ],
206
+ "failed": []
207
+ }
208
+ ```
209
+
105
210
  ## 🤖 Machine-readable JSON output
106
211
 
107
212
  The `--json` flag outputs structured JSON instead of formatted tables, making it easy to parse the output in scripts and pipelines:
@@ -102,6 +102,16 @@ $ datatrail ps kko.event.baseband.raw 308892599 --json
102
102
  ]
103
103
  }
104
104
  },
105
+ "common_paths": {
106
+ "minoc": {
107
+ "common_path": "data/kko/baseband/raw/2023/08/07/astro_308892599",
108
+ "files": [
109
+ "baseband_308892599_129.h5",
110
+ "baseband_308892599_1013.h5",
111
+ ...
112
+ ]
113
+ }
114
+ },
105
115
  "policies": {
106
116
  "replication_policy": {
107
117
  "preferred_storage_elements": ["chime"],
@@ -127,6 +137,13 @@ $ datatrail ps kko.event.baseband.raw 308892599 --json
127
137
  }
128
138
  ```
129
139
 
140
+ The `common_paths` field gives, per storage element, the deepest common
141
+ directory of its file replicas and the file names relative to it, so scripts
142
+ do not have to re-derive the split. When no common directory exists, it is
143
+ `""` and the original paths are listed. Note that `minoc` paths keep any
144
+ collection prefix (such as `cadc:CHIMEFRB`) exactly as reported in
145
+ `file_replica_locations`.
146
+
130
147
  ### Usage in scripts
131
148
 
132
149
  ```python
@@ -145,6 +162,13 @@ data = json.loads(result.stdout)
145
162
  file_locations = data["files"]["file_replica_locations"]
146
163
  minoc_files = file_locations.get("minoc", [])
147
164
 
165
+ # Compose full paths from the derived common path
166
+ minoc = data["common_paths"].get("minoc", {})
167
+ full_paths = [
168
+ f"{minoc['common_path']}/{name}" if minoc["common_path"] else name
169
+ for name in minoc.get("files", [])
170
+ ]
171
+
148
172
  # Access policies
149
173
  replication_policy = data["policies"]["replication_policy"]
150
174
  deletion_policy = data["policies"]["deletion_policy"]
@@ -0,0 +1,69 @@
1
+ # Pulling an inventory
2
+
3
+ `datatrail pull-manifest` downloads the Minoc files in an inventory and writes
4
+ durable transfer state beside it:
5
+
6
+ ```shell
7
+ $> datatrail pull-manifest baseband-inventory.json --directory ./baseband
8
+ ```
9
+
10
+ The default state path is `<inventory-name>.pull.json`. Use `--state` to put it
11
+ elsewhere. Each completed batch is written atomically, so rerunning the same
12
+ command skips completed files whose recorded size still matches and retries
13
+ pending or failed files.
14
+
15
+ Minoc replicas may use `cadc:CHIMEFRB/...`, `data/...`, or `/...` paths, matching
16
+ the formats accepted by dataset downloads. Equivalent paths are downloaded
17
+ once. Paths that escape the destination, collide with one another, or replace
18
+ the inventory, transfer state, or lock files are refused before creating state.
19
+
20
+ Transfers are limited by `--cores`, which defaults to one. A larger value runs
21
+ only that many files at once:
22
+
23
+ ```shell
24
+ $> datatrail pull-manifest baseband-inventory.json --directory ./baseband \
25
+ --cores 4 --force
26
+ ```
27
+
28
+ Each file is downloaded to a temporary sibling, checked against Minoc's size
29
+ when available, and moved into place only after it completes. An interrupted or
30
+ truncated download does not replace the destination.
31
+
32
+ The command exits nonzero when any file fails, the inventory is incomplete, or
33
+ a ready dataset has no Minoc replica. Available files are still downloaded and
34
+ checkpointed, so the next run can continue after the service recovers.
35
+
36
+ Only one transfer command may use a state file or destination directory at a
37
+ time. Competing runs exit before changing transfer state or downloading files,
38
+ even if they use different state files for the same destination. Symlinks to the
39
+ same paths share ownership. The locks are held through confirmation and all
40
+ download batches, and released when the process exits. Leave the hidden `.lock`
41
+ files in place; their presence does not mean a transfer is active.
42
+ Use separate destination trees for concurrent commands; these locks do not
43
+ coordinate a directory with a nested destination used by another command.
44
+
45
+ ## Transfer state
46
+
47
+ The transfer state uses schema `datatrail.pull/v1`:
48
+
49
+ ```json
50
+ {
51
+ "schema": "datatrail.pull/v1",
52
+ "inventory": "/data/baseband-inventory.json",
53
+ "directory": "/data/baseband",
54
+ "inventory_complete": true,
55
+ "unavailable_datasets": [],
56
+ "complete": true,
57
+ "files": [
58
+ {
59
+ "uri": "cadc:CHIMEFRB/example/file.h5",
60
+ "path": "example/file.h5",
61
+ "status": "complete",
62
+ "bytes": 4096
63
+ }
64
+ ]
65
+ }
66
+ ```
67
+
68
+ Keep the state file with its inventory. A state file cannot be reused with a
69
+ different inventory path or destination directory.
@@ -128,9 +128,9 @@ def clear(
128
128
  is_delete = True
129
129
  else:
130
130
  message = (
131
- "⚠️ Delete files and empty parent directories?"
131
+ "WARNING: Delete files and empty parent directories?"
132
132
  if clear_parents
133
- else "⚠️ Delete files?"
133
+ else "WARNING: Delete files?"
134
134
  )
135
135
  is_delete = Confirm.ask(message)
136
136