[Python] Running and Serving star-fastapi using Docker

Discussão em 'Python' iniciado por Stack, Maio 21, 2025.

  1. Stack

    Stack Membro Participativo

    I have just started using the stack-fastapi backend. I navigated to the pgstac directory and then ran the command 'python app.py' to start the server. This brought up the following error and I don't have any idea of where or how to resolve the issue. I have looked for the files described in the traceback:

    > ERROR: Traceback (most recent call last): File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/starlette/routing.py",
    > line 692, in lifespan async with self.lifespan_context(app) as
    > maybe_state: File
    > "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py",
    > line 210, in aenter return await anext(self.gen) ^^^^^^^^^^^^^^^^^^^^^
    > File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/fastapi/routing.py",
    > line 133, in merged_lifespan async with original_context(app) as
    > maybe_original_state: File
    > "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py",
    > line 210, in aenter return await anext(self.gen) ^^^^^^^^^^^^^^^^^^^^^
    > File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/fastapi/routing.py",
    > line 133, in merged_lifespan async with original_context(app) as
    > maybe_original_state: File
    > "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py",
    > line 210, in aenter return await anext(self.gen) ^^^^^^^^^^^^^^^^^^^^^
    > File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/fastapi/routing.py",
    > line 133, in merged_lifespan async with original_context(app) as
    > maybe_original_state: File
    > "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py",
    > line 210, in aenter return await anext(self.gen) ^^^^^^^^^^^^^^^^^^^^^
    > File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/fastapi/routing.py",
    > line 133, in merged_lifespan async with original_context(app) as
    > maybe_original_state: File
    > "/usr/local/Cellar/python@3.12/3.12.4/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py",
    > line 210, in aenter return await anext(self.gen) ^^^^^^^^^^^^^^^^^^^^^
    > File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/stac_fastapi/pgstac/app.py",
    > line 158, in lifespan await connect_to_db(app,
    > add_write_connection_pool=with_transactions) File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/stac_fastapi/pgstac/db.py",
    > line 71, in connect_to_db postgres_settings = PostgresSettings()
    > ^^^^^^^^^^^^^^^^^^ File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/pydantic_settings/main.py", line 176, in init super().init( File
    > "/Users/andrewchibwesha/STAC-FASTAPI/stac-fastapi-pgstac/.venv/lib/python3.12/site-packages/pydantic/main.py",
    > line 253, in init validated_self =
    > self.pydantic_validator.validate_python(data, self_instance=self)
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > pydantic_core._pydantic_core.ValidationError: 5 validation errors for
    > PostgresSettings pguser Field required [type=missing, input_value={},
    > input_type=dict] For further information visit
    > https://errors.pydantic.dev/2.11/v/missing pgpassword Field required
    > [type=missing, input_value={}, input_type=dict] For further
    > information visit https://errors.pydantic.dev/2.11/v/missing pghost
    > Field required [type=missing, input_value={}, input_type=dict] For
    > further information visit https://errors.pydantic.dev/2.11/v/missing
    > pgport Field required [type=missing, input_value={}, input_type=dict]
    > For further information visit
    > https://errors.pydantic.dev/2.11/v/missing pgdatabase Field required
    > [type=missing, input_value={}, input_type=dict] For further
    > information visit https://errors.pydantic.dev/2.11/v/missing
    >
    > ERROR: Application startup failed. Exiting.


    To provide some context - I am referring to the FASTAPI application file, the code is as follows:


    """FastAPI application using PGStac.

    Enables the extensions specified as a comma the ENABLED_EXTENSIONS environment variable If the variable is not set, enables all ext """

    import os from contextlib import asynccontextmanager

    from brotli_asgi import BrotliMiddleware from fastapi import FastAPI from stac_fastapi.api.app import StacApi from


    stac_fastapi.api.middleware import COR from stac_fastapi.api.models import ( EmptyRequest, ItemCollectionUri, JSONResponse, create_get_request_model, create_post_request_model, create_request_model, ) from stac_fastapi.extensions.core import ( CollectionSearchExtension, CollectionSearchFilterExtension, FieldsExtension, FreeTextExtension, ItemCollectionFilterExtension, OffsetPaginationExtension, SearchFilterExtension, SortExtension, TokenPaginationExtension, TransactionExtension, ) from stac_fastapi.extensions.core.fields im from stac_fastapi.extensions.core.free_text from stac_fastapi.extensions.core.query imp from stac_fastapi.extensions.core.sort impo from stac_fastapi.extensions.third_party im from starlette.middleware import Middleware

    from stac_fastapi.pgstac.config import Sett from stac_fastapi.pgstac.core import CoreCr from stac_fastapi.pgstac.db


    import close_db from stac_fastapi.pgstac.extensions import from stac_fastapi.pgstac.extensions.filter from stac_fastapi.pgstac.transactions impor from stac_fastapi.pgstac.types.search impor

    settings = Settings()

    # search extensions search_extensions_map = {
    "query": QueryExtension(),
    "sort": SortExtension(),
    "fields": FieldsExtension(),
    "filter": SearchFilterExtension(client=
    "pagination": TokenPaginationExtension( }

    # collection_search extensions cs_extensions_map = {
    "query": QueryExtension(conformance_cla
    "sort": SortExtension(conformance_class
    "fields": FieldsExtension(conformance_c
    "filter": CollectionSearchFilterExtensi
    "free_text": FreeTextExtension(
    conformance_classes=[FreeTextConfor
    ),
    "pagination": OffsetPaginationExtension }

    # item_collection extensions itm_col_extensions_map = {
    "query": QueryExtension(
    conformance_classes=[QueryConforman
    ),
    "sort": SortExtension(
    conformance_classes=[SortConformanc
    ),
    "fields": FieldsExtension(conformance_c
    "filter": ItemCollectionFilterExtension
    "pagination": TokenPaginationExtension( }

    enabled_extensions = {
    *search_extensions_map.keys(),
    *cs_extensions_map.keys(),
    *itm_col_extensions_map.keys(),
    "collection_search", }

    if ext := os.environ.get("ENABLED_EXTENSION
    enabled_extensions = set(ext.split(",")

    application_extensions = []

    with_transactions = os.environ.get("ENABLE_
    "yes",
    "true",
    "1", ] if with_transactions:
    application_extensions.append(
    TransactionExtension(
    client=TransactionsClient(),
    settings=settings,
    response_class=JSONResponse,
    ),
    )

    application_extensions.append(
    BulkTransactionExtension(client=Bul
    )

    # /search models search_extensions = [
    extension
    for key, extension in search_extensions
    if key in enabled_extensions ] post_request_model = create_post_request_mo get_request_model = create_get_request_mode


    application_extensions.extend(search_extens

    # /collections/{collectionId}/items model items_get_request_model = ItemCollectionUri itm_col_extensions = [
    extension
    for key, extension in itm_col_extension
    if key in enabled_extensions ] if itm_col_extensions:
    items_get_request_model = create_reques
    model_name="ItemCollectionUri",
    base_model=ItemCollectionUri,
    extensions=itm_col_extensions,
    request_type="GET",
    )
    application_extensions.extend(itm_col_e

    # /collections model collections_get_request_model = EmptyReques if "collection_search" in enabled_extension
    cs_extensions = [
    extension
    for key, extension in cs_extensions
    if key in enabled_extensions
    ]
    collection_search_extension = Collectio
    collections_get_request_model = collect
    application_extensions.append(collectio


    @asynccontextmanager async def lifespan(app: FastAPI):
    """FastAPI Lifespan."""
    await connect_to_db(app, add_write_conn
    yield
    await close_db_connection(app)


    api = StacApi(
    app=FastAPI(
    openapi_url=settings.openapi_url,
    docs_url=settings.docs_url,
    redoc_url=None,
    root_path=settings.root_path,
    title=settings.stac_fastapi_title,
    version=settings.stac_fastapi_versi
    description=settings.stac_fastapi_d
    lifespan=lifespan,
    ),
    settings=settings,
    extensions=application_extensions,
    client=CoreCrudClient(pgstac_search_mod
    response_class=JSONResponse,
    items_get_request_model=items_get_reque
    search_get_request_model=get_request_mo
    search_post_request_model=post_request_
    collections_get_request_model=collectio
    middlewares=[
    Middleware(BrotliMiddleware),
    Middleware(ProxyHeaderMiddleware),
    Middleware(
    CORSMiddleware,
    allow_origins=settings.cors_ori
    allow_methods=settings.cors_met
    ),
    ],
    health_check=health_check, ) app = api.app


    def run():
    """Run app from command line using uvic
    try:
    import uvicorn

    uvicorn.run(
    "stac_fastapi.pgstac.app:app",
    host=settings.app_host,
    port=settings.app_port,
    log_level="info",
    reload=settings.reload,
    root_path=os.getenv("UVICORN_RO
    )
    except ImportError as e:
    raise RuntimeError("Uvicorn must be


    if __name__ == "__main__":
    run()


    def create_handler(app):
    """Create a handler to use with AWS Lam
    try:
    from mangum import Mangum

    return Mangum(app)
    except ImportError:
    return None


    handler = create_handler(app)​

    Do you have any suggestions on how to resolve this issue ? Is it that I have not undertaken configuration steps for the pgstac backend, and if so is there a guide to follow ?

    Continue reading...

Compartilhe esta Página