stac-fastapi.core 2.4.0__tar.gz → 3.0.0a0__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 (34) hide show
  1. stac_fastapi_core-3.0.0a0/PKG-INFO +385 -0
  2. stac_fastapi_core-3.0.0a0/README.md +355 -0
  3. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/setup.py +9 -9
  4. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/core.py +50 -25
  5. stac_fastapi_core-3.0.0a0/stac_fastapi/core/datetime_utils.py +39 -0
  6. stac_fastapi_core-3.0.0a0/stac_fastapi/core/extensions/filter.py +180 -0
  7. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/extensions/query.py +2 -2
  8. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/types/core.py +5 -30
  9. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/utilities.py +2 -0
  10. stac_fastapi_core-3.0.0a0/stac_fastapi/core/version.py +2 -0
  11. stac_fastapi_core-3.0.0a0/stac_fastapi.core.egg-info/PKG-INFO +385 -0
  12. stac_fastapi_core-3.0.0a0/stac_fastapi.core.egg-info/requires.txt +12 -0
  13. stac_fastapi_core-2.4.0/PKG-INFO +0 -31
  14. stac_fastapi_core-2.4.0/README.md +0 -1
  15. stac_fastapi_core-2.4.0/stac_fastapi/core/datetime_utils.py +0 -14
  16. stac_fastapi_core-2.4.0/stac_fastapi/core/extensions/filter.py +0 -267
  17. stac_fastapi_core-2.4.0/stac_fastapi/core/version.py +0 -2
  18. stac_fastapi_core-2.4.0/stac_fastapi.core.egg-info/PKG-INFO +0 -31
  19. stac_fastapi_core-2.4.0/stac_fastapi.core.egg-info/requires.txt +0 -13
  20. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/setup.cfg +0 -0
  21. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/__init__.py +0 -0
  22. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/base_database_logic.py +0 -0
  23. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/base_settings.py +0 -0
  24. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/basic_auth.py +0 -0
  25. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/extensions/__init__.py +0 -0
  26. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/models/__init__.py +0 -0
  27. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/models/links.py +0 -0
  28. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/models/search.py +0 -0
  29. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/serializers.py +0 -0
  30. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi/core/session.py +0 -0
  31. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi.core.egg-info/SOURCES.txt +0 -0
  32. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi.core.egg-info/dependency_links.txt +0 -0
  33. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi.core.egg-info/not-zip-safe +0 -0
  34. {stac_fastapi_core-2.4.0 → stac_fastapi_core-3.0.0a0}/stac_fastapi.core.egg-info/top_level.txt +0 -0
