stac-fastapi.extensions 2.4.8__tar.gz → 2.5.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.
Files changed (35) hide show
  1. stac_fastapi_extensions-2.5.0/PKG-INFO +35 -0
  2. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/setup.py +5 -1
  3. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/context.py +10 -0
  4. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/fields/fields.py +1 -1
  5. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/filter/filter.py +2 -1
  6. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/query/query.py +1 -1
  7. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/sort/sort.py +1 -1
  8. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/transaction.py +4 -4
  9. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/third_party/bulk_transactions.py +30 -6
  10. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/version.py +1 -1
  11. stac_fastapi_extensions-2.5.0/stac_fastapi.extensions.egg-info/PKG-INFO +35 -0
  12. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi.extensions.egg-info/SOURCES.txt +2 -1
  13. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi.extensions.egg-info/requires.txt +1 -1
  14. stac_fastapi_extensions-2.5.0/tests/test_transaction.py +121 -0
  15. stac-fastapi.extensions-2.4.8/PKG-INFO +0 -18
  16. stac-fastapi.extensions-2.4.8/stac_fastapi.extensions.egg-info/PKG-INFO +0 -18
  17. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/README.md +0 -0
  18. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/setup.cfg +0 -0
  19. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/__init__.py +0 -0
  20. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/__init__.py +0 -0
  21. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/fields/__init__.py +0 -0
  22. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/fields/request.py +0 -0
  23. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/filter/__init__.py +0 -0
  24. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/filter/request.py +0 -0
  25. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/pagination/__init__.py +0 -0
  26. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/pagination/pagination.py +0 -0
  27. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/pagination/token_pagination.py +0 -0
  28. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/query/__init__.py +0 -0
  29. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/query/request.py +0 -0
  30. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/sort/__init__.py +0 -0
  31. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/core/sort/request.py +0 -0
  32. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi/extensions/third_party/__init__.py +0 -0
  33. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi.extensions.egg-info/dependency_links.txt +0 -0
  34. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi.extensions.egg-info/not-zip-safe +0 -0
  35. {stac-fastapi.extensions-2.4.8 → stac_fastapi_extensions-2.5.0}/stac_fastapi.extensions.egg-info/top_level.txt +0 -0
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.1
2
+ Name: stac-fastapi.extensions
3
+ Version: 2.5.0
4
+ Summary: An implementation of STAC API based on the FastAPI framework.
5
+ Home-page: https://github.com/stac-utils/stac-fastapi
6
+ Author: Arturo Engineering
7
+ Author-email: engineering@arturo.ai
8
+ License: MIT
9
+ Keywords: STAC FastAPI COG
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Information Technology
12
+ Classifier: Intended Audience :: Science/Research
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
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: attrs
22
+ Requires-Dist: pydantic[dotenv]<2
23
+ Requires-Dist: stac_pydantic==2.0.*
24
+ Requires-Dist: stac-fastapi.types
25
+ Requires-Dist: stac-fastapi.api
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: pytest-asyncio; extra == "dev"
30
+ Requires-Dist: pre-commit; extra == "dev"
31
+ Requires-Dist: requests; extra == "dev"
32
+ Provides-Extra: docs
33
+ Requires-Dist: mkdocs; extra == "docs"
34
+ Requires-Dist: mkdocs-material; extra == "docs"
35
+ Requires-Dist: pdocs; extra == "docs"
@@ -7,7 +7,7 @@ with open("README.md") as f:
7
7
 
