eopf-geozarr 0.6.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 (140) hide show
  1. eopf_geozarr-0.6.1/.github/CI.md +143 -0
  2. eopf_geozarr-0.6.1/.github/dependabot.yml +33 -0
  3. eopf_geozarr-0.6.1/.github/workflows/build_uv_cache.yml +42 -0
  4. eopf_geozarr-0.6.1/.github/workflows/ci.yml +99 -0
  5. eopf_geozarr-0.6.1/.github/workflows/docs.yml +41 -0
  6. eopf_geozarr-0.6.1/.github/workflows/release.yml +51 -0
  7. eopf_geozarr-0.6.1/.gitignore +216 -0
  8. eopf_geozarr-0.6.1/.pre-commit-config.yaml +23 -0
  9. eopf_geozarr-0.6.1/.vscode/launch.json +360 -0
  10. eopf_geozarr-0.6.1/CHANGELOG.md +142 -0
  11. eopf_geozarr-0.6.1/LICENSE +205 -0
  12. eopf_geozarr-0.6.1/PKG-INFO +421 -0
  13. eopf_geozarr-0.6.1/README.md +380 -0
  14. eopf_geozarr-0.6.1/attributes/README.md +36 -0
  15. eopf_geozarr-0.6.1/attributes/geo/proj/README.md +391 -0
  16. eopf_geozarr-0.6.1/attributes/geo/proj/schema.json +171 -0
  17. eopf_geozarr-0.6.1/docs/api-reference.md +505 -0
  18. eopf_geozarr-0.6.1/docs/architecture.md +449 -0
  19. eopf_geozarr-0.6.1/docs/assets/logo-eopf-sentinel-explorer-dark-icon.png +0 -0
  20. eopf_geozarr-0.6.1/docs/converter.md +213 -0
  21. eopf_geozarr-0.6.1/docs/examples.md +523 -0
  22. eopf_geozarr-0.6.1/docs/faq.md +531 -0
  23. eopf_geozarr-0.6.1/docs/geozarr-minispec.md +712 -0
  24. eopf_geozarr-0.6.1/docs/geozarr-specification-contribution.md +141 -0
  25. eopf_geozarr-0.6.1/docs/index.md +159 -0
  26. eopf_geozarr-0.6.1/docs/installation.md +159 -0
  27. eopf_geozarr-0.6.1/docs/models/sentinel1.md +54 -0
  28. eopf_geozarr-0.6.1/docs/models/sentinel2.md +86 -0
  29. eopf_geozarr-0.6.1/docs/quickstart.md +233 -0
  30. eopf_geozarr-0.6.1/docs/stylesheets/extra.css +82 -0
  31. eopf_geozarr-0.6.1/examples/convert_local.sh +14 -0
  32. eopf_geozarr-0.6.1/mkdocs.yml +74 -0
  33. eopf_geozarr-0.6.1/pyproject.toml +212 -0
  34. eopf_geozarr-0.6.1/setup.cfg +4 -0
  35. eopf_geozarr-0.6.1/src/eopf_geozarr/__init__.py +30 -0
  36. eopf_geozarr-0.6.1/src/eopf_geozarr/__main__.py +11 -0
  37. eopf_geozarr-0.6.1/src/eopf_geozarr/_version.py +34 -0
  38. eopf_geozarr-0.6.1/src/eopf_geozarr/cli.py +1228 -0
  39. eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/__init__.py +45 -0
  40. eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/fs_utils.py +499 -0
  41. eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/geozarr.py +1766 -0
  42. eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/sentinel1_reprojection.py +372 -0
  43. eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/utils.py +239 -0
  44. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/__init__.py +48 -0
  45. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/__init__.py +0 -0
  46. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/common.py +291 -0
  47. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/geoproj.py +61 -0
  48. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/__init__.py +13 -0
  49. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/geozarr.py +98 -0
  50. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/tms.py +56 -0
  51. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/zcm.py +139 -0
  52. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/projjson.py +690 -0
  53. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/spatial.py +58 -0
  54. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/types.py +115 -0
  55. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/v2.py +138 -0
  56. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/v3.py +68 -0
  57. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/s1.py +956 -0
  58. eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/s2.py +692 -0
  59. eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/__init__.py +4 -0
  60. eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/common.py +467 -0
  61. eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/v2.py +71 -0
  62. eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/v3.py +71 -0
  63. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/__init__.py +2 -0
  64. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/common.py +5 -0
  65. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_band_mapping.py +77 -0
  66. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_converter.py +375 -0
  67. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_data_consolidator.py +217 -0
  68. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_multiscale.py +1077 -0
  69. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_resampling.py +212 -0
  70. eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_validation.py +7 -0
  71. eopf_geozarr-0.6.1/src/eopf_geozarr/types.py +134 -0
  72. eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/PKG-INFO +421 -0
  73. eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/SOURCES.txt +138 -0
  74. eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/dependency_links.txt +1 -0
  75. eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/entry_points.txt +2 -0
  76. eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/requires.txt +14 -0
  77. eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/top_level.txt +1 -0
  78. eopf_geozarr-0.6.1/tests/__init__.py +247 -0
  79. eopf_geozarr-0.6.1/tests/conftest.py +285 -0
  80. eopf_geozarr-0.6.1/tests/test_cli_e2e.py +344 -0
  81. eopf_geozarr-0.6.1/tests/test_conversion.py +618 -0
  82. eopf_geozarr-0.6.1/tests/test_data_api/__init__.py +0 -0
  83. eopf_geozarr-0.6.1/tests/test_data_api/conftest.py +243 -0
  84. eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/epsg26711.json +24 -0
  85. eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/epsg3587.json +30 -0
  86. eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/multiscales.json +63 -0
  87. eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/wkt2.json +17 -0
  88. eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json +19094 -0
  89. eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json +14123 -0
  90. eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json +19094 -0
  91. eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/sentinel_2.json +14142 -0
  92. eopf_geozarr-0.6.1/tests/test_data_api/optimized_geozarr_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json +16320 -0
  93. eopf_geozarr-0.6.1/tests/test_data_api/optimized_geozarr_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json +9981 -0
  94. eopf_geozarr-0.6.1/tests/test_data_api/optimized_geozarr_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json +16320 -0
  95. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/bound_crs.json +198 -0
  96. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/compound_crs.json +123 -0
  97. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/datum_ensemble.json +98 -0
  98. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/explicit_prime_meridian.json +47 -0
  99. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/implicit_prime_meridian.json +43 -0
  100. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/projected_crs.json +124 -0
  101. eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/transformation.json +112 -0
  102. eopf_geozarr-0.6.1/tests/test_data_api/s1_examples/S1A_IW_GRDH_1SDV_20241124T180254_20241124T180319_056700_06F516_BA27.json +9097 -0
  103. eopf_geozarr-0.6.1/tests/test_data_api/s1_examples/S1A_IW_GRDH_1SDV_20241218T180252_20241218T180317_057050_0702F2_0BC2.json +9414 -0
  104. eopf_geozarr-0.6.1/tests/test_data_api/s1_examples/S1C_IW_GRDH_1SDV_20250912T053648_20250912T053713_004087_0081FD_5AA4.json +7573 -0
  105. eopf_geozarr-0.6.1/tests/test_data_api/s2_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json +9165 -0
  106. eopf_geozarr-0.6.1/tests/test_data_api/s2_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json +7836 -0
  107. eopf_geozarr-0.6.1/tests/test_data_api/s2_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json +9165 -0
  108. eopf_geozarr-0.6.1/tests/test_data_api/test_geoproj.py +195 -0
  109. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/__init__.py +0 -0
  110. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_common.py +136 -0
  111. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/__init__.py +0 -0
  112. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/conftest.py +13 -0
  113. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/test_geozarr.py +69 -0
  114. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/test_tms.py +0 -0
  115. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/test_zcm.py +59 -0
  116. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/array-based-pyramid.json +44 -0
  117. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/custom-pyramid-levels.json +50 -0
  118. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/dem-multiresolution.json +68 -0
  119. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/geospatial-pyramid.json +59 -0
  120. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/power-of-2-pyramid.json +45 -0
  121. eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/sentinel-2-multiresolution.json +87 -0
  122. eopf_geozarr-0.6.1/tests/test_data_api/test_projjson.py +777 -0
  123. eopf_geozarr-0.6.1/tests/test_data_api/test_s1.py +25 -0
  124. eopf_geozarr-0.6.1/tests/test_data_api/test_s2.py +25 -0
  125. eopf_geozarr-0.6.1/tests/test_data_api/test_spatial.py +213 -0
  126. eopf_geozarr-0.6.1/tests/test_data_api/test_v2.py +79 -0
  127. eopf_geozarr-0.6.1/tests/test_data_api/test_v3.py +80 -0
  128. eopf_geozarr-0.6.1/tests/test_docs.py +164 -0
  129. eopf_geozarr-0.6.1/tests/test_fs_utils.py +195 -0
  130. eopf_geozarr-0.6.1/tests/test_integration_sentinel1.py +303 -0
  131. eopf_geozarr-0.6.1/tests/test_integration_sentinel2.py +372 -0
  132. eopf_geozarr-0.6.1/tests/test_projjson.py +0 -0
  133. eopf_geozarr-0.6.1/tests/test_reprojection_validation.py +279 -0
  134. eopf_geozarr-0.6.1/tests/test_s2_band_mapping.py +37 -0
  135. eopf_geozarr-0.6.1/tests/test_s2_converter_simplified.py +287 -0
  136. eopf_geozarr-0.6.1/tests/test_s2_data_consolidator.py +567 -0
  137. eopf_geozarr-0.6.1/tests/test_s2_multiscale.py +210 -0
  138. eopf_geozarr-0.6.1/tests/test_s2_multiscale_geo_metadata.py +313 -0
  139. eopf_geozarr-0.6.1/tests/test_s2_resampling.py +474 -0
  140. eopf_geozarr-0.6.1/uv.lock +2826 -0
