stac-fastapi.extensions 3.0.1__tar.gz → 3.0.2__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.
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/PKG-INFO +1 -1
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/collection_search/collection_search.py +101 -1
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/version.py +1 -1
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi.extensions.egg-info/PKG-INFO +1 -1
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_collection_search.py +118 -1
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/README.md +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/setup.cfg +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/setup.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/aggregation/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/aggregation/aggregation.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/aggregation/client.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/aggregation/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/aggregation/types.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/collection_search/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/collection_search/client.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/collection_search/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/fields/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/fields/fields.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/fields/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/filter/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/filter/client.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/filter/filter.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/filter/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/free_text/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/free_text/free_text.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/free_text/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/pagination/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/pagination/pagination.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/pagination/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/pagination/token_pagination.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/query/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/query/query.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/query/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/sort/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/sort/request.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/sort/sort.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/core/transaction.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/third_party/__init__.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/third_party/bulk_transactions.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi.extensions.egg-info/SOURCES.txt +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi.extensions.egg-info/dependency_links.txt +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi.extensions.egg-info/not-zip-safe +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi.extensions.egg-info/requires.txt +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi.extensions.egg-info/top_level.txt +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_aggregation.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_filter.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_free_text.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_query.py +0 -0
- {stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_transaction.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Collection-Search extension."""
|
|
2
2
|
|
|
3
|
+
import warnings
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from typing import List, Optional, Union
|
|
5
6
|
|
|
@@ -8,7 +9,7 @@ from fastapi import APIRouter, FastAPI
|
|
|
8
9
|
from stac_pydantic.api.collections import Collections
|
|
9
10
|
from stac_pydantic.shared import MimeTypes
|
|
10
11
|
|
|
11
|
-
from stac_fastapi.api.models import GeoJSONResponse
|
|
12
|
+
from stac_fastapi.api.models import GeoJSONResponse, create_request_model
|
|
12
13
|
from stac_fastapi.api.routes import create_async_endpoint
|
|
13
14
|
from stac_fastapi.types.config import ApiSettings
|
|
14
15
|
from stac_fastapi.types.extension import ApiExtension
|
|
@@ -71,6 +72,48 @@ class CollectionSearchExtension(ApiExtension):
|
|
|
71
72
|
"""
|
|
72
73
|
pass
|
|
73
74
|
|
|
75
|
+
@classmethod
|
|
76
|
+
def from_extensions(
|
|
77
|
+
cls,
|
|
78
|
+
extensions: List[ApiExtension],
|
|
79
|
+
schema_href: Optional[str] = None,
|
|
80
|
+
) -> "CollectionSearchExtension":
|
|
81
|
+
"""Create CollectionSearchExtension object from extensions."""
|
|
82
|
+
supported_extensions = {
|
|
83
|
+
"FreeTextExtension": ConformanceClasses.FREETEXT,
|
|
84
|
+
"FreeTextAdvancedExtension": ConformanceClasses.FREETEXT,
|
|
85
|
+
"QueryExtension": ConformanceClasses.QUERY,
|
|
86
|
+
"SortExtension": ConformanceClasses.SORT,
|
|
87
|
+
"FieldsExtension": ConformanceClasses.FIELDS,
|
|
88
|
+
"FilterExtension": ConformanceClasses.FILTER,
|
|
89
|
+
}
|
|
90
|
+
conformance_classes = [
|
|
91
|
+
ConformanceClasses.COLLECTIONSEARCH,
|
|
92
|
+
ConformanceClasses.BASIS,
|
|
93
|
+
]
|
|
94
|
+
for ext in extensions:
|
|
95
|
+
conf = supported_extensions.get(ext.__class__.__name__, None)
|
|
96
|
+
if not conf:
|
|
97
|
+
warnings.warn(
|
|
98
|
+
f"Conformance class for `{ext.__class__.__name__}` extension not found.", # noqa: E501
|
|
99
|
+
UserWarning,
|
|
100
|
+
)
|
|
101
|
+
else:
|
|
102
|
+
conformance_classes.append(conf)
|
|
103
|
+
|
|
104
|
+
get_request_model = create_request_model(
|
|
105
|
+
model_name="CollectionsGetRequest",
|
|
106
|
+
base_model=BaseCollectionSearchGetRequest,
|
|
107
|
+
extensions=extensions,
|
|
108
|
+
request_type="GET",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return cls(
|
|
112
|
+
GET=get_request_model,
|
|
113
|
+
conformance_classes=conformance_classes,
|
|
114
|
+
schema_href=schema_href,
|
|
115
|
+
)
|
|
116
|
+
|
|
74
117
|
|
|
75
118
|
@attr.s
|
|
76
119
|
class CollectionSearchPostExtension(CollectionSearchExtension):
|
|
@@ -132,3 +175,60 @@ class CollectionSearchPostExtension(CollectionSearchExtension):
|
|
|
132
175
|
endpoint=create_async_endpoint(self.client.post_all_collections, self.POST),
|
|
133
176
|
)
|
|
134
177
|
app.include_router(self.router)
|
|
178
|
+
|
|
179
|
+
@classmethod
|
|
180
|
+
def from_extensions(
|
|
181
|
+
cls,
|
|
182
|
+
extensions: List[ApiExtension],
|
|
183
|
+
*,
|
|
184
|
+
client: Union[AsyncBaseCollectionSearchClient, BaseCollectionSearchClient],
|
|
185
|
+
settings: ApiSettings,
|
|
186
|
+
schema_href: Optional[str] = None,
|
|
187
|
+
router: Optional[APIRouter] = None,
|
|
188
|
+
) -> "CollectionSearchPostExtension":
|
|
189
|
+
"""Create CollectionSearchPostExtension object from extensions."""
|
|
190
|
+
supported_extensions = {
|
|
191
|
+
"FreeTextExtension": ConformanceClasses.FREETEXT,
|
|
192
|
+
"FreeTextAdvancedExtension": ConformanceClasses.FREETEXT,
|
|
193
|
+
"QueryExtension": ConformanceClasses.QUERY,
|
|
194
|
+
"SortExtension": ConformanceClasses.SORT,
|
|
195
|
+
"FieldsExtension": ConformanceClasses.FIELDS,
|
|
196
|
+
"FilterExtension": ConformanceClasses.FILTER,
|
|
197
|
+
}
|
|
198
|
+
conformance_classes = [
|
|
199
|
+
ConformanceClasses.COLLECTIONSEARCH,
|
|
200
|
+
ConformanceClasses.BASIS,
|
|
201
|
+
]
|
|
202
|
+
for ext in extensions:
|
|
203
|
+
conf = supported_extensions.get(ext.__class__.__name__, None)
|
|
204
|
+
if not conf:
|
|
205
|
+
warnings.warn(
|
|
206
|
+
f"Conformance class for `{ext.__class__.__name__}` extension not found.", # noqa: E501
|
|
207
|
+
UserWarning,
|
|
208
|
+
)
|
|
209
|
+
else:
|
|
210
|
+
conformance_classes.append(conf)
|
|
211
|
+
|
|
212
|
+
get_request_model = create_request_model(
|
|
213
|
+
model_name="CollectionsGetRequest",
|
|
214
|
+
base_model=BaseCollectionSearchGetRequest,
|
|
215
|
+
extensions=extensions,
|
|
216
|
+
request_type="GET",
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
post_request_model = create_request_model(
|
|
220
|
+
model_name="CollectionsPostRequest",
|
|
221
|
+
base_model=BaseCollectionSearchPostRequest,
|
|
222
|
+
extensions=extensions,
|
|
223
|
+
request_type="POST",
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
return cls(
|
|
227
|
+
client=client,
|
|
228
|
+
settings=settings,
|
|
229
|
+
GET=get_request_model,
|
|
230
|
+
POST=post_request_model,
|
|
231
|
+
conformance_classes=conformance_classes,
|
|
232
|
+
router=router or APIRouter(),
|
|
233
|
+
schema_href=schema_href,
|
|
234
|
+
)
|
{stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/tests/test_collection_search.py
RENAMED
|
@@ -2,13 +2,21 @@ import json
|
|
|
2
2
|
from urllib.parse import quote_plus
|
|
3
3
|
|
|
4
4
|
import attr
|
|
5
|
+
import pytest
|
|
5
6
|
from starlette.testclient import TestClient
|
|
6
7
|
|
|
7
8
|
from stac_fastapi.api.app import StacApi
|
|
8
9
|
from stac_fastapi.api.models import create_request_model
|
|
9
10
|
from stac_fastapi.extensions.core import (
|
|
11
|
+
AggregationExtension,
|
|
10
12
|
CollectionSearchExtension,
|
|
11
13
|
CollectionSearchPostExtension,
|
|
14
|
+
FieldsExtension,
|
|
15
|
+
FilterExtension,
|
|
16
|
+
FreeTextAdvancedExtension,
|
|
17
|
+
FreeTextExtension,
|
|
18
|
+
QueryExtension,
|
|
19
|
+
SortExtension,
|
|
12
20
|
)
|
|
13
21
|
from stac_fastapi.extensions.core.collection_search import ConformanceClasses
|
|
14
22
|
from stac_fastapi.extensions.core.collection_search.client import (
|
|
@@ -302,8 +310,8 @@ def test_collection_search_extension_post_models():
|
|
|
302
310
|
client=DummyCoreClient(),
|
|
303
311
|
extensions=[
|
|
304
312
|
CollectionSearchPostExtension(
|
|
305
|
-
settings=settings,
|
|
306
313
|
client=DummyPostClient(),
|
|
314
|
+
settings=settings,
|
|
307
315
|
GET=get_request_model,
|
|
308
316
|
POST=post_request_model,
|
|
309
317
|
conformance_classes=[
|
|
@@ -392,3 +400,112 @@ def test_collection_search_extension_post_models():
|
|
|
392
400
|
assert response_dict["query"]
|
|
393
401
|
assert response_dict["sortby"]
|
|
394
402
|
assert response_dict["fields"]
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
@pytest.mark.parametrize(
|
|
406
|
+
"extensions",
|
|
407
|
+
[
|
|
408
|
+
# with FreeTextExtension
|
|
409
|
+
[
|
|
410
|
+
FieldsExtension(),
|
|
411
|
+
FilterExtension(),
|
|
412
|
+
FreeTextExtension(),
|
|
413
|
+
QueryExtension(),
|
|
414
|
+
SortExtension(),
|
|
415
|
+
],
|
|
416
|
+
# with FreeTextAdvancedExtension
|
|
417
|
+
[
|
|
418
|
+
FieldsExtension(),
|
|
419
|
+
FilterExtension(),
|
|
420
|
+
FreeTextAdvancedExtension(),
|
|
421
|
+
QueryExtension(),
|
|
422
|
+
SortExtension(),
|
|
423
|
+
],
|
|
424
|
+
],
|
|
425
|
+
)
|
|
426
|
+
def test_from_extensions_methods(extensions):
|
|
427
|
+
"""
|
|
428
|
+
Make sure `from_extensions` create the correct
|
|
429
|
+
models and adds desired conformances classes.
|
|
430
|
+
"""
|
|
431
|
+
ext = CollectionSearchExtension.from_extensions(
|
|
432
|
+
extensions,
|
|
433
|
+
)
|
|
434
|
+
collection_search = ext.GET()
|
|
435
|
+
assert collection_search.__class__.__name__ == "CollectionsGetRequest"
|
|
436
|
+
assert hasattr(collection_search, "bbox")
|
|
437
|
+
assert hasattr(collection_search, "datetime")
|
|
438
|
+
assert hasattr(collection_search, "limit")
|
|
439
|
+
assert hasattr(collection_search, "fields")
|
|
440
|
+
assert hasattr(collection_search, "q")
|
|
441
|
+
assert hasattr(collection_search, "sortby")
|
|
442
|
+
assert hasattr(collection_search, "filter")
|
|
443
|
+
assert ext.conformance_classes == [
|
|
444
|
+
ConformanceClasses.COLLECTIONSEARCH,
|
|
445
|
+
ConformanceClasses.BASIS,
|
|
446
|
+
ConformanceClasses.FIELDS,
|
|
447
|
+
ConformanceClasses.FILTER,
|
|
448
|
+
ConformanceClasses.FREETEXT,
|
|
449
|
+
ConformanceClasses.QUERY,
|
|
450
|
+
ConformanceClasses.SORT,
|
|
451
|
+
]
|
|
452
|
+
|
|
453
|
+
ext = CollectionSearchPostExtension.from_extensions(
|
|
454
|
+
extensions,
|
|
455
|
+
client=DummyPostClient(),
|
|
456
|
+
settings=ApiSettings(),
|
|
457
|
+
)
|
|
458
|
+
collection_search = ext.POST()
|
|
459
|
+
assert collection_search.__class__.__name__ == "CollectionsPostRequest"
|
|
460
|
+
assert hasattr(collection_search, "bbox")
|
|
461
|
+
assert hasattr(collection_search, "datetime")
|
|
462
|
+
assert hasattr(collection_search, "limit")
|
|
463
|
+
assert hasattr(collection_search, "fields")
|
|
464
|
+
assert hasattr(collection_search, "q")
|
|
465
|
+
assert hasattr(collection_search, "sortby")
|
|
466
|
+
assert hasattr(collection_search, "filter")
|
|
467
|
+
assert ext.conformance_classes == [
|
|
468
|
+
ConformanceClasses.COLLECTIONSEARCH,
|
|
469
|
+
ConformanceClasses.BASIS,
|
|
470
|
+
ConformanceClasses.FIELDS,
|
|
471
|
+
ConformanceClasses.FILTER,
|
|
472
|
+
ConformanceClasses.FREETEXT,
|
|
473
|
+
ConformanceClasses.QUERY,
|
|
474
|
+
ConformanceClasses.SORT,
|
|
475
|
+
]
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def test_from_extensions_methods_invalid():
|
|
479
|
+
"""Should raise warnings for invalid extensions."""
|
|
480
|
+
extensions = [
|
|
481
|
+
AggregationExtension(),
|
|
482
|
+
]
|
|
483
|
+
with pytest.warns((UserWarning)):
|
|
484
|
+
ext = CollectionSearchExtension.from_extensions(
|
|
485
|
+
extensions,
|
|
486
|
+
)
|
|
487
|
+
collection_search = ext.GET()
|
|
488
|
+
assert collection_search.__class__.__name__ == "CollectionsGetRequest"
|
|
489
|
+
assert hasattr(collection_search, "bbox")
|
|
490
|
+
assert hasattr(collection_search, "datetime")
|
|
491
|
+
assert hasattr(collection_search, "limit")
|
|
492
|
+
assert ext.conformance_classes == [
|
|
493
|
+
ConformanceClasses.COLLECTIONSEARCH,
|
|
494
|
+
ConformanceClasses.BASIS,
|
|
495
|
+
]
|
|
496
|
+
|
|
497
|
+
with pytest.warns((UserWarning)):
|
|
498
|
+
ext = CollectionSearchPostExtension.from_extensions(
|
|
499
|
+
extensions,
|
|
500
|
+
client=DummyPostClient(),
|
|
501
|
+
settings=ApiSettings(),
|
|
502
|
+
)
|
|
503
|
+
collection_search = ext.POST()
|
|
504
|
+
assert collection_search.__class__.__name__ == "CollectionsPostRequest"
|
|
505
|
+
assert hasattr(collection_search, "bbox")
|
|
506
|
+
assert hasattr(collection_search, "datetime")
|
|
507
|
+
assert hasattr(collection_search, "limit")
|
|
508
|
+
assert ext.conformance_classes == [
|
|
509
|
+
ConformanceClasses.COLLECTIONSEARCH,
|
|
510
|
+
ConformanceClasses.BASIS,
|
|
511
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stac_fastapi_extensions-3.0.1 → stac_fastapi_extensions-3.0.2}/stac_fastapi/extensions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|