8
8
  install_requires = [
9
9
  "attrs",
10
- "pydantic[dotenv]",
10
+ "pydantic[dotenv]<2",
11
11
  "stac_pydantic==2.0.*",
12
12
  "stac-fastapi.types",
13
13
  "stac-fastapi.api",
@@ -36,6 +36,10 @@ setup(
36
36
  "Intended Audience :: Information Technology",
37
37
  "Intended Audience :: Science/Research",
38
38
  "Programming Language :: Python :: 3.8",
39
+ "Programming Language :: Python :: 3.9",
40
+ "Programming Language :: Python :: 3.10",
41
+ "Programming Language :: Python :: 3.11",
42
+ "Programming Language :: Python :: 3.12",
39
43
  "License :: OSI Approved :: MIT License",
40
44
  ],
41
45
  keywords="STAC FastAPI COG",
@@ -1,4 +1,6 @@
1
1
  """Context extension."""
2
+
3
+ import warnings
2
4
  from typing import List, Optional
3
5
 
4
6
  import attr
@@ -24,6 +26,14 @@ class ContextExtension(ApiExtension):
24
26
  default="https://raw.githubusercontent.com/stac-api-extensions/context/v1.0.0-rc.2/json-schema/schema.json"
25
27
  )
26
28
 
29
+ def __attrs_post_init__(self):
30
+ """init."""
31
+ warnings.warm(
32
+ "The ContextExtension is deprecated and will be removed in 3.0.",
33
+ DeprecationWarning,
34
+ stacklevel=1,
35
+ )
36
+
27
37
  def register(self, app: FastAPI) -> None:
28
38
  """Register the extension with a FastAPI application.
29
39
 
@@ -32,7 +32,7 @@ class FieldsExtension(ApiExtension):
32
32
  POST = FieldsExtensionPostRequest
33
33
 
34
34
  conformance_classes: List[str] = attr.ib(
35
- factory=lambda: ["https://api.stacspec.org/v1.0.0-rc.3/item-search#fields"]
35
+ factory=lambda: ["https://api.stacspec.org/v1.0.0/item-search#fields"]
36
36
  )
37
37
  default_includes: Set[str] = attr.ib(
38
38
  factory=lambda: {
@@ -57,7 +57,7 @@ class FilterExtension(ApiExtension):
57
57
  GET /queryables
58
58
  GET /collections/{collection_id}/queryables
59
59
 
60
- https://github.com/radiantearth/stac-api-spec/blob/master/fragments/filter/README.md
60
+ https://github.com/stac-api-extensions/filter/blob/main/README.md
61
61
 
62
62
  Attributes:
63
63
  client: Queryables endpoint logic
@@ -76,6 +76,7 @@ class FilterExtension(ApiExtension):
76
76
  FilterConformanceClasses.FEATURES_FILTER,
77
77
  FilterConformanceClasses.ITEM_SEARCH_FILTER,
78
78
  FilterConformanceClasses.BASIC_CQL2,
79
+ FilterConformanceClasses.CQL2_JSON,
79
80
  FilterConformanceClasses.CQL2_TEXT,
80
81
  ]
81
82
  )
@@ -23,7 +23,7 @@ class QueryExtension(ApiExtension):
23
23
  POST = QueryExtensionPostRequest
24
24
 
25
25
  conformance_classes: List[str] = attr.ib(
26
- factory=lambda: ["https://api.stacspec.org/v1.0.0-rc.2/item-search#query"]
26
+ factory=lambda: ["https://api.stacspec.org/v1.0.0/item-search#query"]
27
27
  )
28
28
  schema_href: Optional[str] = attr.ib(default=None)
29
29
 
@@ -22,7 +22,7 @@ class SortExtension(ApiExtension):
22
22
  POST = SortExtensionPostRequest
23
23
 
24
24
  conformance_classes: List[str] = attr.ib(
25
- factory=lambda: ["https://api.stacspec.org/v1.0.0-rc.2/item-search#sort"]
25
+ factory=lambda: ["https://api.stacspec.org/v1.0.0/item-search#sort"]
26
26
  )
27
27
  schema_href: Optional[str] = attr.ib(default=None)
28
28
 
@@ -1,4 +1,5 @@
1
1
  """Transaction extension."""
2
+
2
3
  from typing import List, Optional, Type, Union
3
4
 
4
5
  import attr
@@ -53,8 +54,7 @@ class TransactionExtension(ApiExtension):
53
54
  settings: ApiSettings = attr.ib()
54
55
  conformance_classes: List[str] = attr.ib(
55
56
  factory=lambda: [
56
- "https://api.stacspec.org/v1.0.0-rc.2/ogcapi-features/extensions/transaction",
57
- "http://www.opengis.net/spec/ogcapi-features-4/1.0/conf/simpletx",
57
+ "https://api.stacspec.org/v1.0.0-rc.3/ogcapi-features/extensions/transaction",
58
58
  ]
59
59
  )
60
60
  schema_href: Optional[str] = attr.ib(default=None)
@@ -118,10 +118,10 @@ class TransactionExtension(ApiExtension):
118
118
  )
119
119
 
120
120
  def register_update_collection(self):
121
- """Register update collection endpoint (PUT /collections)."""
121
+ """Register update collection endpoint (PUT /collections/{collection_id})."""
122
122
  self.router.add_api_route(
123
123
  name="Update Collection",
124
- path="/collections",
124
+ path="/collections/{collection_id}",
125
125
  response_model=Collection if self.settings.enable_response_models else None,
126
126
  response_class=self.response_class,
127
127
  response_model_exclude_unset=True,
@@ -1,5 +1,6 @@
1
1
  """Bulk transactions extension."""
2
2
  import abc
3
+ from enum import Enum
3
4
  from typing import Any, Dict, List, Optional, Union
4
5
 
5
6
  import attr
@@ -11,10 +12,18 @@ from stac_fastapi.api.routes import create_async_endpoint
11
12
  from stac_fastapi.types.extension import ApiExtension
12
13
 
13
14
 
15
+ class BulkTransactionMethod(str, Enum):
16
+ """Bulk Transaction Methods."""
17
+
18
+ INSERT = "insert"
19
+ UPSERT = "upsert"
20
+
21
+
14
22
  class Items(BaseModel):
15
23
  """A group of STAC Item objects, in the form of a dictionary from Item.id -> Item."""
16
24
 
17
25
  items: Dict[str, Any]
26
+ method: BulkTransactionMethod = BulkTransactionMethod.INSERT
18
27
 
19
28
  def __iter__(self):
20
29
  """Return an iterable of STAC Item objects."""
@@ -36,7 +45,10 @@ class BaseBulkTransactionsClient(abc.ABC):
36
45
 
37
46
  @abc.abstractmethod
38
47
  def bulk_item_insert(
39
- self, items: Items, chunk_size: Optional[int] = None, **kwargs
48
+ self,
49
+ items: Items,
50
+ chunk_size: Optional[int] = None,
51
+ **kwargs,
40
52
  ) -> str:
41
53
  """Bulk creation of items.
