From 2d6ab09f87b682b03b04d9905b54d6a7d182bb37 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Thu, 4 Jan 2024 14:51:01 +0000 Subject: [PATCH] Add endpoint to get article filters --- app/articles/routes.py | 20 ++++++++++++++++++-- app/articles/schemas.py | 27 ++++++++++++++++++++++++++- app/sources/website.py | 38 ++++++++++++++++++++++++++++++++++---- 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/app/articles/routes.py b/app/articles/routes.py index 26f0475..ecf5838 100644 --- a/app/articles/routes.py +++ b/app/articles/routes.py @@ -1,7 +1,7 @@ from app.articles import router -from app.sources.website import WebsiteArticles +from app.sources.website import WebsiteArticles, get_time_periods, get_topics -from .schemas import ArticleSearchResults +from .schemas import ArticleFilter, ArticleSearchResults @router.get("/") @@ -12,3 +12,19 @@ async def index( website_api.add_query(q or "") results = website_api.get_results(page) return results + + +@router.get("/filters/") +async def filters() -> list[ArticleFilter]: + filters = [] + time_period_filter = ArticleFilter("Time period") + for time_period in get_time_periods(): + time_period_filter.add_filter_option( + time_period["name"], time_period["value"] + ) + filters.filters.append(time_period_filter) + topics_filter = ArticleFilter("Topics") + for topic in get_topics(): + topics_filter.add_filter_option(topic["name"], topic["value"]) + filters.filters.append(topics_filter) + return filters diff --git a/app/articles/schemas.py b/app/articles/schemas.py index d46d669..fb24468 100644 --- a/app/articles/schemas.py +++ b/app/articles/schemas.py @@ -1,5 +1,5 @@ from app.schemas import APIResponse, APIResult -from pydantic import ConfigDict +from pydantic import BaseModel, ConfigDict class Article(APIResult): @@ -20,3 +20,28 @@ class ArticleSearchResults(APIResponse): count: int = 0 results: list[Article] = [] + + +class ArticleFilterOption(BaseModel): + name: str = "" + value: str | int = "" + + def __init__(self, name, value): + super().__init__() + self.name = name + self.value = value + + +class ArticleFilter(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + + title: str = "" + options: list[ArticleFilterOption] = [] + + def __init__(self, title): + super().__init__() + self.title = title + + def add_filter_option(self, name, value): + option = ArticleFilterOption(name, value) + self.options.append(option) diff --git a/app/sources/website.py b/app/sources/website.py index 4debcce..0db92d9 100644 --- a/app/sources/website.py +++ b/app/sources/website.py @@ -4,18 +4,24 @@ from .api import GetAPI -class WebsiteArticles(GetAPI): +class WagtailAPI(GetAPI): def __init__(self): self.api_url = Config().WAGTAIL_API_URL - def add_query(self, query_string: str) -> None: - self.add_parameter("search", query_string) - def build_query_string(self) -> str: return "&".join( ["=".join((key, str(value))) for key, value in self.filters.items()] ) + def get_results(self) -> dict: + url = f"{self.api_url}/pages/?{self.build_query_string()}" + return self.execute(url) + + +class WebsiteArticles(WagtailAPI): + def add_query(self, query_string: str) -> None: + self.add_parameter("search", query_string) + def get_results(self, page: int | None = 1) -> dict: offset = (page - 1) * self.results_per_page self.add_parameter("offset", offset) @@ -39,3 +45,27 @@ def get_results(self, page: int | None = 1) -> dict: response.results.append(article) response.count = raw_results["meta"]["total_count"] return response.toJSON() + + +def get_time_periods(): + api = WagtailAPI() + # api.results_per_page = 100 # TODO: Make higher + api.add_parameter("child_of", 54) # TODO: Make variable + results = api.get_results() + time_periods = [ + {"name": time_period["title"], "value": time_period["id"]} + for time_period in results["items"] + ] + return time_periods + + +def get_topics(): + api = WagtailAPI() + # api.results_per_page = 100 # TODO: Make higher + api.add_parameter("child_of", 53) # TODO: Make variable + results = api.get_results() + topics = [ + {"name": topics["title"], "value": topics["id"]} + for topics in results["items"] + ] + return topics