Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bfc06bb
Create env var for override
kathryn-dale Feb 9, 2026
5e94653
Update test data
kathryn-dale Feb 9, 2026
108b9eb
Update is_public default and testing
kathryn-dale Feb 9, 2026
3cfc6b9
Linting fixes
kathryn-dale Feb 9, 2026
98bdbb1
Merge branch 'main' into task/CDD-2983-reject-validation-with-missing…
kathryn-dale Feb 17, 2026
0ee871f
Merge branch 'main' into task/CDD-2983-reject-validation-with-missing…
kathryn-dale Feb 17, 2026
8c8b809
Update test files
kathryn-dale Feb 17, 2026
975c575
Merge branch 'main' into task/CDD-2983-reject-validation-with-missing…
sahmed06 Feb 25, 2026
7ce69e4
Update tests
kathryn-dale Feb 25, 2026
bf81a47
linting
kathryn-dale Feb 25, 2026
35f6a14
Remove now redundant is_public vs public validation error
kathryn-dale Mar 3, 2026
27317f1
remove unused validation class
kathryn-dale Mar 3, 2026
fe19881
revert accidental change
kathryn-dale Mar 3, 2026
06d6190
Remove tests linked to removed validation
kathryn-dale Mar 3, 2026
df95de1
Merge branch 'main' into task/CDD-2983-reject-validation-with-missing…
kathryn-dale Mar 3, 2026
0abc1a9
linting
kathryn-dale Mar 3, 2026
fd5397e
remove redundant tests
kathryn-dale Mar 3, 2026
5e39ddd
CDD-3206: added an ENFORCE_PUBLIC_DATA_ONLY flag that suppresses non-…
dandammann Mar 18, 2026
fd276be
CDD-3206: amended integration tests to work with both ENFORCE_PUBLIC_…
dandammann Mar 18, 2026
73cf13e
CDD-3206: amended system tests to work with both ENFORCE_PUBLIC_DATA_…
dandammann Mar 18, 2026
423af84
Merge branch 'main' into task/CDD-3206-be---filter-db-query-for-only-…
dandammann Mar 18, 2026
ecc66bc
CDD-3206: linted
dandammann Mar 18, 2026
0ce489f
Merge remote-tracking branch 'origin/task/CDD-3206-be---filter-db-que…
dandammann Mar 18, 2026
2974e3a
CDD-3206: fixed architectural violation
dandammann Mar 18, 2026
c41cb87
Merge branch 'main' into task/CDD-3206-be---filter-db-query-for-only-…
dandammann Mar 18, 2026
8260d70
CDD-3206: made ENFORCE_PUBLIC_DATA_ONLY an environment variable
dandammann Mar 23, 2026
2a055ec
CDD-3206: commented restrict_to_public=True
dandammann Mar 23, 2026
fc56970
Merge remote-tracking branch 'origin/task/CDD-3206-be---filter-db-que…
dandammann Mar 23, 2026
3336eb9
CDD-3206: linted
dandammann Mar 23, 2026
1a9d0ef
Merge branch 'main' into task/CDD-3206-be---filter-db-query-for-only-…
dandammann Mar 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
17 changes: 6 additions & 11 deletions ingestion/data_transfer_models/headline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

import validation
from ingestion.utils import type_hints
from metrics.api.settings.auth import AUTH_ENABLED
from metrics.api.settings.auth import ALLOW_MISSING_IS_PUBLIC_FIELD
from validation.data_transfer_models.base import (
IncomingBaseDataModel,
NonPublicDataSentToPublicIngestionError,
)


Expand Down Expand Up @@ -134,14 +133,6 @@ def validate_confidence_intervals(self) -> Self:
)
return self

@model_validator(mode="after")
def invalidate_non_public_data_for_public_ingestion(self) -> Self:
"""Checks that if this is a public instance of the product then `is_public=False` data is invalidated."""
if not AUTH_ENABLED and not self.is_public:
raise NonPublicDataSentToPublicIngestionError

