sfeos-helpers 5.0.0a0__py3-none-any.whl
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_helpers-5.0.0a0.dist-info/METADATA +558 -0
- sfeos_helpers-5.0.0a0.dist-info/RECORD +20 -0
- sfeos_helpers-5.0.0a0.dist-info/WHEEL +5 -0
- sfeos_helpers-5.0.0a0.dist-info/top_level.txt +1 -0
- stac_fastapi/sfeos_helpers/aggregation/__init__.py +31 -0
- stac_fastapi/sfeos_helpers/aggregation/client.py +469 -0
- stac_fastapi/sfeos_helpers/aggregation/format.py +60 -0
- stac_fastapi/sfeos_helpers/database/__init__.py +71 -0
- stac_fastapi/sfeos_helpers/database/datetime.py +60 -0
- stac_fastapi/sfeos_helpers/database/document.py +48 -0
- stac_fastapi/sfeos_helpers/database/index.py +130 -0
- stac_fastapi/sfeos_helpers/database/mapping.py +38 -0
- stac_fastapi/sfeos_helpers/database/query.py +85 -0
- stac_fastapi/sfeos_helpers/database/utils.py +50 -0
- stac_fastapi/sfeos_helpers/filter/__init__.py +44 -0
- stac_fastapi/sfeos_helpers/filter/client.py +98 -0
- stac_fastapi/sfeos_helpers/filter/cql2.py +39 -0
- stac_fastapi/sfeos_helpers/filter/transform.py +133 -0
- stac_fastapi/sfeos_helpers/mappings.py +262 -0
- stac_fastapi/sfeos_helpers/version.py +2 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"""Shared mappings for stac-fastapi elasticsearch and opensearch backends.
|
|
2
|
+
|
|
3
|
+
This module contains shared constants, mappings, and type definitions used by both
|
|
4
|
+
the Elasticsearch and OpenSearch implementations of STAC FastAPI. It includes:
|
|
5
|
+
|
|
6
|
+
1. Index name constants and character translation tables
|
|
7
|
+
2. Mapping definitions for Collections and Items
|
|
8
|
+
3. Aggregation mappings for search queries
|
|
9
|
+
4. Type conversion mappings between Elasticsearch/OpenSearch and JSON Schema types
|
|
10
|
+
|
|
11
|
+
The sfeos_helpers package is organized as follows:
|
|
12
|
+
- database_logic_helpers.py: Shared database operations
|
|
13
|
+
- filter.py: Shared filter extension implementation
|
|
14
|
+
- mappings.py: Shared constants and mapping definitions (this file)
|
|
15
|
+
- utilities.py: Shared utility functions
|
|
16
|
+
|
|
17
|
+
When adding new functionality to this package, consider:
|
|
18
|
+
1. Will this code be used by both Elasticsearch and OpenSearch implementations?
|
|
19
|
+
2. Is the functionality stable and unlikely to diverge between implementations?
|
|
20
|
+
3. Is the function well-documented with clear input/output contracts?
|
|
21
|
+
|
|
22
|
+
Function Naming Conventions:
|
|
23
|
+
- All shared functions should end with `_shared` to clearly indicate they're meant to be used by both implementations
|
|
24
|
+
- Function names should be descriptive and indicate their purpose
|
|
25
|
+
- Parameter names should be consistent across similar functions
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import os
|
|
29
|
+
from typing import Any, Dict, Literal, Protocol
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# stac_pydantic classes extend _GeometryBase, which doesn't have a type field,
|
|
33
|
+
# So create our own Protocol for typing
|
|
34
|
+
# Union[ Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection]
|
|
35
|
+
class Geometry(Protocol): # noqa
|
|
36
|
+
type: str
|
|
37
|
+
coordinates: Any
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
COLLECTIONS_INDEX = os.getenv("STAC_COLLECTIONS_INDEX", "collections")
|
|
41
|
+
ITEMS_INDEX_PREFIX = os.getenv("STAC_ITEMS_INDEX_PREFIX", "items_")
|
|
42
|
+
|
|
43
|
+
ES_INDEX_NAME_UNSUPPORTED_CHARS = {
|
|
44
|
+
"\\",
|
|
45
|
+
"/",
|
|
46
|
+
"*",
|
|
47
|
+
"?",
|
|
48
|
+
'"',
|
|
49
|
+
"<",
|
|
50
|
+
">",
|
|
51
|
+
"|",
|
|
52
|
+
" ",
|
|
53
|
+
",",
|
|
54
|
+
"#",
|
|
55
|
+
":",
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
_ES_INDEX_NAME_UNSUPPORTED_CHARS_TABLE = str.maketrans(
|
|
59
|
+
"", "", "".join(ES_INDEX_NAME_UNSUPPORTED_CHARS)
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
ITEM_INDICES = f"{ITEMS_INDEX_PREFIX}*,-*kibana*,-{COLLECTIONS_INDEX}*"
|
|
63
|
+
|
|
64
|
+
DEFAULT_SORT = {
|
|
65
|
+
"properties.datetime": {"order": "desc"},
|
|
66
|
+
"id": {"order": "desc"},
|
|
67
|
+
"collection": {"order": "desc"},
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
ES_ITEMS_SETTINGS = {
|
|
71
|
+
"index": {
|
|
72
|
+
"sort.field": list(DEFAULT_SORT.keys()),
|
|
73
|
+
"sort.order": [v["order"] for v in DEFAULT_SORT.values()],
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
ES_MAPPINGS_DYNAMIC_TEMPLATES = [
|
|
78
|
+
# Common https://github.com/radiantearth/stac-spec/blob/master/item-spec/common-metadata.md
|
|
79
|
+
{
|
|
80
|
+
"descriptions": {
|
|
81
|
+
"match_mapping_type": "string",
|
|
82
|
+
"match": "description",
|
|
83
|
+
"mapping": {"type": "text"},
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"titles": {
|
|
88
|
+
"match_mapping_type": "string",
|
|
89
|
+
"match": "title",
|
|
90
|
+
"mapping": {"type": "text"},
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
# Projection Extension https://github.com/stac-extensions/projection
|
|
94
|
+
{"proj_epsg": {"match": "proj:epsg", "mapping": {"type": "integer"}}},
|
|
95
|
+
{
|
|
96
|
+
"proj_projjson": {
|
|
97
|
+
"match": "proj:projjson",
|
|
98
|
+
"mapping": {"type": "object", "enabled": False},
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"proj_centroid": {
|
|
103
|
+
"match": "proj:centroid",
|
|
104
|
+
"mapping": {"type": "geo_point"},
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"proj_geometry": {
|
|
109
|
+
"match": "proj:geometry",
|
|
110
|
+
"mapping": {"type": "object", "enabled": False},
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"no_index_href": {
|
|
115
|
+
"match": "href",
|
|
116
|
+
"mapping": {"type": "text", "index": False},
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
# Default all other strings not otherwise specified to keyword
|
|
120
|
+
{"strings": {"match_mapping_type": "string", "mapping": {"type": "keyword"}}},
|
|
121
|
+
{"long_to_double": {"match_mapping_type": "long", "mapping": {"type": "double"}}},
|
|
122
|
+
{
|
|
123
|
+
"double_to_double": {
|
|
124
|
+
"match_mapping_type": "double",
|
|
125
|
+
"mapping": {"type": "double"},
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
ES_ITEMS_MAPPINGS = {
|
|
131
|
+
"numeric_detection": False,
|
|
132
|
+
"dynamic_templates": ES_MAPPINGS_DYNAMIC_TEMPLATES,
|
|
133
|
+
"properties": {
|
|
134
|
+
"id": {"type": "keyword"},
|
|
135
|
+
"collection": {"type": "keyword"},
|
|
136
|
+
"geometry": {"type": "geo_shape"},
|
|
137
|
+
"assets": {"type": "object", "enabled": False},
|
|
138
|
+
"links": {"type": "object", "enabled": False},
|
|
139
|
+
"properties": {
|
|
140
|
+
"type": "object",
|
|
141
|
+
"properties": {
|
|
142
|
+
# Common https://github.com/radiantearth/stac-spec/blob/master/item-spec/common-metadata.md
|
|
143
|
+
"datetime": {"type": "date"},
|
|
144
|
+
"start_datetime": {"type": "date"},
|
|
145
|
+
"end_datetime": {"type": "date"},
|
|
146
|
+
"created": {"type": "date"},
|
|
147
|
+
"updated": {"type": "date"},
|
|
148
|
+
# Satellite Extension https://github.com/stac-extensions/sat
|
|
149
|
+
"sat:absolute_orbit": {"type": "integer"},
|
|
150
|
+
"sat:relative_orbit": {"type": "integer"},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
ES_COLLECTIONS_MAPPINGS = {
|
|
157
|
+
"numeric_detection": False,
|
|
158
|
+
"dynamic_templates": ES_MAPPINGS_DYNAMIC_TEMPLATES,
|
|
159
|
+
"properties": {
|
|
160
|
+
"id": {"type": "keyword"},
|
|
161
|
+
"extent.spatial.bbox": {"type": "long"},
|
|
162
|
+
"extent.temporal.interval": {"type": "date"},
|
|
163
|
+
"providers": {"type": "object", "enabled": False},
|
|
164
|
+
"links": {"type": "object", "enabled": False},
|
|
165
|
+
"item_assets": {"type": "object", "enabled": False},
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Shared aggregation mapping for both Elasticsearch and OpenSearch
|
|
170
|
+
AGGREGATION_MAPPING: Dict[str, Dict[str, Any]] = {
|
|
171
|
+
"total_count": {"value_count": {"field": "id"}},
|
|
172
|
+
"collection_frequency": {"terms": {"field": "collection", "size": 100}},
|
|
173
|
+
"platform_frequency": {"terms": {"field": "properties.platform", "size": 100}},
|
|
174
|
+
"cloud_cover_frequency": {
|
|
175
|
+
"range": {
|
|
176
|
+
"field": "properties.eo:cloud_cover",
|
|
177
|
+
"ranges": [
|
|
178
|
+
{"to": 5},
|
|
179
|
+
{"from": 5, "to": 15},
|
|
180
|
+
{"from": 15, "to": 40},
|
|
181
|
+
{"from": 40},
|
|
182
|
+
],
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"datetime_frequency": {
|
|
186
|
+
"date_histogram": {
|
|
187
|
+
"field": "properties.datetime",
|
|
188
|
+
"calendar_interval": "month",
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"datetime_min": {"min": {"field": "properties.datetime"}},
|
|
192
|
+
"datetime_max": {"max": {"field": "properties.datetime"}},
|
|
193
|
+
"grid_code_frequency": {
|
|
194
|
+
"terms": {
|
|
195
|
+
"field": "properties.grid:code",
|
|
196
|
+
"missing": "none",
|
|
197
|
+
"size": 10000,
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"sun_elevation_frequency": {
|
|
201
|
+
"histogram": {"field": "properties.view:sun_elevation", "interval": 5}
|
|
202
|
+
},
|
|
203
|
+
"sun_azimuth_frequency": {
|
|
204
|
+
"histogram": {"field": "properties.view:sun_azimuth", "interval": 5}
|
|
205
|
+
},
|
|
206
|
+
"off_nadir_frequency": {
|
|
207
|
+
"histogram": {"field": "properties.view:off_nadir", "interval": 5}
|
|
208
|
+
},
|
|
209
|
+
"centroid_geohash_grid_frequency": {
|
|
210
|
+
"geohash_grid": {
|
|
211
|
+
"field": "properties.proj:centroid",
|
|
212
|
+
"precision": 1,
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"centroid_geohex_grid_frequency": {
|
|
216
|
+
"geohex_grid": {
|
|
217
|
+
"field": "properties.proj:centroid",
|
|
218
|
+
"precision": 0,
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"centroid_geotile_grid_frequency": {
|
|
222
|
+
"geotile_grid": {
|
|
223
|
+
"field": "properties.proj:centroid",
|
|
224
|
+
"precision": 0,
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"geometry_geohash_grid_frequency": {
|
|
228
|
+
"geohash_grid": {
|
|
229
|
+
"field": "geometry",
|
|
230
|
+
"precision": 1,
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"geometry_geotile_grid_frequency": {
|
|
234
|
+
"geotile_grid": {
|
|
235
|
+
"field": "geometry",
|
|
236
|
+
"precision": 0,
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
ES_MAPPING_TYPE_TO_JSON: Dict[
|
|
242
|
+
str, Literal["string", "number", "boolean", "object", "array", "null"]
|
|
243
|
+
] = {
|
|
244
|
+
"date": "string",
|
|
245
|
+
"date_nanos": "string",
|
|
246
|
+
"keyword": "string",
|
|
247
|
+
"match_only_text": "string",
|
|
248
|
+
"text": "string",
|
|
249
|
+
"wildcard": "string",
|
|
250
|
+
"byte": "number",
|
|
251
|
+
"double": "number",
|
|
252
|
+
"float": "number",
|
|
253
|
+
"half_float": "number",
|
|
254
|
+
"long": "number",
|
|
255
|
+
"scaled_float": "number",
|
|
256
|
+
"short": "number",
|
|
257
|
+
"token_count": "number",
|
|
258
|
+
"unsigned_long": "number",
|
|
259
|
+
"geo_point": "object",
|
|
260
|
+
"geo_shape": "object",
|
|
261
|
+
"nested": "array",
|
|
262
|
+
}
|