sfeos-tools 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sfeos_tools-0.1.0/LICENSE +21 -0
- sfeos_tools-0.1.0/PKG-INFO +243 -0
- sfeos_tools-0.1.0/README.md +179 -0
- sfeos_tools-0.1.0/pyproject.toml +92 -0
- sfeos_tools-0.1.0/setup.cfg +4 -0
- sfeos_tools-0.1.0/sfeos_tools/__init__.py +3 -0
- sfeos_tools-0.1.0/sfeos_tools/cli.py +336 -0
- sfeos_tools-0.1.0/sfeos_tools/reindex.py +122 -0
- sfeos_tools-0.1.0/sfeos_tools.egg-info/PKG-INFO +243 -0
- sfeos_tools-0.1.0/sfeos_tools.egg-info/SOURCES.txt +12 -0
- sfeos_tools-0.1.0/sfeos_tools.egg-info/dependency_links.txt +1 -0
- sfeos_tools-0.1.0/sfeos_tools.egg-info/entry_points.txt +2 -0
- sfeos_tools-0.1.0/sfeos_tools.egg-info/requires.txt +17 -0
- sfeos_tools-0.1.0/sfeos_tools.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Healy Hyperspatial, Jonathan Healy and CloudFerro S.A.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,243 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: sfeos-tools
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: CLI tools for managing stac-fastapi-elasticsearch-opensearch deployments
|
5
|
+
Author: CloudFerro S.A.
|
6
|
+
Author-email: Jonathan Healy <jon@healy-hypersaptial.dev>
|
7
|
+
Maintainer-email: Jonathan Healy <jon@healy-hypersaptial.dev>
|
8
|
+
License: MIT License
|
9
|
+
|
10
|
+
Copyright (c) 2025 Healy Hyperspatial, Jonathan Healy and CloudFerro S.A.
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
14
|
+
in the Software without restriction, including without limitation the rights
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
17
|
+
furnished to do so, subject to the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
20
|
+
copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28
|
+
SOFTWARE.
|
29
|
+
|
30
|
+
Project-URL: Homepage, https://github.com/Healy-Hyperspatial/sfeos-tools
|
31
|
+
Project-URL: Documentation, https://github.com/Healy-Hyperspatial/sfeos-tools#readme
|
32
|
+
Project-URL: Issues, https://github.com/Healy-Hyperspatial/sfeos-tools/issues
|
33
|
+
Project-URL: Source, https://github.com/Healy-Hyperspatial/sfeos-tools
|
34
|
+
Classifier: Development Status :: 4 - Beta
|
35
|
+
Classifier: Intended Audience :: Developers
|
36
|
+
Classifier: Intended Audience :: Science/Research
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
38
|
+
Classifier: Programming Language :: Python :: 3.8
|
39
|
+
Classifier: Programming Language :: Python :: 3.9
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
43
|
+
Classifier: Topic :: Scientific/Engineering
|
44
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
45
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
46
|
+
Requires-Python: >=3.8
|
47
|
+
Description-Content-Type: text/markdown
|
48
|
+
License-File: LICENSE
|
49
|
+
Requires-Dist: click>=8.0.0
|
50
|
+
Provides-Extra: elasticsearch
|
51
|
+
Requires-Dist: stac-fastapi-elasticsearch; extra == "elasticsearch"
|
52
|
+
Provides-Extra: opensearch
|
53
|
+
Requires-Dist: stac-fastapi-opensearch; extra == "opensearch"
|
54
|
+
Provides-Extra: dev
|
55
|
+
Requires-Dist: stac-fastapi-elasticsearch; extra == "dev"
|
56
|
+
Requires-Dist: stac-fastapi-opensearch; extra == "dev"
|
57
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
58
|
+
Requires-Dist: pytest-cov>=2.0; extra == "dev"
|
59
|
+
Requires-Dist: black>=21.0; extra == "dev"
|
60
|
+
Requires-Dist: isort>=5.0; extra == "dev"
|
61
|
+
Requires-Dist: mypy>=0.900; extra == "dev"
|
62
|
+
Requires-Dist: flake8>=4.0.0; extra == "dev"
|
63
|
+
Dynamic: license-file
|
64
|
+
|
65
|
+
# SFEOS Tools
|
66
|
+
|
67
|
+
CLI tools for managing [stac-fastapi-elasticsearch-opensearch](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch) deployments.
|
68
|
+
|
69
|
+
## Table of Contents
|
70
|
+
|
71
|
+
- [Installation](#installation)
|
72
|
+
- [For Elasticsearch](#for-elasticsearch)
|
73
|
+
- [For OpenSearch](#for-opensearch)
|
74
|
+
- [For Development](#for-development-both-backends)
|
75
|
+
- [Usage](#usage)
|
76
|
+
- [Commands](#commands)
|
77
|
+
- [add-bbox-shape](#add-bbox-shape)
|
78
|
+
- [reindex](#reindex)
|
79
|
+
- [Development](#development)
|
80
|
+
- [License](#license)
|
81
|
+
|
82
|
+
## Installation
|
83
|
+
|
84
|
+
### For Elasticsearch
|
85
|
+
|
86
|
+
```bash
|
87
|
+
pip install sfeos-tools[elasticsearch]
|
88
|
+
```
|
89
|
+
|
90
|
+
Or for local development:
|
91
|
+
```bash
|
92
|
+
pip install -e sfeos_tools[elasticsearch]
|
93
|
+
```
|
94
|
+
|
95
|
+
### For OpenSearch
|
96
|
+
|
97
|
+
```bash
|
98
|
+
pip install sfeos-tools[opensearch]
|
99
|
+
```
|
100
|
+
|
101
|
+
Or for local development:
|
102
|
+
```bash
|
103
|
+
pip install -e sfeos_tools[opensearch]
|
104
|
+
```
|
105
|
+
|
106
|
+
### For Development (both backends)
|
107
|
+
|
108
|
+
```bash
|
109
|
+
pip install sfeos-tools[dev]
|
110
|
+
```
|
111
|
+
|
112
|
+
Or for local development:
|
113
|
+
```bash
|
114
|
+
pip install -e sfeos_tools[dev]
|
115
|
+
```
|
116
|
+
|
117
|
+
## Usage
|
118
|
+
|
119
|
+
After installation, the `sfeos-tools` command will be available:
|
120
|
+
|
121
|
+
```bash
|
122
|
+
# View available commands
|
123
|
+
sfeos-tools --help
|
124
|
+
|
125
|
+
# View version
|
126
|
+
sfeos-tools --version
|
127
|
+
```
|
128
|
+
|
129
|
+
## Commands
|
130
|
+
|
131
|
+
### add-bbox-shape
|
132
|
+
|
133
|
+
Adds a `bbox_shape` field to existing collections for spatial search support. This migration is required for collections created before spatial search was added. Collections created or updated after this feature will automatically have the `bbox_shape` field.
|
134
|
+
|
135
|
+
```bash
|
136
|
+
sfeos-tools add-bbox-shape --backend [elasticsearch|opensearch] [options]
|
137
|
+
```
|
138
|
+
|
139
|
+
Options:
|
140
|
+
- `--backend`: Database backend to use (required, choices: elasticsearch, opensearch)
|
141
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
142
|
+
- `--port`: Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)
|
143
|
+
- `--use-ssl/--no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
144
|
+
- `--user`: Database username (default: ES_USER env var)
|
145
|
+
- `--password`: Database password (default: ES_PASS env var)
|
146
|
+
|
147
|
+
### reindex
|
148
|
+
|
149
|
+
Reindexes all STAC indexes to the next version and updates aliases. This command performs the following actions:
|
150
|
+
- Creates/updates index templates
|
151
|
+
- Reindexes collections and item indexes to a new version
|
152
|
+
- Applies asset migration script for compatibility
|
153
|
+
- Switches aliases to the new indexes
|
154
|
+
|
155
|
+
```bash
|
156
|
+
sfeos-tools reindex --backend [elasticsearch|opensearch] [options]
|
157
|
+
```
|
158
|
+
|
159
|
+
Options:
|
160
|
+
- `--backend`: Database backend to use (required, choices: elasticsearch, opensearch)
|
161
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
162
|
+
- `--port`: Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)
|
163
|
+
- `--use-ssl/--no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
164
|
+
- `--user`: Database username (default: ES_USER env var)
|
165
|
+
- `--password`: Database password (default: ES_PASS env var)
|
166
|
+
- `--yes`: Skip confirmation prompt
|
167
|
+
|
168
|
+
Example:
|
169
|
+
```bash
|
170
|
+
# Reindex Elasticsearch with custom host and no SSL
|
171
|
+
sfeos-tools reindex --backend elasticsearch --host localhost --port 9200 --no-ssl
|
172
|
+
|
173
|
+
# Reindex OpenSearch with default settings
|
174
|
+
sfeos-tools reindex --backend opensearch
|
175
|
+
```
|
176
|
+
|
177
|
+
# Get help for a specific command
|
178
|
+
sfeos-tools add-bbox-shape --help
|
179
|
+
```
|
180
|
+
|
181
|
+
## Commands
|
182
|
+
|
183
|
+
### add-bbox-shape
|
184
|
+
|
185
|
+
Add `bbox_shape` field to existing collections for spatial search support.
|
186
|
+
|
187
|
+
**Basic usage:**
|
188
|
+
|
189
|
+
```bash
|
190
|
+
# Elasticsearch
|
191
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
192
|
+
|
193
|
+
# OpenSearch
|
194
|
+
sfeos-tools add-bbox-shape --backend opensearch
|
195
|
+
```
|
196
|
+
|
197
|
+
**Connection options:**
|
198
|
+
|
199
|
+
```bash
|
200
|
+
# Local Docker Compose (no SSL)
|
201
|
+
sfeos-tools add-bbox-shape --backend elasticsearch --no-ssl
|
202
|
+
|
203
|
+
# Remote server with SSL
|
204
|
+
sfeos-tools add-bbox-shape \
|
205
|
+
--backend elasticsearch \
|
206
|
+
--host db.example.com \
|
207
|
+
--port 9200 \
|
208
|
+
--user admin \
|
209
|
+
--password secret
|
210
|
+
|
211
|
+
# Using environment variables
|
212
|
+
ES_HOST=my-cluster.cloud.com ES_PORT=9243 ES_USER=elastic ES_PASS=changeme \
|
213
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
214
|
+
```
|
215
|
+
|
216
|
+
**Available options:**
|
217
|
+
|
218
|
+
- `--backend`: Database backend (elasticsearch or opensearch) - **required**
|
219
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
220
|
+
- `--port`: Database port (default: 9200 or ES_PORT env var)
|
221
|
+
- `--use-ssl / --no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
222
|
+
- `--user`: Database username (default: ES_USER env var)
|
223
|
+
- `--password`: Database password (default: ES_PASS env var)
|
224
|
+
|
225
|
+
## Development
|
226
|
+
|
227
|
+
To develop sfeos-tools locally:
|
228
|
+
|
229
|
+
```bash
|
230
|
+
# Install in editable mode with dev dependencies
|
231
|
+
pip install -e ./sfeos_tools[dev]
|
232
|
+
|
233
|
+
# Run the CLI
|
234
|
+
sfeos-tools --help
|
235
|
+
|
236
|
+
# Run tests
|
237
|
+
pytest
|
238
|
+
|
239
|
+
# Format code
|
240
|
+
pre-commit install
|
241
|
+
pre-commit run --all-files
|
242
|
+
```
|
243
|
+
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# SFEOS Tools
|
2
|
+
|
3
|
+
CLI tools for managing [stac-fastapi-elasticsearch-opensearch](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch) deployments.
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
- [Installation](#installation)
|
8
|
+
- [For Elasticsearch](#for-elasticsearch)
|
9
|
+
- [For OpenSearch](#for-opensearch)
|
10
|
+
- [For Development](#for-development-both-backends)
|
11
|
+
- [Usage](#usage)
|
12
|
+
- [Commands](#commands)
|
13
|
+
- [add-bbox-shape](#add-bbox-shape)
|
14
|
+
- [reindex](#reindex)
|
15
|
+
- [Development](#development)
|
16
|
+
- [License](#license)
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
### For Elasticsearch
|
21
|
+
|
22
|
+
```bash
|
23
|
+
pip install sfeos-tools[elasticsearch]
|
24
|
+
```
|
25
|
+
|
26
|
+
Or for local development:
|
27
|
+
```bash
|
28
|
+
pip install -e sfeos_tools[elasticsearch]
|
29
|
+
```
|
30
|
+
|
31
|
+
### For OpenSearch
|
32
|
+
|
33
|
+
```bash
|
34
|
+
pip install sfeos-tools[opensearch]
|
35
|
+
```
|
36
|
+
|
37
|
+
Or for local development:
|
38
|
+
```bash
|
39
|
+
pip install -e sfeos_tools[opensearch]
|
40
|
+
```
|
41
|
+
|
42
|
+
### For Development (both backends)
|
43
|
+
|
44
|
+
```bash
|
45
|
+
pip install sfeos-tools[dev]
|
46
|
+
```
|
47
|
+
|
48
|
+
Or for local development:
|
49
|
+
```bash
|
50
|
+
pip install -e sfeos_tools[dev]
|
51
|
+
```
|
52
|
+
|
53
|
+
## Usage
|
54
|
+
|
55
|
+
After installation, the `sfeos-tools` command will be available:
|
56
|
+
|
57
|
+
```bash
|
58
|
+
# View available commands
|
59
|
+
sfeos-tools --help
|
60
|
+
|
61
|
+
# View version
|
62
|
+
sfeos-tools --version
|
63
|
+
```
|
64
|
+
|
65
|
+
## Commands
|
66
|
+
|
67
|
+
### add-bbox-shape
|
68
|
+
|
69
|
+
Adds a `bbox_shape` field to existing collections for spatial search support. This migration is required for collections created before spatial search was added. Collections created or updated after this feature will automatically have the `bbox_shape` field.
|
70
|
+
|
71
|
+
```bash
|
72
|
+
sfeos-tools add-bbox-shape --backend [elasticsearch|opensearch] [options]
|
73
|
+
```
|
74
|
+
|
75
|
+
Options:
|
76
|
+
- `--backend`: Database backend to use (required, choices: elasticsearch, opensearch)
|
77
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
78
|
+
- `--port`: Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)
|
79
|
+
- `--use-ssl/--no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
80
|
+
- `--user`: Database username (default: ES_USER env var)
|
81
|
+
- `--password`: Database password (default: ES_PASS env var)
|
82
|
+
|
83
|
+
### reindex
|
84
|
+
|
85
|
+
Reindexes all STAC indexes to the next version and updates aliases. This command performs the following actions:
|
86
|
+
- Creates/updates index templates
|
87
|
+
- Reindexes collections and item indexes to a new version
|
88
|
+
- Applies asset migration script for compatibility
|
89
|
+
- Switches aliases to the new indexes
|
90
|
+
|
91
|
+
```bash
|
92
|
+
sfeos-tools reindex --backend [elasticsearch|opensearch] [options]
|
93
|
+
```
|
94
|
+
|
95
|
+
Options:
|
96
|
+
- `--backend`: Database backend to use (required, choices: elasticsearch, opensearch)
|
97
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
98
|
+
- `--port`: Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)
|
99
|
+
- `--use-ssl/--no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
100
|
+
- `--user`: Database username (default: ES_USER env var)
|
101
|
+
- `--password`: Database password (default: ES_PASS env var)
|
102
|
+
- `--yes`: Skip confirmation prompt
|
103
|
+
|
104
|
+
Example:
|
105
|
+
```bash
|
106
|
+
# Reindex Elasticsearch with custom host and no SSL
|
107
|
+
sfeos-tools reindex --backend elasticsearch --host localhost --port 9200 --no-ssl
|
108
|
+
|
109
|
+
# Reindex OpenSearch with default settings
|
110
|
+
sfeos-tools reindex --backend opensearch
|
111
|
+
```
|
112
|
+
|
113
|
+
# Get help for a specific command
|
114
|
+
sfeos-tools add-bbox-shape --help
|
115
|
+
```
|
116
|
+
|
117
|
+
## Commands
|
118
|
+
|
119
|
+
### add-bbox-shape
|
120
|
+
|
121
|
+
Add `bbox_shape` field to existing collections for spatial search support.
|
122
|
+
|
123
|
+
**Basic usage:**
|
124
|
+
|
125
|
+
```bash
|
126
|
+
# Elasticsearch
|
127
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
128
|
+
|
129
|
+
# OpenSearch
|
130
|
+
sfeos-tools add-bbox-shape --backend opensearch
|
131
|
+
```
|
132
|
+
|
133
|
+
**Connection options:**
|
134
|
+
|
135
|
+
```bash
|
136
|
+
# Local Docker Compose (no SSL)
|
137
|
+
sfeos-tools add-bbox-shape --backend elasticsearch --no-ssl
|
138
|
+
|
139
|
+
# Remote server with SSL
|
140
|
+
sfeos-tools add-bbox-shape \
|
141
|
+
--backend elasticsearch \
|
142
|
+
--host db.example.com \
|
143
|
+
--port 9200 \
|
144
|
+
--user admin \
|
145
|
+
--password secret
|
146
|
+
|
147
|
+
# Using environment variables
|
148
|
+
ES_HOST=my-cluster.cloud.com ES_PORT=9243 ES_USER=elastic ES_PASS=changeme \
|
149
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
150
|
+
```
|
151
|
+
|
152
|
+
**Available options:**
|
153
|
+
|
154
|
+
- `--backend`: Database backend (elasticsearch or opensearch) - **required**
|
155
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
156
|
+
- `--port`: Database port (default: 9200 or ES_PORT env var)
|
157
|
+
- `--use-ssl / --no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
158
|
+
- `--user`: Database username (default: ES_USER env var)
|
159
|
+
- `--password`: Database password (default: ES_PASS env var)
|
160
|
+
|
161
|
+
## Development
|
162
|
+
|
163
|
+
To develop sfeos-tools locally:
|
164
|
+
|
165
|
+
```bash
|
166
|
+
# Install in editable mode with dev dependencies
|
167
|
+
pip install -e ./sfeos_tools[dev]
|
168
|
+
|
169
|
+
# Run the CLI
|
170
|
+
sfeos-tools --help
|
171
|
+
|
172
|
+
# Run tests
|
173
|
+
pytest
|
174
|
+
|
175
|
+
# Format code
|
176
|
+
pre-commit install
|
177
|
+
pre-commit run --all-files
|
178
|
+
```
|
179
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "sfeos-tools"
|
7
|
+
version = "0.1.0"
|
8
|
+
description = "CLI tools for managing stac-fastapi-elasticsearch-opensearch deployments"
|
9
|
+
readme = "README.md"
|
10
|
+
authors = [
|
11
|
+
{name = "Jonathan Healy", email = "jon@healy-hypersaptial.dev"},
|
12
|
+
{name = "CloudFerro S.A."}
|
13
|
+
]
|
14
|
+
license = {file = "LICENSE"}
|
15
|
+
maintainers = [
|
16
|
+
{name = "Jonathan Healy", email = "jon@healy-hypersaptial.dev"}
|
17
|
+
]
|
18
|
+
requires-python = ">=3.8"
|
19
|
+
classifiers = [
|
20
|
+
"Development Status :: 4 - Beta",
|
21
|
+
"Intended Audience :: Developers",
|
22
|
+
"Intended Audience :: Science/Research",
|
23
|
+
"License :: OSI Approved :: MIT License",
|
24
|
+
"Programming Language :: Python :: 3.8",
|
25
|
+
"Programming Language :: Python :: 3.9",
|
26
|
+
"Programming Language :: Python :: 3.10",
|
27
|
+
"Programming Language :: Python :: 3.11",
|
28
|
+
"Programming Language :: Python :: 3.12",
|
29
|
+
"Topic :: Scientific/Engineering",
|
30
|
+
"Topic :: Scientific/Engineering :: GIS",
|
31
|
+
"Topic :: Software Development :: Libraries :: Python Modules"
|
32
|
+
]
|
33
|
+
dependencies = [
|
34
|
+
"click>=8.0.0",
|
35
|
+
]
|
36
|
+
|
37
|
+
[project.urls]
|
38
|
+
Homepage = "https://github.com/Healy-Hyperspatial/sfeos-tools"
|
39
|
+
Documentation = "https://github.com/Healy-Hyperspatial/sfeos-tools#readme"
|
40
|
+
Issues = "https://github.com/Healy-Hyperspatial/sfeos-tools/issues"
|
41
|
+
Source = "https://github.com/Healy-Hyperspatial/sfeos-tools"
|
42
|
+
|
43
|
+
[project.optional-dependencies]
|
44
|
+
elasticsearch = [
|
45
|
+
"stac-fastapi-elasticsearch",
|
46
|
+
]
|
47
|
+
opensearch = [
|
48
|
+
"stac-fastapi-opensearch",
|
49
|
+
]
|
50
|
+
dev = [
|
51
|
+
"stac-fastapi-elasticsearch",
|
52
|
+
"stac-fastapi-opensearch",
|
53
|
+
# Development tools
|
54
|
+
"pytest>=6.0",
|
55
|
+
"pytest-cov>=2.0",
|
56
|
+
"black>=21.0",
|
57
|
+
"isort>=5.0",
|
58
|
+
"mypy>=0.900",
|
59
|
+
"flake8>=4.0.0",
|
60
|
+
]
|
61
|
+
|
62
|
+
[project.scripts]
|
63
|
+
sfeos-tools = "sfeos_tools.cli:cli"
|
64
|
+
|
65
|
+
[tool.black]
|
66
|
+
line-length = 88
|
67
|
+
target-version = ["py38"]
|
68
|
+
include = '\.pyi?$'
|
69
|
+
|
70
|
+
[tool.isort]
|
71
|
+
profile = "black"
|
72
|
+
multi_line_output = 3
|
73
|
+
include_trailing_comma = true
|
74
|
+
force_grid_wrap = false
|
75
|
+
use_parentheses = true
|
76
|
+
ensure_newline_before_comments = true
|
77
|
+
line_length = 88
|
78
|
+
|
79
|
+
[tool.pytest.ini_options]
|
80
|
+
testpaths = ["tests"]
|
81
|
+
python_files = "test_*.py"
|
82
|
+
addopts = "-v --cov=sfeos_tool --cov-report=term-missing"
|
83
|
+
|
84
|
+
[tool.coverage.report]
|
85
|
+
exclude_lines = [
|
86
|
+
"pragma: no cover",
|
87
|
+
"def __repr__",
|
88
|
+
"raise NotImplementedError",
|
89
|
+
"if __name__ == .__main__.:",
|
90
|
+
"pass",
|
91
|
+
"raise ImportError",
|
92
|
+
]
|
@@ -0,0 +1,336 @@
|
|
1
|
+
"""SFEOS CLI Tools - Utilities for managing stac-fastapi-elasticsearch-opensearch deployments.
|
2
|
+
|
3
|
+
This tool provides various utilities for managing and maintaining SFEOS deployments,
|
4
|
+
including database migrations, maintenance tasks, and more.
|
5
|
+
|
6
|
+
Usage:
|
7
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
8
|
+
sfeos-tools add-bbox-shape --backend opensearch
|
9
|
+
"""
|
10
|
+
|
11
|
+
import asyncio
|
12
|
+
import logging
|
13
|
+
import sys
|
14
|
+
|
15
|
+
import click
|
16
|
+
from stac_fastapi.sfeos_helpers.database import add_bbox_shape_to_collection
|
17
|
+
from stac_fastapi.sfeos_helpers.mappings import COLLECTIONS_INDEX
|
18
|
+
|
19
|
+
from .reindex import run as unified_reindex_run
|
20
|
+
|
21
|
+
logging.basicConfig(level=logging.INFO)
|
22
|
+
logger = logging.getLogger(__name__)
|
23
|
+
|
24
|
+
|
25
|
+
async def process_collection_bbox_shape(client, collection_doc, backend):
|
26
|
+
"""Process a single collection document to add bbox_shape field.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
client: Elasticsearch/OpenSearch client
|
30
|
+
collection_doc: Collection document from database
|
31
|
+
backend: Backend type ('elasticsearch' or 'opensearch')
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
bool: True if collection was updated, False if no update was needed
|
35
|
+
"""
|
36
|
+
collection = collection_doc["_source"]
|
37
|
+
collection_id = collection.get("id", collection_doc["_id"])
|
38
|
+
|
39
|
+
# Use the shared function to add bbox_shape
|
40
|
+
was_added = add_bbox_shape_to_collection(collection)
|
41
|
+
|
42
|
+
if not was_added:
|
43
|
+
return False
|
44
|
+
|
45
|
+
# Update the collection in the database
|
46
|
+
if backend == "elasticsearch":
|
47
|
+
await client.index(
|
48
|
+
index=COLLECTIONS_INDEX,
|
49
|
+
id=collection_id,
|
50
|
+
document=collection,
|
51
|
+
refresh=True,
|
52
|
+
)
|
53
|
+
else: # opensearch
|
54
|
+
await client.index(
|
55
|
+
index=COLLECTIONS_INDEX,
|
56
|
+
id=collection_id,
|
57
|
+
body=collection,
|
58
|
+
refresh=True,
|
59
|
+
)
|
60
|
+
|
61
|
+
logger.info(f"Collection '{collection_id}': Added bbox_shape field")
|
62
|
+
return True
|
63
|
+
|
64
|
+
|
65
|
+
async def run_add_bbox_shape(backend):
|
66
|
+
"""Add bbox_shape field to all existing collections.
|
67
|
+
|
68
|
+
Args:
|
69
|
+
backend: Backend type ('elasticsearch' or 'opensearch')
|
70
|
+
"""
|
71
|
+
import os
|
72
|
+
|
73
|
+
logger.info(
|
74
|
+
f"Starting migration: Adding bbox_shape to existing collections ({backend})"
|
75
|
+
)
|
76
|
+
|
77
|
+
# Log connection info (showing what will be used by the client)
|
78
|
+
es_host = os.getenv("ES_HOST", "localhost")
|
79
|
+
es_port = os.getenv(
|
80
|
+
"ES_PORT", "9200"
|
81
|
+
) # Both backends default to 9200 in their config
|
82
|
+
es_use_ssl = os.getenv("ES_USE_SSL", "true")
|
83
|
+
logger.info(f"Connecting to {backend} at {es_host}:{es_port} (SSL: {es_use_ssl})")
|
84
|
+
|
85
|
+
# Create client based on backend
|
86
|
+
if backend == "elasticsearch":
|
87
|
+
from stac_fastapi.elasticsearch.config import AsyncElasticsearchSettings
|
88
|
+
|
89
|
+
settings = AsyncElasticsearchSettings()
|
90
|
+
else: # opensearch
|
91
|
+
from stac_fastapi.opensearch.config import AsyncOpensearchSettings
|
92
|
+
|
93
|
+
settings = AsyncOpensearchSettings()
|
94
|
+
|
95
|
+
client = settings.create_client
|
96
|
+
|
97
|
+
try:
|
98
|
+
# Get all collections
|
99
|
+
response = await client.search(
|
100
|
+
index=COLLECTIONS_INDEX,
|
101
|
+
body={
|
102
|
+
"query": {"match_all": {}},
|
103
|
+
"size": 10000,
|
104
|
+
}, # Adjust size if you have more collections
|
105
|
+
)
|
106
|
+
|
107
|
+
total_collections = response["hits"]["total"]["value"]
|
108
|
+
logger.info(f"Found {total_collections} collections to process")
|
109
|
+
|
110
|
+
updated_count = 0
|
111
|
+
skipped_count = 0
|
112
|
+
|
113
|
+
for hit in response["hits"]["hits"]:
|
114
|
+
was_updated = await process_collection_bbox_shape(client, hit, backend)
|
115
|
+
if was_updated:
|
116
|
+
updated_count += 1
|
117
|
+
else:
|
118
|
+
skipped_count += 1
|
119
|
+
|
120
|
+
logger.info(
|
121
|
+
f"Migration complete: {updated_count} collections updated, {skipped_count} skipped"
|
122
|
+
)
|
123
|
+
|
124
|
+
except Exception as e:
|
125
|
+
logger.error(f"Migration failed with error: {e}")
|
126
|
+
raise
|
127
|
+
finally:
|
128
|
+
await client.close()
|
129
|
+
|
130
|
+
|
131
|
+
@click.group()
|
132
|
+
@click.version_option(version="0.1.0", prog_name="sfeos-tools")
|
133
|
+
def cli():
|
134
|
+
"""SFEOS Tools - Utilities for managing stac-fastapi-elasticsearch-opensearch deployments."""
|
135
|
+
pass
|
136
|
+
|
137
|
+
|
138
|
+
@cli.command("add-bbox-shape")
|
139
|
+
@click.option(
|
140
|
+
"--backend",
|
141
|
+
type=click.Choice(["elasticsearch", "opensearch"], case_sensitive=False),
|
142
|
+
required=True,
|
143
|
+
help="Database backend to use",
|
144
|
+
)
|
145
|
+
@click.option(
|
146
|
+
"--host",
|
147
|
+
type=str,
|
148
|
+
default=None,
|
149
|
+
help="Database host (default: localhost or ES_HOST env var)",
|
150
|
+
)
|
151
|
+
@click.option(
|
152
|
+
"--port",
|
153
|
+
type=int,
|
154
|
+
default=None,
|
155
|
+
help="Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)",
|
156
|
+
)
|
157
|
+
@click.option(
|
158
|
+
"--use-ssl/--no-ssl",
|
159
|
+
default=None,
|
160
|
+
help="Use SSL connection (default: true or ES_USE_SSL env var)",
|
161
|
+
)
|
162
|
+
@click.option(
|
163
|
+
"--user",
|
164
|
+
type=str,
|
165
|
+
default=None,
|
166
|
+
help="Database username (default: ES_USER env var)",
|
167
|
+
)
|
168
|
+
@click.option(
|
169
|
+
"--password",
|
170
|
+
type=str,
|
171
|
+
default=None,
|
172
|
+
help="Database password (default: ES_PASS env var)",
|
173
|
+
)
|
174
|
+
def add_bbox_shape(backend, host, port, use_ssl, user, password):
|
175
|
+
"""Add bbox_shape field to existing collections for spatial search support.
|
176
|
+
|
177
|
+
This migration is required for collections created before spatial search
|
178
|
+
was added. Collections created or updated after this feature will
|
179
|
+
automatically have the bbox_shape field.
|
180
|
+
|
181
|
+
Examples:
|
182
|
+
sfeos_tools.py add-bbox-shape --backend elasticsearch
|
183
|
+
sfeos_tools.py add-bbox-shape --backend opensearch --host db.example.com --port 9200
|
184
|
+
sfeos_tools.py add-bbox-shape --backend elasticsearch --no-ssl --host localhost
|
185
|
+
"""
|
186
|
+
import os
|
187
|
+
|
188
|
+
# Set environment variables from CLI options if provided
|
189
|
+
if host:
|
190
|
+
os.environ["ES_HOST"] = host
|
191
|
+
if port:
|
192
|
+
os.environ["ES_PORT"] = str(port)
|
193
|
+
if use_ssl is not None:
|
194
|
+
os.environ["ES_USE_SSL"] = "true" if use_ssl else "false"
|
195
|
+
if user:
|
196
|
+
os.environ["ES_USER"] = user
|
197
|
+
if password:
|
198
|
+
os.environ["ES_PASS"] = password
|
199
|
+
|
200
|
+
try:
|
201
|
+
asyncio.run(run_add_bbox_shape(backend.lower()))
|
202
|
+
click.echo(click.style("✓ Migration completed successfully", fg="green"))
|
203
|
+
except KeyboardInterrupt:
|
204
|
+
click.echo(click.style("\n✗ Migration interrupted by user", fg="yellow"))
|
205
|
+
sys.exit(1)
|
206
|
+
except Exception as e:
|
207
|
+
error_msg = str(e)
|
208
|
+
click.echo(click.style(f"✗ Migration failed: {error_msg}", fg="red"))
|
209
|
+
|
210
|
+
# Provide helpful hints for common errors
|
211
|
+
if "TLS" in error_msg or "SSL" in error_msg:
|
212
|
+
click.echo(
|
213
|
+
click.style(
|
214
|
+
"\n💡 Hint: If you're connecting to a local Docker Compose instance, "
|
215
|
+
"try adding --no-ssl flag",
|
216
|
+
fg="yellow",
|
217
|
+
)
|
218
|
+
)
|
219
|
+
elif "Connection refused" in error_msg:
|
220
|
+
click.echo(
|
221
|
+
click.style(
|
222
|
+
"\n💡 Hint: Make sure your database is running and accessible at the specified host:port",
|
223
|
+
fg="yellow",
|
224
|
+
)
|
225
|
+
)
|
226
|
+
sys.exit(1)
|
227
|
+
|
228
|
+
|
229
|
+
@cli.command("reindex")
|
230
|
+
@click.option(
|
231
|
+
"--backend",
|
232
|
+
type=click.Choice(["elasticsearch", "opensearch"], case_sensitive=False),
|
233
|
+
required=True,
|
234
|
+
help="Database backend to use",
|
235
|
+
)
|
236
|
+
@click.option(
|
237
|
+
"--host",
|
238
|
+
type=str,
|
239
|
+
default=None,
|
240
|
+
help="Database host (default: localhost or ES_HOST env var)",
|
241
|
+
)
|
242
|
+
@click.option(
|
243
|
+
"--port",
|
244
|
+
type=int,
|
245
|
+
default=None,
|
246
|
+
help="Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)",
|
247
|
+
)
|
248
|
+
@click.option(
|
249
|
+
"--use-ssl/--no-ssl",
|
250
|
+
default=None,
|
251
|
+
help="Use SSL connection (default: true or ES_USE_SSL env var)",
|
252
|
+
)
|
253
|
+
@click.option(
|
254
|
+
"--user",
|
255
|
+
type=str,
|
256
|
+
default=None,
|
257
|
+
help="Database username (default: ES_USER env var)",
|
258
|
+
)
|
259
|
+
@click.option(
|
260
|
+
"--password",
|
261
|
+
type=str,
|
262
|
+
default=None,
|
263
|
+
help="Database password (default: ES_PASS env var)",
|
264
|
+
)
|
265
|
+
@click.option(
|
266
|
+
"--yes",
|
267
|
+
is_flag=True,
|
268
|
+
help="Skip confirmation prompt",
|
269
|
+
)
|
270
|
+
def reindex(backend, host, port, use_ssl, user, password, yes):
|
271
|
+
"""Reindex all STAC indexes to the next version and update aliases.
|
272
|
+
|
273
|
+
For Elasticsearch, this runs a migration that:
|
274
|
+
- Creates/updates index templates
|
275
|
+
- Reindexes collections and item indexes to a new version
|
276
|
+
- Applies asset migration script for compatibility
|
277
|
+
- Switches aliases to the new indexes
|
278
|
+
"""
|
279
|
+
import os
|
280
|
+
|
281
|
+
backend = backend.lower()
|
282
|
+
|
283
|
+
if not yes:
|
284
|
+
proceed = click.confirm(
|
285
|
+
"This will reindex all collections and item indexes and update aliases. Proceed?",
|
286
|
+
default=False,
|
287
|
+
)
|
288
|
+
if not proceed:
|
289
|
+
click.echo(click.style("Aborted", fg="yellow"))
|
290
|
+
return
|
291
|
+
|
292
|
+
# Set environment variables from CLI options if provided
|
293
|
+
if host:
|
294
|
+
os.environ["ES_HOST"] = host
|
295
|
+
if port:
|
296
|
+
os.environ["ES_PORT"] = str(port)
|
297
|
+
if use_ssl is not None:
|
298
|
+
os.environ["ES_USE_SSL"] = "true" if use_ssl else "false"
|
299
|
+
if user:
|
300
|
+
os.environ["ES_USER"] = user
|
301
|
+
if password:
|
302
|
+
os.environ["ES_PASS"] = password
|
303
|
+
|
304
|
+
try:
|
305
|
+
asyncio.run(unified_reindex_run(backend))
|
306
|
+
click.echo(
|
307
|
+
click.style(
|
308
|
+
f"✓ Reindex ({backend.title()}) completed successfully", fg="green"
|
309
|
+
)
|
310
|
+
)
|
311
|
+
except KeyboardInterrupt:
|
312
|
+
click.echo(click.style("\n✗ Reindex interrupted by user", fg="yellow"))
|
313
|
+
sys.exit(1)
|
314
|
+
except Exception as e:
|
315
|
+
error_msg = str(e)
|
316
|
+
click.echo(click.style(f"✗ Reindex failed: {error_msg}", fg="red"))
|
317
|
+
# Provide helpful hints for common errors
|
318
|
+
if "TLS" in error_msg or "SSL" in error_msg:
|
319
|
+
click.echo(
|
320
|
+
click.style(
|
321
|
+
"\n💡 Hint: If you're connecting to a local Docker Compose instance, try adding --no-ssl flag",
|
322
|
+
fg="yellow",
|
323
|
+
)
|
324
|
+
)
|
325
|
+
elif "Connection refused" in error_msg:
|
326
|
+
click.echo(
|
327
|
+
click.style(
|
328
|
+
"\n💡 Hint: Make sure your database is running and accessible at the specified host:port",
|
329
|
+
fg="yellow",
|
330
|
+
)
|
331
|
+
)
|
332
|
+
sys.exit(1)
|
333
|
+
|
334
|
+
|
335
|
+
if __name__ == "__main__":
|
336
|
+
cli()
|
@@ -0,0 +1,122 @@
|
|
1
|
+
"""Reindex ES/OS database for mapping update."""
|
2
|
+
|
3
|
+
import asyncio
|
4
|
+
import time
|
5
|
+
from typing import Any, Dict
|
6
|
+
|
7
|
+
from stac_fastapi.sfeos_helpers.mappings import COLLECTIONS_INDEX, ITEMS_INDEX_PREFIX
|
8
|
+
|
9
|
+
|
10
|
+
async def _reindex_single_index(
|
11
|
+
client, index: str, new_index: str, aliases: Dict[str, Any]
|
12
|
+
):
|
13
|
+
"""Reindex a single index to a new version and switch aliases."""
|
14
|
+
print(f"reindexing {index} to {new_index}")
|
15
|
+
|
16
|
+
await client.options(ignore_status=400).indices.create(index=new_index)
|
17
|
+
|
18
|
+
# Asset migration script for data compatibility
|
19
|
+
script = {
|
20
|
+
"source": (
|
21
|
+
"if (ctx._source.containsKey('assets')){List l = new ArrayList();"
|
22
|
+
"for (key in ctx._source.assets.keySet()) {def item = ctx._source.assets[key];"
|
23
|
+
" item['es_key'] = key; l.add(item)}ctx._source.assets=l} "
|
24
|
+
"if (ctx._source.containsKey('item_assets')){ List a = new ArrayList();"
|
25
|
+
" for (key in ctx._source.item_assets.keySet()) {def item = ctx._source.item_assets[key];"
|
26
|
+
" item['es_key'] = key; a.add(item)}ctx._source.item_assets=a}"
|
27
|
+
),
|
28
|
+
"lang": "painless",
|
29
|
+
}
|
30
|
+
|
31
|
+
reindex_resp = await client.reindex(
|
32
|
+
dest={"index": new_index},
|
33
|
+
source={"index": [index]},
|
34
|
+
wait_for_completion=False,
|
35
|
+
script=script,
|
36
|
+
)
|
37
|
+
|
38
|
+
task_id = reindex_resp["task"]
|
39
|
+
|
40
|
+
reindex_complete = False
|
41
|
+
while not reindex_complete:
|
42
|
+
task_resp = await client.tasks.get(task_id=task_id)
|
43
|
+
|
44
|
+
if "completed" in task_resp and task_resp["completed"]:
|
45
|
+
reindex_complete = True
|
46
|
+
elif "error" in task_resp:
|
47
|
+
reindex_complete = True
|
48
|
+
print(f"Reindex failed for {index} with error: {task_resp['error']}")
|
49
|
+
else:
|
50
|
+
time.sleep(60)
|
51
|
+
|
52
|
+
actions = []
|
53
|
+
for alias in aliases["aliases"]:
|
54
|
+
actions.extend(
|
55
|
+
[
|
56
|
+
{"add": {"index": new_index, "alias": alias}},
|
57
|
+
{"remove": {"index": index, "alias": alias}},
|
58
|
+
]
|
59
|
+
)
|
60
|
+
|
61
|
+
if actions:
|
62
|
+
await client.indices.update_aliases(actions=actions)
|
63
|
+
|
64
|
+
|
65
|
+
async def run(backend: str = "elasticsearch"):
|
66
|
+
"""Reindex all STAC indexes for mapping update for the given backend.
|
67
|
+
|
68
|
+
backend: 'elasticsearch' or 'opensearch'
|
69
|
+
"""
|
70
|
+
backend = backend.lower()
|
71
|
+
|
72
|
+
# Lazy imports so the package dependencies remain optional per backend
|
73
|
+
if backend == "elasticsearch":
|
74
|
+
from stac_fastapi.elasticsearch.config import AsyncElasticsearchSettings
|
75
|
+
from stac_fastapi.elasticsearch.database_logic import create_index_templates
|
76
|
+
|
77
|
+
settings = AsyncElasticsearchSettings()
|
78
|
+
elif backend == "opensearch":
|
79
|
+
from stac_fastapi.opensearch.config import AsyncOpensearchSettings
|
80
|
+
from stac_fastapi.opensearch.database_logic import create_index_templates
|
81
|
+
|
82
|
+
settings = AsyncOpensearchSettings()
|
83
|
+
else:
|
84
|
+
raise ValueError(f"Unsupported backend: {backend}")
|
85
|
+
|
86
|
+
client = settings.create_client
|
87
|
+
|
88
|
+
try:
|
89
|
+
# Ensure latest templates are applied
|
90
|
+
await create_index_templates()
|
91
|
+
|
92
|
+
# Collections index
|
93
|
+
collection_response = await client.indices.get_alias(name=COLLECTIONS_INDEX)
|
94
|
+
collections = await client.search(index=COLLECTIONS_INDEX)
|
95
|
+
|
96
|
+
collection_index, collection_aliases = next(iter(collection_response.items()))
|
97
|
+
collection_index_name, version = collection_index.rsplit("-", 1)
|
98
|
+
new_collection_index = (
|
99
|
+
f"{collection_index_name}-{str(int(version) + 1).zfill(6)}"
|
100
|
+
)
|
101
|
+
|
102
|
+
await _reindex_single_index(
|
103
|
+
client, collection_index, new_collection_index, collection_aliases
|
104
|
+
)
|
105
|
+
|
106
|
+
# Items per collection
|
107
|
+
for collection in collections["hits"]["hits"]:
|
108
|
+
item_indexes = await client.indices.get_alias(
|
109
|
+
name=f"{ITEMS_INDEX_PREFIX}{collection['_id']}*"
|
110
|
+
)
|
111
|
+
|
112
|
+
for item_index, aliases in item_indexes.items():
|
113
|
+
item_index_name, version = item_index.rsplit("-", 1)
|
114
|
+
new_item_index = f"{item_index_name}-{str(int(version) + 1).zfill(6)}"
|
115
|
+
|
116
|
+
await _reindex_single_index(client, item_index, new_item_index, aliases)
|
117
|
+
finally:
|
118
|
+
await client.close()
|
119
|
+
|
120
|
+
|
121
|
+
if __name__ == "__main__":
|
122
|
+
asyncio.run(run("elasticsearch"))
|
@@ -0,0 +1,243 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: sfeos-tools
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: CLI tools for managing stac-fastapi-elasticsearch-opensearch deployments
|
5
|
+
Author: CloudFerro S.A.
|
6
|
+
Author-email: Jonathan Healy <jon@healy-hypersaptial.dev>
|
7
|
+
Maintainer-email: Jonathan Healy <jon@healy-hypersaptial.dev>
|
8
|
+
License: MIT License
|
9
|
+
|
10
|
+
Copyright (c) 2025 Healy Hyperspatial, Jonathan Healy and CloudFerro S.A.
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
14
|
+
in the Software without restriction, including without limitation the rights
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
17
|
+
furnished to do so, subject to the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
20
|
+
copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28
|
+
SOFTWARE.
|
29
|
+
|
30
|
+
Project-URL: Homepage, https://github.com/Healy-Hyperspatial/sfeos-tools
|
31
|
+
Project-URL: Documentation, https://github.com/Healy-Hyperspatial/sfeos-tools#readme
|
32
|
+
Project-URL: Issues, https://github.com/Healy-Hyperspatial/sfeos-tools/issues
|
33
|
+
Project-URL: Source, https://github.com/Healy-Hyperspatial/sfeos-tools
|
34
|
+
Classifier: Development Status :: 4 - Beta
|
35
|
+
Classifier: Intended Audience :: Developers
|
36
|
+
Classifier: Intended Audience :: Science/Research
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
38
|
+
Classifier: Programming Language :: Python :: 3.8
|
39
|
+
Classifier: Programming Language :: Python :: 3.9
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
43
|
+
Classifier: Topic :: Scientific/Engineering
|
44
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
45
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
46
|
+
Requires-Python: >=3.8
|
47
|
+
Description-Content-Type: text/markdown
|
48
|
+
License-File: LICENSE
|
49
|
+
Requires-Dist: click>=8.0.0
|
50
|
+
Provides-Extra: elasticsearch
|
51
|
+
Requires-Dist: stac-fastapi-elasticsearch; extra == "elasticsearch"
|
52
|
+
Provides-Extra: opensearch
|
53
|
+
Requires-Dist: stac-fastapi-opensearch; extra == "opensearch"
|
54
|
+
Provides-Extra: dev
|
55
|
+
Requires-Dist: stac-fastapi-elasticsearch; extra == "dev"
|
56
|
+
Requires-Dist: stac-fastapi-opensearch; extra == "dev"
|
57
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
58
|
+
Requires-Dist: pytest-cov>=2.0; extra == "dev"
|
59
|
+
Requires-Dist: black>=21.0; extra == "dev"
|
60
|
+
Requires-Dist: isort>=5.0; extra == "dev"
|
61
|
+
Requires-Dist: mypy>=0.900; extra == "dev"
|
62
|
+
Requires-Dist: flake8>=4.0.0; extra == "dev"
|
63
|
+
Dynamic: license-file
|
64
|
+
|
65
|
+
# SFEOS Tools
|
66
|
+
|
67
|
+
CLI tools for managing [stac-fastapi-elasticsearch-opensearch](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch) deployments.
|
68
|
+
|
69
|
+
## Table of Contents
|
70
|
+
|
71
|
+
- [Installation](#installation)
|
72
|
+
- [For Elasticsearch](#for-elasticsearch)
|
73
|
+
- [For OpenSearch](#for-opensearch)
|
74
|
+
- [For Development](#for-development-both-backends)
|
75
|
+
- [Usage](#usage)
|
76
|
+
- [Commands](#commands)
|
77
|
+
- [add-bbox-shape](#add-bbox-shape)
|
78
|
+
- [reindex](#reindex)
|
79
|
+
- [Development](#development)
|
80
|
+
- [License](#license)
|
81
|
+
|
82
|
+
## Installation
|
83
|
+
|
84
|
+
### For Elasticsearch
|
85
|
+
|
86
|
+
```bash
|
87
|
+
pip install sfeos-tools[elasticsearch]
|
88
|
+
```
|
89
|
+
|
90
|
+
Or for local development:
|
91
|
+
```bash
|
92
|
+
pip install -e sfeos_tools[elasticsearch]
|
93
|
+
```
|
94
|
+
|
95
|
+
### For OpenSearch
|
96
|
+
|
97
|
+
```bash
|
98
|
+
pip install sfeos-tools[opensearch]
|
99
|
+
```
|
100
|
+
|
101
|
+
Or for local development:
|
102
|
+
```bash
|
103
|
+
pip install -e sfeos_tools[opensearch]
|
104
|
+
```
|
105
|
+
|
106
|
+
### For Development (both backends)
|
107
|
+
|
108
|
+
```bash
|
109
|
+
pip install sfeos-tools[dev]
|
110
|
+
```
|
111
|
+
|
112
|
+
Or for local development:
|
113
|
+
```bash
|
114
|
+
pip install -e sfeos_tools[dev]
|
115
|
+
```
|
116
|
+
|
117
|
+
## Usage
|
118
|
+
|
119
|
+
After installation, the `sfeos-tools` command will be available:
|
120
|
+
|
121
|
+
```bash
|
122
|
+
# View available commands
|
123
|
+
sfeos-tools --help
|
124
|
+
|
125
|
+
# View version
|
126
|
+
sfeos-tools --version
|
127
|
+
```
|
128
|
+
|
129
|
+
## Commands
|
130
|
+
|
131
|
+
### add-bbox-shape
|
132
|
+
|
133
|
+
Adds a `bbox_shape` field to existing collections for spatial search support. This migration is required for collections created before spatial search was added. Collections created or updated after this feature will automatically have the `bbox_shape` field.
|
134
|
+
|
135
|
+
```bash
|
136
|
+
sfeos-tools add-bbox-shape --backend [elasticsearch|opensearch] [options]
|
137
|
+
```
|
138
|
+
|
139
|
+
Options:
|
140
|
+
- `--backend`: Database backend to use (required, choices: elasticsearch, opensearch)
|
141
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
142
|
+
- `--port`: Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)
|
143
|
+
- `--use-ssl/--no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
144
|
+
- `--user`: Database username (default: ES_USER env var)
|
145
|
+
- `--password`: Database password (default: ES_PASS env var)
|
146
|
+
|
147
|
+
### reindex
|
148
|
+
|
149
|
+
Reindexes all STAC indexes to the next version and updates aliases. This command performs the following actions:
|
150
|
+
- Creates/updates index templates
|
151
|
+
- Reindexes collections and item indexes to a new version
|
152
|
+
- Applies asset migration script for compatibility
|
153
|
+
- Switches aliases to the new indexes
|
154
|
+
|
155
|
+
```bash
|
156
|
+
sfeos-tools reindex --backend [elasticsearch|opensearch] [options]
|
157
|
+
```
|
158
|
+
|
159
|
+
Options:
|
160
|
+
- `--backend`: Database backend to use (required, choices: elasticsearch, opensearch)
|
161
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
162
|
+
- `--port`: Database port (default: 9200 for ES, 9202 for OS, or ES_PORT env var)
|
163
|
+
- `--use-ssl/--no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
164
|
+
- `--user`: Database username (default: ES_USER env var)
|
165
|
+
- `--password`: Database password (default: ES_PASS env var)
|
166
|
+
- `--yes`: Skip confirmation prompt
|
167
|
+
|
168
|
+
Example:
|
169
|
+
```bash
|
170
|
+
# Reindex Elasticsearch with custom host and no SSL
|
171
|
+
sfeos-tools reindex --backend elasticsearch --host localhost --port 9200 --no-ssl
|
172
|
+
|
173
|
+
# Reindex OpenSearch with default settings
|
174
|
+
sfeos-tools reindex --backend opensearch
|
175
|
+
```
|
176
|
+
|
177
|
+
# Get help for a specific command
|
178
|
+
sfeos-tools add-bbox-shape --help
|
179
|
+
```
|
180
|
+
|
181
|
+
## Commands
|
182
|
+
|
183
|
+
### add-bbox-shape
|
184
|
+
|
185
|
+
Add `bbox_shape` field to existing collections for spatial search support.
|
186
|
+
|
187
|
+
**Basic usage:**
|
188
|
+
|
189
|
+
```bash
|
190
|
+
# Elasticsearch
|
191
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
192
|
+
|
193
|
+
# OpenSearch
|
194
|
+
sfeos-tools add-bbox-shape --backend opensearch
|
195
|
+
```
|
196
|
+
|
197
|
+
**Connection options:**
|
198
|
+
|
199
|
+
```bash
|
200
|
+
# Local Docker Compose (no SSL)
|
201
|
+
sfeos-tools add-bbox-shape --backend elasticsearch --no-ssl
|
202
|
+
|
203
|
+
# Remote server with SSL
|
204
|
+
sfeos-tools add-bbox-shape \
|
205
|
+
--backend elasticsearch \
|
206
|
+
--host db.example.com \
|
207
|
+
--port 9200 \
|
208
|
+
--user admin \
|
209
|
+
--password secret
|
210
|
+
|
211
|
+
# Using environment variables
|
212
|
+
ES_HOST=my-cluster.cloud.com ES_PORT=9243 ES_USER=elastic ES_PASS=changeme \
|
213
|
+
sfeos-tools add-bbox-shape --backend elasticsearch
|
214
|
+
```
|
215
|
+
|
216
|
+
**Available options:**
|
217
|
+
|
218
|
+
- `--backend`: Database backend (elasticsearch or opensearch) - **required**
|
219
|
+
- `--host`: Database host (default: localhost or ES_HOST env var)
|
220
|
+
- `--port`: Database port (default: 9200 or ES_PORT env var)
|
221
|
+
- `--use-ssl / --no-ssl`: Use SSL connection (default: true or ES_USE_SSL env var)
|
222
|
+
- `--user`: Database username (default: ES_USER env var)
|
223
|
+
- `--password`: Database password (default: ES_PASS env var)
|
224
|
+
|
225
|
+
## Development
|
226
|
+
|
227
|
+
To develop sfeos-tools locally:
|
228
|
+
|
229
|
+
```bash
|
230
|
+
# Install in editable mode with dev dependencies
|
231
|
+
pip install -e ./sfeos_tools[dev]
|
232
|
+
|
233
|
+
# Run the CLI
|
234
|
+
sfeos-tools --help
|
235
|
+
|
236
|
+
# Run tests
|
237
|
+
pytest
|
238
|
+
|
239
|
+
# Format code
|
240
|
+
pre-commit install
|
241
|
+
pre-commit run --all-files
|
242
|
+
```
|
243
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
LICENSE
|
2
|
+
README.md
|
3
|
+
pyproject.toml
|
4
|
+
sfeos_tools/__init__.py
|
5
|
+
sfeos_tools/cli.py
|
6
|
+
sfeos_tools/reindex.py
|
7
|
+
sfeos_tools.egg-info/PKG-INFO
|
8
|
+
sfeos_tools.egg-info/SOURCES.txt
|
9
|
+
sfeos_tools.egg-info/dependency_links.txt
|
10
|
+
sfeos_tools.egg-info/entry_points.txt
|
11
|
+
sfeos_tools.egg-info/requires.txt
|
12
|
+
sfeos_tools.egg-info/top_level.txt
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
click>=8.0.0
|
2
|
+
|
3
|
+
[dev]
|
4
|
+
stac-fastapi-elasticsearch
|
5
|
+
stac-fastapi-opensearch
|
6
|
+
pytest>=6.0
|
7
|
+
pytest-cov>=2.0
|
8
|
+
black>=21.0
|
9
|
+
isort>=5.0
|
10
|
+
mypy>=0.900
|
11
|
+
flake8>=4.0.0
|
12
|
+
|
13
|
+
[elasticsearch]
|
14
|
+
stac-fastapi-elasticsearch
|
15
|
+
|
16
|
+
[opensearch]
|
17
|
+
stac-fastapi-opensearch
|
@@ -0,0 +1 @@
|
|
1
|
+
sfeos_tools
|