diff --git a/CHANGES.md b/CHANGES.md index e1a7e29ff..1c5ed2c00 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,7 +9,9 @@ ### Changed * Added option for default route dependencies `*` can be used for `path` or `method` to match all allowed route. ([#705](https://github.com/stac-utils/stac-fastapi/pull/705)) -* moved `AsyncBaseFiltersClient` and `BaseFiltersClient` classes in `stac_fastapi.extensions.core.filter.client` submodule ([#704](https://github.com/stac-utils/stac-fastapi/pull/704)) +* Moved `AsyncBaseFiltersClient` and `BaseFiltersClient` classes in `stac_fastapi.extensions.core.filter.client` submodule ([#704](https://github.com/stac-utils/stac-fastapi/pull/704)) +* Removed `default_includes` from `stac_fastapi.types.config.ApiSettings` ([#706](https://github.com/stac-utils/stac-fastapi/pull/706)) +* Deprecated *Fields* extension `PostFieldsExtension.filter_fields` property ([#706](https://github.com/stac-utils/stac-fastapi/pull/706)) ## [3.0.0a2] - 2024-05-31 diff --git a/docs/src/tips-and-tricks.md b/docs/src/tips-and-tricks.md index a5ca8cb68..ef9a97ae8 100644 --- a/docs/src/tips-and-tricks.md +++ b/docs/src/tips-and-tricks.md @@ -45,3 +45,55 @@ For the landing page, you can set the API title, description and version using e - `STAC FASTAPI_TITLE` (string) should be a self-explanatory title for your API. - `STAC FASTAPI_DESCRIPTION` (string) should be a good description for your API. It can contain CommonMark. - `STAC_FASTAPI_LANDING_ID` (string) is a unique identifier for your Landing page. + + +## Default `includes` in Fields extension (POST request) + +The [**Fields** API extension](https://github.com/stac-api-extensions/fields) enables to filter in/out STAC Items keys (e.g `geometry`). The default behavior is to not filter out anything, but this can be overridden by providing a custom `FieldsExtensionPostRequest` class: + +```python +from typing import Optional, Set + +import attr +from stac_fastapi.extensions import FieldsExtension as FieldsExtensionBase +from stac_fastapi.extensions.core.fields import requests +from pydantic import BaseModel, Field + + +class PostFieldsExtension(requests.PostFieldsExtension): + include: Optional[Set[str]] = Field( + default_factory=lambda: { + "id", + "type", + "stac_version", + "geometry", + "bbox", + "links", + "assets", + "properties.datetime", + "collection", + } + ) + exclude: Optional[Set[str]] = set() + + +class FieldsExtensionPostRequest(BaseModel): + """Additional fields and schema for the POST request.""" + + fields: Optional[PostFieldsExtension] = Field(PostFieldsExtension()) + + +class FieldsExtension(FieldsExtensionBase): + """Override the POST model""" + + POST = FieldsExtensionPostRequest + + +from stac_fastapi.api.app import StacApi + +stac = StacApi( + extensions=[ + FieldsExtension() + ] +) +``` diff --git a/stac_fastapi/api/stac_fastapi/api/app.py b/stac_fastapi/api/stac_fastapi/api/app.py index 7eb7c4e80..5fe7f9d08 100644 --- a/stac_fastapi/api/stac_fastapi/api/app.py +++ b/stac_fastapi/api/stac_fastapi/api/app.py @@ -458,10 +458,6 @@ def __attrs_post_init__(self): self.client.title = self.title self.client.description = self.description - fields_ext = self.get_extension(FieldsExtension) - if fields_ext: - self.settings.default_includes = fields_ext.default_includes - Settings.set(self.settings) self.app.state.settings = self.settings diff --git a/stac_fastapi/api/tests/test_api.py b/stac_fastapi/api/tests/test_api.py index deff0c070..d559a377a 100644 --- a/stac_fastapi/api/tests/test_api.py +++ b/stac_fastapi/api/tests/test_api.py @@ -2,7 +2,10 @@ from starlette.testclient import TestClient from stac_fastapi.api.app import StacApi -from stac_fastapi.extensions.core import TokenPaginationExtension, TransactionExtension +from stac_fastapi.extensions.core import ( + TokenPaginationExtension, + TransactionExtension, +) from stac_fastapi.types import config, core diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/fields.py b/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/fields.py index 25b6fe252..90b4b2697 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/fields.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/fields.py @@ -1,6 +1,6 @@ """Fields extension.""" -from typing import List, Optional, Set +from typing import List, Optional import attr from fastapi import FastAPI @@ -35,19 +35,6 @@ class FieldsExtension(ApiExtension): conformance_classes: List[str] = attr.ib( factory=lambda: ["https://api.stacspec.org/v1.0.0/item-search#fields"] ) - default_includes: Set[str] = attr.ib( - factory=lambda: { - "id", - "type", - "stac_version", - "geometry", - "bbox", - "links", - "assets", - "properties.datetime", - "collection", - } - ) schema_href: Optional[str] = attr.ib(default=None) def register(self, app: FastAPI) -> None: diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/request.py b/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/request.py index 4cfbd3293..e08572ca0 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/request.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/core/fields/request.py @@ -1,11 +1,11 @@ """Request models for the fields extension.""" +import warnings from typing import Dict, Optional, Set import attr from pydantic import BaseModel, Field -from stac_fastapi.types.config import Settings from stac_fastapi.types.search import APIRequest, str2list @@ -39,6 +39,7 @@ def _get_field_dict(fields: Optional[Set[str]]) -> Dict: field_dict[parent].add(key) else: field_dict[field] = ... # type:ignore + return field_dict @property @@ -49,10 +50,17 @@ def filter_fields(self) -> Dict: the included and excluded fields passed to the API Ref: https://pydantic-docs.helpmanual.io/usage/exporting_models/#advanced-include-and-exclude """ + warnings.warn( + """The `PostFieldsExtension.filter_fields` + method is deprecated and will be removed in 3.0.""", + DeprecationWarning, + stacklevel=1, + ) + # Always include default_includes, even if they # exist in the exclude list. include = (self.include or set()) - (self.exclude or set()) - include |= Settings.get().default_includes or set() + include |= set() return { "include": self._get_field_dict(include), diff --git a/stac_fastapi/types/stac_fastapi/types/config.py b/stac_fastapi/types/stac_fastapi/types/config.py index d692043cc..75d0bd399 100644 --- a/stac_fastapi/types/stac_fastapi/types/config.py +++ b/stac_fastapi/types/stac_fastapi/types/config.py @@ -1,6 +1,6 @@ """stac_fastapi.types.config module.""" -from typing import Optional, Set +from typing import Optional from pydantic_settings import BaseSettings, SettingsConfigDict @@ -19,10 +19,6 @@ class ApiSettings(BaseSettings): as distinct columns in the database. """ - # TODO: Remove `default_includes` attribute so we can use - # `pydantic.BaseSettings` instead - default_includes: Optional[Set[str]] = None - stac_fastapi_title: str = "stac-fastapi" stac_fastapi_description: str = "stac-fastapi" stac_fastapi_version: str = "0.1"