42
54
 
@@ -55,7 +67,11 @@ class AsyncBaseBulkTransactionsClient(abc.ABC):
55
67
  """BulkTransactionsClient."""
56
68
 
57
69
  @abc.abstractmethod
58
- async def bulk_item_insert(self, items: Items, **kwargs) -> str:
70
+ async def bulk_item_insert(
71
+ self,
72
+ items: Items,
73
+ **kwargs,
74
+ ) -> str:
59
75
  """Bulk creation of items.
60
76
 
61
77
  Args:
@@ -77,11 +93,19 @@ class BulkTransactionExtension(ApiExtension):
77
93
  attribute "items", that has a value that is an object with a group of
78
94
  attributes that are the ids of each Item, and the value is the Item entity.
79
95
 
96
+ Optionally, clients can specify a "method" attribute that is either "insert"
97
+ or "upsert". If "insert", then the items will be inserted if they do not
98
+ exist, and an error will be returned if they do. If "upsert", then the items
99
+ will be inserted if they do not exist, and updated if they do. This defaults
100
+ to "insert".
101
+
80
102
  {
81
- "items": {
82
- "id1": { "type": "Feature", ... },
83
- "id2": { "type": "Feature", ... },
84
- "id3": { "type": "Feature", ... }
103
+ "items": {
104
+ "id1": { "type": "Feature", ... },
105
+ "id2": { "type": "Feature", ... },
106
+ "id3": { "type": "Feature", ... }
107
+ },
108
+ "method": "insert"
85
109
  }
86
110
  """
