Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion deployment/aws/lambda/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
ARG PYTHON_VERSION=3.10
ARG PYTHON_VERSION=3.12

FROM --platform=linux/amd64 public.ecr.aws/lambda/python:${PYTHON_VERSION}

WORKDIR /tmp

# Install system dependencies to compile (numexpr)
RUN dnf install -y gcc-c++ && dnf clean all

RUN pip install pip -U
# Install TiTiler from local source. This is necessary because
# pyproject.toml refers to TiTiler dependencies (core, extensions,
# mosaic, and application) that also use filesystem paths.
COPY . /titiler
RUN pip install "/titiler/src/titiler/application" "mangum>=0.10.0" -t /asset --no-binary pydantic

RUN mkdir -p /asset/lib
RUN cp /lib64/libexpat.so.1 /asset/lib/

# Reduce package size and remove useless files
RUN cd /asset && find . -type f -name '*.pyc' | while read f; do n=$(echo $f | sed 's/__pycache__\///' | sed 's/.cpython-[0-9]*//'); cp $f $n; done;
RUN cd /asset && find . -type d -a -name '__pycache__' -print0 | xargs -0 rm -rf
Expand Down
2 changes: 1 addition & 1 deletion dockerfiles/Dockerfile.gunicorn
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ENV CURL_CA_BUNDLE /etc/ssl/certs/ca-certificates.crt
COPY src/titiler/ /tmp/titiler/
RUN python -m pip install -U pip
RUN python -m pip install /tmp/titiler/core /tmp/titiler/extensions["cogeo,stac"] /tmp/titiler/mosaic /tmp/titiler/application --no-cache-dir --upgrade
RUN rm -rf /tmp/titiler
# RUN rm -rf /tmp/titiler
Copy link

Copilot AI Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The removal of the temporary titiler directory is commented out; clarify whether this is for debugging purposes or if it should be restored for production cleanliness.

Suggested change
# RUN rm -rf /tmp/titiler
RUN rm -rf /tmp/titiler

Copilot uses AI. Check for mistakes.

ENV MODULE_NAME titiler.application.main
ENV VARIABLE_NAME app
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "titiler"
description = "A modern dynamic tile server built on top of FastAPI and Rasterio/GDAL."
readme = "README.md"
requires-python = ">=3.8"
requires-python = "3.12"
license = {file = "LICENSE"}
authors = [
{name = "Vincent Sarago", email = "vincent@developmentseed.com"},
Expand Down Expand Up @@ -31,10 +31,10 @@ version="0.11.6"
dependencies = [
# Configured for volume-mount path of Lambda Dockerfile. For local
# development, update accordingly for your local filesystem path:
"titiler.core @ file:///titiler/src/titiler/core",
"titiler.extensions @ file:///titiler/src/titiler/extensions",
"titiler.mosaic @ file:///titiler/src/titiler/mosaic",
"titiler.application @ file:///titiler/src/titiler/application",
"titiler.core @ file:///titiler/src//titiler/core",
"titiler.extensions @ file:///titiler/src//titiler/extensions",
"titiler.mosaic @ file:///titiler/src//titiler/mosaic",
"titiler.application @ file:///titiler/src//titiler/application",
]

[project.optional-dependencies]
Expand Down
6 changes: 3 additions & 3 deletions src/titiler/application/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ dynamic = ["version"]
dependencies = [
# Configured for volume-mount path of Lambda Dockerfile. For local
# development, update accordingly for your local filesystem path:
"titiler.core @ file:///titiler/src/titiler/core",
"titiler.extensions[cogeo,stac] @ file:///titiler/src/titiler/extensions",
"titiler.mosaic @ file:///titiler/src/titiler/mosaic",
"titiler.core @ file:///titiler/src//titiler/core",
"titiler.extensions[cogeo,stac] @ file:///titiler/src//titiler/extensions",
"titiler.mosaic @ file:///titiler/src//titiler/mosaic",
"starlette-cramjam>=0.3,<0.4",
"python-dotenv",
]
Expand Down
2 changes: 2 additions & 0 deletions src/titiler/application/titiler/application/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
LoggerMiddleware,
LowerCaseQueryStringMiddleware,
TotalTimeMiddleware,
BlockVRTMiddleware,
Copy link

Copilot AI Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlockVRTMiddleware appears to be added twice to the middleware stack; consider consolidating its registration to a single instance to avoid potential duplicate processing.

Copilot uses AI. Check for mistakes.
)
from titiler.extensions import (
cogValidateExtension,
Expand Down Expand Up @@ -173,6 +174,7 @@
if api_settings.lower_case_query_parameters:
app.add_middleware(LowerCaseQueryStringMiddleware)

app.add_middleware(BlockVRTMiddleware)

router = APIRouter(prefix=global_prefix)

Expand Down
42 changes: 41 additions & 1 deletion src/titiler/core/titiler/core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
from typing import Optional, Set

from fastapi.logger import logger
import rasterio
from starlette.datastructures import MutableHeaders
from starlette.requests import Request
from starlette.types import ASGIApp, Message, Receive, Scope, Send

from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response

class CacheControlMiddleware:
"""MiddleWare to add CacheControl in response headers."""
Expand Down Expand Up @@ -166,3 +168,41 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send):
request.scope["query_string"] = query_string.encode(DECODE_FORMAT)

await self.app(scope, receive, send)

class BlockVRTMiddleware(BaseHTTPMiddleware):
"""Middleware to block requests with vrt in the path."""
async def dispatch(self, request: Request, call_next):
"""Handle call."""
# Check path for VRT
logger.info(f"Processing request: {request.url}")
if ".vrt" in request.scope["path"].lower():
return Response(
content="VRT files are not supported.",
status_code=403,
)

# Check URL parameter for VRT
url_param = request.query_params.get("url", "").lower()
if ".vrt" in url_param:
return Response(
content="VRT files are not supported in URL parameters.",
status_code=403,
)

# TODO: check if we need this.
if url_param.startswith(("http://", "https://", "s3://", "gs://", "azure://")):

try:
with rasterio.open(url_param, sharing=False) as src:
if src.driver == "VRT":
return Response(
content="VRT files are not supported in URL parameters.",
status_code=403,
)
except Exception:
# If rasterio fails to open the file, we assume it's not a VRT
pass

# Continue with the request if no VRT detected
response = await call_next(request)
return response
2 changes: 1 addition & 1 deletion src/titiler/extensions/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dynamic = ["version"]
dependencies = [
# Configured for volume-mount path of Lambda Dockerfile. For local
# development, update accordingly for your local filesystem path:
"titiler.core @ file:///titiler/src/titiler/core",
"titiler.core @ file:///titiler/src//titiler/core",
]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion src/titiler/mosaic/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dynamic = ["version"]
dependencies = [
# Configured for volume-mount path of Lambda Dockerfile. For local
# development, update accordingly for your local filesystem path:
"titiler.core @ file:///titiler/src/titiler/core",
"titiler.core @ file:///titiler/src//titiler/core",
Copy link

Copilot AI Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dependency path includes an extra forward slash which might be redundant; verify if this is intentional or if it could be standardized to ensure consistency.

Suggested change
"titiler.core @ file:///titiler/src//titiler/core",
"titiler.core @ file:///titiler/src/titiler/core",

Copilot uses AI. Check for mistakes.
"cogeo-mosaic>=5.0,<5.2",
]

Expand Down
Loading