Merge branch 'main' of https://git.4angle.com/edward/agenda
This commit is contained in:
commit
943d45bd27
|
@ -1,24 +1,18 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import configparser
|
import configparser
|
||||||
import json
|
|
||||||
import operator
|
import operator
|
||||||
import os
|
import os
|
||||||
import typing
|
import typing
|
||||||
import warnings
|
import warnings
|
||||||
from datetime import date, datetime, time, timedelta, timezone
|
from datetime import date, datetime, time, timedelta
|
||||||
from time import time as unixtime
|
|
||||||
|
|
||||||
import dateutil
|
import dateutil
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
import dateutil.tz
|
import dateutil.tz
|
||||||
import exchange_calendars
|
|
||||||
import holidays
|
import holidays
|
||||||
import httpx
|
|
||||||
import lxml
|
import lxml
|
||||||
import pandas
|
|
||||||
import pytz
|
import pytz
|
||||||
import yaml
|
import yaml
|
||||||
from dateutil.easter import easter
|
|
||||||
from dateutil.relativedelta import FR, relativedelta
|
from dateutil.relativedelta import FR, relativedelta
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
|
@ -29,9 +23,12 @@ from . import (
|
||||||
fx,
|
fx,
|
||||||
gwr,
|
gwr,
|
||||||
markets,
|
markets,
|
||||||
|
stock_market,
|
||||||
|
subscription,
|
||||||
sun,
|
sun,
|
||||||
thespacedevs,
|
thespacedevs,
|
||||||
travel,
|
travel,
|
||||||
|
uk_holiday,
|
||||||
waste_schedule,
|
waste_schedule,
|
||||||
)
|
)
|
||||||
from .types import Event
|
from .types import Event
|
||||||
|
@ -62,51 +59,6 @@ config.read(config_filename)
|
||||||
data_dir = config.get("data", "dir")
|
data_dir = config.get("data", "dir")
|
||||||
|
|
||||||
|
|
||||||
def next_uk_mothers_day(input_date: date) -> date:
|
|
||||||
"""Calculate the date of the next UK Mother's Day from the current date."""
|
|
||||||
current_year = input_date.year
|
|
||||||
|
|
||||||
easter_date = easter(current_year)
|
|
||||||
|
|
||||||
# Calculate the date of Mother's Day, which is the fourth Sunday of Lent
|
|
||||||
mothers_day = easter_date + timedelta(weeks=3)
|
|
||||||
|
|
||||||
# Check if Mother's Day has already passed this year
|
|
||||||
if input_date > mothers_day:
|
|
||||||
# If it has passed, calculate for the next year
|
|
||||||
easter_date = easter(current_year + 1)
|
|
||||||
mothers_day = easter_date + timedelta(weeks=3)
|
|
||||||
|
|
||||||
return mothers_day
|
|
||||||
|
|
||||||
|
|
||||||
def next_uk_fathers_day(input_date: date) -> date:
|
|
||||||
"""Calculate the date of the next UK Father's Day from the current date."""
|
|
||||||
# Get the current date
|
|
||||||
# Calculate the day of the week for the current date (0 = Monday, 6 = Sunday)
|
|
||||||
current_day_of_week = input_date.weekday()
|
|
||||||
|
|
||||||
# Calculate the number of days until the next Sunday
|
|
||||||
days_until_sunday = (6 - current_day_of_week) % 7
|
|
||||||
|
|
||||||
# Calculate the date of the next Sunday
|
|
||||||
next_sunday = input_date + timedelta(days=days_until_sunday)
|
|
||||||
|
|
||||||
# Calculate the date of Father's Day, which is the third Sunday of June
|
|
||||||
fathers_day = date(next_sunday.year, 6, 1) + timedelta(
|
|
||||||
weeks=2, days=next_sunday.weekday()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if Father's Day has already passed this year
|
|
||||||
if input_date > fathers_day:
|
|
||||||
# If it has passed, calculate for the next year
|
|
||||||
fathers_day = date(fathers_day.year + 1, 6, 1) + timedelta(
|
|
||||||
weeks=2, days=next_sunday.weekday()
|
|
||||||
)
|
|
||||||
|
|
||||||
return fathers_day
|
|
||||||
|
|
||||||
|
|
||||||
def timezone_transition(
|
def timezone_transition(
|
||||||
start_dt: datetime, end_dt: datetime, key: str, tz_name: str
|
start_dt: datetime, end_dt: datetime, key: str, tz_name: str
|
||||||
) -> list[Event]:
|
) -> list[Event]:
|
||||||
|
@ -119,29 +71,6 @@ def timezone_transition(
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
async def get_next_bank_holiday(start_date: date, end_date: date) -> list[Event]:
|
|
||||||
"""Date and name of the next UK bank holiday."""
|
|
||||||
url = "https://www.gov.uk/bank-holidays.json"
|
|
||||||
filename = os.path.join(data_dir, "bank-holidays.json")
|
|
||||||
mtime = os.path.getmtime(filename)
|
|
||||||
if (unixtime() - mtime) > 60 * 60 * 6: # six hours
|
|
||||||
async with httpx.AsyncClient() as client:
|
|
||||||
r = await client.get(url)
|
|
||||||
open(filename, "w").write(r.text)
|
|
||||||
|
|
||||||
events = json.load(open(filename))["england-and-wales"]["events"]
|
|
||||||
hols: list[Event] = []
|
|
||||||
for event in events:
|
|
||||||
event_date = datetime.strptime(event["date"], "%Y-%m-%d").date()
|
|
||||||
if event_date < start_date:
|
|
||||||
continue
|
|
||||||
if event_date > end_date:
|
|
||||||
break
|
|
||||||
hols.append(Event(name="bank_holiday", date=event_date, title=event["title"]))
|
|
||||||
|
|
||||||
return hols
|
|
||||||
|
|
||||||
|
|
||||||
def uk_financial_year_end(input_date: date) -> date:
|
def uk_financial_year_end(input_date: date) -> date:
|
||||||
"""Next date of the end of the UK financial year, April 5th."""
|
"""Next date of the end of the UK financial year, April 5th."""
|
||||||
# Determine the year of the input date
|
# Determine the year of the input date
|
||||||
|
@ -158,60 +87,6 @@ def uk_financial_year_end(input_date: date) -> date:
|
||||||
return uk_financial_year_end
|
return uk_financial_year_end
|
||||||
|
|
||||||
|
|
||||||
def timedelta_display(delta: timedelta) -> str:
|
|
||||||
"""Format timedelta as a human readable string."""
|
|
||||||
total_seconds = int(delta.total_seconds())
|
|
||||||
days, remainder = divmod(total_seconds, 24 * 60 * 60)
|
|
||||||
hours, remainder = divmod(remainder, 60 * 60)
|
|
||||||
mins, secs = divmod(remainder, 60)
|
|
||||||
|
|
||||||
return " ".join(
|
|
||||||
f"{v:>3} {label}"
|
|
||||||
for v, label in ((days, "days"), (hours, "hrs"), (mins, "mins"))
|
|
||||||
if v
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def stock_markets() -> list[str]:
|
|
||||||
"""Stock markets open and close times."""
|
|
||||||
# The trading calendars code is slow, maybe there is a faster way to do this
|
|
||||||
# Or we could cache the result
|
|
||||||
now = pandas.Timestamp.now(timezone.utc)
|
|
||||||
now_local = pandas.Timestamp.now(here)
|
|
||||||
markets = [
|
|
||||||
("XLON", "London"),
|
|
||||||
("XNYS", "US"),
|
|
||||||
]
|
|
||||||
reply = []
|
|
||||||
for code, label in markets:
|
|
||||||
cal = exchange_calendars.get_calendar(code)
|
|
||||||
|
|
||||||
if cal.is_open_on_minute(now_local):
|
|
||||||
next_close = cal.next_close(now).tz_convert(here)
|
|
||||||
next_close = next_close.replace(minute=round(next_close.minute, -1))
|
|
||||||
delta_close = timedelta_display(next_close - now_local)
|
|
||||||
|
|
||||||
prev_open = cal.previous_open(now).tz_convert(here)
|
|
||||||
prev_open = prev_open.replace(minute=round(prev_open.minute, -1))
|
|
||||||
delta_open = timedelta_display(now_local - prev_open)
|
|
||||||
|
|
||||||
msg = (
|
|
||||||
f"{label:>6} market opened {delta_open} ago, "
|
|
||||||
+ f"closes in {delta_close} ({next_close:%H:%M})"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
ts = cal.next_open(now)
|
|
||||||
ts = ts.replace(minute=round(ts.minute, -1))
|
|
||||||
ts = ts.tz_convert(here)
|
|
||||||
delta = timedelta_display(ts - now_local)
|
|
||||||
msg = f"{label:>6} market opens in {delta}" + (
|
|
||||||
f" ({ts:%H:%M})" if (ts - now_local) < timedelta(days=1) else ""
|
|
||||||
)
|
|
||||||
|
|
||||||
reply.append(msg)
|
|
||||||
return reply
|
|
||||||
|
|
||||||
|
|
||||||
def get_us_holidays(start_date: date, end_date: date) -> list[Event]:
|
def get_us_holidays(start_date: date, end_date: date) -> list[Event]:
|
||||||
"""Date and name of next US holiday."""
|
"""Date and name of next US holiday."""
|
||||||
found: list[Event] = []
|
found: list[Event] = []
|
||||||
|
@ -272,7 +147,7 @@ def as_date(d: date | datetime) -> date:
|
||||||
|
|
||||||
|
|
||||||
def get_accommodation(filepath: str) -> list[Event]:
|
def get_accommodation(filepath: str) -> list[Event]:
|
||||||
"""Get birthdays from config."""
|
"""Get accomodation from config."""
|
||||||
with open(filepath) as f:
|
with open(filepath) as f:
|
||||||
return [
|
return [
|
||||||
Event(
|
Event(
|
||||||
|
@ -330,7 +205,7 @@ async def get_data(now: datetime) -> typing.Mapping[str, str | object]:
|
||||||
) = await asyncio.gather(
|
) = await asyncio.gather(
|
||||||
fx.get_gbpusd(config),
|
fx.get_gbpusd(config),
|
||||||
gwr.advance_ticket_date(data_dir),
|
gwr.advance_ticket_date(data_dir),
|
||||||
get_next_bank_holiday(last_year, next_year),
|
uk_holiday.bank_holiday_list(last_year, next_year, data_dir),
|
||||||
thespacedevs.get_launches(rocket_dir, limit=40),
|
thespacedevs.get_launches(rocket_dir, limit=40),
|
||||||
waste_collection_events(),
|
waste_collection_events(),
|
||||||
bristol_waste_collection_events(today),
|
bristol_waste_collection_events(today),
|
||||||
|
@ -343,15 +218,15 @@ async def get_data(now: datetime) -> typing.Mapping[str, str | object]:
|
||||||
"bank_holiday": bank_holiday,
|
"bank_holiday": bank_holiday,
|
||||||
"us_holiday": get_us_holidays(last_year, next_year),
|
"us_holiday": get_us_holidays(last_year, next_year),
|
||||||
"next_us_presidential_election": next_us_presidential_election,
|
"next_us_presidential_election": next_us_presidential_election,
|
||||||
"stock_markets": stock_markets(),
|
"stock_markets": stock_market.open_and_close(),
|
||||||
"uk_clock_change": timezone_transition(
|
"uk_clock_change": timezone_transition(
|
||||||
minus_365, plus_365, "uk_clock_change", "Europe/London"
|
minus_365, plus_365, "uk_clock_change", "Europe/London"
|
||||||
),
|
),
|
||||||
"us_clock_change": timezone_transition(
|
"us_clock_change": timezone_transition(
|
||||||
minus_365, plus_365, "us_clock_change", "America/New_York"
|
minus_365, plus_365, "us_clock_change", "America/New_York"
|
||||||
),
|
),
|
||||||
"mothers_day": next_uk_mothers_day(today),
|
"mothers_day": uk_holiday.get_mothers_day(today),
|
||||||
"fathers_day": next_uk_fathers_day(today),
|
"fathers_day": uk_holiday.get_fathers_day(today),
|
||||||
"uk_financial_year_end": uk_financial_year_end(today),
|
"uk_financial_year_end": uk_financial_year_end(today),
|
||||||
"xmas_last_posting_dates": xmas_last_posting_dates,
|
"xmas_last_posting_dates": xmas_last_posting_dates,
|
||||||
"gwr_advance_tickets": gwr_advance_tickets,
|
"gwr_advance_tickets": gwr_advance_tickets,
|
||||||
|
@ -381,7 +256,13 @@ async def get_data(now: datetime) -> typing.Mapping[str, str | object]:
|
||||||
reply["sunset"] = sun.sunset(observer)
|
reply["sunset"] = sun.sunset(observer)
|
||||||
|
|
||||||
for key, value in xmas_last_posting_dates.items():
|
for key, value in xmas_last_posting_dates.items():
|
||||||
events.append(Event(name=f"xmas_last_{key}", date=value))
|
events.append(
|
||||||
|
Event(
|
||||||
|
name=f"xmas_last_{key}",
|
||||||
|
date=value,
|
||||||
|
url="https://www.postoffice.co.uk/last-posting-dates",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
my_data = config["data"]["personal-data"]
|
my_data = config["data"]["personal-data"]
|
||||||
events += birthday.get_birthdays(last_year, os.path.join(my_data, "entities.yaml"))
|
events += birthday.get_birthdays(last_year, os.path.join(my_data, "entities.yaml"))
|
||||||
|
@ -390,6 +271,8 @@ async def get_data(now: datetime) -> typing.Mapping[str, str | object]:
|
||||||
events += conference.get_list(os.path.join(my_data, "conferences.yaml"))
|
events += conference.get_list(os.path.join(my_data, "conferences.yaml"))
|
||||||
events += backwell_bins + bristol_bins
|
events += backwell_bins + bristol_bins
|
||||||
|
|
||||||
|
events += subscription.get_events(os.path.join(my_data, "subscriptions.yaml"))
|
||||||
|
|
||||||
next_up_series = Event(
|
next_up_series = Event(
|
||||||
date=date(2026, 6, 1),
|
date=date(2026, 6, 1),
|
||||||
title="70 Up",
|
title="70 Up",
|
||||||
|
|
63
agenda/stock_market.py
Normal file
63
agenda/stock_market.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
"""Stock market open and close times."""
|
||||||
|
|
||||||
|
from datetime import timedelta, timezone
|
||||||
|
|
||||||
|
import dateutil.tz
|
||||||
|
import exchange_calendars
|
||||||
|
import pandas
|
||||||
|
|
||||||
|
here = dateutil.tz.tzlocal()
|
||||||
|
|
||||||
|
|
||||||
|
def timedelta_display(delta: timedelta) -> str:
|
||||||
|
"""Format timedelta as a human readable string."""
|
||||||
|
total_seconds = int(delta.total_seconds())
|
||||||
|
days, remainder = divmod(total_seconds, 24 * 60 * 60)
|
||||||
|
hours, remainder = divmod(remainder, 60 * 60)
|
||||||
|
mins, secs = divmod(remainder, 60)
|
||||||
|
|
||||||
|
return " ".join(
|
||||||
|
f"{v:>3} {label}"
|
||||||
|
for v, label in ((days, "days"), (hours, "hrs"), (mins, "mins"))
|
||||||
|
if v
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def open_and_close() -> list[str]:
|
||||||
|
"""Stock markets open and close times."""
|
||||||
|
# The trading calendars code is slow, maybe there is a faster way to do this
|
||||||
|
# Or we could cache the result
|
||||||
|
now = pandas.Timestamp.now(timezone.utc)
|
||||||
|
now_local = pandas.Timestamp.now(here)
|
||||||
|
markets = [
|
||||||
|
("XLON", "London"),
|
||||||
|
("XNYS", "US"),
|
||||||
|
]
|
||||||
|
reply = []
|
||||||
|
for code, label in markets:
|
||||||
|
cal = exchange_calendars.get_calendar(code)
|
||||||
|
|
||||||
|
if cal.is_open_on_minute(now_local):
|
||||||
|
next_close = cal.next_close(now).tz_convert(here)
|
||||||
|
next_close = next_close.replace(minute=round(next_close.minute, -1))
|
||||||
|
delta_close = timedelta_display(next_close - now_local)
|
||||||
|
|
||||||
|
prev_open = cal.previous_open(now).tz_convert(here)
|
||||||
|
prev_open = prev_open.replace(minute=round(prev_open.minute, -1))
|
||||||
|
delta_open = timedelta_display(now_local - prev_open)
|
||||||
|
|
||||||
|
msg = (
|
||||||
|
f"{label:>6} market opened {delta_open} ago, "
|
||||||
|
+ f"closes in {delta_close} ({next_close:%H:%M})"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ts = cal.next_open(now)
|
||||||
|
ts = ts.replace(minute=round(ts.minute, -1))
|
||||||
|
ts = ts.tz_convert(here)
|
||||||
|
delta = timedelta_display(ts - now_local)
|
||||||
|
msg = f"{label:>6} market opens in {delta}" + (
|
||||||
|
f" ({ts:%H:%M})" if (ts - now_local) < timedelta(days=1) else ""
|
||||||
|
)
|
||||||
|
|
||||||
|
reply.append(msg)
|
||||||
|
return reply
|
|
@ -38,6 +38,25 @@ def get(
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_trains(from_date: date, filepath: str) -> list[Event]:
|
||||||
|
"""Get train events."""
|
||||||
|
events: list[Event] = []
|
||||||
|
for item in yaml.safe_load(open(filepath)):
|
||||||
|
if item["depart"].date() < from_date:
|
||||||
|
continue
|
||||||
|
events += [
|
||||||
|
Event(
|
||||||
|
date=leg["depart"],
|
||||||
|
end_date=leg["arrive"],
|
||||||
|
name="transport",
|
||||||
|
title=f'train from {leg["from"]} to {leg["to"]}',
|
||||||
|
url=item.get("url"),
|
||||||
|
)
|
||||||
|
for leg in item["legs"]
|
||||||
|
]
|
||||||
|
return events
|
||||||
|
|
||||||
|
|
||||||
def flight_number(flight: Leg) -> str:
|
def flight_number(flight: Leg) -> str:
|
||||||
"""Flight number."""
|
"""Flight number."""
|
||||||
airline_code = flight["airline"]
|
airline_code = flight["airline"]
|
||||||
|
@ -49,7 +68,7 @@ def flight_number(flight: Leg) -> str:
|
||||||
|
|
||||||
def all_events(from_date: date, data_dir: str) -> list[Event]:
|
def all_events(from_date: date, data_dir: str) -> list[Event]:
|
||||||
"""Get all flights and rail journeys."""
|
"""Get all flights and rail journeys."""
|
||||||
trains = get(from_date, "train", os.path.join(data_dir, "trains.yaml"))
|
trains = get_trains(from_date, os.path.join(data_dir, "trains.yaml"))
|
||||||
flights = get(
|
flights = get(
|
||||||
from_date, "flight", os.path.join(data_dir, "flights.yaml"), extra=flight_number
|
from_date, "flight", os.path.join(data_dir, "flights.yaml"), extra=flight_number
|
||||||
)
|
)
|
||||||
|
|
81
agenda/uk_holiday.py
Normal file
81
agenda/uk_holiday.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
"""UK holidays."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from datetime import date, datetime, timedelta
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
from dateutil.easter import easter
|
||||||
|
|
||||||
|
from .types import Event
|
||||||
|
|
||||||
|
|
||||||
|
async def bank_holiday_list(
|
||||||
|
start_date: date, end_date: date, data_dir: str
|
||||||
|
) -> list[Event]:
|
||||||
|
"""Date and name of the next UK bank holiday."""
|
||||||
|
url = "https://www.gov.uk/bank-holidays.json"
|
||||||
|
filename = os.path.join(data_dir, "bank-holidays.json")
|
||||||
|
mtime = os.path.getmtime(filename)
|
||||||
|
if (time() - mtime) > 60 * 60 * 6: # six hours
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
r = await client.get(url)
|
||||||
|
open(filename, "w").write(r.text)
|
||||||
|
|
||||||
|
events = json.load(open(filename))["england-and-wales"]["events"]
|
||||||
|
hols: list[Event] = []
|
||||||
|
for event in events:
|
||||||
|
event_date = datetime.strptime(event["date"], "%Y-%m-%d").date()
|
||||||
|
if event_date < start_date:
|
||||||
|
continue
|
||||||
|
if event_date > end_date:
|
||||||
|
break
|
||||||
|
hols.append(Event(name="bank_holiday", date=event_date, title=event["title"]))
|
||||||
|
|
||||||
|
return hols
|
||||||
|
|
||||||
|
|
||||||
|
def get_mothers_day(input_date: date) -> date:
|
||||||
|
"""Calculate the date of the next UK Mother's Day from the current date."""
|
||||||
|
current_year = input_date.year
|
||||||
|
|
||||||
|
easter_date = easter(current_year)
|
||||||
|
|
||||||
|
# Calculate the date of Mother's Day, which is the fourth Sunday of Lent
|
||||||
|
mothers_day = easter_date + timedelta(weeks=3)
|
||||||
|
|
||||||
|
# Check if Mother's Day has already passed this year
|
||||||
|
if input_date > mothers_day:
|
||||||
|
# If it has passed, calculate for the next year
|
||||||
|
easter_date = easter(current_year + 1)
|
||||||
|
mothers_day = easter_date + timedelta(weeks=3)
|
||||||
|
|
||||||
|
return mothers_day
|
||||||
|
|
||||||
|
|
||||||
|
def get_fathers_day(input_date: date) -> date:
|
||||||
|
"""Calculate the date of the next UK Father's Day from the current date."""
|
||||||
|
# Get the current date
|
||||||
|
# Calculate the day of the week for the current date (0 = Monday, 6 = Sunday)
|
||||||
|
current_day_of_week = input_date.weekday()
|
||||||
|
|
||||||
|
# Calculate the number of days until the next Sunday
|
||||||
|
days_until_sunday = (6 - current_day_of_week) % 7
|
||||||
|
|
||||||
|
# Calculate the date of the next Sunday
|
||||||
|
next_sunday = input_date + timedelta(days=days_until_sunday)
|
||||||
|
|
||||||
|
# Calculate the date of Father's Day, which is the third Sunday of June
|
||||||
|
fathers_day = date(next_sunday.year, 6, 1) + timedelta(
|
||||||
|
weeks=2, days=next_sunday.weekday()
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if Father's Day has already passed this year
|
||||||
|
if input_date > fathers_day:
|
||||||
|
# If it has passed, calculate for the next year
|
||||||
|
fathers_day = date(fathers_day.year + 1, 6, 1) + timedelta(
|
||||||
|
weeks=2, days=next_sunday.weekday()
|
||||||
|
)
|
||||||
|
|
||||||
|
return fathers_day
|
|
@ -13,7 +13,7 @@ import pytz
|
||||||
|
|
||||||
from .types import Event
|
from .types import Event
|
||||||
|
|
||||||
ttl_hours = 6
|
ttl_hours = 12
|
||||||
|
|
||||||
uk_tz = pytz.timezone("Europe/London")
|
uk_tz = pytz.timezone("Europe/London")
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ async def get_bristol_gov_uk_data(uprn: str) -> httpx.Response:
|
||||||
|
|
||||||
_uprn = str(uprn).zfill(12)
|
_uprn = str(uprn).zfill(12)
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=10) as client:
|
async with httpx.AsyncClient(timeout=20) as client:
|
||||||
# Initialise form
|
# Initialise form
|
||||||
payload = {"servicetypeid": "7dce896c-b3ba-ea11-a812-000d3a7f1cdc"}
|
payload = {"servicetypeid": "7dce896c-b3ba-ea11-a812-000d3a7f1cdc"}
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
|
|
Loading…
Reference in a new issue