stac-fastapi

repository·main·Indexed 43 days ago

https://github.com/stac-utils/stac-fastapi

A Python library and FastAPI-based implementation of the SpatioTemporal Asset Catalog (STAC) API specification. Version 7.0.0 provides the infrastructure to build compliant STAC APIs, including core API logic, shared types, and various extensions for pagination, aggregation, and filtering. It supports multiple backends, with PostgreSQL + PostGIS + PgSTAC being the recommended implementation.

Tokens
14.4K
Snippets
36
Records
56
Agent score
55%

What's inside stac-fastapi

  1. Overview of stac-fastapi packages and namespaces

    main

    The stac-fastapi project is a Python library for building STAC-compliant (SpatioTemporal Asset Catalogs) FastAPI applications. It is organized into several modular packages:

    • stac_fastapi.api: The API layer that enforces the stac-api-spec.
    • stac_fastapi.extensions: Provides abstract base classes for implementing STAC API extensions and third-party extensions.
    • stac_fastapi.types: Contains shared types and abstract base classes used throughout the library.
  2. Explore the stac_fastapi namespace structure

    main

    The stac_fastapi package is organized into several specialized sub-modules that provide the core functionality for STAC (SpatioTemporal Asset Catalog) API implementations:

    • stac_fastapi.api: Contains the core API logic and endpoint definitions.
    • stac_fastapi.extensions: Provides additional functionality and extensions to the base STAC API.
    • stac_fastapi.types: Defines the data models and type definitions used throughout the library to ensure STAC compliance.
  3. Use pagination extensions in stac-fastapi

    main

    The stac_fastapi.extensions.pagination module provides various pagination strategies for STAC API implementations. You can choose between different pagination sub-modules depending on your requirements:

    • stac_fastapi.extensions.pagination.pagination: General pagination utilities.
    • stac_fastapi.extensions.pagination.offset_pagination: Implements offset-based pagination (using offset and limit).
    • stac_fastapi.extensions.pagination.token_pagination: Implements token-based (cursor) pagination for better performance on large datasets.
    • stac_fastapi.extensions.pagination.request: Utilities for handling pagination parameters within incoming requests.
  4. Handle datetime as strings in GET request models

    main

    Starting with stac-fastapi v4.0, the datetime attribute in BaseSearchGetRequest, ItemCollectionUri, and BaseCollectionSearchGetRequest models has changed from a Python datetime.datetime type to a string type. This ensures the attribute matches the validation behavior of Pydantic models. When receiving a GET request, the datetime value passed to your client implementation will now be a string (the raw user input) rather than a parsed datetime object.

    To work with parsed dates, use the .parse_datetime(), .start_date, and .end_date methods provided by the request models.

    from stac_fastapi.types.search import BaseSearchGetRequest
    import datetime
    
    # For an Interval (e.g., "start/end")
    search = BaseSearchGetRequest(datetime="2020-01-01T00:00:00.00001Z/2020-01-02T00:00:00.00001Z")
    search.parse_datetime()
    print(search.start_date) # datetime.datetime(2020, 1, 1, ...)
    print(search.end_date)   # datetime.datetime(2020, 1, 2, ...)
    
    # For a Single date
    search = BaseSearchGetRequest(datetime="2020-01-01T00:00:00.00001Z")
    search.parse_datetime()
    print(search.start_date) # datetime.datetime(2020, 1, 1, ...)
    print(search.end_date)   # None
  5. Implement Custom GET Request Models using APIRequest

    main

    Most GET endpoints use stac_fastapi.types.search.APIRequest as a base class. These classes are constructed using the attrs library.

    Requirements for custom models:

    1. Use the @attr.s decorator.
    2. Use Type Hints for every attribute.
    3. Use Annotated[{type}, fastapi.Query()] for FastAPI query parameter integration.
    4. If using a converter, the type hint must be defined directly in the converter signature.

    Example: Defining a custom request with a query alias:

    @attr.s
    class SomeRequest(APIRequest):
        user_number: Annotated[Optional[int], Query(alias="user-number")] = attr.ib(default=None)

    Example: Using a converter:

    def _ids_converter(
        val: Annotated[
            Optional[str],
            Query(
                description="Array of Item ids to return.",
            ),
        ] = None,
    ) -> Optional[List[str]]:
        return str2list(val)
    
    @attr.s
    class BaseSearchGetRequest(APIRequest):
        ids: Optional[List[str]] = attr.ib(default=None, converter=_ids_converter)
  6. Quickstart: Install and launch a PgSTAC API

    main

    To get a basic STAC API running using the PgSTAC backend, follow these steps to install the core components, the backend, and then launch the server using uvicorn.

    Note: The API will be accessible at http://localhost:8080.

    # Install core software from PyPI
    python -m pip install stac-fastapi.types stac-fastapi.api stac-fastapi.extensions uvicorn
    
    # Install a backend of your choice, here's PgSTAC
    python -m pip install stac-fastapi.pgstac
    
    # Launch the API
    uvicorn stac_fastapi.pgstac.app:app --host 0.0.0.0 --port 8080
  7. Handle model validation when using the Fields extension

    main

    In stac-fastapi v3.0 and later, using the FieldsExtension can cause model validation errors if the /search endpoint returns items that do not strictly adhere to the STAC specification (which can happen when specific fields are filtered out).

    To prevent validation failures at the application level when the fields option is present in a request, you must bypass the validation step at the Client level. This is achieved by returning a JSONResponse instead of a STAC object (like stac.ItemCollection) within your post_search and get_search client methods when the fields parameter is detected.

    from fastapi.responses import JSONResponse
    
    class MyCoreClient(BaseCoreClient):
        def post_search(
            self, search_request: BaseSearchPostRequest, **kwargs
        ) -> stac.ItemCollection:
            resp = {"not": "a proper stac item"}
    
            # If `fields` extension is enabled, return a JSONResponse 
            # to avoid Item validation errors
            if getattr(search_request, "fields", None):
                return JSONResponse(content=resp)
    
            return resp
    
        def get_search(
            self, 
            collections: Optional[List[str]] = None, 
            **kwargs
        ) -> stac.ItemCollection:
            resp = {"not": "a proper stac item"}
    
            # If `fields` is in kwargs, return a JSONResponse to avoid validation
            if "fields" in kwargs:
                return JSONResponse(content=resp)
    
            return resp
  8. Configure Application Middlewares in StacApi

    main

    By default, the StacApi class enables three middlewares: BrotliMiddleware, CORSMiddleware, and ProxyHeaderMiddleware. To customize or overwrite these defaults (for example, to restrict CORS origins), pass a list of starlette.middleware.Middleware objects to the middlewares argument when initializing StacApi.

    from starlette.middleware import Middleware
    from stac_fastapi.api.app import StacApi
    from starlette.middleware.cors import CORSMiddleware
    
    api = StacApi(
        ...
        middlewares=[
            Middleware(CORSMiddleware, allow_origins=["https://myendpoints.io"])
        ],
        ...
    )
  9. Install STAC FastAPI core dependencies

    main

    To use STAC FastAPI, install the core packages and uvicorn via pip. It is recommended to use a virtual environment.

    # Create a virtual environment
    python -m venv env
    source ./env/bin/activate
    
    # Install core dependencies
    python -m pip install stac-fastapi.types stac-fastapi.api stac-fastapi.extensions uvicorn
  10. Migrate from stac-fastapi v3.0 to v4.0

    main

    When upgrading from version 3.0 to 4.0, ensure you address the following breaking changes:

    1. Datetime Types: Update logic that expects datetime.datetime objects in BaseSearchGetRequest, ItemCollectionUri, or BaseCollectionSearchGetRequest GET models; these now receive string types.
    2. Filter Renaming: Update references to filter to filter_expr when interacting with FilterExtensionGetRequest or FilterExtensionPostRequest attributes.
    3. Client Attribute Removal: The post_request_model attribute has been removed from BaseCoreClient and AsyncBaseCoreClient.
    4. Python Version: Support for python3.8 has been removed.