@@ -0,0 +1,143 @@
1
+ # CI/CD Documentation
2
+
3
+ This directory contains the GitHub Actions workflows and configuration for the eopf-geozarr project.
4
+
5
+ ## Workflows
6
+
7
+ ### 1. CI Workflow (`ci.yml`)
8
+ **Triggers:** Push to main, Pull requests to main
9
+
10
+ **Jobs:**
11
+ - **pre-commit**: Runs pre-commit hooks for code quality
12
+ - **test**: Runs tests on Python 3.11 and 3.12 on Ubuntu
13
+ - **test-network**: Runs network-dependent tests (only on main branch pushes)
14
+ - **docs**: Builds documentation
15
+ - **security**: Runs security scans with bandit and safety
16
+
17
+ **Features:**
18
+ - Code coverage reporting with Codecov
19
+ - Artifact uploads for documentation and security reports
20
+ - Separate network tests to avoid CI failures from external dependencies
21
+
22
+ ### 2. Code Quality Workflow (`code-quality.yml`)
23
+ **Triggers:** Pull requests to main
24
+
25
+ **Jobs:**
26
+ - **lint**: Runs black, isort, flake8, and mypy
27
+ - **test-coverage**: Runs tests with coverage requirements (80% minimum)
28
+ - **security-scan**: Runs bandit and safety security checks
29
+
30
+ **Purpose:** Ensures code quality standards before merging PRs
31
+
32
+ ### 3. Release Workflow (`release.yml`)
33
+ **Triggers:** GitHub releases
34
+
35
+ **Jobs:**
36
+ - **build**: Builds the Python package and validates it
37
+ - **publish**: Publishes to PyPI using trusted publishing
38
+
39
+ **Features:**
40
+ - Automated PyPI publishing on releases
41
+ - Package validation before publishing
42
+ - Uses GitHub's trusted publishing for secure PyPI uploads
43
+
44
+ ### 4. Documentation Workflow (`docs.yml`)
45
+ **Triggers:** Push to main, Pull requests to main
46
+
47
+ **Jobs:**
48
+ - **build-docs**: Builds Sphinx documentation
49
+ - **deploy**: Deploys to GitHub Pages (main branch only)
50
+
51
+ **Features:**
52
+ - Automatic documentation deployment
53
+ - Documentation artifacts for PR previews
54
+
55
+ ## Configuration Files
56
+
57
+ ### Pre-commit Configuration (`.pre-commit-config.yaml`)
58
+ Defines hooks for:
59
+ - Code formatting (black, isort)
60
+ - Linting (flake8, mypy)
61
+ - Security scanning (bandit)
62
+ - General file checks (trailing whitespace, YAML validation, etc.)
63
+
64
+ ### Dependabot Configuration (`dependabot.yml`)
65
+ Automated dependency updates for:
66
+ - Python packages (weekly)
67
+ - GitHub Actions (weekly)
68
+ - Assigned to `developmentseed/data-model-developers` team
69
+
70
+ ## Setup Instructions
71
+
72
+ ### For Developers
73
+
74
+ 1. **Install pre-commit hooks:**
75
+ ```bash
76
+ pip install -e ".[dev]"
77
+ pre-commit install
78
+ ```
79
+
80
+ 2. **Run code quality checks locally:**
81
+ ```bash
82
+ black --check eopf_geozarr/
83
+ isort --check-only eopf_geozarr/
84
+ flake8 eopf_geozarr/
85
+ mypy eopf_geozarr/
86
+ ```
87
+
88
+ 3. **Run tests:**
89
+ ```bash
90
+ pytest eopf_geozarr/tests/ -v --tb=short -m "not network"
91
+ ```
92
+
93
+ ### For Repository Maintainers
94
+
95
+ 1. **Enable GitHub Pages:**
96
+ - Go to repository Settings > Pages
97
+ - Set source to "GitHub Actions"
98
+
99
+ 2. **Configure PyPI Publishing:**
100
+ - Set up trusted publishing on PyPI
101
+ - No secrets needed with trusted publishing
102
+
103
+ 3. **Configure Codecov:**
104
+ - Add repository to Codecov
105
+ - No additional configuration needed
106
+
107
+ ## Code Quality Standards
108
+
109
+ - **Code Coverage:** Minimum 80% required
110
+ - **Code Style:** Black formatting with 100 character line length
111
+ - **Import Sorting:** isort with black profile
112
+ - **Type Checking:** mypy with strict settings
113
+ - **Security:** bandit security scanning
114
+ - **Documentation:** All public APIs must be documented
115
+
116
+ ## Testing Strategy
117
+
118
+ - **Unit Tests:** Fast tests without external dependencies
119
+ - **Integration Tests:** Tests with real data processing
120
+ - **Network Tests:** Tests requiring internet access (marked with `@pytest.mark.network`)
121
+ - **End-to-End Tests:** CLI testing with real workflows
122
+
123
+ ## Release Process
124
+
125
+ 1. Update version in `pyproject.toml`
126
+ 2. Update `CHANGELOG.md`
127
+ 3. Create a GitHub release with tag
128
+ 4. Package is automatically built and published to PyPI
129
+
130
+ ## Troubleshooting
131
+
132
+ ### Common Issues
133
+
134
+ 1. **Pre-commit failures:** Run `pre-commit run --all-files` to fix issues
135
+ 2. **Test failures:** Check if network tests are failing due to external dependencies
136
+ 3. **Coverage failures:** Add tests or exclude lines with `# pragma: no cover`
137
+ 4. **Security scan failures:** Review bandit reports and add exclusions if needed
138
+
139
+ ### Getting Help
140
+
141
+ - Check workflow logs in the Actions tab
142
+ - Review the specific job that failed
143
+ - Common fixes are usually code formatting or missing tests
@@ -0,0 +1,33 @@
1
+ version: 2
2
+ updates:
3
+ # Enable version updates for Python dependencies
4
+ - package-ecosystem: "pip"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ day: "monday"
9
+ time: "09:00"
10
+ open-pull-requests-limit: 10
11
+ reviewers:
12
+ - "developmentseed/data-model-developers"
13
+ assignees:
14
+ - "developmentseed/data-model-developers"
15
+ commit-message:
16
+ prefix: "deps"
17
+ include: "scope"
18
+
19
+ # Enable version updates for GitHub Actions
20
+ - package-ecosystem: "github-actions"
21
+ directory: "/"
22
+ schedule:
23
+ interval: "weekly"
24
+ day: "monday"
25
+ time: "09:00"
26
+ open-pull-requests-limit: 5
27
+ reviewers:
28
+ - "developmentseed/data-model-developers"
29
+ assignees:
30
+ - "developmentseed/data-model-developers"
31
+ commit-message:
32
+ prefix: "ci"
33
+ include: "scope"
@@ -0,0 +1,42 @@
1
+ name: Build uv cache
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - "uv.lock"
9
+ - "pyproject.toml"
10
+ workflow_dispatch:
11
+ schedule:
12
+ - cron: "0 0 */5 * *" # Every 5 days, before cache expiry
13
+
14
+ jobs:
15
+ build-cache:
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - name: Checkout repository
20
+ uses: actions/checkout@v5
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v7
24
+ with:
25
+ version: "0.8.4"
26
+ python-version: "3.13"
27
+ enable-cache: false
28
+
29
+ - name: Install dependencies and populate cache
30
+ run: |
31
+ echo "Building global UV cache..."
32
+ uv sync --group dev --group test
33
+ echo "Cache populated successfully"
34
+
35
+ - name: Save uv caches
36
+ uses: actions/cache/save@v4
37
+ with:
38
+ path: |
39
+ ~/.cache/uv
40
+ ~/.local/share/uv
41
+ .venv
42
+ key: uv-main-${{ hashFiles('uv.lock') }}
@@ -0,0 +1,99 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ pre-commit:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v5
14
+ - uses: actions/setup-python@v6
15
+ with:
16
+ python-version: '3.11'
17
+ - uses: pre-commit/action@v3.0.1
18
+
19
+ test:
20
+ runs-on: ${{ matrix.os }}
21
+ strategy:
22
+ matrix:
23
+ os: [ubuntu-latest]
24
+ python-version: ['3.11', '3.12']
25
+
26
+ steps:
27
+ - uses: actions/checkout@v5
28
+
29
+ - name: Restore global uv cache
30
+ id: cache-restore
31
+ uses: actions/cache/restore@v4
32
+ with:
33
+ path: |
34
+ ~/.cache/uv
35
+ ~/.local/share/uv
36
+ .venv
37
+ key: uv-main-${{ hashFiles('uv.lock') }}
38
+ restore-keys: |
39
+ uv-main-
40
+
41
+ - name: Install uv
42
+ uses: astral-sh/setup-uv@v7
43
+ with:
44
+ version: "0.8.4"
45
+ python-version: "3.13"
46
+ enable-cache: false
47
+
48
+ - name: Install dependencies
49
+ run: uv sync --group dev --group test
50
+
51
+ - name: Run tests
52
+ run: |
53
+ uv run pytest tests/ -v --tb=short -m "not network" --cov=eopf_geozarr --cov-report=xml --cov-report=term-missing
54
+
55
+ - name: Upload coverage to Codecov
56
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
57
+ uses: codecov/codecov-action@v5
58
+ with:
59
+ file: ./coverage.xml
60
+ flags: unittests
61
+ name: codecov-umbrella
62
+
63
+ - name: Save uv caches
64
+ if: steps.cache-restore.outputs.cache-hit != 'true'
65
+ uses: actions/cache/save@v4
66
+ with:
67
+ path: |
68
+ ~/.cache/uv
69
+ ~/.local/share/uv
70
+ .venv
71
+ key: uv-main-${{ hashFiles('uv.lock') }}
72
+
73
+ security:
74
+ runs-on: ubuntu-latest
75
+ steps:
76
+ - uses: actions/checkout@v5
77
+
78
+ - name: Set up Python
79
+ uses: actions/setup-python@v6
80
+ with:
81
+ python-version: '3.11'
82
+
83
+ - name: Install dependencies
84
+ run: |
85
+ python -m pip install --upgrade pip
86
+ pip install bandit safety
87
+
88
+ - name: Run security checks
89
+ run: |
90
+ bandit -r eopf_geozarr/ -f json -o bandit-report.json || true
91
+ safety check --json --output safety-report.json || true
92
+
93
+ - name: Upload security reports
94
+ uses: actions/upload-artifact@v5
95
+ with:
96
+ name: security-reports
97
+ path: |
98
+ bandit-report.json
99
+ safety-report.json
@@ -0,0 +1,41 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+ paths:
9
+ - "docs/**"
10
+
11
+ jobs:
12
+ build-docs:
13
+ permissions:
14
+ contents: write
15
+ pages: write
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v5
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v6
22
+ with:
23
+ python-version: '3.11'
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v7
27
+ with:
28
+ version: "0.8.4"
29
+ python-version: "3.13"
30
+ enable-cache: false
31
+
32
+ - name: Install dependencies
33
+ run: uv sync --group docs
34
+
35
+ - name: Build docs
36
+ if: github.event_name == 'pull_request'
37
+ run: uv run -- mkdocs build
38
+
39
+ - name: Deploy docs
40
+ if: github.event_name == 'push'
41
+ run: uv run -- mkdocs gh-deploy --force
@@ -0,0 +1,51 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v5
12
+
13
+ - name: Set up Python
14
+ uses: actions/setup-python@v6
15
+ with:
16
+ python-version: '3.11'
17
+
18
+ - name: Install build dependencies
19
+ run: |
20
+ python -m pip install --upgrade pip
21
+ pip install build twine
22
+
23
+ - name: Build package
24
+ run: python -m build
25
+
26
+ - name: Check package
27
+ run: twine check dist/*
28
+
29
+ - name: Upload build artifacts
30
+ uses: actions/upload-artifact@v5
31
+ with:
32
+ name: dist
33
+ path: dist/
34
+
35
+ publish:
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ permissions:
39
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
40
+
41
+ steps:
42
+ - name: Download build artifacts
43
+ uses: actions/download-artifact@v6
44
+ with:
45
+ name: dist
46
+ path: dist/
47
+
48
+ - name: Publish to PyPI
49
+ uses: pypa/gh-action-pypi-publish@release/v1
50
+ with:
51
+ packages-dir: dist/
@@ -0,0 +1,216 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+ #poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ #pdm.lock
116
+ #pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ #pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .envrc
140
+ .venv
141
+ env/
142
+ venv/
143
+ ENV/
144
+ env.bak/
145
+ venv.bak/
146
+
147
+ # Spyder project settings
148
+ .spyderproject
149
+ .spyproject
150
+
151
+ # Rope project settings
152
+ .ropeproject
153
+
154
+ # mkdocs documentation
155
+ /site
156
+
157
+ # mypy
158
+ .mypy_cache/
159
+ .dmypy.json
160
+ dmypy.json
161
+
162
+ # Pyre type checker
163
+ .pyre/
164
+
165
+ # pytype static type analyzer
166
+ .pytype/
167
+
168
+ # Cython debug symbols
169
+ cython_debug/
170
+
171
+ # PyCharm
172
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
175
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
+ #.idea/
177
+
178
+ # Abstra
179
+ # Abstra is an AI-powered process automation framework.
180
+ # Ignore directories containing user credentials, local state, and settings.
181
+ # Learn more at https://abstra.io/docs
182
+ .abstra/
183
+
184
+ # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
+ # you could uncomment the following to ignore the entire vscode folder
189
+ # .vscode/
190
+
191
+ # Ruff stuff:
192
+ .ruff_cache/
193
+
194
+ # PyPI configuration file
195
+ .pypirc
196
+
197
+ # Cursor
198
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
+ # refer to https://docs.cursor.com/context/ignore-files
201
+ .cursorignore
202
+ .cursorindexingignore
203
+
204
+ # Marimo
205
+ marimo/_static/
206
+ marimo/_lsp/
207
+ __marimo__/
208
+
209
+ tests-output/
210
+
211
+ # uv
212
+ uv.lock
213
+ .vscode/settings.json
214
+
215
+ # VCS versioning
216
+ src/eopf_geozarr/_version.py
@@ -0,0 +1,23 @@
1
+ repos:
2
+ - repo: https://github.com/abravalheri/validate-pyproject
3
+ rev: v0.24.1
4
+ hooks:
5
+ - id: validate-pyproject
6
+
7
+ - repo: https://github.com/astral-sh/ruff-pre-commit
8
+ rev: v0.14.3
9
+ hooks:
10
+ - id: ruff-check
11
+ args: ["--fix", "--show-fixes"]
12
+ - id: ruff-format
13
+
14
+ - repo: https://github.com/pre-commit/mirrors-mypy
15
+ rev: v1.11.2
16
+ hooks:
17
+ - id: mypy
18
+ language_version: python
19
+ exclude: tests/.*
20
+ additional_dependencies:
21
+ - types-attrs
22
+ - typing-extensions>=4.15.0
23
+ - pydantic>=2.12