diff --git a/agenda/__init__.py b/agenda/__init__.py index a854859..2ce3e87 100644 --- a/agenda/__init__.py +++ b/agenda/__init__.py @@ -1,3 +1,4 @@ +import asyncio import configparser import json import operator @@ -288,16 +289,21 @@ def bristol_waste_collection_events(start_date: date) -> list[Event]: return waste_schedule.get_bristol_gov_uk(start_date, data_dir, uprn) -def get_data(now: datetime) -> typing.Mapping[str, str | object]: +async def get_data(now: datetime) -> typing.Mapping[str, str | object]: """Get data to display on agenda dashboard.""" rocket_dir = os.path.join(data_dir, "thespacedevs") today = now.date() last_week = today - timedelta(weeks=1) last_year = today - timedelta(days=365) + gbpusd, gwr_advance_tickets = await asyncio.gather( + fx.get_gbpusd(config), + gwr.advance_ticket_date(data_dir), + ) + reply = { "now": now, - "gbpusd": fx.get_gbpusd(config), + "gbpusd": gbpusd, "next_economist": economist.next_pub_date(today), "bank_holiday": get_next_bank_holiday(today), "us_holiday": get_us_holidays(today), @@ -309,7 +315,7 @@ def get_data(now: datetime) -> typing.Mapping[str, str | object]: "fathers_day": next_uk_fathers_day(today), "uk_financial_year_end": uk_financial_year_end(today), "xmas_last_posting_dates": xmas_last_posting_dates, - "gwr_advance_tickets": gwr.advance_ticket_date(data_dir), + "gwr_advance_tickets": gwr_advance_tickets, "critical_mass": critical_mass(today), "market": ( markets.windmill_hill(last_year) diff --git a/agenda/fx.py b/agenda/fx.py index 5d397e1..34a7eac 100644 --- a/agenda/fx.py +++ b/agenda/fx.py @@ -7,10 +7,10 @@ import typing from datetime import datetime, timedelta from decimal import Decimal -import requests +import httpx -def get_gbpusd(config: configparser.ConfigParser) -> Decimal: +async def get_gbpusd(config: configparser.ConfigParser) -> Decimal: """Get the current value for GBPUSD, with caching.""" access_key = config.get("exchangerate", "access_key") data_dir = config.get("data", "dir") @@ -35,7 +35,9 @@ def get_gbpusd(config: configparser.ConfigParser) -> Decimal: params = {"currencies": "GBP,USD", "access_key": access_key} filename = f"{fx_dir}/{now_str}_GBPUSD.json" - r = requests.get(url, params=params) + async with httpx.AsyncClient() as client: + r = await client.get(url, params=params) + open(filename, "w").write(r.text) data = json.loads(r.text, parse_float=Decimal) diff --git a/agenda/gwr.py b/agenda/gwr.py index 9471866..6924449 100644 --- a/agenda/gwr.py +++ b/agenda/gwr.py @@ -5,7 +5,7 @@ import re from datetime import date, datetime from time import time -import requests +import httpx url = "https://www.gwr.com/your-tickets/choosing-your-ticket/advance-tickets" @@ -29,18 +29,20 @@ def extract_weekday_date(html: str) -> date | None: return datetime.strptime(date_str, "%A %d %B %Y").date() -def advance_tickets_page_html(data_dir: str, ttl: int = 60 * 60 * 6) -> str: +async def advance_tickets_page_html(data_dir: str, ttl: int = 60 * 60 * 6) -> str: """Get advance-tickets web page HTML with cache.""" filename = os.path.join(data_dir, "advance-tickets.html") mtime = os.path.getmtime(filename) if os.path.exists(filename) else 0 if (time() - mtime) < ttl: # use cache return open(filename).read() - html = requests.get(url).text + async with httpx.AsyncClient() as client: + r = await client.get(url) + html = r.text open(filename, "w").write(html) return html -def advance_ticket_date(data_dir: str) -> date | None: +async def advance_ticket_date(data_dir: str) -> date | None: """Get GWR advance tickets date with cache.""" - html = advance_tickets_page_html(data_dir) + html = await advance_tickets_page_html(data_dir) return extract_weekday_date(html) diff --git a/web_view.py b/web_view.py index 1bd66e7..4d430b7 100755 --- a/web_view.py +++ b/web_view.py @@ -45,10 +45,10 @@ def exception_handler(e: werkzeug.exceptions.InternalServerError) -> tuple[str, @app.route("/") -def index() -> str: +async def index() -> str: """Index page.""" now = datetime.now() - data = get_data(now) + data = await get_data(now) return flask.render_template("index.html", today=now.date(), **data)