return self


class HeadlineDTO(IncomingBaseDataModel):
data: list[InboundHeadlineSpecificFields]
Expand Down Expand Up @@ -183,7 +174,11 @@ def _build_enriched_headline_specific_fields(
upper_confidence=individual_time_series.get("upper_confidence", None),
metric_value=individual_time_series["metric_value"],
lower_confidence=individual_time_series.get("lower_confidence", None),
is_public=individual_time_series.get("is_public", True),
is_public=(
individual_time_series["is_public"]
if not ALLOW_MISSING_IS_PUBLIC_FIELD
else individual_time_series.get("is_public", True)
),
)
for individual_time_series in source_data["data"]
if individual_time_series["metric_value"] is not None
Expand Down
20 changes: 7 additions & 13 deletions ingestion/data_transfer_models/time_series.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import datetime
from typing import Self

from pydantic import BaseModel, field_validator, model_validator
from pydantic import BaseModel, field_validator
from pydantic.fields import Field

import validation
from ingestion.utils import type_hints
from metrics.api.settings.auth import AUTH_ENABLED
from metrics.api.settings.auth import ALLOW_MISSING_IS_PUBLIC_FIELD
from validation.data_transfer_models.base import (
IncomingBaseDataModel,
NonPublicDataSentToPublicIngestionError,
)


