diff --git a/CHANGES.md b/CHANGES.md index 07a80ad05..68bcc505e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Deprecated + +- Deprecated `BulkTransactionExtension` (`POST /collections/{collection_id}/bulk_items`). Use `TransactionExtension` instead, which supports `ItemCollection` payloads on `POST /collections/{collection_id}/items`. ([#987](https://github.com/stac-utils/stac-fastapi/pull/987)) + ### Fixed - Return a `Location` header with the URI of the newly created resource for `POST /collections/{collection_id}/items` (single `Item`) and `POST /collections` in the Transaction extension, as required by the spec. `ItemCollection` payloads still return 201 without a `Location` header. The header is also added when a client returns a `Response` object directly, unless it already sets `Location` or returns an error status. ([#982](https://github.com/stac-utils/stac-fastapi/pull/982)) diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/bulk_transactions/bulk_transactions.py b/stac_fastapi/extensions/stac_fastapi/extensions/bulk_transactions/bulk_transactions.py index 242026188..a12deea61 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/bulk_transactions/bulk_transactions.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/bulk_transactions/bulk_transactions.py @@ -1,6 +1,7 @@ """Bulk transactions extension.""" import abc +import warnings from collections.abc import Sequence from enum import StrEnum from typing import Any, TypedDict @@ -123,6 +124,10 @@ async def bulk_item_insert( class BulkTransactionExtension(ApiExtension): """Bulk Transaction Extension. + Deprecated: this extension is deprecated and will be removed in a future + release. Use `TransactionExtension` instead, which supports `ItemCollection` + payloads on `POST /collections/{collection_id}/items`. + Bulk Transaction extension adds the `POST /collections/{collection_id}/bulk_items` endpoint to the application for efficient bulk insertion of items. The input to this is an object with an @@ -151,6 +156,17 @@ class BulkTransactionExtension(ApiExtension): route_dependencies: Sequence[Depends] | None = attr.ib(default=None) enable_response_models: bool = attr.ib(default=True) + def __attrs_post_init__(self): + """Warn about the extension's deprecation.""" + warnings.warn( + "BulkTransactionExtension is deprecated and will be removed in a " + "future release. Use TransactionExtension instead, which supports " + "ItemCollection payloads on " + "POST /collections/{collection_id}/items.", + DeprecationWarning, + stacklevel=2, + ) + def register(self, app: FastAPI) -> None: """Register the extension with a FastAPI application. @@ -166,6 +182,7 @@ def register(self, app: FastAPI) -> None: router.add_api_route( name="Bulk Create Item", path="/collections/{collection_id}/bulk_items", + deprecated=True, response_model=BulkTransactionModel, responses={ 200: { diff --git a/stac_fastapi/extensions/tests/test_bulk_transactions.py b/stac_fastapi/extensions/tests/test_bulk_transactions.py index 1a7181a8e..b98ee0033 100644 --- a/stac_fastapi/extensions/tests/test_bulk_transactions.py +++ b/stac_fastapi/extensions/tests/test_bulk_transactions.py @@ -50,10 +50,17 @@ def test_base_client_chunks(): assert chunks_large == [[1, 2, 3, 4, 5, 6, 7]] +def test_bulk_transaction_extension_deprecated(): + """BulkTransactionExtension emits a DeprecationWarning.""" + with pytest.warns(DeprecationWarning, match="deprecated"): + BulkTransactionExtension(client=Mock(spec=AsyncBaseBulkTransactionsClient)) + + def test_bulk_transaction_extension_defaults(): """Test the default instantiation of the BulkTransactionExtension.""" mock_client = Mock(spec=AsyncBaseBulkTransactionsClient) - ext = BulkTransactionExtension(client=mock_client) + with pytest.warns(DeprecationWarning, match="deprecated"): + ext = BulkTransactionExtension(client=mock_client) assert ext.client == mock_client assert ext.schema_href is None @@ -67,12 +74,13 @@ def test_bulk_transaction_extension_customization(): custom_schema = "https://example.com/bulk-schema.json" custom_dependencies = [Depends(must_be_bob)] - ext = BulkTransactionExtension( - client=mock_client, - conformance_classes=custom_conformance, - schema_href=custom_schema, - route_dependencies=custom_dependencies, - ) + with pytest.warns(DeprecationWarning, match="deprecated"): + ext = BulkTransactionExtension( + client=mock_client, + conformance_classes=custom_conformance, + schema_href=custom_schema, + route_dependencies=custom_dependencies, + ) assert ext.conformance_classes == custom_conformance assert ext.schema_href == custom_schema @@ -154,13 +162,14 @@ def client( ) -> Iterator[TestClient]: """Fixture to set up the TestClient with the BulkTransactionExtension.""" settings = ApiSettings() - api = StacApi( - settings=settings, - client=core_client, - extensions=[ - BulkTransactionExtension(client=bulk_transactions_client), - ], - ) + with pytest.warns(DeprecationWarning, match="deprecated"): + api = StacApi( + settings=settings, + client=core_client, + extensions=[ + BulkTransactionExtension(client=bulk_transactions_client), + ], + ) with TestClient(api.app) as client: yield client @@ -169,13 +178,14 @@ def client( def client_with_error(core_client: DummyCoreClient) -> Iterator[TestClient]: """Fixture to set up the TestClient with the BulkTransactionExtension.""" settings = ApiSettings() - api = StacApi( - settings=settings, - client=core_client, - extensions=[ - BulkTransactionExtension(client=DummyBulkTransactionsClientWithError()), - ], - ) + with pytest.warns(DeprecationWarning, match="deprecated"): + api = StacApi( + settings=settings, + client=core_client, + extensions=[ + BulkTransactionExtension(client=DummyBulkTransactionsClientWithError()), + ], + ) with TestClient(api.app) as client: yield client @@ -242,16 +252,17 @@ def test_bulk_item_invalid_method(client: TestClient, item: dict) -> None: def test_bulk_item_insert_with_route_dependencies(item: dict) -> None: """Test route dependencies are applied to the bulk transactions route.""" settings = ApiSettings() - api = StacApi( - settings=settings, - client=DummyCoreClient(), - extensions=[ - BulkTransactionExtension( - client=DummyBulkTransactionsClient(), - route_dependencies=[Depends(must_be_bob)], - ), - ], - ) + with pytest.warns(DeprecationWarning, match="deprecated"): + api = StacApi( + settings=settings, + client=DummyCoreClient(), + extensions=[ + BulkTransactionExtension( + client=DummyBulkTransactionsClient(), + route_dependencies=[Depends(must_be_bob)], + ), + ], + ) payload = { "items": {item["id"]: item}, "method": "insert",