From 8f15dd53442ea02e2a93c9efe8eff9f3c46ff58e Mon Sep 17 00:00:00 2001 From: hrodmn Date: Wed, 18 Dec 2024 15:28:30 -0600 Subject: [PATCH] move max datetime limit to ApiSettings --- tests/test_app.py | 15 +++++++++++++++ titiler/cmr/settings.py | 1 + titiler/cmr/timeseries.py | 10 ++++++++++ uv.lock | 3 +-- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/test_app.py b/tests/test_app.py index 1bdfeae..cab25a6 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -454,3 +454,18 @@ def test_unbounded_start(app, xarray_query_params) -> None: ) assert response.status_code == 400 + + +def test_max_datetime(app, xarray_query_params) -> None: + """Make sure a request that yields too many sub-requests returns a 400""" + + response = app.get( + "/timeseries", + params={ + **xarray_query_params, + "datetime": "2008-10-12T00:00:01Z/2024-10-12T23:59:59Z", + "step": "P1D", + }, + ) + + assert response.status_code == 400 diff --git a/titiler/cmr/settings.py b/titiler/cmr/settings.py index 5b78624..7d483f8 100644 --- a/titiler/cmr/settings.py +++ b/titiler/cmr/settings.py @@ -14,6 +14,7 @@ class ApiSettings(BaseSettings): cors_origins: str = "*" cachecontrol: str = "public, max-age=3600" root_path: str = "" + time_series_max_requests: int = 995 debug: bool = False model_config = { diff --git a/titiler/cmr/timeseries.py b/titiler/cmr/timeseries.py index de5b471..b088780 100644 --- a/titiler/cmr/timeseries.py +++ b/titiler/cmr/timeseries.py @@ -41,6 +41,7 @@ from titiler.cmr.dependencies import ConceptID from titiler.cmr.errors import InvalidDatetime from titiler.cmr.factory import Endpoints +from titiler.cmr.settings import ApiSettings from titiler.cmr.utils import parse_datetime from titiler.core.algorithm import algorithms as available_algorithms from titiler.core.dependencies import CoordCRSParams, DefaultDependency, DstCRSParams @@ -50,6 +51,8 @@ from titiler.core.resources.enums import ImageType from titiler.core.resources.responses import GeoJSONResponse +settings = ApiSettings() + # this section should eventually get moved to titiler.extensions.timeseries timeseries_img_endpoint_params: Dict[str, Any] = { "responses": { @@ -342,6 +345,13 @@ def timeseries_cmr_query( "list of comma-separated datetime strings", ) + if len(datetime_params) > settings.time_series_max_requests: + raise HTTPException( + status_code=400, + detail=f"this request ({len(datetime_params)}) exceeds the maximum number of distinct " + f"time series points/intervals of {settings.time_series_max_requests}", + ) + return [ CMRQueryParameters( concept_id=concept_id, diff --git a/uv.lock b/uv.lock index 16c9230..0d251e8 100644 --- a/uv.lock +++ b/uv.lock @@ -3692,7 +3692,7 @@ wheels = [ [[package]] name = "titiler-cmr" -version = "0.1.3.dev13+g3fa0b95.d20241206" +version = "0.1.3.dev19+g24a756f.d20241218" source = { editable = "." } dependencies = [ { name = "cftime" }, @@ -3759,7 +3759,6 @@ requires-dist = [ { name = "isodate", specifier = ">=0.7.2" }, { name = "orjson", specifier = "~=3.10.7" }, { name = "pillow", specifier = ">=11.0.0" }, - { name = "pre-commit", marker = "extra == 'dev'" }, { name = "psutil", specifier = ">=6.0.0" }, { name = "pydantic", specifier = ">=2.4,<3.0" }, { name = "pydantic-settings", specifier = "~=2.0" },