87
111
 
@@ -1,2 +1,2 @@
1
1
  """Library version."""
2
- __version__ = "2.4.8"
2
+ __version__ = "2.5.0"
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.1
2
+ Name: stac-fastapi.extensions
3
+ Version: 2.5.0
4
+ Summary: An implementation of STAC API based on the FastAPI framework.
5
+ Home-page: https://github.com/stac-utils/stac-fastapi
6
+ Author: Arturo Engineering
7
+ Author-email: engineering@arturo.ai
8
+ License: MIT
9
+ Keywords: STAC FastAPI COG
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Information Technology
12
+ Classifier: Intended Audience :: Science/Research
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
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: attrs
22
+ Requires-Dist: pydantic[dotenv]<2
23
+ Requires-Dist: stac_pydantic==2.0.*
24
+ Requires-Dist: stac-fastapi.types
25
+ Requires-Dist: stac-fastapi.api
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: pytest-asyncio; extra == "dev"
30
+ Requires-Dist: pre-commit; extra == "dev"
31
+ Requires-Dist: requests; extra == "dev"
32
+ Provides-Extra: docs
33
+ Requires-Dist: mkdocs; extra == "docs"
34
+ Requires-Dist: mkdocs-material; extra == "docs"
35
+ Requires-Dist: pdocs; extra == "docs"
@@ -28,4 +28,5 @@ stac_fastapi/extensions/core/sort/__init__.py
28
28
  stac_fastapi/extensions/core/sort/request.py
29
29
  stac_fastapi/extensions/core/sort/sort.py
30
30
  stac_fastapi/extensions/third_party/__init__.py
31
- stac_fastapi/extensions/third_party/bulk_transactions.py
31
+ stac_fastapi/extensions/third_party/bulk_transactions.py
32
+ tests/test_transaction.py
@@ -1,5 +1,5 @@
1
1
  attrs
2
- pydantic[dotenv]
2
+ pydantic[dotenv]<2
3
3
  stac_pydantic==2.0.*
4
4
  stac-fastapi.types
5
5
  stac-fastapi.api
