stac-fastapi.api 2.4.9__tar.gz → 2.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/PKG-INFO +7 -1
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/setup.py +7 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/app.py +24 -23
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/models.py +5 -3
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/routes.py +16 -15
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/version.py +1 -1
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/PKG-INFO +7 -1
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/requires.txt +3 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/tests/test_api.py +2 -2
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/README.md +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/setup.cfg +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/__init__.py +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/config.py +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/errors.py +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/middleware.py +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi/api/openapi.py +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/SOURCES.txt +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/dependency_links.txt +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/not-zip-safe +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/top_level.txt +0 -0
- {stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/tests/test_middleware.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stac-fastapi.api
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.1
|
|
4
4
|
Summary: An implementation of STAC API based on the FastAPI framework.
|
|
5
5
|
Home-page: https://github.com/stac-utils/stac-fastapi
|
|
6
6
|
Author: Arturo Engineering
|
|
@@ -11,6 +11,10 @@ Classifier: Intended Audience :: Developers
|
|
|
11
11
|
Classifier: Intended Audience :: Information Technology
|
|
12
12
|
Classifier: Intended Audience :: Science/Research
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
18
|
Classifier: License :: OSI Approved :: MIT License
|
|
15
19
|
Requires-Python: >=3.8
|
|
16
20
|
Description-Content-Type: text/markdown
|
|
@@ -27,6 +31,8 @@ Requires-Dist: pytest-asyncio; extra == "dev"
|
|
|
27
31
|
Requires-Dist: pre-commit; extra == "dev"
|
|
28
32
|
Requires-Dist: requests; extra == "dev"
|
|
29
33
|
Requires-Dist: pystac[validation]==1.*; extra == "dev"
|
|
34
|
+
Provides-Extra: benchmark
|
|
35
|
+
Requires-Dist: pytest-benchmark; extra == "benchmark"
|
|
30
36
|
Provides-Extra: docs
|
|
31
37
|
Requires-Dist: mkdocs; extra == "docs"
|
|
32
38
|
Requires-Dist: mkdocs-material; extra == "docs"
|
|
@@ -23,6 +23,9 @@ extra_reqs = {
|
|
|
23
23
|
"requests",
|
|
24
24
|
"pystac[validation]==1.*",
|
|
25
25
|
],
|
|
26
|
+
"benchmark": [
|
|
27
|
+
"pytest-benchmark",
|
|
28
|
+
],
|
|
26
29
|
"docs": ["mkdocs", "mkdocs-material", "pdocs"],
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -38,6 +41,10 @@ setup(
|
|
|
38
41
|
"Intended Audience :: Information Technology",
|
|
39
42
|
"Intended Audience :: Science/Research",
|
|
40
43
|
"Programming Language :: Python :: 3.8",
|
|
44
|
+
"Programming Language :: Python :: 3.9",
|
|
45
|
+
"Programming Language :: Python :: 3.10",
|
|
46
|
+
"Programming Language :: Python :: 3.11",
|
|
47
|
+
"Programming Language :: Python :: 3.12",
|
|
41
48
|
"License :: OSI Approved :: MIT License",
|
|
42
49
|
],
|
|
43
50
|
keywords="STAC FastAPI COG",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Fastapi app creation."""
|
|
2
|
+
|
|
2
3
|
from typing import Any, Dict, List, Optional, Tuple, Type, Union
|
|
3
4
|
|
|
4
5
|
import attr
|
|
@@ -83,10 +84,22 @@ class StacApi:
|
|
|
83
84
|
converter=update_openapi,
|
|
84
85
|
)
|
|
85
86
|
router: APIRouter = attr.ib(default=attr.Factory(APIRouter))
|
|
86
|
-
title: str = attr.ib(
|
|
87
|
-
|
|
87
|
+
title: str = attr.ib(
|
|
88
|
+
default=attr.Factory(
|
|
89
|
+
lambda self: self.settings.stac_fastapi_title, takes_self=True
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
api_version: str = attr.ib(
|
|
93
|
+
default=attr.Factory(
|
|
94
|
+
lambda self: self.settings.stac_fastapi_version, takes_self=True
|
|
95
|
+
)
|
|
96
|
+
)
|
|
88
97
|
stac_version: str = attr.ib(default=STAC_VERSION)
|
|
89
|
-
description: str = attr.ib(
|
|
98
|
+
description: str = attr.ib(
|
|
99
|
+
default=attr.Factory(
|
|
100
|
+
lambda self: self.settings.stac_fastapi_description, takes_self=True
|
|
101
|
+
)
|
|
102
|
+
)
|
|
90
103
|
search_get_request_model: Type[BaseSearchGetRequest] = attr.ib(
|
|
91
104
|
default=BaseSearchGetRequest
|
|
92
105
|
)
|
|
@@ -132,9 +145,7 @@ class StacApi:
|
|
|
132
145
|
response_model_exclude_unset=False,
|
|
133
146
|
response_model_exclude_none=True,
|
|
134
147
|
methods=["GET"],
|
|
135
|
-
endpoint=create_async_endpoint(
|
|
136
|
-
self.client.landing_page, EmptyRequest, self.response_class
|
|
137
|
-
),
|
|
148
|
+
endpoint=create_async_endpoint(self.client.landing_page, EmptyRequest),
|
|
138
149
|
)
|
|
139
150
|
|
|
140
151
|
def register_conformance_classes(self):
|
|
@@ -153,9 +164,7 @@ class StacApi:
|
|
|
153
164
|
response_model_exclude_unset=True,
|
|
154
165
|
response_model_exclude_none=True,
|
|
155
166
|
methods=["GET"],
|
|
156
|
-
endpoint=create_async_endpoint(
|
|
157
|
-
self.client.conformance, EmptyRequest, self.response_class
|
|
158
|
-
),
|
|
167
|
+
endpoint=create_async_endpoint(self.client.conformance, EmptyRequest),
|
|
159
168
|
)
|
|
160
169
|
|
|
161
170
|
def register_get_item(self):
|
|
@@ -172,9 +181,7 @@ class StacApi:
|
|
|
172
181
|
response_model_exclude_unset=True,
|
|
173
182
|
response_model_exclude_none=True,
|
|
174
183
|
methods=["GET"],
|
|
175
|
-
endpoint=create_async_endpoint(
|
|
176
|
-
self.client.get_item, ItemUri, GeoJSONResponse
|
|
177
|
-
),
|
|
184
|
+
endpoint=create_async_endpoint(self.client.get_item, ItemUri),
|
|
178
185
|
)
|
|
179
186
|
|
|
180
187
|
def register_post_search(self):
|
|
@@ -195,7 +202,7 @@ class StacApi:
|
|
|
195
202
|
response_model_exclude_none=True,
|
|
196
203
|
methods=["POST"],
|
|
197
204
|
endpoint=create_async_endpoint(
|
|
198
|
-
self.client.post_search, self.search_post_request_model
|
|
205
|
+
self.client.post_search, self.search_post_request_model
|
|
199
206
|
),
|
|
200
207
|
)
|
|
201
208
|
|
|
@@ -217,7 +224,7 @@ class StacApi:
|
|
|
217
224
|
response_model_exclude_none=True,
|
|
218
225
|
methods=["GET"],
|
|
219
226
|
endpoint=create_async_endpoint(
|
|
220
|
-
self.client.get_search, self.search_get_request_model
|
|
227
|
+
self.client.get_search, self.search_get_request_model
|
|
221
228
|
),
|
|
222
229
|
)
|
|
223
230
|
|
|
@@ -237,9 +244,7 @@ class StacApi:
|
|
|
237
244
|
response_model_exclude_unset=True,
|
|
238
245
|
response_model_exclude_none=True,
|
|
239
246
|
methods=["GET"],
|
|
240
|
-
endpoint=create_async_endpoint(
|
|
241
|
-
self.client.all_collections, EmptyRequest, self.response_class
|
|
242
|
-
),
|
|
247
|
+
endpoint=create_async_endpoint(self.client.all_collections, EmptyRequest),
|
|
243
248
|
)
|
|
244
249
|
|
|
245
250
|
def register_get_collection(self):
|
|
@@ -256,9 +261,7 @@ class StacApi:
|
|
|
256
261
|
response_model_exclude_unset=True,
|
|
257
262
|
response_model_exclude_none=True,
|
|
258
263
|
methods=["GET"],
|
|
259
|
-
endpoint=create_async_endpoint(
|
|
260
|
-
self.client.get_collection, CollectionUri, self.response_class
|
|
261
|
-
),
|
|
264
|
+
endpoint=create_async_endpoint(self.client.get_collection, CollectionUri),
|
|
262
265
|
)
|
|
263
266
|
|
|
264
267
|
def register_get_item_collection(self):
|
|
@@ -287,9 +290,7 @@ class StacApi:
|
|
|
287
290
|
response_model_exclude_unset=True,
|
|
288
291
|
response_model_exclude_none=True,
|
|
289
292
|
methods=["GET"],
|
|
290
|
-
endpoint=create_async_endpoint(
|
|
291
|
-
self.client.item_collection, request_model, GeoJSONResponse
|
|
292
|
-
),
|
|
293
|
+
endpoint=create_async_endpoint(self.client.item_collection, request_model),
|
|
293
294
|
)
|
|
294
295
|
|
|
295
296
|
def register_core(self):
|
|
@@ -7,13 +7,15 @@ import attr
|
|
|
7
7
|
from fastapi import Body, Path
|
|
8
8
|
from pydantic import BaseModel, create_model
|
|
9
9
|
from pydantic.fields import UndefinedType
|
|
10
|
+
from stac_pydantic.shared import BBox
|
|
10
11
|
|
|
11
12
|
from stac_fastapi.types.extension import ApiExtension
|
|
13
|
+
from stac_fastapi.types.rfc3339 import DateTimeType
|
|
12
14
|
from stac_fastapi.types.search import (
|
|
13
15
|
APIRequest,
|
|
14
16
|
BaseSearchGetRequest,
|
|
15
17
|
BaseSearchPostRequest,
|
|
16
|
-
|
|
18
|
+
str2bbox,
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
|
|
@@ -124,8 +126,8 @@ class ItemCollectionUri(CollectionUri):
|
|
|
124
126
|
"""Get item collection."""
|
|
125
127
|
|
|
126
128
|
limit: int = attr.ib(default=10)
|
|
127
|
-
bbox: Optional[
|
|
128
|
-
datetime: Optional[
|
|
129
|
+
bbox: Optional[BBox] = attr.ib(default=None, converter=str2bbox)
|
|
130
|
+
datetime: Optional[DateTimeType] = attr.ib(default=None)
|
|
129
131
|
|
|
130
132
|
|
|
131
133
|
class POSTTokenPagination(BaseModel):
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""Route factories."""
|
|
2
|
+
|
|
2
3
|
import functools
|
|
3
4
|
import inspect
|
|
5
|
+
import warnings
|
|
4
6
|
from typing import Any, Callable, Dict, List, Optional, Type, TypedDict, Union
|
|
5
7
|
|
|
6
8
|
from fastapi import Depends, params
|
|
@@ -8,18 +10,16 @@ from fastapi.dependencies.utils import get_parameterless_sub_dependant
|
|
|
8
10
|
from pydantic import BaseModel
|
|
9
11
|
from starlette.concurrency import run_in_threadpool
|
|
10
12
|
from starlette.requests import Request
|
|
11
|
-
from starlette.responses import
|
|
13
|
+
from starlette.responses import Response
|
|
12
14
|
from starlette.routing import BaseRoute, Match
|
|
13
15
|
from starlette.status import HTTP_204_NO_CONTENT
|
|
14
16
|
|
|
15
17
|
from stac_fastapi.api.models import APIRequest
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
def _wrap_response(resp: Any
|
|
19
|
-
if
|
|
20
|
+
def _wrap_response(resp: Any) -> Any:
|
|
21
|
+
if resp is not None:
|
|
20
22
|
return resp
|
|
21
|
-
elif resp is not None:
|
|
22
|
-
return response_class(resp)
|
|
23
23
|
else: # None is returned as 204 No Content
|
|
24
24
|
return Response(status_code=HTTP_204_NO_CONTENT)
|
|
25
25
|
|
|
@@ -37,12 +37,19 @@ def sync_to_async(func):
|
|
|
37
37
|
def create_async_endpoint(
|
|
38
38
|
func: Callable,
|
|
39
39
|
request_model: Union[Type[APIRequest], Type[BaseModel], Dict],
|
|
40
|
-
response_class: Type[Response] =
|
|
40
|
+
response_class: Optional[Type[Response]] = None,
|
|
41
41
|
):
|
|
42
42
|
"""Wrap a function in a coroutine which may be used to create a FastAPI endpoint.
|
|
43
43
|
|
|
44
44
|
Synchronous functions are executed asynchronously using a background thread.
|
|
45
45
|
"""
|
|
46
|
+
|
|
47
|
+
if response_class:
|
|
48
|
+
warnings.warn(
|
|
49
|
+
"`response_class` option is deprecated, please set the Response class directly in the endpoint.", # noqa: E501
|
|
50
|
+
DeprecationWarning,
|
|
51
|
+
)
|
|
52
|
+
|
|
46
53
|
if not inspect.iscoroutinefunction(func):
|
|
47
54
|
func = sync_to_async(func)
|
|
48
55
|
|
|
@@ -53,9 +60,7 @@ def create_async_endpoint(
|
|
|
53
60
|
request_data: request_model = Depends(), # type:ignore
|
|
54
61
|
):
|
|
55
62
|
"""Endpoint."""
|
|
56
|
-
return _wrap_response(
|
|
57
|
-
await func(request=request, **request_data.kwargs()), response_class
|
|
58
|
-
)
|
|
63
|
+
return _wrap_response(await func(request=request, **request_data.kwargs()))
|
|
59
64
|
|
|
60
65
|
elif issubclass(request_model, BaseModel):
|
|
61
66
|
|
|
@@ -64,9 +69,7 @@ def create_async_endpoint(
|
|
|
64
69
|
request_data: request_model, # type:ignore
|
|
65
70
|
):
|
|
66
71
|
"""Endpoint."""
|
|
67
|
-
return _wrap_response(
|
|
68
|
-
await func(request_data, request=request), response_class
|
|
69
|
-
)
|
|
72
|
+
return _wrap_response(await func(request_data, request=request))
|
|
70
73
|
|
|
71
74
|
else:
|
|
72
75
|
|
|
@@ -75,9 +78,7 @@ def create_async_endpoint(
|
|
|
75
78
|
request_data: Dict[str, Any], # type:ignore
|
|
76
79
|
):
|
|
77
80
|
"""Endpoint."""
|
|
78
|
-
return _wrap_response(
|
|
79
|
-
await func(request_data, request=request), response_class
|
|
80
|
-
)
|
|
81
|
+
return _wrap_response(await func(request_data, request=request))
|
|
81
82
|
|
|
82
83
|
return _endpoint
|
|
83
84
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Library version."""
|
|
2
|
-
__version__ = "2.
|
|
2
|
+
__version__ = "2.5.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stac-fastapi.api
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.1
|
|
4
4
|
Summary: An implementation of STAC API based on the FastAPI framework.
|
|
5
5
|
Home-page: https://github.com/stac-utils/stac-fastapi
|
|
6
6
|
Author: Arturo Engineering
|
|
@@ -11,6 +11,10 @@ Classifier: Intended Audience :: Developers
|
|
|
11
11
|
Classifier: Intended Audience :: Information Technology
|
|
12
12
|
Classifier: Intended Audience :: Science/Research
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
18
|
Classifier: License :: OSI Approved :: MIT License
|
|
15
19
|
Requires-Python: >=3.8
|
|
16
20
|
Description-Content-Type: text/markdown
|
|
@@ -27,6 +31,8 @@ Requires-Dist: pytest-asyncio; extra == "dev"
|
|
|
27
31
|
Requires-Dist: pre-commit; extra == "dev"
|
|
28
32
|
Requires-Dist: requests; extra == "dev"
|
|
29
33
|
Requires-Dist: pystac[validation]==1.*; extra == "dev"
|
|
34
|
+
Provides-Extra: benchmark
|
|
35
|
+
Requires-Dist: pytest-benchmark; extra == "benchmark"
|
|
30
36
|
Provides-Extra: docs
|
|
31
37
|
Requires-Dist: mkdocs; extra == "docs"
|
|
32
38
|
Requires-Dist: mkdocs-material; extra == "docs"
|
|
@@ -61,7 +61,7 @@ class TestRouteDependencies:
|
|
|
61
61
|
def test_build_api_with_route_dependencies(self):
|
|
62
62
|
routes = [
|
|
63
63
|
{"path": "/collections", "method": "POST"},
|
|
64
|
-
{"path": "/collections", "method": "PUT"},
|
|
64
|
+
{"path": "/collections/{collectionId}", "method": "PUT"},
|
|
65
65
|
{"path": "/collections/{collectionId}", "method": "DELETE"},
|
|
66
66
|
{"path": "/collections/{collectionId}/items", "method": "POST"},
|
|
67
67
|
{"path": "/collections/{collectionId}/items/{itemId}", "method": "PUT"},
|
|
@@ -74,7 +74,7 @@ class TestRouteDependencies:
|
|
|
74
74
|
def test_add_route_dependencies_after_building_api(self):
|
|
75
75
|
routes = [
|
|
76
76
|
{"path": "/collections", "method": "POST"},
|
|
77
|
-
{"path": "/collections", "method": "PUT"},
|
|
77
|
+
{"path": "/collections/{collectionId}", "method": "PUT"},
|
|
78
78
|
{"path": "/collections/{collectionId}", "method": "DELETE"},
|
|
79
79
|
{"path": "/collections/{collectionId}/items", "method": "POST"},
|
|
80
80
|
{"path": "/collections/{collectionId}/items/{itemId}", "method": "PUT"},
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stac-fastapi.api-2.4.9 → stac_fastapi_api-2.5.1}/stac_fastapi.api.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|