diff --git a/CHANGES.md b/CHANGES.md index 08dbbd0b..b4651174 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [5.0.2] - 2025-04-03 + +### Fixed + +- fix root-path handling when setting in uvicorn command + ## [5.0.1] - 2025-03-27 ### Fixed @@ -402,7 +408,8 @@ As a part of this release, this repository was extracted from the main - First PyPi release! -[Unreleased]: +[Unreleased]: +[5.0.2]: [5.0.1]: [5.0.0]: [4.0.3]: diff --git a/Dockerfile b/Dockerfile index f699d795..217f0fb7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ ARG PYTHON_VERSION=3.12 -FROM python:${PYTHON_VERSION}-slim as base +FROM python:${PYTHON_VERSION}-slim AS base # Any python libraries that require system libraries to be installed will likely # need the following packages in order to build @@ -12,7 +12,7 @@ RUN apt-get update && \ ENV CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt -FROM base as builder +FROM base AS builder WORKDIR /app diff --git a/docker-compose.yml b/docker-compose.yml index 2dcafa95..725a52eb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -89,9 +89,7 @@ services: app-nginx: extends: service: app - command: bash -c "./scripts/wait-for-it.sh database:5432 && uvicorn stac_fastapi.pgstac.app:app --host 0.0.0.0 --port 8082 --proxy-headers --forwarded-allow-ips=*" - environment: - - ROOT_PATH=/api/v1/pgstac + command: bash -c "./scripts/wait-for-it.sh database:5432 && uvicorn stac_fastapi.pgstac.app:app --host 0.0.0.0 --port 8082 --proxy-headers --forwarded-allow-ips=* --root-path=/api/v1/pgstac" networks: default: diff --git a/stac_fastapi/pgstac/models/links.py b/stac_fastapi/pgstac/models/links.py index b7a75f55..ae7e3cfb 100644 --- a/stac_fastapi/pgstac/models/links.py +++ b/stac_fastapi/pgstac/models/links.py @@ -51,7 +51,32 @@ def base_url(self): @property def url(self): """Get the current request url.""" - url = urljoin(str(self.request.base_url), self.request.url.path.lstrip("/")) + base_url = self.request.base_url + path = self.request.url.path + + # root path can be set in the request scope in two different ways: + # - by uvicorn when running with --root-path + # - by FastAPI when running with FastAPI(root_path="...") + # + # When root path is set by uvicorn, request.url.path will have the root path prefix. + # eg. if root path is "/api" and the path is "/collections", + # the request.url.path will be "/api/collections" + # + # We need to remove the root path prefix from the path before + # joining the base_url and path to get the full url to avoid + # having root_path twice in the url + if ( + root_path := self.request.scope.get("root_path") + ) and not self.request.app.root_path: + # self.request.app.root_path is set by FastAPI when running with FastAPI(root_path="...") + # If self.request.app.root_path is not set but self.request.scope.get("root_path") is set, + # then the root path is set by uvicorn + # So we need to remove the root path prefix from the path before + # joining the base_url and path to get the full url + if path.startswith(root_path): + path = path[len(root_path) :] + + url = urljoin(str(base_url), path.lstrip("/")) if qs := self.request.url.query: url += f"?{qs}"