Skip to content

Commit

Permalink
Add base and extension conformance distinction
Browse files Browse the repository at this point in the history
  • Loading branch information
moradology committed Aug 12, 2021
1 parent 1a344f1 commit 95f905f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
61 changes: 48 additions & 13 deletions stac_fastapi/types/stac_fastapi/types/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class BaseTransactionsClient(abc.ABC):
"""Defines a pattern for implementing the STAC transaction extension."""


@abc.abstractmethod
def create_item(self, item: stac_types.Item, **kwargs) -> stac_types.Item:
"""Create a new item.
Expand Down Expand Up @@ -231,22 +232,16 @@ class LandingPageMixin:
landing_page_id: str = attr.ib(default="stac-fastapi")
title: str = attr.ib(default="stac-fastapi")
description: str = attr.ib(default="stac-fastapi")
conformance_classes: List[str] = attr.ib(
factory=lambda: [
"https://api.stacspec.org/v1.0.0-beta.2/core",
"https://api.stacspec.org/v1.0.0-beta.2/ogcapi-features",
"https://api.stacspec.org/v1.0.0-beta.2/item-search",
]
)

def _landing_page(self, base_url: str) -> stac_types.LandingPage:

def _landing_page(self, base_url: str, conformance_classes: List[str]) -> stac_types.LandingPage:
landing_page = stac_types.LandingPage(
type="Catalog",
id=self.landing_page_id,
title=self.title,
description=self.description,
stac_version=self.stac_version,
conformsTo=self.conformance_classes,
conformsTo=conformance_classes,
links=[
{
"rel": Relations.self.value,
Expand Down Expand Up @@ -290,6 +285,16 @@ class BaseCoreClient(LandingPageMixin, abc.ABC):
extensions: list of registered api extensions.
"""

base_conformance_classes: List[str] = attr.ib(
factory=lambda: [
"https://api.stacspec.org/v1.0.0-beta.2/core",
"https://api.stacspec.org/v1.0.0-beta.2/ogcapi-features",
"https://api.stacspec.org/v1.0.0-beta.2/item-search",
"http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core",
"http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30",
"http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson",
]
)
extensions: List[ApiExtension] = attr.ib(default=attr.Factory(list))
conformance_classes: List[str] = attr.ib(
factory=lambda: [
Expand All @@ -298,6 +303,16 @@ class BaseCoreClient(LandingPageMixin, abc.ABC):
]
)

def conformance_classes(self) -> List[str]:
"""Generate conformance classes by adding extension conformance to base conformance classes"""
base_conformance_classes = self.base_conformance_classes.copy()

for extension in self.extensions:
extension_classes = getattr(extension, "conformance_classes", [])
base_conformance_classes.extend(extension_classes)

return list(set(base_conformance_classes))

def extension_is_enabled(self, extension: Type[ApiExtension]) -> bool:
"""Check if an api extension is enabled."""
return any([isinstance(ext, extension) for ext in self.extensions])
Expand All @@ -311,7 +326,7 @@ def landing_page(self, **kwargs) -> stac_types.LandingPage:
API landing page, serving as an entry point to the API.
"""
base_url = str(kwargs["request"].base_url)
landing_page = self._landing_page(base_url=base_url)
landing_page = self._landing_page(base_url=base_url, conformance_classes=self.conformance_classes())
collections = self.all_collections(request=kwargs["request"])
for collection in collections:
landing_page["links"].append(
Expand All @@ -332,7 +347,7 @@ def conformance(self, **kwargs) -> stac_types.Conformance:
Returns:
Conformance classes which the server conforms to.
"""
return Conformance(conformsTo=self.conformance_classes)
return Conformance(conformsTo=self.conformance_classes())

@abc.abstractmethod
def post_search(
Expand Down Expand Up @@ -440,6 +455,16 @@ class AsyncBaseCoreClient(LandingPageMixin, abc.ABC):
extensions: list of registered api extensions.
"""

base_conformance_classes: List[str] = attr.ib(
factory=lambda: [
"https://api.stacspec.org/v1.0.0-beta.2/core",
"https://api.stacspec.org/v1.0.0-beta.2/ogcapi-features",
"https://api.stacspec.org/v1.0.0-beta.2/item-search",
"http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core",
"http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30",
"http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson",
]
)
extensions: List[ApiExtension] = attr.ib(default=attr.Factory(list))
conformance_classes: List[str] = attr.ib(
factory=lambda: [
Expand All @@ -448,6 +473,16 @@ class AsyncBaseCoreClient(LandingPageMixin, abc.ABC):
]
)

def conformance_classes(self) -> List[str]:
"""Generate conformance classes by adding extension conformance to base conformance classes"""
conformance_classes = self.base_conformance_classes.copy()

for extension in self.extensions:
extension_classes = getattr(extension, "conformance_classes", [])
conformance_classes.extend(extension_classes)

return list(set(conformance_classes))

def extension_is_enabled(self, extension: Type[ApiExtension]) -> bool:
"""Check if an api extension is enabled."""
return any([isinstance(ext, extension) for ext in self.extensions])
Expand All @@ -461,7 +496,7 @@ async def landing_page(self, **kwargs) -> stac_types.LandingPage:
API landing page, serving as an entry point to the API.
"""
base_url = str(kwargs["request"].base_url)
landing_page = self._landing_page(base_url=base_url)
landing_page = self._landing_page(base_url=base_url, conformance_classes=self.conformance_classes())
collections = await self.all_collections(request=kwargs["request"])
for collection in collections:
landing_page["links"].append(
Expand All @@ -482,7 +517,7 @@ async def conformance(self, **kwargs) -> stac_types.Conformance:
Returns:
Conformance classes which the server conforms to.
"""
return Conformance(conformsTo=self.conformance_classes)
return Conformance(conformsTo=self.conformance_classes())

@abc.abstractmethod
async def post_search(
Expand Down
3 changes: 3 additions & 0 deletions stac_fastapi/types/stac_fastapi/types/extension.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""base api extension."""
import abc
from typing import List

import attr
from fastapi import FastAPI
Expand All @@ -9,6 +10,8 @@
class ApiExtension(abc.ABC):
"""Abstract base class for defining API extensions."""

conformance_classes: List[str] = attr.ib(factory=list)

@abc.abstractmethod
def register(self, app: FastAPI) -> None:
"""Register the extension with a FastAPI application.
Expand Down

0 comments on commit 95f905f

Please sign in to comment.