@@ -0,0 +1,121 @@
1
+ import json
2
+ from typing import Iterator, Union
3
+
4
+ import pytest
5
+ from starlette.testclient import TestClient
6
+
7
+ from stac_fastapi.api.app import StacApi
8
+ from stac_fastapi.extensions.core import TransactionExtension
9
+ from stac_fastapi.types.config import ApiSettings
10
+ from stac_fastapi.types.core import BaseCoreClient, BaseTransactionsClient
11
+ from stac_fastapi.types.stac import Item, ItemCollection
12
+
13
+
14
+ class DummyCoreClient(BaseCoreClient):
15
+ def all_collections(self, *args, **kwargs):
16
+ raise NotImplementedError
17
+
18
+ def get_collection(self, *args, **kwargs):
19
+ raise NotImplementedError
20
+
21
+ def get_item(self, *args, **kwargs):
22
+ raise NotImplementedError
23
+
24
+ def get_search(self, *args, **kwargs):
25
+ raise NotImplementedError
26
+
27
+ def post_search(self, *args, **kwargs):
28
+ raise NotImplementedError
29
+
30
+ def item_collection(self, *args, **kwargs):
31
+ raise NotImplementedError
32
+
33
+
34
+ class DummyTransactionsClient(BaseTransactionsClient):
35
+ """Defines a pattern for implementing the STAC transaction extension."""
36
+
37
+ def create_item(self, item: Union[Item, ItemCollection], *args, **kwargs):
38
+ return {"created": True, "type": item["type"]}
39
+
40
+ def update_item(self, *args, **kwargs):
41
+ raise NotImplementedError
42
+
43
+ def delete_item(self, *args, **kwargs):
44
+ raise NotImplementedError
45
+
46
+ def create_collection(self, *args, **kwargs):
47
+ raise NotImplementedError
48
+
49
+ def update_collection(self, *args, **kwargs):
50
+ raise NotImplementedError
51
+
52
+ def delete_collection(self, *args, **kwargs):
53
+ raise NotImplementedError
54
+
55
+
56
+ def test_create_item(client: TestClient, item: Item) -> None:
57
+ response = client.post("/collections/a-collection/items", content=json.dumps(item))
58
+ assert response.is_success, response.text
59
+ assert response.json()["type"] == "Feature"
60
+
61
+
62
+ def test_create_item_collection(
63
+ client: TestClient, item_collection: ItemCollection
64
+ ) -> None:
65
+ response = client.post(
66
+ "/collections/a-collection/items", content=json.dumps(item_collection)
67
+ )
68
+ assert response.is_success, response.text
69
+ assert response.json()["type"] == "FeatureCollection"
70
+
71
+
72
+ @pytest.fixture
73
+ def client(
74
+ core_client: DummyCoreClient, transactions_client: DummyTransactionsClient
75
+ ) -> Iterator[TestClient]:
76
+ settings = ApiSettings()
77
+ api = StacApi(
78
+ settings=settings,
79
+ client=core_client,
80
+ extensions=[
81
+ TransactionExtension(client=transactions_client, settings=settings),
82
+ ],
83
+ )
84
+ with TestClient(api.app) as client:
85
+ yield client
86
+
87
+
88
+ @pytest.fixture
89
+ def core_client() -> DummyCoreClient:
90
+ return DummyCoreClient()
91
+
92
+
93
+ @pytest.fixture
94
+ def transactions_client() -> DummyTransactionsClient:
95
+ return DummyTransactionsClient()
96
+
97
+
98
+ @pytest.fixture
99
+ def item_collection(item: Item) -> ItemCollection:
100
+ return {
101
+ "type": "FeatureCollection",
102
+ "features": [item],
103
+ "links": [],
104
+ "context": None,
105
+ }
106
+
107
+
108
+ @pytest.fixture
109
+ def item() -> Item:
110
+ return {
111
+ "type": "Feature",
112
+ "stac_version": "1.0.0",
113
+ "stac_extensions": [],
114
+ "id": "test_item",
115
+ "geometry": {"type": "Point", "coordinates": [-105, 40]},
116
+ "bbox": [-105, 40, -105, 40],
117
+ "properties": {},
118
+ "links": [],
119
+ "assets": {},
120
+ "collection": "test_collection",
121
+ }
@@ -1,18 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: stac-fastapi.extensions
3
- Version: 2.4.8
4
- Summary: An implementation of STAC API based on the FastAPI framework.
5
- Home-page: https://github.com/stac-utils/stac-fastapi
6
- Author: Arturo Engineering
7
- Author-email: engineering@arturo.ai
8
- License: MIT
9
- Keywords: STAC FastAPI COG
10
- Classifier: Intended Audience :: Developers
11
- Classifier: Intended Audience :: Information Technology
12
- Classifier: Intended Audience :: Science/Research
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: License :: OSI Approved :: MIT License
15
- Requires-Python: >=3.8
16
- Description-Content-Type: text/markdown
17
- Provides-Extra: dev
18
- Provides-Extra: docs
@@ -1,18 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: stac-fastapi.extensions
3
- Version: 2.4.8
4
- Summary: An implementation of STAC API based on the FastAPI framework.
5
- Home-page: https://github.com/stac-utils/stac-fastapi
6
- Author: Arturo Engineering
7
- Author-email: engineering@arturo.ai
8
- License: MIT
9
- Keywords: STAC FastAPI COG
10
- Classifier: Intended Audience :: Developers
11
- Classifier: Intended Audience :: Information Technology
12
- Classifier: Intended Audience :: Science/Research
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: License :: OSI Approved :: MIT License
15
- Requires-Python: >=3.8
16
- Description-Content-Type: text/markdown
17
- Provides-Extra: dev
18
- Provides-Extra: docs