@@ -0,0 +1,385 @@
1
+ Metadata-Version: 2.1
2
+ Name: stac-fastapi.core
3
+ Version: 3.0.0a0
4
+ Summary: Core library for the Elasticsearch and Opensearch stac-fastapi backends.
5
+ Home-page: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
6
+ License: MIT
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Intended Audience :: Information Technology
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: fastapi-slim
19
+ Requires-Dist: attrs>=23.2.0
20
+ Requires-Dist: pydantic[dotenv]
21
+ Requires-Dist: stac_pydantic>=3
22
+ Requires-Dist: stac-fastapi.types==3.0.0a
23
+ Requires-Dist: stac-fastapi.api==3.0.0a
24
+ Requires-Dist: stac-fastapi.extensions==3.0.0a
25
+ Requires-Dist: orjson
26
+ Requires-Dist: overrides
27
+ Requires-Dist: geojson-pydantic
28
+ Requires-Dist: pygeofilter==0.2.1
29
+ Requires-Dist: typing_extensions==4.8.0
30
+
31
+ # stac-fastapi-elasticsearch-opensearch (sfeos)
32
+
33
+ <!-- markdownlint-disable MD033 MD041 -->
34
+
35
+ <p align="left">
36
+ <img src="https://github.com/radiantearth/stac-site/raw/master/images/logo/stac-030-long.png" width=600>
37
+ <p align="left"><b>Elasticsearch and Opensearch backends for the stac-fastapi project.</b></p>
38
+ <p align="left"><b>Featuring stac-fastapi.core for simplifying the creation and maintenance of custom STAC api backends.</b></p>
39
+ </p>
40
+
41
+
42
+ [![PyPI version](https://badge.fury.io/py/stac-fastapi.elasticsearch.svg)](https://badge.fury.io/py/stac-fastapi.elasticsearch)
43
+ [![Join the chat at https://gitter.im/stac-fastapi-elasticsearch/community](https://badges.gitter.im/stac-fastapi-elasticsearch/community.svg)](https://gitter.im/stac-fastapi-elasticsearch/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
44
+
45
+
46
+ ---
47
+
48
+ **Online Documentation**: [https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch](https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/)
49
+
50
+ **Source Code**: [https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch)
51
+
52
+
53
+ ---
54
+
55
+ ### Notes:
56
+
57
+ - Our Api core library can be used to create custom backends. See [stac-fastapi-mongo](https://github.com/Healy-Hyperspatial/stac-fastapi-mongo) for a working example.
58
+ - Reach out on our [Gitter](https://app.gitter.im/#/room/#stac-fastapi-elasticsearch_community:gitter.im) channel or feel free to add to our [Discussions](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/discussions) page here on github.
59
+ - There is [Postman](https://documenter.getpostman.com/view/12888943/2s8ZDSdRHA) documentation here for examples on how to run some of the API routes locally - after starting the elasticsearch backend via the docker-compose.yml file.
60
+ - The `/examples` folder shows an example of running stac-fastapi-elasticsearch from PyPI in docker without needing any code from the repository. There is also a Postman collection here that you can load into Postman for testing the API routes.
61
+
62
+ - For changes, see the [Changelog](CHANGELOG.md)
63
+ - We are always welcoming contributions. For the development notes: [Contributing](CONTRIBUTING.md)
64
+
65
+
66
+ ### To install from PyPI:
67
+
68
+ ```shell
69
+ pip install stac_fastapi.elasticsearch
70
+ ```
71
+ or
72
+ ```
73
+ pip install stac_fastapi.opensearch
74
+ ```
75
+
76
+ ## Build Elasticsearch API backend
77
+
78
+ ```shell
79
+ docker-compose up elasticsearch
80
+ docker-compose build app-elasticsearch
81
+ ```
82
+
83
+ ## Running Elasticsearch API on localhost:8080
84
+
85
+ ```shell
86
+ docker-compose up app-elasticsearch
87
+ ```
88
+
89
+ By default, docker-compose uses Elasticsearch 8.x and OpenSearch 2.11.1.
90
+ If you wish to use a different version, put the following in a
91
+ file named `.env` in the same directory you run docker-compose from:
92
+
93
+ ```shell
94
+ ELASTICSEARCH_VERSION=7.17.1
95
+ OPENSEARCH_VERSION=2.11.0
96
+ ```
97
+ The most recent Elasticsearch 7.x versions should also work. See the [opensearch-py docs](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md) for compatibility information.
98
+
99
+ To create a new Collection:
100
+
101
+ ```shell
102
+ curl -X "POST" "http://localhost:8080/collections" \
103
+ -H 'Content-Type: application/json; charset=utf-8' \
104
+ -d $'{
105
+ "id": "my_collection"
106
+ }'
107
+ ```
108
+
109
+ Note: this "Collections Transaction" behavior is not part of the STAC API, but may be soon.
110
+
111
+ ## Configure the API
112
+
113
+ By default the API title and description are set to `stac-fastapi-<backend>`. Change the API title and description from the default by setting the `STAC_FASTAPI_TITLE` and `STAC_FASTAPI_DESCRIPTION` environment variables, respectively.
114
+
115
+ By default the API will read from and write to the `collections` and `items_<collection name>` indices. To change the API collections index and the items index prefix, change the `STAC_COLLECTIONS_INDEX` and `STAC_ITEMS_INDEX_PREFIX` environment variables.
116
+
117
+ The application root path is left as the base url by default. If deploying to AWS Lambda with a Gateway API, you will need to define the app root path to be the same as the Gateway API stage name where you will deploy the API. The app root path can be defined with the `STAC_FASTAPI_ROOT_PATH` environment variable (`/v1`, for example)
118
+
119
+ ## Collection pagination
120
+
121
+ The collections route handles optional `limit` and `token` parameters. The `links` field that is
122
+ returned from the `/collections` route contains a `next` link with the token that can be used to
123
+ get the next page of results.
124
+
125
+ ```shell
126
+ curl -X "GET" "http://localhost:8080/collections?limit=1&token=example_token"
127
+ ```
128
+
129
+ ## Ingesting Sample Data CLI Tool
130
+
131
+ ```shell
132
+ Usage: data_loader.py [OPTIONS]
133
+
134
+ Load STAC items into the database.
135
+
136
+ Options:
137
+ --base-url TEXT Base URL of the STAC API [required]
138
+ --collection-id TEXT ID of the collection to which items are added
139
+ --use-bulk Use bulk insert method for items
140
+ --data-dir PATH Directory containing collection.json and feature
141
+ collection file
142
+ --help Show this message and exit.
143
+ ```
144
+
145
+ ```shell
146
+ python3 data_loader.py --base-url http://localhost:8080
147
+ ```
148
+
149
+
150
+ ## Elasticsearch Mappings
151
+
152
+ Mappings apply to search index, not source. The mappings are stored in index templates on application startup.
153
+ These templates will be used implicitly when creating new Collection and Item indices.
154
+
155
+
156
+ ## Managing Elasticsearch Indices
157
+ ### Snapshots
158
+
159
+ This section covers how to create a snapshot repository and then create and restore snapshots with this.
160
+
161
+ Create a snapshot repository. This puts the files in the `elasticsearch/snapshots` in this git repo clone, as
162
+ the elasticsearch.yml and docker-compose files create a mapping from that directory to
163
+ `/usr/share/elasticsearch/snapshots` within the Elasticsearch container and grant permissions on using it.
164
+
165
+ ```shell
166
+ curl -X "PUT" "http://localhost:9200/_snapshot/my_fs_backup" \
167
+ -H 'Content-Type: application/json; charset=utf-8' \
168
+ -d $'{
169
+ "type": "fs",
170
+ "settings": {
171
+ "location": "/usr/share/elasticsearch/snapshots/my_fs_backup"
172
+ }
173
+ }'
174
+ ```
175
+
176
+ The next step is to create a snapshot of one or more indices into this snapshot repository. This command creates
177
+ a snapshot named `my_snapshot_2` and waits for the action to be completed before returning. This can also be done
178
+ asynchronously, and queried for status. The `indices` parameter determines which indices are snapshotted, and
179
+ can include wildcards.
180
+
181
+ ```shell
182
+ curl -X "PUT" "http://localhost:9200/_snapshot/my_fs_backup/my_snapshot_2?wait_for_completion=true" \
183
+ -H 'Content-Type: application/json; charset=utf-8' \
184
+ -d $'{
185
+ "metadata": {
186
+ "taken_because": "dump of all items",
187
+ "taken_by": "pvarner"
188
+ },
189
+ "include_global_state": false,
190
+ "ignore_unavailable": false,
191
+ "indices": "items_my-collection"
192
+ }'
193
+ ```
194
+
195
+ To see the status of this snapshot:
196
+
197
+ ```shell
198
+ curl http://localhost:9200/_snapshot/my_fs_backup/my_snapshot_2
199
+ ```
200
+
201
+ To see all the snapshots:
202
+
203
+ ```shell
204
+ curl http://localhost:9200/_snapshot/my_fs_backup/_all
205
+ ```
206
+
207
+ To restore a snapshot, run something similar to the following. This specific command will restore any indices that
208
+ match `items_*` and rename them so that the new index name will be suffixed with `-copy`.
209
+
210
+ ```shell
211
+ curl -X "POST" "http://localhost:9200/_snapshot/my_fs_backup/my_snapshot_2/_restore?wait_for_completion=true" \
212
+ -H 'Content-Type: application/json; charset=utf-8' \
213
+ -d $'{
214
+ "include_aliases": false,
215
+ "include_global_state": false,
216
+ "ignore_unavailable": true,
217
+ "rename_replacement": "items_$1-copy",
218
+ "indices": "items_*",
219
+ "rename_pattern": "items_(.+)"
220
+ }'
221
+ ```
222
+
223
+ Now the item documents have been restored in to the new index (e.g., `my-collection-copy`), but the value of the
224
+ `collection` field in those documents is still the original value of `my-collection`. To update these to match the
225
+ new collection name, run the following Elasticsearch Update By Query command, substituting the old collection name
226
+ into the term filter and the new collection name into the script parameter:
227
+
228
+ ```shell
229
+ curl -X "POST" "http://localhost:9200/items_my-collection-copy/_update_by_query" \
230
+ -H 'Content-Type: application/json; charset=utf-8' \
231
+ -d $'{
232
+ "query": {
233
+ "match_all": {}
234
+ },
235
+ "script": {
236
+ "lang": "painless",
237
+ "params": {
238
+ "collection": "my-collection-copy"
239
+ },
240
+ "source": "ctx._source.collection = params.collection"
241
+ }
242
+ }'
243
+ ```
244
+
245
+ Then, create a new collection through the api with the new name for each of the restored indices:
246
+
247
+ ```shell
248
+ curl -X "POST" "http://localhost:8080/collections" \
249
+ -H 'Content-Type: application/json' \
250
+ -d $'{
251
+ "id": "my-collection-copy"
252
+ }'
253
+ ```
254
+
255
+ Voila! You have a copy of the collection now that has a resource URI (`/collections/my-collection-copy`) and can be
256
+ correctly queried by collection name.
257
+
258
+ ### Reindexing
259
+ This section covers how to reindex documents stored in Elasticsearch/OpenSearch.
260
+ A reindex operation might be useful to apply changes to documents or to correct dynamically generated mappings.
261
+
262
+ The index templates will make sure that manually created indices will also have the correct mappings and settings.
263
+
264
+ In this example, we will make a copy of an existing Item index `items_my-collection-000001` but change the Item identifier to be lowercase.
265
+
266
+ ```shell
267
+ curl -X "POST" "http://localhost:9200/_reindex" \
268
+ -H 'Content-Type: application/json' \
269
+ -d $'{
270
+ "source": {
271
+ "index": "items_my-collection-000001"
272
+ },
273
+ "dest": {
274
+ "index": "items_my-collection-000002"
275
+ },
276
+ "script": {
277
+ "source": "ctx._source.id = ctx._source.id.toLowerCase()",
278
+ "lang": "painless"
279
+ }
280
+ }'
281
+ ```
282
+
283
+ If we are happy with the data in the newly created index, we can move the alias `items_my-collection` to the new index `items_my-collection-000002`.
284
+ ```shell
285
+ curl -X "POST" "http://localhost:9200/_aliases" \
286
+ -h 'Content-Type: application/json' \
287
+ -d $'{
288
+ "actions": [
289
+ {
290
+ "remove": {
291
+ "index": "*",
292
+ "alias": "items_my-collection"
293
+ }
294
+ },
295
+ {
296
+ "add": {
297
+ "index": "items_my-collection-000002",
298
+ "alias": "items_my-collection"
299
+ }
300
+ }
301
+ ]
302
+ }'
303
+ ```
304
+
305
+ The modified Items with lowercase identifiers will now be visible to users accessing `my-collection` in the STAC API.
306
+
307
+
308
+ ## Basic Auth
309
+
310
+ #### Environment Variable Configuration
311
+
312
+ Basic authentication is an optional feature. You can enable it by setting the environment variable `BASIC_AUTH` as a JSON string.
313
+
314
+ Example:
315
+ ```
316
+ BASIC_AUTH={"users":[{"username":"user","password":"pass","permissions":"*"}]}
317
+ ```
318
+
319
+ ### User Permissions Configuration
320
+
321
+ In order to set endpoints with specific access permissions, you can configure the `users` key with a list of user objects. Each user object should contain the username, password, and their respective permissions.
322
+
323
+ Example: This example illustrates the configuration for two users: an **admin** user with full permissions (*) and a **reader** user with limited permissions to specific read-only endpoints.
324
+ ```json
325
+ {
326
+ "users": [
327
+ {
328
+ "username": "admin",
329
+ "password": "admin",
330
+ "permissions": "*"
331
+ },
332
+ {
333
+ "username": "reader",
334
+ "password": "reader",
335
+ "permissions": [
336
+ {"path": "/", "method": ["GET"]},
337
+ {"path": "/conformance", "method": ["GET"]},
338
+ {"path": "/collections/{collection_id}/items/{item_id}", "method": ["GET"]},
339
+ {"path": "/search", "method": ["GET", "POST"]},
340
+ {"path": "/collections", "method": ["GET"]},
341
+ {"path": "/collections/{collection_id}", "method": ["GET"]},
342
+ {"path": "/collections/{collection_id}/items", "method": ["GET"]},
343
+ {"path": "/queryables", "method": ["GET"]},
344
+ {"path": "/queryables/collections/{collection_id}/queryables", "method": ["GET"]},
345
+ {"path": "/_mgmt/ping", "method": ["GET"]}
346
+ ]
347
+ }
348
+ ]
349
+ }
350
+ ```
351
+
352
+
353
+ ### Public Endpoints Configuration
354
+
355
+ In order to set endpoints with public access, you can configure the public_endpoints key with a list of endpoint objects. Each endpoint object should specify the path and method of the endpoint.
356
+
357
+ Example: This example demonstrates the configuration for public endpoints, allowing access without authentication to read-only endpoints.
358
+ ```json
359
+ {
360
+ "public_endpoints": [
361
+ {"path": "/", "method": "GET"},
362
+ {"path": "/conformance", "method": "GET"},
363
+ {"path": "/collections/{collection_id}/items/{item_id}", "method": "GET"},
364
+ {"path": "/search", "method": "GET"},
365
+ {"path": "/search", "method": "POST"},
366
+ {"path": "/collections", "method": "GET"},
367
+ {"path": "/collections/{collection_id}", "method": "GET"},
368
+ {"path": "/collections/{collection_id}/items", "method": "GET"},
369
+ {"path": "/queryables", "method": "GET"},
370
+ {"path": "/queryables/collections/{collection_id}/queryables", "method": "GET"},
371
+ {"path": "/_mgmt/ping", "method": "GET"}
372
+ ],
373
+ "users": [
374
+ {
375
+ "username": "admin",
376
+ "password": "admin",
377
+ "permissions": "*"
378
+ }
379
+ ]
380
+ }
381
+ ```
382
+
383
+ ### Docker Compose Configurations
384
+
385
+ See `docker-compose.basic_auth_protected.yml` and `docker-compose.basic_auth_public.yml` for basic authentication configurations.