Expand Down Expand Up @@ -43,14 +41,6 @@ def cast_embargo_to_uk_timezone(
"""
return validation.cast_date_to_uk_timezone(date_value=embargo)

@model_validator(mode="after")
def invalidate_non_public_data_for_public_ingestion(self) -> Self:
"""Checks that if this is a public instance of the product then `is_public=False` data is invalidated."""
if not AUTH_ENABLED and not self.is_public:
raise NonPublicDataSentToPublicIngestionError

return self


class TimeSeriesDTO(IncomingBaseDataModel):
metric_frequency: str
Expand Down Expand Up @@ -128,7 +118,11 @@ def _build_enriched_time_series_specific_fields(
"in_reporting_delay_period", False
),
force_write=individual_time_series.get("force_write", False),
is_public=individual_time_series.get("is_public", True),
is_public=(
individual_time_series["is_public"]
if not ALLOW_MISSING_IS_PUBLIC_FIELD
else individual_time_series.get("is_public", True)
),
)
for individual_time_series in source_data["time_series"]
if individual_time_series["metric_value"] is not None
Expand Down
9 changes: 9 additions & 0 deletions metrics/api/permissions/fluent_permissions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from collections.abc import Iterable
from dataclasses import dataclass

from metrics.api.settings import auth
from metrics.data.models.rbac_models import RBACPermission


def is_public_data_only_enforced() -> bool:
"""Whether public-only data is currently enforced."""
return auth.ENFORCE_PUBLIC_DATA_ONLY


def validate_permissions_for_non_public(
*,
theme: str,
Expand All @@ -22,6 +28,9 @@ def validate_permissions_for_non_public(
False otherwise.

"""
if is_public_data_only_enforced():
return False

requested_data_parameters = RequestedDataParameters(
theme=theme,
sub_theme=sub_theme,
Expand Down
28 changes: 28 additions & 0 deletions metrics/api/settings/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,32 @@ def is_auth_enabled() -> bool:
return str(os.environ.get("AUTH_ENABLED", "")).lower() in {"true", "1"}


def is_allow_missing_is_public_field() -> bool:
return str(os.environ.get("ALLOW_MISSING_IS_PUBLIC_FIELD", "")).lower() in {
"true",
"1",
}


def is_enforce_public_data_only() -> bool:
return str(os.environ.get("ENFORCE_PUBLIC_DATA_ONLY", "true")).lower() in {
"true",
"1",
}


AUTH_ENABLED = is_auth_enabled()
ALLOW_MISSING_IS_PUBLIC_FIELD = is_allow_missing_is_public_field()

# If False, non-authorized RBAC paths return only public headline/time-series rows,
# while authorized RBAC paths can include non-public rows when permitted.
# If True, RBAC non-public row access is suppressed and only public dashboard API
# row data is returned, except:
# a) `/api/audit/*` endpoints can still return public and non-public
# diagnostics.
# b) Metadata/master-table endpoints (not headline/time-series rows)
# remain unfiltered.
#
# Note: This flag is only used by the private API, because we are not allowing
# non-public data through the public API anyway.
ENFORCE_PUBLIC_DATA_ONLY = is_enforce_public_data_only()
10 changes: 8 additions & 2 deletions metrics/data/managers/core_models/time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.utils import timezone

from metrics.api.permissions.fluent_permissions import (
is_public_data_only_enforced,
validate_permissions_for_non_public,
)
from metrics.data.models import RBACPermission
Expand Down Expand Up @@ -466,9 +467,14 @@ def get_available_geographies(self, *, topic: str) -> models.QuerySet:
[Row(geography__name='England', geography__geography_type__name='Nation')]>`

"""
queryset = self.filter(metric__topic__name=topic)

if is_public_data_only_enforced():
queryset = queryset.filter(is_public=True)
queryset = self._exclude_data_under_embargo(queryset=queryset)

return (
self.filter(metric__topic__name=topic)
.values_list(
queryset.values_list(
"geography__name",
"geography__geography_type__name",
"geography__geography_code",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def get_queryset(self) -> "APITimeSeriesQuerySet":
"""
kwargs: dict[str, str] = self.get_kwargs_from_request()
return self.api_time_series_manager.get_distinct_column_values_with_filters(
lookup_field=self.lookup_field, restrict_to_public=True, **kwargs
lookup_field=self.lookup_field,
restrict_to_public=True, # because we are not allowing non-public data through the public API
**kwargs
)

def build_timeseries_dto_slice(self) -> list[APITimeSeriesDTO]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ def get_queryset(self) -> "APITimeSeriesQuerySet":
"""
kwargs: dict[str, str] = self.get_formatted_kwargs_from_request()
return self.api_time_series_manager.get_distinct_column_values_with_filters(
lookup_field=self.lookup_field, restrict_to_public=True, **kwargs
lookup_field=self.lookup_field,
restrict_to_public=True, # because we are not allowing non-public data through the public API
**kwargs
)

def build_timeseries_dto_slice(self) -> list[APITimeSeriesDTO]:
"""Builds a list of simple `APITimeSeriesDTO` from the kwargs of the request and the given `value`

Returns:
List[APITimeSeriesDTO]: List of created data transfer objects

"""
queryset = self.get_queryset()
return [
Expand Down
2 changes: 1 addition & 1 deletion public_api/version_02/views/timeseries_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ def get_queryset(self):
geography_type=self.kwargs["geography_type"],
geography=self.kwargs["geography"],
metric=self.kwargs["metric"],
restrict_to_public=True,
restrict_to_public=True, # because we are not allowing non-public data through the public API
)
2 changes: 1 addition & 1 deletion public_api/views/timeseries_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,5 @@ def get_queryset(self):
geography_type=self.kwargs["geography_type"],
geography=self.kwargs["geography"],
metric=self.kwargs["metric"],
restrict_to_public=True,
restrict_to_public=True, # because we are not allowing non-public data through the public API
)
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"England","geography_code":"E92000001","age":"all","sex":"all","stratum":"12m","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2010-03-31","metric_value":93.61,"embargo":null},{"epiweek":13,"date":"2011-03-31","metric_value":94.15,"embargo":null},{"epiweek":13,"date":"2012-03-31","metric_value":94.67,"embargo":null},{"epiweek":13,"date":"2013-03-31","metric_value":94.74,"embargo":null},{"epiweek":14,"date":"2014-03-31","metric_value":94.34,"embargo":null},{"epiweek":14,"date":"2015-03-31","metric_value":94.23,"embargo":null},{"epiweek":13,"date":"2016-03-31","metric_value":93.56,"embargo":null},{"epiweek":13,"date":"2017-03-31","metric_value":93.41,"embargo":null},{"epiweek":13,"date":"2018-03-31","metric_value":93.12,"embargo":null},{"epiweek":13,"date":"2019-03-31","metric_value":92.09,"embargo":null},{"epiweek":14,"date":"2020-03-31","metric_value":92.57,"embargo":null},{"epiweek":13,"date":"2021-03-31","metric_value":92.04,"embargo":null},{"epiweek":13,"date":"2022-03-31","metric_value":91.84,"embargo":null},{"epiweek":13,"date":"2023-03-31","metric_value":91.8,"embargo":null},{"epiweek":13,"date":"2024-03-31","metric_value":91.22,"embargo":null}],"refresh_date":"2025-08-01 11:00:53"}
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"England","geography_code":"E92000001","age":"all","sex":"all","stratum":"12m","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2010-03-31","metric_value":93.61,"embargo":null,"is_public":true},{"epiweek":13,"date":"2011-03-31","metric_value":94.15,"embargo":null,"is_public":true},{"epiweek":13,"date":"2012-03-31","metric_value":94.67,"embargo":null,"is_public":true},{"epiweek":13,"date":"2013-03-31","metric_value":94.74,"embargo":null,"is_public":true},{"epiweek":14,"date":"2014-03-31","metric_value":94.34,"embargo":null,"is_public":true},{"epiweek":14,"date":"2015-03-31","metric_value":94.23,"embargo":null,"is_public":true},{"epiweek":13,"date":"2016-03-31","metric_value":93.56,"embargo":null,"is_public":true},{"epiweek":13,"date":"2017-03-31","metric_value":93.41,"embargo":null,"is_public":true},{"epiweek":13,"date":"2018-03-31","metric_value":93.12,"embargo":null,"is_public":true},{"epiweek":13,"date":"2019-03-31","metric_value":92.09,"embargo":null,"is_public":true},{"epiweek":14,"date":"2020-03-31","metric_value":92.57,"embargo":null,"is_public":true},{"epiweek":13,"date":"2021-03-31","metric_value":92.04,"embargo":null,"is_public":true},{"epiweek":13,"date":"2022-03-31","metric_value":91.84,"embargo":null,"is_public":true},{"epiweek":13,"date":"2023-03-31","metric_value":91.8,"embargo":null,"is_public":true},{"epiweek":13,"date":"2024-03-31","metric_value":91.22,"embargo":null,"is_public":true}],"refresh_date":"2025-08-01 11:00:53"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"England","geography_code":"E92000001","age":"all","sex":"all","stratum":"24m","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2010-03-31","metric_value":95.29,"embargo":null},{"epiweek":13,"date":"2011-03-31","metric_value":95.98,"embargo":null},{"epiweek":13,"date":"2012-03-31","metric_value":96.14,"embargo":null},{"epiweek":13,"date":"2013-03-31","metric_value":96.3,"embargo":null},{"epiweek":14,"date":"2014-03-31","metric_value":96.14,"embargo":null},{"epiweek":14,"date":"2015-03-31","metric_value":95.74,"embargo":null},{"epiweek":13,"date":"2016-03-31","metric_value":95.24,"embargo":null},{"epiweek":13,"date":"2017-03-31","metric_value":95.15,"embargo":null},{"epiweek":13,"date":"2018-03-31","metric_value":95.1,"embargo":null},{"epiweek":13,"date":"2019-03-31","metric_value":94.17,"embargo":null},{"epiweek":14,"date":"2020-03-31","metric_value":93.85,"embargo":null},{"epiweek":13,"date":"2021-03-31","metric_value":93.85,"embargo":null},{"epiweek":13,"date":"2022-03-31","metric_value":93.04,"embargo":null},{"epiweek":13,"date":"2023-03-31","metric_value":92.62,"embargo":null},{"epiweek":13,"date":"2024-03-31","metric_value":92.44,"embargo":null}],"refresh_date":"2025-08-01 11:00:53"}
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"England","geography_code":"E92000001","age":"all","sex":"all","stratum":"24m","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2010-03-31","metric_value":95.29,"embargo":null,"is_public":true},{"epiweek":13,"date":"2011-03-31","metric_value":95.98,"embargo":null,"is_public":true},{"epiweek":13,"date":"2012-03-31","metric_value":96.14,"embargo":null,"is_public":true},{"epiweek":13,"date":"2013-03-31","metric_value":96.3,"embargo":null,"is_public":true},{"epiweek":14,"date":"2014-03-31","metric_value":96.14,"embargo":null,"is_public":true},{"epiweek":14,"date":"2015-03-31","metric_value":95.74,"embargo":null,"is_public":true},{"epiweek":13,"date":"2016-03-31","metric_value":95.24,"embargo":null,"is_public":true},{"epiweek":13,"date":"2017-03-31","metric_value":95.15,"embargo":null,"is_public":true},{"epiweek":13,"date":"2018-03-31","metric_value":95.1,"embargo":null,"is_public":true},{"epiweek":13,"date":"2019-03-31","metric_value":94.17,"embargo":null,"is_public":true},{"epiweek":14,"date":"2020-03-31","metric_value":93.85,"embargo":null,"is_public":true},{"epiweek":13,"date":"2021-03-31","metric_value":93.85,"embargo":null,"is_public":true},{"epiweek":13,"date":"2022-03-31","metric_value":93.04,"embargo":null,"is_public":true},{"epiweek":13,"date":"2023-03-31","metric_value":92.62,"embargo":null,"is_public":true},{"epiweek":13,"date":"2024-03-31","metric_value":92.44,"embargo":null,"is_public":true}],"refresh_date":"2025-08-01 11:00:53"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"England","geography_code":"E92000001","age":"all","sex":"all","stratum":"5y","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2016-03-31","metric_value":95.57,"embargo":null},{"epiweek":13,"date":"2017-03-31","metric_value":95.59,"embargo":null},{"epiweek":13,"date":"2018-03-31","metric_value":95.56,"embargo":null},{"epiweek":13,"date":"2019-03-31","metric_value":95.04,"embargo":null},{"epiweek":14,"date":"2020-03-31","metric_value":95.24,"embargo":null},{"epiweek":13,"date":"2021-03-31","metric_value":95.24,"embargo":null},{"epiweek":13,"date":"2022-03-31","metric_value":94.39,"embargo":null},{"epiweek":13,"date":"2023-03-31","metric_value":93.2,"embargo":null},{"epiweek":13,"date":"2024-03-31","metric_value":92.62,"embargo":null},{"epiweek":14,"date":"2014-03-31","metric_value":95.6,"embargo":null},{"epiweek":14,"date":"2015-03-31","metric_value":95.56,"embargo":null}],"refresh_date":"2025-08-01 11:00:53"}
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"England","geography_code":"E92000001","age":"all","sex":"all","stratum":"5y","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2016-03-31","metric_value":95.57,"embargo":null,"is_public":true},{"epiweek":13,"date":"2017-03-31","metric_value":95.59,"embargo":null,"is_public":true},{"epiweek":13,"date":"2018-03-31","metric_value":95.56,"embargo":null,"is_public":true},{"epiweek":13,"date":"2019-03-31","metric_value":95.04,"embargo":null,"is_public":true},{"epiweek":14,"date":"2020-03-31","metric_value":95.24,"embargo":null,"is_public":true},{"epiweek":13,"date":"2021-03-31","metric_value":95.24,"embargo":null,"is_public":true},{"epiweek":13,"date":"2022-03-31","metric_value":94.39,"embargo":null,"is_public":true},{"epiweek":13,"date":"2023-03-31","metric_value":93.2,"embargo":null,"is_public":true},{"epiweek":13,"date":"2024-03-31","metric_value":92.62,"embargo":null,"is_public":true},{"epiweek":14,"date":"2014-03-31","metric_value":95.6,"embargo":null,"is_public":true},{"epiweek":14,"date":"2015-03-31","metric_value":95.56,"embargo":null,"is_public":true}],"refresh_date":"2025-08-01 11:00:53"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"Northern Ireland","geography_code":"N92000002","age":"all","sex":"all","stratum":"12m","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2010-03-31","metric_value":97.77,"embargo":null},{"epiweek":13,"date":"2011-03-31","metric_value":97.51,"embargo":null},{"epiweek":13,"date":"2012-03-31","metric_value":97.57,"embargo":null},{"epiweek":13,"date":"2013-03-31","metric_value":97.56,"embargo":null},{"epiweek":14,"date":"2014-03-31","metric_value":97.48,"embargo":null},{"epiweek":14,"date":"2015-03-31","metric_value":96.84,"embargo":null},{"epiweek":13,"date":"2016-03-31","metric_value":97.22,"embargo":null},{"epiweek":13,"date":"2017-03-31","metric_value":97.04,"embargo":null},{"epiweek":13,"date":"2018-03-31","metric_value":96.2,"embargo":null},{"epiweek":13,"date":"2019-03-31","metric_value":94.52,"embargo":null},{"epiweek":14,"date":"2020-03-31","metric_value":94.45,"embargo":null},{"epiweek":13,"date":"2021-03-31","metric_value":94.53,"embargo":null},{"epiweek":13,"date":"2022-03-31","metric_value":93.52,"embargo":null},{"epiweek":13,"date":"2023-03-31","metric_value":93.1,"embargo":null},{"epiweek":13,"date":"2024-03-31","metric_value":91.8,"embargo":null}],"refresh_date":"2025-08-01 11:00:53"}
{"parent_theme":"immunisation","child_theme":"childhood-vaccines","topic":"6-in-1","metric_group":"coverage","metric":"6-in-1_coverage_coverageByYear","geography_type":"Nation","geography":"Northern Ireland","geography_code":"N92000002","age":"all","sex":"all","stratum":"12m","metric_frequency":"annual","time_series":[{"epiweek":13,"date":"2010-03-31","metric_value":97.77,"embargo":null,"is_public":true},{"epiweek":13,"date":"2011-03-31","metric_value":97.51,"embargo":null,"is_public":true},{"epiweek":13,"date":"2012-03-31","metric_value":97.57,"embargo":null,"is_public":true},{"epiweek":13,"date":"2013-03-31","metric_value":97.56,"embargo":null,"is_public":true},{"epiweek":14,"date":"2014-03-31","metric_value":97.48,"embargo":null,"is_public":true},{"epiweek":14,"date":"2015-03-31","metric_value":96.84,"embargo":null,"is_public":true},{"epiweek":13,"date":"2016-03-31","metric_value":97.22,"embargo":null,"is_public":true},{"epiweek":13,"date":"2017-03-31","metric_value":97.04,"embargo":null,"is_public":true},{"epiweek":13,"date":"2018-03-31","metric_value":96.2,"embargo":null,"is_public":true},{"epiweek":13,"date":"2019-03-31","metric_value":94.52,"embargo":null,"is_public":true},{"epiweek":14,"date":"2020-03-31","metric_value":94.45,"embargo":null,"is_public":true},{"epiweek":13,"date":"2021-03-31","metric_value":94.53,"embargo":null,"is_public":true},{"epiweek":13,"date":"2022-03-31","metric_value":93.52,"embargo":null,"is_public":true},{"epiweek":13,"date":"2023-03-31","metric_value":93.1,"embargo":null,"is_public":true},{"epiweek":13,"date":"2024-03-31","metric_value":91.8,"embargo":null,"is_public":true}],"refresh_date":"2025-08-01 11:00:53"}
Loading
Loading