Skip to content

Commit

Permalink
date_from and date_to query fix for v2 averages (#369)
Browse files Browse the repository at this point in the history
  • Loading branch information
russbiggs authored Aug 22, 2024
1 parent 7b84550 commit 8123f74
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 10 deletions.
91 changes: 85 additions & 6 deletions openaq_api/openaq_api/routers/averages.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import logging
from datetime import date, datetime
from enum import StrEnum
from typing import Annotated

from fastapi import APIRouter, Depends, Query

from openaq_api.v3.models.queries import (
DatetimeFromQuery,
DatetimeToQuery,
Paging,
TemporalQuery,
QueryBaseModel,
Expand All @@ -21,6 +20,87 @@
router = APIRouter()


class DateFromQuery(QueryBaseModel):
"""Pydantic query model for the `datetime_from` query parameter
Inherits from QueryBaseModel
Attributes:
datetime_from: date or datetime in ISO-8601 format to filter results to a
date range.
"""

date_from: datetime | date | None = Query(
None,
description="From when?",
examples=["2022-10-01T11:19:38-06:00", "2022-10-01"],
)

def where(self) -> str:
"""Generates SQL condition for filtering to datetime.
Overrides the base QueryBaseModel `where` method
If `date_from` is a `date` or `datetime` without a timezone a timezone
is added as UTC.
Returns:
string of WHERE clause if `date_from` is set
"""
tz = self.map("timezone", "timezone")
dt = self.map("datetime", "datetime")

if self.date_from is None:
return None
elif isinstance(self.date_from, datetime):
if self.date_from.tzinfo is None:
return f"{dt} > (:date_from::timestamp AT TIME ZONE {tz})"
else:
return f"{dt} > :date_from"
elif isinstance(self.date_from, date):
return f"{dt} > (:date_from::timestamp AT TIME ZONE {tz})"


class DateToQuery(QueryBaseModel):
"""Pydantic query model for the `date_to` query parameter
Inherits from QueryBaseModel
Attributes:
date_to: date or datetime in ISO-8601 format to filter results to a
date range.
"""

date_to: datetime | date | None = Query(
None,
description="To when?",
examples=["2022-10-01T11:19:38-06:00", "2022-10-01"],
)

def where(self) -> str:
"""Generates SQL condition for filtering to datetime.
Overrides the base QueryBaseModel `where` method
If `date_to` is a `date` or `datetime` without a timezone a timezone
is added as UTC.
Returns:
string of WHERE clause if `date_to` is set
"""
tz = self.map("timezone", "timezone")
dt = self.map("datetime", "datetime")
if self.date_to is None:
return None
elif isinstance(self.date_to, datetime):
if self.date_to.tzinfo is None:
return f"{dt} <= (:date_to::timestamp AT TIME ZONE {tz})"
else:
return f"{dt} <= :date_to"
elif isinstance(self.date_to, date):
return f"{dt} <= (:date_to::timestamp AT TIME ZONE {tz})"


class SpatialTypes(StrEnum):
country = "country"
location = "location"
Expand Down Expand Up @@ -59,12 +139,11 @@ class AveragesQueries(
Paging,
SpatialTypeQuery,
LocationQuery,
DatetimeFromQuery,
DatetimeToQuery,
DateFromQuery,
DateToQuery,
ParametersQuery,
TemporalQuery,
):
...
): ...


@router.get(
Expand Down
1 change: 0 additions & 1 deletion openaq_api/openaq_api/v3/models/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,6 @@ def where(self) -> str:
"""
tz = self.map("timezone", "timezone")
dt = self.map("datetime", "datetime")

if self.datetime_to is None:
return None
elif isinstance(self.datetime_to, datetime):
Expand Down
5 changes: 2 additions & 3 deletions openaq_api/openaq_api/v3/routers/countries.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

router = APIRouter(
prefix="/v3",
tags=["v3-alpha"],
tags=["v3"],
include_in_schema=True,
)

Expand Down Expand Up @@ -61,8 +61,7 @@ class CountriesSorting(SortingBase):
)


class CountriesQueries(Paging, ParametersQuery, ProviderQuery, CountriesSorting):
...
class CountriesQueries(Paging, ParametersQuery, ProviderQuery, CountriesSorting): ...


@router.get(
Expand Down

0 comments on commit 8123f74

Please sign in to comment.