diff --git a/.gitignore b/.gitignore index bbd9556f..c3981bc4 100644 --- a/.gitignore +++ b/.gitignore @@ -120,22 +120,10 @@ celerybeat-schedule ## Plugin-specific files: # IntelliJ -/out/ .idea/ # mpeltonen/sbt-idea plugin .idea_modules/ - -# Django -backend/storage -backend/static -backend/.env -#backend/djcore - -/docker/basemap/data/ -/docker/basemap/gebco/ -/proxy/node_modules/ - -/Arpav-PPCV - .venv + +docker/traefik/basicauth-users.txt diff --git a/README.md b/README.md index 47301f48..febe9e75 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,13 @@ project's container registry. This is governed by a two-stage workflow, orchestr The strategy described above employs an installation of the [webhook](https://github.com/adnanh/webhook) server, together with some custom deployment scripts. +Relevant places to look for configuration in the staging environment, in addition to the `${HOME}` directory: + +- `/opt/traefik` +- `/etc/system/system/docker.service.d` +- `/etc/system/system/traefik.service` +- `/etc/system/system/webhook.service` + ##### Production environment diff --git a/arpav_ppcv/config.py b/arpav_ppcv/config.py index b0a077cd..6984d3c4 100644 --- a/arpav_ppcv/config.py +++ b/arpav_ppcv/config.py @@ -19,6 +19,25 @@ class ContactSettings(pydantic.BaseModel): email: str = "info@geobeyond.it" +class PrefectSettings(pydantic.BaseModel): + num_flow_retries: int = 5 + flow_retry_delay_seconds: int = 5 + num_task_retries: int = 5 + task_retry_delay_seconds: int = 5 + observation_stations_refresher_flow_cron_schedule: str = ( + "0 1 * * 1" # run once every week, at 01:00 on monday + ) + observation_monthly_measurements_refresher_flow_cron_schedule: str = ( + "0 2 * * 1" # run once every week, at 02:00 on monday + ) + observation_seasonal_measurements_refresher_flow_cron_schedule: str = ( + "0 3 * * 1" # run once every week, at 03:00 on monday + ) + observation_yearly_measurements_refresher_flow_cron_schedule: str = ( + "0 4 * * 1" # run once every week, at 04:00 on monday + ) + + class ThreddsServerSettings(pydantic.BaseModel): base_url: str = "http://localhost:8080/thredds" wms_service_url_fragment: str = "wms" @@ -74,8 +93,9 @@ class ArpavPpcvSettings(BaseSettings): # noqa templates_dir: Optional[Path] = Path(__file__).parent / "webapp/templates" static_dir: Optional[Path] = Path(__file__).parent / "webapp/static" thredds_server: ThreddsServerSettings = ThreddsServerSettings() + prefect: PrefectSettings = PrefectSettings() martin_tile_server_base_url: str = "http://localhost:3000" - nearest_station_radius_meters: int = 10_000 + nearest_station_radius_meters: int = 200 v2_api_mount_prefix: str = "/api/v2" log_config_file: Path | None = None session_secret_key: str = "changeme" diff --git a/arpav_ppcv/main.py b/arpav_ppcv/main.py index 0f652704..b829c4b0 100644 --- a/arpav_ppcv/main.py +++ b/arpav_ppcv/main.py @@ -31,6 +31,7 @@ from .cliapp.app import app as cli_app from .bootstrapper.cliapp import app as bootstrapper_app from .observations_harvester.cliapp import app as observations_harvester_app +from .prefect.cliapp import app as prefect_app from .thredds import crawler app = typer.Typer() @@ -43,6 +44,7 @@ app.add_typer(observations_harvester_app, name="observations-harvester") app.add_typer(bootstrapper_app, name="bootstrap") app.add_typer(translations_app, name="translations") +app.add_typer(prefect_app, name="prefect") @app.callback() diff --git a/arpav_ppcv/observations_harvester/cliapp.py b/arpav_ppcv/observations_harvester/cliapp.py index a0c68980..66623e15 100644 --- a/arpav_ppcv/observations_harvester/cliapp.py +++ b/arpav_ppcv/observations_harvester/cliapp.py @@ -1,40 +1,63 @@ -import httpx -import sqlmodel import typer -from rich import print -from typing import ( - Annotated, - Literal, -) +from typing import Annotated -from .. import database -from . import operations +from ..prefect.flows import observations as observations_flows app = typer.Typer() @app.command() -def refresh_stations(ctx: typer.Context) -> None: - client = httpx.Client() - with sqlmodel.Session(ctx.obj["engine"]) as session: - created = operations.refresh_stations(client, session) - print(f"Created {len(created)} stations:") - print("\n".join(s.code for s in created)) +def refresh_stations( + variable: Annotated[ + str, + typer.Option( + help=( + "Name of the variable to process. If not provided, all " + "variables are processed." + ) + ), + ] = None, + refresh_monthly: Annotated[ + bool, + typer.Option( + help=( + "Refresh stations that have monthly measurements for " + "the input month." + ) + ), + ] = True, + refresh_seasonal: Annotated[ + bool, + typer.Option( + help=( + "Refresh stations that have seasonal measurements for " + "the input season." + ) + ), + ] = True, + refresh_yearly: Annotated[ + bool, typer.Option(help=("Refresh stations that have yearly measurements")) + ] = True, +) -> None: + observations_flows.refresh_stations( + variable_name=variable, + refresh_stations_with_monthly_data=refresh_monthly, + refresh_stations_with_seasonal_data=refresh_seasonal, + refresh_stations_with_yearly_data=refresh_yearly, + ) @app.command() def refresh_monthly_measurements( - ctx: typer.Context, station: Annotated[ - list[str], + str, typer.Option( - default_factory=list, help=( "Code of the station to process. If not provided, all " "stations are processed." ), ), - ], + ] = None, variable: Annotated[ str, typer.Option( @@ -45,29 +68,16 @@ def refresh_monthly_measurements( ), ] = None, ) -> None: - client = httpx.Client() - with sqlmodel.Session(ctx.obj["engine"]) as session: - for station_code in station: - print(f"Processing station: {station_code!r}...") - created = _refresh_measurements( - session, client, variable, station_code, "monthly" - ) - print(f"Created {len(created)} monthly measurements:") - print( - "\n".join( - f"{m.station.code}-{m.variable.name}-{m.date.strftime('%Y-%m-%d')}" - for m in created - ) - ) + observations_flows.refresh_monthly_measurements( + station_code=station, variable_name=variable + ) @app.command() def refresh_seasonal_measurements( - ctx: typer.Context, station: Annotated[ - list[str], + str, typer.Option( - default_factory=list, help=( "Code of the station to process. If not provided, all " "stations are processed." @@ -84,35 +94,23 @@ def refresh_seasonal_measurements( ), ] = None, ) -> None: - client = httpx.Client() - with sqlmodel.Session(ctx.obj["engine"]) as session: - if len(station) > 0: - for station_code in station: - print(f"Processing station {station_code!r}...") - created = _refresh_measurements( - session, client, variable, station_code, "seasonal" - ) - else: - created = _refresh_measurements(session, client, variable, None, "seasonal") - print(f"Created {len(created)} seasonal measurements:") - print( - "\n".join(f"{m.station.code}-{m.variable.name}-{m.year}" for m in created) - ) + observations_flows.refresh_seasonal_measurements( + station_code=station, + variable_name=variable, + ) @app.command() def refresh_yearly_measurements( - ctx: typer.Context, station: Annotated[ - list[str], + str, typer.Option( - default_factory=list, help=( "Code of the station to process. If not provided, all " "stations are processed." ), ), - ], + ] = None, variable: Annotated[ str, typer.Option( @@ -123,55 +121,6 @@ def refresh_yearly_measurements( ), ] = None, ) -> None: - client = httpx.Client() - with sqlmodel.Session(ctx.obj["engine"]) as session: - if len(station) > 0: - for station_code in station: - print(f"Processing station {station_code!r}...") - created = _refresh_measurements( - session, client, variable, station_code, "yearly" - ) - else: - created = _refresh_measurements(session, client, variable, None, "yearly") - print(f"Created {len(created)} yearly measurements:") - print( - "\n".join(f"{m.station.code}-{m.variable.name}-{m.year}" for m in created) - ) - - -def _refresh_measurements( - db_session: sqlmodel.Session, - client: httpx.Client, - variable_name: str | None, - station_code: str | None, - measurement_type: Literal["monthly", "seasonal", "yearly"], -) -> list: - if station_code is not None: - db_station = database.get_station_by_code(db_session, station_code) - if db_station is not None: - station_id = db_station.id - else: - raise SystemExit("Invalid station code") - else: - station_id = None - if variable_name is not None: - db_variable = database.get_variable_by_name(db_session, variable_name) - if db_variable is not None: - variable_id = db_variable.id - else: - raise SystemExit("Invalid variable name") - else: - variable_id = None - - handler = { - "monthly": operations.refresh_monthly_measurements, - "seasonal": operations.refresh_seasonal_measurements, - "yearly": operations.refresh_yearly_measurements, - }[measurement_type] - - return handler( - client, - db_session, - station_id=station_id, - variable_id=variable_id, + observations_flows.refresh_yearly_measurements( + station_code=station, variable_name=variable ) diff --git a/arpav_ppcv/observations_harvester/operations.py b/arpav_ppcv/observations_harvester/operations.py index 86f9225d..51b79367 100644 --- a/arpav_ppcv/observations_harvester/operations.py +++ b/arpav_ppcv/observations_harvester/operations.py @@ -1,7 +1,14 @@ import datetime as dt import logging import uuid -from typing import Optional +from collections.abc import ( + Generator, + Sequence, +) +from typing import ( + Callable, + Optional, +) import geojson_pydantic import httpx @@ -19,77 +26,119 @@ logger = logging.getLogger(__name__) -def harvest_stations( - client: httpx.Client, db_session: sqlmodel.Session -) -> list[observations.StationCreate]: - existing_stations = {s.code: s for s in database.collect_all_stations(db_session)} - stations_create = {} - coord_converter = pyproj.Transformer.from_crs( - pyproj.CRS("epsg:4258"), pyproj.CRS("epsg:4326"), always_xy=True - ).transform - existing_variables = database.collect_all_variables(db_session) - for idx, variable in enumerate(existing_variables): +def fetch_remote_stations( + client: httpx.Client, + variables: Sequence[observations.Variable], + fetch_stations_with_months: bool, + fetch_stations_with_seasons: bool, + fetch_stations_with_yearly_measurements: bool, +) -> Generator[dict, None, None]: + station_url = ( + "https://api.arpa.veneto.it/REST/v1/clima_indicatori/staz_attive_lunghe" + ) + for variable in variables: logger.info( - f"({idx+1}/{len(existing_variables)}) Processing stations for " - f"variable {variable.name!r}..." + f"Retrieving stations with monthly measurements for variable " + f"{variable.name!r}..." ) - response = client.get( - "https://api.arpa.veneto.it/REST/v1/clima_indicatori/staz_attive", - params={"indicatore": variable.name}, - ) - response.raise_for_status() - for raw_station in response.json().get("data", []): - station_code = str(raw_station["statcd"]) - if raw_start := raw_station.get("iniziovalidita"): - try: - active_since = dt.date(*(int(i) for i in raw_start.split("-"))) - except TypeError: - logger.warning( - f"Could not extract a valid date from the input {raw_start!r}" - ) - active_since = None - else: - active_since = None - if raw_end := raw_station.get("finevalidita"): - try: - active_until = dt.date(*raw_end.split("-")) - except TypeError: - logger.warning( - f"Could not extract a valid date from the input {raw_end!r}" - ) - active_until = None - else: - active_until = None - if ( - station_code not in existing_stations - and station_code not in stations_create - ): - pt_4258 = shapely.Point( - raw_station["EPSG4258_LON"], raw_station["EPSG4258_LAT"] + if fetch_stations_with_months: + for month in range(1, 13): + logger.info(f"Processing month {month}...") + month_response = client.get( + station_url, + params={ + "indicatore": variable.name, + "tabella": "M", + "periodo": str(month), + }, ) - pt_4326 = shapely.ops.transform(coord_converter, pt_4258) - station_create = observations.StationCreate( - code=station_code, - geom=geojson_pydantic.Point( - type="Point", coordinates=(pt_4326.x, pt_4326.y) - ), - altitude_m=raw_station["altitude"], - name=raw_station["statnm"], - type_=raw_station["stattype"].lower().replace(" ", "_"), - active_since=active_since, - active_until=active_until, + month_response.raise_for_status() + for raw_station in month_response.json().get("data", []): + yield raw_station + if fetch_stations_with_seasons: + for season in range(1, 5): + logger.info(f"Processing season {season}...") + season_response = client.get( + station_url, + params={ + "indicatore": variable.name, + "tabella": "S", + "periodo": str(season), + }, ) - stations_create[station_create.code] = station_create - return list(stations_create.values()) + season_response.raise_for_status() + for raw_station in season_response.json().get("data", []): + yield raw_station + if fetch_stations_with_yearly_measurements: + logger.info("Processing year...") + year_response = client.get( + station_url, + params={ + "indicatore": variable.name, + "tabella": "A", + "periodo": "0", + }, + ) + year_response.raise_for_status() + for raw_station in year_response.json().get("data", []): + yield raw_station -def refresh_stations( - client: httpx.Client, db_session: sqlmodel.Session -) -> list[observations.Station]: - to_create = harvest_stations(client, db_session) - logger.info(f"About to create {len(to_create)} stations...") - created_variables = database.create_many_stations(db_session, to_create) - return created_variables +def parse_station( + raw_station: dict, coord_converter: Callable +) -> observations.StationCreate: + station_code = str(raw_station["statcd"]) + if raw_start := raw_station.get("iniziovalidita"): + try: + active_since = dt.date(*(int(i) for i in raw_start.split("-"))) + except TypeError: + logger.warning( + f"Could not extract a valid date from the input {raw_start!r}" + ) + active_since = None + else: + active_since = None + if raw_end := raw_station.get("finevalidita"): + try: + active_until = dt.date(*raw_end.split("-")) + except TypeError: + logger.warning(f"Could not extract a valid date from the input {raw_end!r}") + active_until = None + else: + active_until = None + pt_4258 = shapely.Point(raw_station["EPSG4258_LON"], raw_station["EPSG4258_LAT"]) + pt_4326 = shapely.ops.transform(coord_converter, pt_4258) + return observations.StationCreate( + code=station_code, + geom=geojson_pydantic.Point(type="Point", coordinates=(pt_4326.x, pt_4326.y)), + altitude_m=raw_station["altitude"], + name=raw_station["statnm"], + type_=raw_station.get("stattype", "").lower().replace(" ", "_"), + active_since=active_since, + active_until=active_until, + ) + + +def harvest_stations( + client: httpx.Client, + variables_to_refresh: Sequence[observations.Variable], + fetch_stations_with_months: bool, + fetch_stations_with_seasons: bool, + fetch_stations_with_yearly_measurements: bool, +) -> set[observations.StationCreate]: + coord_converter = pyproj.Transformer.from_crs( + pyproj.CRS("epsg:4258"), pyproj.CRS("epsg:4326"), always_xy=True + ).transform + stations = set() + for raw_station in fetch_remote_stations( + client, + variables_to_refresh, + fetch_stations_with_months, + fetch_stations_with_seasons, + fetch_stations_with_yearly_measurements, + ): + stations.add(parse_station(raw_station, coord_converter)) + return stations def harvest_monthly_measurements( @@ -121,7 +170,7 @@ def harvest_monthly_measurements( ) existing = {} for db_measurement in existing_measurements: - measurement_id = _build_monthly_measurement_id(db_measurement) + measurement_id = build_monthly_measurement_id(db_measurement) existing[measurement_id] = db_measurement response = client.get( "https://api.arpa.veneto.it/REST/v1/clima_indicatori", @@ -140,7 +189,7 @@ def harvest_monthly_measurements( value=raw_measurement["valore"], date=dt.date(raw_measurement["anno"], month, 1), ) - measurement_id = _build_monthly_measurement_id( + measurement_id = build_monthly_measurement_id( monthly_measurement_create ) if measurement_id not in existing: @@ -193,7 +242,7 @@ def harvest_seasonal_measurements( ) existing = {} for db_measurement in existing_measurements: - measurement_id = _build_seasonal_measurement_id(db_measurement) + measurement_id = build_seasonal_measurement_id(db_measurement) existing[measurement_id] = db_measurement season_query_param = { @@ -220,7 +269,7 @@ def harvest_seasonal_measurements( year=int(raw_measurement["anno"]), season=current_season, ) - measurement_id = _build_seasonal_measurement_id(measurement_create) + measurement_id = build_seasonal_measurement_id(measurement_create) if measurement_id not in existing: measurements_create.append(measurement_create) return measurements_create @@ -242,7 +291,7 @@ def refresh_seasonal_measurements( return created_measurements -def _build_monthly_measurement_id( +def build_monthly_measurement_id( measurement: observations.MonthlyMeasurement | observations.MonthlyMeasurementCreate, ) -> str: @@ -252,7 +301,7 @@ def _build_monthly_measurement_id( ) -def _build_seasonal_measurement_id( +def build_seasonal_measurement_id( measurement: observations.SeasonalMeasurement | observations.SeasonalMeasurementCreate, ) -> str: @@ -262,7 +311,7 @@ def _build_seasonal_measurement_id( ) -def _build_yearly_measurement_id( +def build_yearly_measurement_id( measurement: observations.YearlyMeasurement | observations.YearlyMeasurementCreate, ) -> str: return f"{measurement.station_id}-{measurement.variable_id}-{measurement.year}" @@ -314,7 +363,7 @@ def harvest_yearly_measurements( ) existing = {} for db_measurement in existing_measurements: - measurement_id = _build_yearly_measurement_id(db_measurement) + measurement_id = build_yearly_measurement_id(db_measurement) existing[measurement_id] = db_measurement response = client.get( "https://api.arpa.veneto.it/REST/v1/clima_indicatori", @@ -333,7 +382,7 @@ def harvest_yearly_measurements( value=raw_measurement["valore"], year=int(raw_measurement["anno"]), ) - measurement_id = _build_yearly_measurement_id(yearly_measurement_create) + measurement_id = build_yearly_measurement_id(yearly_measurement_create) if measurement_id not in existing: yearly_measurements_create.append(yearly_measurement_create) return yearly_measurements_create diff --git a/arpav_ppcv/prefect/__init__.py b/arpav_ppcv/prefect/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/arpav_ppcv/prefect/cliapp.py b/arpav_ppcv/prefect/cliapp.py new file mode 100644 index 00000000..dba98a3a --- /dev/null +++ b/arpav_ppcv/prefect/cliapp.py @@ -0,0 +1,57 @@ +import prefect +import typer + +from ..config import ArpavPpcvSettings +from .flows import observations as observations_flows + +app = typer.Typer() + + +@app.command() +def start_periodic_tasks( + ctx: typer.Context, + refresh_stations: bool = False, + refresh_monthly_measurements: bool = False, + refresh_seasonal_measurements: bool = False, + refresh_yearly_measurements: bool = False, +): + """Starts a prefect worker to perform background tasks. + + This starts a prefect worker that periodically performs the following tasks (if + enabled via the respective flags): + + - refreshing observation stations + - refreshing observation monthly measurements for known stations + - refreshing observation seasonal measurements for known stations + - refreshing observation yearly measurements for known stations + + """ + settings: ArpavPpcvSettings = ctx.obj["settings"] + to_serve = [] + if refresh_stations: + stations_refresher_deployment = ( + observations_flows.refresh_stations.to_deployment( + name="stations_refresher", + cron=settings.prefect.observation_stations_refresher_flow_cron_schedule, + ) + ) + to_serve.append(stations_refresher_deployment) + if refresh_monthly_measurements: + monthly_measurement_refresher_deployment = observations_flows.refresh_monthly_measurements.to_deployment( + name="monthly_measurement_refresher", + cron=settings.prefect.observation_monthly_measurements_refresher_flow_cron_schedule, + ) + to_serve.append(monthly_measurement_refresher_deployment) + if refresh_seasonal_measurements: + seasonal_measurement_refresher_deployment = observations_flows.refresh_seasonal_measurements.to_deployment( + name="seasonal_measurement_refresher", + cron=settings.prefect.observation_seasonal_measurements_refresher_flow_cron_schedule, + ) + to_serve.append(seasonal_measurement_refresher_deployment) + if refresh_yearly_measurements: + yearly_measurement_refresher_deployment = observations_flows.refresh_yearly_measurements.to_deployment( + name="yearly_measurement_refresher", + cron=settings.prefect.observation_yearly_measurements_refresher_flow_cron_schedule, + ) + to_serve.append(yearly_measurement_refresher_deployment) + prefect.serve(*to_serve) diff --git a/arpav_ppcv/prefect/flows/__init__.py b/arpav_ppcv/prefect/flows/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/arpav_ppcv/prefect/flows/observations.py b/arpav_ppcv/prefect/flows/observations.py new file mode 100644 index 00000000..b2a83791 --- /dev/null +++ b/arpav_ppcv/prefect/flows/observations.py @@ -0,0 +1,512 @@ +import datetime as dt +from typing import Sequence + +import httpx +import sqlmodel +import prefect +import prefect.artifacts +import pyproj + +from arpav_ppcv import database +from arpav_ppcv.config import get_settings +from arpav_ppcv.observations_harvester import operations +from arpav_ppcv.schemas import ( + base, + observations, +) + +# this is a module global because we need to configure the prefect flow and +# task with values from it +settings = get_settings() + + +@prefect.task( + retries=settings.prefect.num_task_retries, + retry_delay_seconds=settings.prefect.task_retry_delay_seconds, +) +def harvest_stations( + client: httpx.Client, + variable: observations.Variable, + fetch_stations_with_months: bool, + fetch_stations_with_seasons: bool, + fetch_stations_with_yearly_measurements: bool, +) -> set[observations.StationCreate]: + coord_converter = pyproj.Transformer.from_crs( + pyproj.CRS("epsg:4258"), pyproj.CRS("epsg:4326"), always_xy=True + ).transform + stations = set() + retriever = operations.fetch_remote_stations( + client=client, + variables=[variable], + fetch_stations_with_months=fetch_stations_with_months, + fetch_stations_with_seasons=fetch_stations_with_seasons, + fetch_stations_with_yearly_measurements=fetch_stations_with_yearly_measurements, + ) + for raw_station in retriever: + stations.add(operations.parse_station(raw_station, coord_converter)) + return stations + + +@prefect.task( + retries=settings.prefect.num_task_retries, + retry_delay_seconds=settings.prefect.task_retry_delay_seconds, +) +def find_new_stations( + db_stations: Sequence[observations.Station], + new_stations: Sequence[observations.StationCreate], +) -> list[observations.StationCreate]: + possibly_new_stations = {s.code: s for s in new_stations} + existing_stations = {s.code: s for s in db_stations} + to_create = [] + for possibly_new_station in possibly_new_stations.values(): + if existing_stations.get(possibly_new_station.code) is None: + print( + f"About to create station {possibly_new_station.code} - " + f"{possibly_new_station.name}..." + ) + to_create.append(possibly_new_station) + else: + print( + f"Station {possibly_new_station.code} - {possibly_new_station.name} " + f"is already known" + ) + for existing_station in existing_stations.values(): + if possibly_new_stations.get(existing_station.code) is None: + print( + f"Station {existing_station.code} - {existing_station.name} is not " + f"found on the remote. Maybe it can be deleted? The system does not " + f"delete stations so please check manually if this should be deleted " + f"or not" + ) + return to_create + + +@prefect.flow( + log_prints=True, + retries=settings.prefect.num_flow_retries, + retry_delay_seconds=settings.prefect.flow_retry_delay_seconds, +) +def refresh_stations( + variable_name: str | None = None, + refresh_stations_with_monthly_data: bool = True, + refresh_stations_with_seasonal_data: bool = True, + refresh_stations_with_yearly_data: bool = True, +): + settings = get_settings() + client = httpx.Client() + with sqlmodel.Session(database.get_engine(settings)) as db_session: + db_variables = _get_variables(db_session, variable_name) + if len(db_variables) > 0: + to_filter_for_new_stations = set() + to_wait_on = [] + for variable in db_variables: + print( + f"refreshing stations that have values for " + f"variable {variable.name!r}..." + ) + if refresh_stations_with_monthly_data: + monthly_future = harvest_stations.submit( + client, + variable, + fetch_stations_with_months=True, + fetch_stations_with_seasons=False, + fetch_stations_with_yearly_measurements=False, + ) + to_wait_on.append(monthly_future) + if refresh_stations_with_seasonal_data: + seasonal_future = harvest_stations.submit( + client, + variable, + fetch_stations_with_months=False, + fetch_stations_with_seasons=True, + fetch_stations_with_yearly_measurements=False, + ) + to_wait_on.append(seasonal_future) + if refresh_stations_with_yearly_data: + yearly_future = harvest_stations.submit( + client, + variable, + fetch_stations_with_months=False, + fetch_stations_with_seasons=False, + fetch_stations_with_yearly_measurements=True, + ) + to_wait_on.append(yearly_future) + for future in to_wait_on: + to_filter_for_new_stations.update(future.result()) + to_create = find_new_stations( + database.collect_all_stations(db_session), + list(to_filter_for_new_stations), + ) + if len(to_create) > 0: + print(f"Found {len(to_create)} new stations. Creating them now...") + for s in to_create: + print(f"- ({s.code}) {s.name}") + created = database.create_many_stations(db_session, to_create) + else: + created = [] + print("No new stations found.") + prefect.artifacts.create_table_artifact( + key="stations-created", + table=[{"id": s.id, "code": s.code, "name": s.name} for s in created], + description=f"# Created {len(created)} stations", + ) + else: + print("There are no variables to process, skipping...") + + +@prefect.task( + retries=settings.prefect.num_task_retries, + retry_delay_seconds=settings.prefect.task_retry_delay_seconds, +) +def harvest_monthly_measurements( + client: httpx.Client, + db_session: sqlmodel.Session, + station: observations.Station, + variable: observations.Variable, + month: int, +) -> list[observations.MonthlyMeasurementCreate]: + existing_measurements = database.collect_all_monthly_measurements( + db_session, + station_id_filter=station.id, + variable_id_filter=variable.id, + month_filter=month, + ) + existing = {} + for db_measurement in existing_measurements: + measurement_id = operations.build_monthly_measurement_id(db_measurement) + existing[measurement_id] = db_measurement + response = client.get( + "https://api.arpa.veneto.it/REST/v1/clima_indicatori", + params={ + "statcd": station.code, + "indicatore": variable.name, + "tabella": "M", + "periodo": month, + }, + ) + response.raise_for_status() + to_create = [] + for raw_measurement in response.json().get("data", []): + measurement_create = observations.MonthlyMeasurementCreate( + station_id=station.id, + variable_id=variable.id, + value=raw_measurement["valore"], + date=dt.date(raw_measurement["anno"], month, 1), + ) + measurement_id = operations.build_monthly_measurement_id(measurement_create) + if measurement_id not in existing: + to_create.append(measurement_create) + return to_create + + +@prefect.flow( + log_prints=True, + retries=settings.prefect.num_flow_retries, + retry_delay_seconds=settings.prefect.flow_retry_delay_seconds, +) +def refresh_monthly_measurements( + station_code: str | None = None, + variable_name: str | None = None, + month: int | None = None, +): + settings = get_settings() + client = httpx.Client() + all_created = [] + with sqlmodel.Session(database.get_engine(settings)) as db_session: + if len(db_variables := _get_variables(db_session, variable_name)) > 0: + if len(db_stations := _get_stations(db_session, station_code)) > 0: + for db_station in db_stations: + to_create = [] + to_wait_for = [] + print(f"Processing station: {db_station.name!r}...") + for db_variable in db_variables: + print(f"Processing variable: {db_variable.name!r}...") + if len(months := _get_months(month)) > 0: + for current_month in months: + print(f"Processing month: {current_month!r}...") + fut = harvest_monthly_measurements.submit( + client, + db_session, + db_station, + db_variable, + current_month, + ) + to_wait_for.append(fut) + else: + print("There are no months to process, skipping...") + for future in to_wait_for: + to_create.extend(future.result()) + print(f"creating {len(to_create)} new monthly measurements...") + created = database.create_many_monthly_measurements( + db_session, to_create + ) + all_created.extend(created) + else: + print("There are no stations to process, skipping...") + else: + print("There are no variables to process, skipping...") + prefect.artifacts.create_table_artifact( + key="monthly-measurements-created", + table=_build_created_measurements_table(all_created), + description=f"# Created {len(all_created)} monthly measurements", + ) + + +@prefect.task( + retries=settings.prefect.num_task_retries, + retry_delay_seconds=settings.prefect.task_retry_delay_seconds, +) +def harvest_seasonal_measurements( + client: httpx.Client, + db_session: sqlmodel.Session, + station: observations.Station, + variable: observations.Variable, + season: base.Season, +) -> list[observations.SeasonalMeasurementCreate]: + existing_measurements = database.collect_all_seasonal_measurements( + db_session, + station_id_filter=station.id, + variable_id_filter=variable.id, + season_filter=season, + ) + existing = {} + for db_measurement in existing_measurements: + measurement_id = operations.build_seasonal_measurement_id(db_measurement) + existing[measurement_id] = db_measurement + + season_query_param = { + base.Season.WINTER: 1, + base.Season.SPRING: 2, + base.Season.SUMMER: 3, + base.Season.AUTUMN: 4, + }[season] + response = client.get( + "https://api.arpa.veneto.it/REST/v1/clima_indicatori", + params={ + "statcd": station.code, + "indicatore": variable.name, + "tabella": "S", + "periodo": season_query_param, + }, + ) + response.raise_for_status() + to_create = [] + for raw_measurement in response.json().get("data", []): + measurement_create = observations.SeasonalMeasurementCreate( + station_id=station.id, + variable_id=variable.id, + value=raw_measurement["valore"], + year=int(raw_measurement["anno"]), + season=season, + ) + measurement_id = operations.build_seasonal_measurement_id(measurement_create) + if measurement_id not in existing: + to_create.append(measurement_create) + return to_create + + +@prefect.flow( + log_prints=True, + retries=settings.prefect.num_flow_retries, + retry_delay_seconds=settings.prefect.flow_retry_delay_seconds, +) +def refresh_seasonal_measurements( + station_code: str | None = None, + variable_name: str | None = None, + season_name: str | None = None, +): + settings = get_settings() + client = httpx.Client() + all_created = [] + with sqlmodel.Session(database.get_engine(settings)) as db_session: + if len(db_variables := _get_variables(db_session, variable_name)) > 0: + if len(db_stations := _get_stations(db_session, station_code)) > 0: + for db_station in db_stations: + to_create = [] + to_wait_for = [] + print(f"Processing station: {db_station.name!r}...") + for db_variable in db_variables: + print(f"Processing variable: {db_variable.name!r}...") + if len(seasons := _get_seasons(season_name)) > 0: + for season in seasons: + print(f"Processing season: {season!r}...") + fut = harvest_seasonal_measurements.submit( + client, db_session, db_station, db_variable, season + ) + to_wait_for.append(fut) + else: + print("There are no seasons to process, skipping...") + for future in to_wait_for: + to_create.extend(future.result()) + print(f"creating {len(to_create)} new seasonal measurements...") + created = database.create_many_seasonal_measurements( + db_session, to_create + ) + all_created.extend(created) + else: + print("There are no stations to process, skipping...") + else: + print("There are no variables to process, skipping...") + prefect.artifacts.create_table_artifact( + key="seasonal-measurements-created", + table=_build_created_measurements_table(all_created), + description=f"# Created {len(all_created)} seasonal measurements", + ) + + +@prefect.task( + retries=settings.prefect.num_task_retries, + retry_delay_seconds=settings.prefect.task_retry_delay_seconds, +) +def harvest_yearly_measurements( + client: httpx.Client, + db_session: sqlmodel.Session, + station: observations.Station, + variable: observations.Variable, +) -> list[observations.YearlyMeasurementCreate]: + to_create = [] + existing_measurements = database.collect_all_yearly_measurements( + db_session, + station_id_filter=station.id, + variable_id_filter=variable.id, + ) + existing = {} + for db_measurement in existing_measurements: + measurement_id = operations.build_yearly_measurement_id(db_measurement) + existing[measurement_id] = db_measurement + response = client.get( + "https://api.arpa.veneto.it/REST/v1/clima_indicatori", + params={ + "statcd": station.code, + "indicatore": variable.name, + "tabella": "A", + "periodo": "0", + }, + ) + response.raise_for_status() + for raw_measurement in response.json().get("data", []): + yearly_measurement_create = observations.YearlyMeasurementCreate( + station_id=station.id, + variable_id=variable.id, + value=raw_measurement["valore"], + year=int(raw_measurement["anno"]), + ) + measurement_id = operations.build_yearly_measurement_id( + yearly_measurement_create + ) + if measurement_id not in existing: + to_create.append(yearly_measurement_create) + return to_create + + +@prefect.flow( + log_prints=True, + retries=settings.prefect.num_flow_retries, + retry_delay_seconds=settings.prefect.flow_retry_delay_seconds, +) +def refresh_yearly_measurements( + station_code: str | None = None, + variable_name: str | None = None, +): + settings = get_settings() + client = httpx.Client() + all_created = [] + with sqlmodel.Session(database.get_engine(settings)) as db_session: + if len(db_variables := _get_variables(db_session, variable_name)) > 0: + if len(db_stations := _get_stations(db_session, station_code)) > 0: + for db_station in db_stations: + to_create = [] + to_wait_for = [] + print(f"Processing station: {db_station.name!r}...") + for db_variable in db_variables: + print(f"Processing variable: {db_variable.name!r}...") + fut = harvest_yearly_measurements.submit( + client, db_session, db_station, db_variable + ) + to_wait_for.append(fut) + for future in to_wait_for: + to_create.extend(future.result()) + print(f"creating {len(to_create)} new yearly measurements...") + created = database.create_many_yearly_measurements( + db_session, to_create + ) + all_created.extend(created) + else: + print("There are no stations to process, skipping...") + else: + print("There are no variables to process, skipping...") + prefect.artifacts.create_table_artifact( + key="yearly-measurements-created", + table=_build_created_measurements_table(all_created), + description=f"# Created {len(all_created)} yearly measurements", + ) + + +def _get_stations( + db_session: sqlmodel.Session, station_code: str | None = None +) -> list[observations.Station]: + if station_code is not None: + station = database.get_station_by_code(db_session, station_code) + result = [station] if station else [] + else: + result = database.collect_all_stations(db_session) + return result + + +def _get_variables( + db_session: sqlmodel.Session, variable_name: str | None = None +) -> list[observations.Variable]: + if variable_name is not None: + variable = database.get_variable_by_name(db_session, variable_name) + result = [variable] if variable else [] + else: + result = database.collect_all_variables(db_session) + return result + + +def _get_seasons(season_name: str | None = None) -> list[base.Season]: + if season_name is not None: + try: + result = [base.Season(season_name.upper())] + except ValueError: + print(f"Invalid season name: {season_name!r}") + result = [] + else: + result = [s for s in base.Season] + return result + + +def _get_months(month_index: int | None = None) -> list[int]: + if month_index is not None: + if 1 <= month_index <= 12: + result = [month_index] + else: + print(f"Invalid month index: {month_index!r}") + result = [] + else: + result = list(range(1, 13)) + return result + + +def _build_created_measurements_table( + measurements: Sequence[observations.MonthlyMeasurement] + | Sequence[observations.SeasonalMeasurement] + | Sequence[observations.YearlyMeasurement], +) -> list[dict]: + aggregated_items = {} + for measurement in measurements: + station_identifier = f"{measurement.station.name} ({measurement.station.code})" + station_items = aggregated_items.setdefault(station_identifier, {}) + variable_items = station_items.setdefault(measurement.variable.name, []) + variable_items.append(measurement) + table_contents = [] + for station_identifier, station_items in aggregated_items.items(): + for variable_name, measurement_items in station_items.items(): + table_contents.append( + { + "station": station_identifier, + "variable": variable_name, + "number of new measurements": len(measurement_items), + } + ) + return table_contents diff --git a/arpav_ppcv/schemas/observations.py b/arpav_ppcv/schemas/observations.py index e24947a3..79094b19 100644 --- a/arpav_ppcv/schemas/observations.py +++ b/arpav_ppcv/schemas/observations.py @@ -131,6 +131,25 @@ class StationCreate(sqlmodel.SQLModel): active_since: Optional[dt.date] = None active_until: Optional[dt.date] = None + def __hash__(self): + return hash( + "".join( + ( + self.code, + self.geom.model_dump_json(), + str(self.altitude_m) or "", + self.name, + self.type_, + self.active_since.isoformat() + if self.active_since is not None + else "", + self.active_until.isoformat() + if self.active_until is not None + else "", + ) + ) + ) + class StationUpdate(sqlmodel.SQLModel): code: Optional[str] = None diff --git a/docker/compose.dev.yaml b/docker/compose.dev.yaml index 4d343b26..305c40e6 100644 --- a/docker/compose.dev.yaml +++ b/docker/compose.dev.yaml @@ -62,6 +62,8 @@ services: ARPAV_PPCV__CORS_ORIGINS: '["*"]' ARPAV_PPCV__CORS_METHODS: '["*"]' ARPAV_PPCV__ALLOW_CORS_CREDENTIALS: true + PREFECT_API_URL: "http://prefect-server:4200/api" + PREFECT_DEBUG_MODE: true ports: - target: 5001 published: 5001 @@ -157,6 +159,57 @@ services: source: /$PWD/docker/martin/config.yaml target: /martin-config.yaml + prefect-server: + command: ["prefect", "server", "start"] + environment: + PREFECT_API_DATABASE_CONNECTION_URL: "postgresql+asyncpg://prefect:prefectpassword@prefect-db/prefect" + PREFECT_API_URL: "http://0.0.0.0:4200/api" + PREFECT_CLI_PROMPT: false + PREFECT_DEBUG_MODE: true + PREFECT_HOME: "/prefect_home" + PREFECT_SERVER_ALLOW_EPHEMERAL_MODE: false + PREFECT_SERVER_API_HOST: "0.0.0.0" + PREFECT_SERVER_API_PORT: "4200" + PREFECT_SERVER_CSRF_PROTECTION_ENABLED: true + PREFECT_UI_API_URL: "http://localhost:8877/prefect/api" + PREFECT_UI_URL: "http://localhost:8877/prefect/ui" + PREFECT_UI_SERVE_BASE: "/prefect/ui" + + volumes: + - prefect-server-home:/prefect_home + + prefect-static-worker: + image: *webapp-image + command: [ + "start-periodic-tasks", + "--refresh-stations", + "--refresh-monthly-measurements", + "--refresh-seasonal-measurements", + "--refresh-yearly-measurements", + ] + environment: + PREFECT_API_URL: "http://prefect-server:4200/api" + ARPAV_PPCV__PREFECT__OBSERVATION_STATIONS_REFRESHER_FLOW_CRON_SCHEDULE: "*/5 * * * *" + PREFECT_DEBUG_MODE: true + <<: *common-env + volumes: + *common-volumes + + prefect-db: + environment: + POSTGRES_USER: prefect + POSTGRES_PASSWORD: prefectpassword + POSTGRES_DB: prefect + volumes: + - prefect-db-data:/var/lib/postgresql/data + # The below command adds a more verbose logging of operations - DON'T USE THIS IN PRODUCTION! + # The server's performance is impacted by this command. Moreover, logged statements may contain + # sensitive information + command: "-clog_statement=all" + volumes: db-data: test-db-data: + prefect-server-home: + prefect-worker-home: + prefect-db-data: diff --git a/docker/compose.yaml b/docker/compose.yaml index 364a0765..2b8b0a2a 100644 --- a/docker/compose.yaml +++ b/docker/compose.yaml @@ -23,6 +23,9 @@ # blocks with a name like `x-something`. Then we mark these as being YAML # anchors. Later in the file we refer to them using YAML aliases. +x-prefect-image: &prefect-image "prefecthq/prefect:3.0.0rc17-python3.10" +x-backend-image: &backend-image "ghcr.io/geobeyond/arpav-ppcv-backend/arpav-ppcv-backend:latest" + x-postgres-db-healthcheck: &postgres-db-healthcheck interval: 10s timeout: 3s @@ -34,7 +37,20 @@ x-postgres-db-healthcheck: &postgres-db-healthcheck response=$$(echo 'SELECT 1' | psql $${args}) if [ $${response} = '1' ]; then exit 0; - else echo "+++++++++++++DB $${POSTGRES_DB} is not up+++++++++++++"; exit 1; + else echo "+++++++++++++ DB $${POSTGRES_DB} is not up+++++++++++++"; exit 1; + fi + + +x-prefect-server-healthcheck: &prefect-server-healthcheck + interval: 10s + timeout: 3s + start_period: 1m + retries: 10 + test: | + status=$$(python -c 'import httpx; print(httpx.get("http://127.0.0.1:4200/api/health").status_code)') + if [ $${status} = '200' ]; + then exit 0; + else echo "+++++++++++++ Prefect server is not up+++++++++++++"; exit 1; fi name: arpav-ppcv @@ -47,16 +63,19 @@ services: - type: bind source: /var/run/docker.sock target: /var/run/docker.sock + - type: bind + source: ${ARPAV_PPCV_TRAEFIK_BASIC_AUTH_USERS_FILE:-/$PWD/docker/traefik/basicauth-users.txt} + target: /traefikauth/usersfile frontend: image: "ghcr.io/geobeyond/arpav-ppcv/arpav-ppcv:latest" labels: - "traefik.enable=true" - - "traefik.http.routers.arpav-frontend-router.rule=!PathRegexp(`^/(api|admin|vector-tiles)`)" + - "traefik.http.routers.arpav-frontend-router.rule=!PathRegexp(`^/(api|admin|prefect|vector-tiles)`)" - "traefik.http.services.arpav-frontend-service.loadbalancer.server.port=80" webapp: - image: "ghcr.io/geobeyond/arpav-ppcv-backend/arpav-ppcv-backend:latest" + image: *backend-image labels: - "traefik.enable=true" - "traefik.http.routers.arpav-backend-router.rule=PathRegexp(`^/(api|admin)`)" @@ -82,3 +101,32 @@ services: depends_on: db: condition: service_healthy + + prefect-server: + image: *prefect-image + labels: + - "traefik.enable=true" + - "traefik.http.routers.prefect-router.rule=PathPrefix(`/prefect`)" + - "traefik.http.services.prefect-service.loadbalancer.server.port=4200" + - "traefik.http.middlewares.middleware-chain.chain.middlewares=prefect-auth,replace-prefect-path-middleware" + - "traefik.http.middlewares.replace-prefect-path-middleware.replacepathregex.regex=/prefect/api" + - "traefik.http.middlewares.replace-prefect-path-middleware.replacepathregex.replacement=/api" + - "traefik.http.middlewares.prefect-auth.basicauth.usersfile=/traefikauth/usersfile" + - "traefik.http.routers.prefect-router.middlewares=middleware-chain" + depends_on: + prefect-db: + condition: service_healthy + healthcheck: *prefect-server-healthcheck + + prefect-static-worker: + image: *backend-image + entrypoint: ["tini", "-g", "--", "poetry", "run", "arpav-ppcv", "prefect"] + depends_on: + prefect-server: + condition: service_healthy + + prefect-db: + image: "postgis/postgis:16-3.4" + environment: + PG_DATA: /var/lib/postgresql/data/pgdata + healthcheck: *postgres-db-healthcheck diff --git a/poetry.lock b/poetry.lock index 5ed2e297..c48add20 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,24 @@ # This file is automatically @generated by Poetry and should not be changed by hand. +[[package]] +name = "aiosqlite" +version = "0.20.0" +description = "asyncio bridge to the standard sqlite3 module" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"}, + {file = "aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7"}, +] + +[package.dependencies] +typing_extensions = ">=4.0" + +[package.extras] +dev = ["attribution (==1.7.0)", "black (==24.2.0)", "coverage[toml] (==7.4.1)", "flake8 (==7.0.0)", "flake8-bugbear (==24.2.6)", "flit (==3.9.0)", "mypy (==1.8.0)", "ufmt (==2.3.0)", "usort (==1.0.8.post1)"] +docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] + [[package]] name = "alembic" version = "1.13.1" @@ -83,6 +102,26 @@ files = [ {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, ] +[[package]] +name = "apprise" +version = "1.8.1" +description = "Push Notifications that work with just about every platform!" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "apprise-1.8.1-py3-none-any.whl", hash = "sha256:371ea400305bd3bf5e8af8e56f151e131ee6357ae009418f9dc3c279909ba0ee"}, + {file = "apprise-1.8.1.tar.gz", hash = "sha256:08a20fe72672b7e90f7969d5b879d657c2e2db385a8a8c10f54cba565bf237f2"}, +] + +[package.dependencies] +certifi = "*" +click = ">=5.0" +markdown = "*" +PyYAML = "*" +requests = "*" +requests-oauthlib = "*" + [[package]] name = "argon2-cffi" version = "23.1.0" @@ -162,6 +201,21 @@ types-python-dateutil = ">=2.8.10" doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] test = ["dateparser (>=1.0.0,<2.0.0)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (>=3.0.0,<4.0.0)"] +[[package]] +name = "asgi-lifespan" +version = "2.1.0" +description = "Programmatic startup/shutdown of ASGI apps." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgi-lifespan-2.1.0.tar.gz", hash = "sha256:5e2effaf0bfe39829cf2d64e7ecc47c7d86d676a6599f7afba378c31f5e3a308"}, + {file = "asgi_lifespan-2.1.0-py3-none-any.whl", hash = "sha256:ed840706680e28428c01e14afb3875d7d76d3206f3d5b2f2294e059b5c23804f"}, +] + +[package.dependencies] +sniffio = "*" + [[package]] name = "asttokens" version = "2.4.1" @@ -196,11 +250,81 @@ files = [ [package.dependencies] typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "asyncpg" +version = "0.29.0" +description = "An asyncio PostgreSQL driver" +category = "main" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "asyncpg-0.29.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72fd0ef9f00aeed37179c62282a3d14262dbbafb74ec0ba16e1b1864d8a12169"}, + {file = "asyncpg-0.29.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52e8f8f9ff6e21f9b39ca9f8e3e33a5fcdceaf5667a8c5c32bee158e313be385"}, + {file = "asyncpg-0.29.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e6823a7012be8b68301342ba33b4740e5a166f6bbda0aee32bc01638491a22"}, + {file = "asyncpg-0.29.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:746e80d83ad5d5464cfbf94315eb6744222ab00aa4e522b704322fb182b83610"}, + {file = "asyncpg-0.29.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ff8e8109cd6a46ff852a5e6bab8b0a047d7ea42fcb7ca5ae6eaae97d8eacf397"}, + {file = "asyncpg-0.29.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:97eb024685b1d7e72b1972863de527c11ff87960837919dac6e34754768098eb"}, + {file = "asyncpg-0.29.0-cp310-cp310-win32.whl", hash = "sha256:5bbb7f2cafd8d1fa3e65431833de2642f4b2124be61a449fa064e1a08d27e449"}, + {file = "asyncpg-0.29.0-cp310-cp310-win_amd64.whl", hash = "sha256:76c3ac6530904838a4b650b2880f8e7af938ee049e769ec2fba7cd66469d7772"}, + {file = "asyncpg-0.29.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4900ee08e85af01adb207519bb4e14b1cae8fd21e0ccf80fac6aa60b6da37b4"}, + {file = "asyncpg-0.29.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a65c1dcd820d5aea7c7d82a3fdcb70e096f8f70d1a8bf93eb458e49bfad036ac"}, + {file = "asyncpg-0.29.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b52e46f165585fd6af4863f268566668407c76b2c72d366bb8b522fa66f1870"}, + {file = "asyncpg-0.29.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc600ee8ef3dd38b8d67421359779f8ccec30b463e7aec7ed481c8346decf99f"}, + {file = "asyncpg-0.29.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:039a261af4f38f949095e1e780bae84a25ffe3e370175193174eb08d3cecab23"}, + {file = "asyncpg-0.29.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6feaf2d8f9138d190e5ec4390c1715c3e87b37715cd69b2c3dfca616134efd2b"}, + {file = "asyncpg-0.29.0-cp311-cp311-win32.whl", hash = "sha256:1e186427c88225ef730555f5fdda6c1812daa884064bfe6bc462fd3a71c4b675"}, + {file = "asyncpg-0.29.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfe73ffae35f518cfd6e4e5f5abb2618ceb5ef02a2365ce64f132601000587d3"}, + {file = "asyncpg-0.29.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6011b0dc29886ab424dc042bf9eeb507670a3b40aece3439944006aafe023178"}, + {file = "asyncpg-0.29.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b544ffc66b039d5ec5a7454667f855f7fec08e0dfaf5a5490dfafbb7abbd2cfb"}, + {file = "asyncpg-0.29.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d84156d5fb530b06c493f9e7635aa18f518fa1d1395ef240d211cb563c4e2364"}, + {file = "asyncpg-0.29.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54858bc25b49d1114178d65a88e48ad50cb2b6f3e475caa0f0c092d5f527c106"}, + {file = "asyncpg-0.29.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bde17a1861cf10d5afce80a36fca736a86769ab3579532c03e45f83ba8a09c59"}, + {file = "asyncpg-0.29.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:37a2ec1b9ff88d8773d3eb6d3784dc7e3fee7756a5317b67f923172a4748a175"}, + {file = "asyncpg-0.29.0-cp312-cp312-win32.whl", hash = "sha256:bb1292d9fad43112a85e98ecdc2e051602bce97c199920586be83254d9dafc02"}, + {file = "asyncpg-0.29.0-cp312-cp312-win_amd64.whl", hash = "sha256:2245be8ec5047a605e0b454c894e54bf2ec787ac04b1cb7e0d3c67aa1e32f0fe"}, + {file = "asyncpg-0.29.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0009a300cae37b8c525e5b449233d59cd9868fd35431abc470a3e364d2b85cb9"}, + {file = "asyncpg-0.29.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cad1324dbb33f3ca0cd2074d5114354ed3be2b94d48ddfd88af75ebda7c43cc"}, + {file = "asyncpg-0.29.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012d01df61e009015944ac7543d6ee30c2dc1eb2f6b10b62a3f598beb6531548"}, + {file = "asyncpg-0.29.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000c996c53c04770798053e1730d34e30cb645ad95a63265aec82da9093d88e7"}, + {file = "asyncpg-0.29.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e0bfe9c4d3429706cf70d3249089de14d6a01192d617e9093a8e941fea8ee775"}, + {file = "asyncpg-0.29.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:642a36eb41b6313ffa328e8a5c5c2b5bea6ee138546c9c3cf1bffaad8ee36dd9"}, + {file = "asyncpg-0.29.0-cp38-cp38-win32.whl", hash = "sha256:a921372bbd0aa3a5822dd0409da61b4cd50df89ae85150149f8c119f23e8c408"}, + {file = "asyncpg-0.29.0-cp38-cp38-win_amd64.whl", hash = "sha256:103aad2b92d1506700cbf51cd8bb5441e7e72e87a7b3a2ca4e32c840f051a6a3"}, + {file = "asyncpg-0.29.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5340dd515d7e52f4c11ada32171d87c05570479dc01dc66d03ee3e150fb695da"}, + {file = "asyncpg-0.29.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e17b52c6cf83e170d3d865571ba574577ab8e533e7361a2b8ce6157d02c665d3"}, + {file = "asyncpg-0.29.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f100d23f273555f4b19b74a96840aa27b85e99ba4b1f18d4ebff0734e78dc090"}, + {file = "asyncpg-0.29.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48e7c58b516057126b363cec8ca02b804644fd012ef8e6c7e23386b7d5e6ce83"}, + {file = "asyncpg-0.29.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9ea3f24eb4c49a615573724d88a48bd1b7821c890c2effe04f05382ed9e8810"}, + {file = "asyncpg-0.29.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8d36c7f14a22ec9e928f15f92a48207546ffe68bc412f3be718eedccdf10dc5c"}, + {file = "asyncpg-0.29.0-cp39-cp39-win32.whl", hash = "sha256:797ab8123ebaed304a1fad4d7576d5376c3a006a4100380fb9d517f0b59c1ab2"}, + {file = "asyncpg-0.29.0-cp39-cp39-win_amd64.whl", hash = "sha256:cce08a178858b426ae1aa8409b5cc171def45d4293626e7aa6510696d46decd8"}, + {file = "asyncpg-0.29.0.tar.gz", hash = "sha256:d1c49e1f44fffafd9a55e1a9b101590859d881d639ea2922516f5d9c512d354e"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.12.0\""} + +[package.extras] +docs = ["Sphinx (>=5.3.0,<5.4.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["flake8 (>=6.1,<7.0)", "uvloop (>=0.15.3)"] + [[package]] name = "attrs" version = "23.2.0" description = "Classes Without Boilerplate" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -303,6 +427,18 @@ webencodings = "*" [package.extras] css = ["tinycss2 (>=1.1.0,<1.3)"] +[[package]] +name = "cachetools" +version = "5.4.0" +description = "Extensible memoizing collections and decorators" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, + {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, +] + [[package]] name = "cattrs" version = "23.2.3" @@ -345,7 +481,7 @@ files = [ name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -579,6 +715,18 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "cloudpickle" +version = "3.0.0" +description = "Pickler class to extend the standard pickle.Pickler functionality" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cloudpickle-3.0.0-py3-none-any.whl", hash = "sha256:246ee7d0c295602a036e86369c77fecda4ab17b506496730f2f576d9016fd9c7"}, + {file = "cloudpickle-3.0.0.tar.gz", hash = "sha256:996d9a482c6fb4f33c1a35335cf8afd065d2a56e973270364840712d9131a882"}, +] + [[package]] name = "colorama" version = "0.4.6" @@ -673,6 +821,18 @@ mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pill test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] +[[package]] +name = "coolname" +version = "2.2.0" +description = "Random name and slug generator" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "coolname-2.2.0-py2.py3-none-any.whl", hash = "sha256:4d1563186cfaf71b394d5df4c744f8c41303b6846413645e31d31915cdeb13e8"}, + {file = "coolname-2.2.0.tar.gz", hash = "sha256:6c5d5731759104479e7ca195a9b64f7900ac5bead40183c09323c7d0be9e75c7"}, +] + [[package]] name = "coverage" version = "7.5.3" @@ -741,6 +901,72 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "croniter" +version = "3.0.3" +description = "croniter provides iteration for datetime object with cron like format" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.6" +files = [ + {file = "croniter-3.0.3-py2.py3-none-any.whl", hash = "sha256:b3bd11f270dc54ccd1f2397b813436015a86d30ffc5a7a9438eec1ed916f2101"}, + {file = "croniter-3.0.3.tar.gz", hash = "sha256:34117ec1741f10a7bd0ec3ad7d8f0eb8fa457a2feb9be32e6a2250e158957668"}, +] + +[package.dependencies] +python-dateutil = "*" +pytz = ">2021.1" + +[[package]] +name = "cryptography" +version = "43.0.0" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, + {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, + {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, + {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, + {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, + {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, + {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "cycler" version = "0.12.1" @@ -779,6 +1005,29 @@ platformdirs = ">=2.6.2" rich = ">=10.11.0" typing-extensions = ">=4.8.0" +[[package]] +name = "dateparser" +version = "1.2.0" +description = "Date parsing library designed to parse dates from HTML pages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"}, + {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"}, +] + +[package.dependencies] +python-dateutil = "*" +pytz = "*" +regex = "<2019.02.19 || >2019.02.19,<2021.8.27 || >2021.8.27" +tzlocal = "*" + +[package.extras] +calendars = ["convertdate", "hijri-converter"] +fasttext = ["fasttext"] +langdetect = ["langdetect"] + [[package]] name = "debugpy" version = "1.8.1" @@ -847,6 +1096,29 @@ files = [ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] +[[package]] +name = "docker" +version = "7.1.0" +description = "A Python library for the Docker Engine API." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"}, + {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"}, +] + +[package.dependencies] +pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} +requests = ">=2.26.0" +urllib3 = ">=1.26.0" + +[package.extras] +dev = ["coverage (==7.2.7)", "pytest (==7.4.2)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.1.0)", "ruff (==0.1.8)"] +docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"] +ssh = ["paramiko (>=2.4.3)"] +websockets = ["websocket-client (>=1.3.0)"] + [[package]] name = "exceptiongroup" version = "1.2.1" @@ -879,14 +1151,14 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastapi" -version = "0.110.3" +version = "0.112.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.110.3-py3-none-any.whl", hash = "sha256:fd7600612f755e4050beb74001310b5a7e1796d149c2ee363124abdfa0289d32"}, - {file = "fastapi-0.110.3.tar.gz", hash = "sha256:555700b0159379e94fdbfc6bb66a0f1c43f4cf7060f25239af3d84b63a656626"}, + {file = "fastapi-0.112.0-py3-none-any.whl", hash = "sha256:3487ded9778006a45834b8c816ec4a48d522e2631ca9e75ec5a774f1b052f821"}, + {file = "fastapi-0.112.0.tar.gz", hash = "sha256:d262bc56b7d101d1f4e8fc0ad2ac75bb9935fec504d2b7117686cec50710cf05"}, ] [package.dependencies] @@ -895,7 +1167,8 @@ starlette = ">=0.37.2,<0.38.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email_validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +all = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "fastjsonschema" @@ -1007,6 +1280,46 @@ files = [ {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, ] +[[package]] +name = "fsspec" +version = "2024.6.1" +description = "File-system specification" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e"}, + {file = "fsspec-2024.6.1.tar.gz", hash = "sha256:fad7d7e209dd4c1208e3bbfda706620e0da5142bebbd9c384afb95b07e798e49"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +dev = ["pre-commit", "ruff"] +doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] +test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] +test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] +tqdm = ["tqdm"] + [[package]] name = "geoalchemy2" version = "0.14.7" @@ -1088,6 +1401,23 @@ files = [ {file = "graphql_core-3.2.3-py3-none-any.whl", hash = "sha256:5766780452bd5ec8ba133f8bf287dc92713e3868ddd83aee4faab9fc3e303dc3"}, ] +[[package]] +name = "graphviz" +version = "0.20.3" +description = "Simple Python interface for Graphviz" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "graphviz-0.20.3-py3-none-any.whl", hash = "sha256:81f848f2904515d8cd359cc611faba817598d2feaac4027b266aa3eda7b3dde5"}, + {file = "graphviz-0.20.3.zip", hash = "sha256:09d6bc81e6a9fa392e7ba52135a9d49f1ed62526f96499325930e87ca1b5925d"}, +] + +[package.extras] +dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"] +docs = ["sphinx (>=5,<7)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] +test = ["coverage", "pytest (>=7,<8.1)", "pytest-cov", "pytest-mock (>=3)"] + [[package]] name = "greenlet" version = "3.0.3" @@ -1160,6 +1490,21 @@ files = [ docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] +[[package]] +name = "griffe" +version = "0.47.0" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "griffe-0.47.0-py3-none-any.whl", hash = "sha256:07a2fd6a8c3d21d0bbb0decf701d62042ccc8a576645c7f8799fe1f10de2b2de"}, + {file = "griffe-0.47.0.tar.gz", hash = "sha256:95119a440a3c932b13293538bdbc405bee4c36428547553dc6b327e7e7d35e5a"}, +] + +[package.dependencies] +colorama = ">=0.4" + [[package]] name = "h11" version = "0.14.0" @@ -1172,6 +1517,34 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] +[[package]] +name = "h2" +version = "4.1.0" +description = "HTTP/2 State-Machine based protocol implementation" +category = "main" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, + {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, +] + +[package.dependencies] +hpack = ">=4.0,<5" +hyperframe = ">=6.0,<7" + +[[package]] +name = "hpack" +version = "4.0.0" +description = "Pure-Python HPACK header compression" +category = "main" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, + {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, +] + [[package]] name = "httpcore" version = "1.0.5" @@ -1194,55 +1567,6 @@ http2 = ["h2 (>=3,<5)"] socks = ["socksio (>=1.0.0,<2.0.0)"] trio = ["trio (>=0.22.0,<0.26.0)"] -[[package]] -name = "httptools" -version = "0.6.1" -description = "A collection of framework independent HTTP protocol utils." -category = "main" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"}, - {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"}, - {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"}, - {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"}, - {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"}, - {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"}, - {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"}, - {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"}, - {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"}, - {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"}, - {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"}, - {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"}, - {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"}, - {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"}, - {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"}, - {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"}, - {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"}, - {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"}, - {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"}, - {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"}, - {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"}, - {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"}, - {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"}, - {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"}, - {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"}, - {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"}, - {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"}, - {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"}, - {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"}, - {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"}, - {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"}, - {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"}, - {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"}, - {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"}, - {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"}, - {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"}, -] - -[package.extras] -test = ["Cython (>=0.29.24,<0.30.0)"] - [[package]] name = "httpx" version = "0.27.0" @@ -1258,6 +1582,7 @@ files = [ [package.dependencies] anyio = "*" certifi = "*" +h2 = {version = ">=3,<5", optional = true, markers = "extra == \"http2\""} httpcore = ">=1.0.0,<2.0.0" idna = "*" sniffio = "*" @@ -1268,6 +1593,33 @@ cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (>=1.0.0,<2.0.0)"] +[[package]] +name = "humanize" +version = "4.10.0" +description = "Python humanize utilities" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "humanize-4.10.0-py3-none-any.whl", hash = "sha256:39e7ccb96923e732b5c2e27aeaa3b10a8dfeeba3eb965ba7b74a3eb0e30040a6"}, + {file = "humanize-4.10.0.tar.gz", hash = "sha256:06b6eb0293e4b85e8d385397c5868926820db32b9b654b932f57fa41c23c9978"}, +] + +[package.extras] +tests = ["freezegun", "pytest", "pytest-cov"] + +[[package]] +name = "hyperframe" +version = "6.0.1" +description = "HTTP/2 framing layer for Python" +category = "main" +optional = false +python-versions = ">=3.6.1" +files = [ + {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, + {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, +] + [[package]] name = "identify" version = "2.5.36" @@ -1295,6 +1647,22 @@ files = [ {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] +[[package]] +name = "importlib-resources" +version = "6.1.3" +description = "Read resources from Python packages" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.1.3-py3-none-any.whl", hash = "sha256:4c0269e3580fe2634d364b39b38b961540a7738c02cb984e98add8b4221d793d"}, + {file = "importlib_resources-6.1.3.tar.gz", hash = "sha256:56fb4525197b78544a3354ea27793952ab93f935bb4bf746b846bb1015020f2b"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["jaraco.collections", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -1503,6 +1871,22 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jinja2-humanize-extension" +version = "0.4.0" +description = "a jinja2 extension to use humanize library inside jinja2 templates" +category = "main" +optional = false +python-versions = ">=3.0" +files = [ + {file = "jinja2_humanize_extension-0.4.0-py3-none-any.whl", hash = "sha256:b6326e2da0f7d425338bebf58848e830421defbce785f12ae812e65128518156"}, + {file = "jinja2_humanize_extension-0.4.0.tar.gz", hash = "sha256:e7d69b1c20f32815bbec722330ee8af14b1287bb1c2b0afa590dbf031cadeaa0"}, +] + +[package.dependencies] +humanize = ">=3.14.0" +jinja2 = "*" + [[package]] name = "json5" version = "0.9.25" @@ -1515,11 +1899,26 @@ files = [ {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, ] +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + [[package]] name = "jsonpointer" version = "2.4" description = "Identify specific nodes in a JSON document (RFC 6901)" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" files = [ @@ -1531,7 +1930,7 @@ files = [ name = "jsonschema" version = "4.22.0" description = "An implementation of JSON Schema validation for Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1561,7 +1960,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.12.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2091,6 +2490,22 @@ babel = ["Babel"] lingua = ["lingua"] testing = ["pytest"] +[[package]] +name = "markdown" +version = "3.6" +description = "Python implementation of John Gruber's Markdown." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, + {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, +] + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -2592,6 +3007,84 @@ files = [ {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] +[[package]] +name = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + +[[package]] +name = "orjson" +version = "3.10.6" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.6-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:fb0ee33124db6eaa517d00890fc1a55c3bfe1cf78ba4a8899d71a06f2d6ff5c7"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c1c4b53b24a4c06547ce43e5fee6ec4e0d8fe2d597f4647fc033fd205707365"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eadc8fd310edb4bdbd333374f2c8fec6794bbbae99b592f448d8214a5e4050c0"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61272a5aec2b2661f4fa2b37c907ce9701e821b2c1285d5c3ab0207ebd358d38"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57985ee7e91d6214c837936dc1608f40f330a6b88bb13f5a57ce5257807da143"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:633a3b31d9d7c9f02d49c4ab4d0a86065c4a6f6adc297d63d272e043472acab5"}, + {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1c680b269d33ec444afe2bdc647c9eb73166fa47a16d9a75ee56a374f4a45f43"}, + {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f759503a97a6ace19e55461395ab0d618b5a117e8d0fbb20e70cfd68a47327f2"}, + {file = "orjson-3.10.6-cp310-none-win32.whl", hash = "sha256:95a0cce17f969fb5391762e5719575217bd10ac5a189d1979442ee54456393f3"}, + {file = "orjson-3.10.6-cp310-none-win_amd64.whl", hash = "sha256:df25d9271270ba2133cc88ee83c318372bdc0f2cd6f32e7a450809a111efc45c"}, + {file = "orjson-3.10.6-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b1ec490e10d2a77c345def52599311849fc063ae0e67cf4f84528073152bb2ba"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d43d3feb8f19d07e9f01e5b9be4f28801cf7c60d0fa0d279951b18fae1932b"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3045267e98fe749408eee1593a142e02357c5c99be0802185ef2170086a863"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c27bc6a28ae95923350ab382c57113abd38f3928af3c80be6f2ba7eb8d8db0b0"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d27456491ca79532d11e507cadca37fb8c9324a3976294f68fb1eff2dc6ced5a"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05ac3d3916023745aa3b3b388e91b9166be1ca02b7c7e41045da6d12985685f0"}, + {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1335d4ef59ab85cab66fe73fd7a4e881c298ee7f63ede918b7faa1b27cbe5212"}, + {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4bbc6d0af24c1575edc79994c20e1b29e6fb3c6a570371306db0993ecf144dc5"}, + {file = "orjson-3.10.6-cp311-none-win32.whl", hash = "sha256:450e39ab1f7694465060a0550b3f6d328d20297bf2e06aa947b97c21e5241fbd"}, + {file = "orjson-3.10.6-cp311-none-win_amd64.whl", hash = "sha256:227df19441372610b20e05bdb906e1742ec2ad7a66ac8350dcfd29a63014a83b"}, + {file = "orjson-3.10.6-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ea2977b21f8d5d9b758bb3f344a75e55ca78e3ff85595d248eee813ae23ecdfb"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6f3d167d13a16ed263b52dbfedff52c962bfd3d270b46b7518365bcc2121eed"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f710f346e4c44a4e8bdf23daa974faede58f83334289df80bc9cd12fe82573c7"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7275664f84e027dcb1ad5200b8b18373e9c669b2a9ec33d410c40f5ccf4b257e"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0943e4c701196b23c240b3d10ed8ecd674f03089198cf503105b474a4f77f21f"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:446dee5a491b5bc7d8f825d80d9637e7af43f86a331207b9c9610e2f93fee22a"}, + {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:64c81456d2a050d380786413786b057983892db105516639cb5d3ee3c7fd5148"}, + {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:960db0e31c4e52fa0fc3ecbaea5b2d3b58f379e32a95ae6b0ebeaa25b93dfd34"}, + {file = "orjson-3.10.6-cp312-none-win32.whl", hash = "sha256:a6ea7afb5b30b2317e0bee03c8d34c8181bc5a36f2afd4d0952f378972c4efd5"}, + {file = "orjson-3.10.6-cp312-none-win_amd64.whl", hash = "sha256:874ce88264b7e655dde4aeaacdc8fd772a7962faadfb41abe63e2a4861abc3dc"}, + {file = "orjson-3.10.6-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:66680eae4c4e7fc193d91cfc1353ad6d01b4801ae9b5314f17e11ba55e934183"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caff75b425db5ef8e8f23af93c80f072f97b4fb3afd4af44482905c9f588da28"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3722fddb821b6036fd2a3c814f6bd9b57a89dc6337b9924ecd614ebce3271394"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2c116072a8533f2fec435fde4d134610f806bdac20188c7bd2081f3e9e0133f"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6eeb13218c8cf34c61912e9df2de2853f1d009de0e46ea09ccdf3d757896af0a"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965a916373382674e323c957d560b953d81d7a8603fbeee26f7b8248638bd48b"}, + {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03c95484d53ed8e479cade8628c9cea00fd9d67f5554764a1110e0d5aa2de96e"}, + {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e060748a04cccf1e0a6f2358dffea9c080b849a4a68c28b1b907f272b5127e9b"}, + {file = "orjson-3.10.6-cp38-none-win32.whl", hash = "sha256:738dbe3ef909c4b019d69afc19caf6b5ed0e2f1c786b5d6215fbb7539246e4c6"}, + {file = "orjson-3.10.6-cp38-none-win_amd64.whl", hash = "sha256:d40f839dddf6a7d77114fe6b8a70218556408c71d4d6e29413bb5f150a692ff7"}, + {file = "orjson-3.10.6-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:697a35a083c4f834807a6232b3e62c8b280f7a44ad0b759fd4dce748951e70db"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd502f96bf5ea9a61cbc0b2b5900d0dd68aa0da197179042bdd2be67e51a1e4b"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f215789fb1667cdc874c1b8af6a84dc939fd802bf293a8334fce185c79cd359b"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2debd8ddce948a8c0938c8c93ade191d2f4ba4649a54302a7da905a81f00b56"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5410111d7b6681d4b0d65e0f58a13be588d01b473822483f77f513c7f93bd3b2"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb1f28a137337fdc18384079fa5726810681055b32b92253fa15ae5656e1dddb"}, + {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bf2fbbce5fe7cd1aa177ea3eab2b8e6a6bc6e8592e4279ed3db2d62e57c0e1b2"}, + {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:79b9b9e33bd4c517445a62b90ca0cc279b0f1f3970655c3df9e608bc3f91741a"}, + {file = "orjson-3.10.6-cp39-none-win32.whl", hash = "sha256:30b0a09a2014e621b1adf66a4f705f0809358350a757508ee80209b2d8dae219"}, + {file = "orjson-3.10.6-cp39-none-win_amd64.whl", hash = "sha256:49e3bc615652617d463069f91b867a4458114c5b104e13b7ae6872e5f79d0844"}, + {file = "orjson-3.10.6.tar.gz", hash = "sha256:e54b63d0a7c6c54a5f5f726bc93a2078111ef060fec4ecbf34c5db800ca3b3a7"}, +] + [[package]] name = "overrides" version = "7.7.0" @@ -2689,6 +3182,118 @@ files = [ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["docopt", "pytest"] +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "pendulum" +version = "3.0.0" +description = "Python datetimes made easy" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pendulum-3.0.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2cf9e53ef11668e07f73190c805dbdf07a1939c3298b78d5a9203a86775d1bfd"}, + {file = "pendulum-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fb551b9b5e6059377889d2d878d940fd0bbb80ae4810543db18e6f77b02c5ef6"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c58227ac260d5b01fc1025176d7b31858c9f62595737f350d22124a9a3ad82d"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60fb6f415fea93a11c52578eaa10594568a6716602be8430b167eb0d730f3332"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b69f6b4dbcb86f2c2fe696ba991e67347bcf87fe601362a1aba6431454b46bde"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:138afa9c373ee450ede206db5a5e9004fd3011b3c6bbe1e57015395cd076a09f"}, + {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:83d9031f39c6da9677164241fd0d37fbfc9dc8ade7043b5d6d62f56e81af8ad2"}, + {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c2308af4033fa534f089595bcd40a95a39988ce4059ccd3dc6acb9ef14ca44a"}, + {file = "pendulum-3.0.0-cp310-none-win_amd64.whl", hash = "sha256:9a59637cdb8462bdf2dbcb9d389518c0263799189d773ad5c11db6b13064fa79"}, + {file = "pendulum-3.0.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3725245c0352c95d6ca297193192020d1b0c0f83d5ee6bb09964edc2b5a2d508"}, + {file = "pendulum-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c035f03a3e565ed132927e2c1b691de0dbf4eb53b02a5a3c5a97e1a64e17bec"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597e66e63cbd68dd6d58ac46cb7a92363d2088d37ccde2dae4332ef23e95cd00"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99a0f8172e19f3f0c0e4ace0ad1595134d5243cf75985dc2233e8f9e8de263ca"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77d8839e20f54706aed425bec82a83b4aec74db07f26acd039905d1237a5e1d4"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afde30e8146292b059020fbc8b6f8fd4a60ae7c5e6f0afef937bbb24880bdf01"}, + {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:660434a6fcf6303c4efd36713ca9212c753140107ee169a3fc6c49c4711c2a05"}, + {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dee9e5a48c6999dc1106eb7eea3e3a50e98a50651b72c08a87ee2154e544b33e"}, + {file = "pendulum-3.0.0-cp311-none-win_amd64.whl", hash = "sha256:d4cdecde90aec2d67cebe4042fd2a87a4441cc02152ed7ed8fb3ebb110b94ec4"}, + {file = "pendulum-3.0.0-cp311-none-win_arm64.whl", hash = "sha256:773c3bc4ddda2dda9f1b9d51fe06762f9200f3293d75c4660c19b2614b991d83"}, + {file = "pendulum-3.0.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:409e64e41418c49f973d43a28afe5df1df4f1dd87c41c7c90f1a63f61ae0f1f7"}, + {file = "pendulum-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a38ad2121c5ec7c4c190c7334e789c3b4624798859156b138fcc4d92295835dc"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fde4d0b2024b9785f66b7f30ed59281bd60d63d9213cda0eb0910ead777f6d37"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2c5675769fb6d4c11238132962939b960fcb365436b6d623c5864287faa319"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8af95e03e066826f0f4c65811cbee1b3123d4a45a1c3a2b4fc23c4b0dff893b5"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2165a8f33cb15e06c67070b8afc87a62b85c5a273e3aaa6bc9d15c93a4920d6f"}, + {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ad5e65b874b5e56bd942546ea7ba9dd1d6a25121db1c517700f1c9de91b28518"}, + {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17fe4b2c844bbf5f0ece69cfd959fa02957c61317b2161763950d88fed8e13b9"}, + {file = "pendulum-3.0.0-cp312-none-win_amd64.whl", hash = "sha256:78f8f4e7efe5066aca24a7a57511b9c2119f5c2b5eb81c46ff9222ce11e0a7a5"}, + {file = "pendulum-3.0.0-cp312-none-win_arm64.whl", hash = "sha256:28f49d8d1e32aae9c284a90b6bb3873eee15ec6e1d9042edd611b22a94ac462f"}, + {file = "pendulum-3.0.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:d4e2512f4e1a4670284a153b214db9719eb5d14ac55ada5b76cbdb8c5c00399d"}, + {file = "pendulum-3.0.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:3d897eb50883cc58d9b92f6405245f84b9286cd2de6e8694cb9ea5cb15195a32"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e169cc2ca419517f397811bbe4589cf3cd13fca6dc38bb352ba15ea90739ebb"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17c3084a4524ebefd9255513692f7e7360e23c8853dc6f10c64cc184e1217ab"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:826d6e258052715f64d05ae0fc9040c0151e6a87aae7c109ba9a0ed930ce4000"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2aae97087872ef152a0c40e06100b3665d8cb86b59bc8471ca7c26132fccd0f"}, + {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ac65eeec2250d03106b5e81284ad47f0d417ca299a45e89ccc69e36130ca8bc7"}, + {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a5346d08f3f4a6e9e672187faa179c7bf9227897081d7121866358af369f44f9"}, + {file = "pendulum-3.0.0-cp37-none-win_amd64.whl", hash = "sha256:235d64e87946d8f95c796af34818c76e0f88c94d624c268693c85b723b698aa9"}, + {file = "pendulum-3.0.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:6a881d9c2a7f85bc9adafcfe671df5207f51f5715ae61f5d838b77a1356e8b7b"}, + {file = "pendulum-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d7762d2076b9b1cb718a6631ad6c16c23fc3fac76cbb8c454e81e80be98daa34"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e8e36a8130819d97a479a0e7bf379b66b3b1b520e5dc46bd7eb14634338df8c"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7dc843253ac373358ffc0711960e2dd5b94ab67530a3e204d85c6e8cb2c5fa10"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a78ad3635d609ceb1e97d6aedef6a6a6f93433ddb2312888e668365908c7120"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a137e9e0d1f751e60e67d11fc67781a572db76b2296f7b4d44554761049d6"}, + {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c95984037987f4a457bb760455d9ca80467be792236b69d0084f228a8ada0162"}, + {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d29c6e578fe0f893766c0d286adbf0b3c726a4e2341eba0917ec79c50274ec16"}, + {file = "pendulum-3.0.0-cp38-none-win_amd64.whl", hash = "sha256:deaba8e16dbfcb3d7a6b5fabdd5a38b7c982809567479987b9c89572df62e027"}, + {file = "pendulum-3.0.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b11aceea5b20b4b5382962b321dbc354af0defe35daa84e9ff3aae3c230df694"}, + {file = "pendulum-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a90d4d504e82ad236afac9adca4d6a19e4865f717034fc69bafb112c320dcc8f"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:825799c6b66e3734227756fa746cc34b3549c48693325b8b9f823cb7d21b19ac"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad769e98dc07972e24afe0cff8d365cb6f0ebc7e65620aa1976fcfbcadc4c6f3"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6fc26907eb5fb8cc6188cc620bc2075a6c534d981a2f045daa5f79dfe50d512"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c717eab1b6d898c00a3e0fa7781d615b5c5136bbd40abe82be100bb06df7a56"}, + {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3ddd1d66d1a714ce43acfe337190be055cdc221d911fc886d5a3aae28e14b76d"}, + {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:822172853d7a9cf6da95d7b66a16c7160cb99ae6df55d44373888181d7a06edc"}, + {file = "pendulum-3.0.0-cp39-none-win_amd64.whl", hash = "sha256:840de1b49cf1ec54c225a2a6f4f0784d50bd47f68e41dc005b7f67c7d5b5f3ae"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b1f74d1e6ffe5d01d6023870e2ce5c2191486928823196f8575dcc786e107b1"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:729e9f93756a2cdfa77d0fc82068346e9731c7e884097160603872686e570f07"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e586acc0b450cd21cbf0db6bae386237011b75260a3adceddc4be15334689a9a"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22e7944ffc1f0099a79ff468ee9630c73f8c7835cd76fdb57ef7320e6a409df4"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fa30af36bd8e50686846bdace37cf6707bdd044e5cb6e1109acbad3277232e04"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:440215347b11914ae707981b9a57ab9c7b6983ab0babde07063c6ee75c0dc6e7"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:314c4038dc5e6a52991570f50edb2f08c339debdf8cea68ac355b32c4174e820"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5acb1d386337415f74f4d1955c4ce8d0201978c162927d07df8eb0692b2d8533"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a789e12fbdefaffb7b8ac67f9d8f22ba17a3050ceaaa635cd1cc4645773a4b1e"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:860aa9b8a888e5913bd70d819306749e5eb488e6b99cd6c47beb701b22bdecf5"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5ebc65ea033ef0281368217fbf59f5cb05b338ac4dd23d60959c7afcd79a60a0"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9fef18ab0386ef6a9ac7bad7e43ded42c83ff7ad412f950633854f90d59afa8"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1c134ba2f0571d0b68b83f6972e2307a55a5a849e7dac8505c715c531d2a8795"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:385680812e7e18af200bb9b4a49777418c32422d05ad5a8eb85144c4a285907b"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eec91cd87c59fb32ec49eb722f375bd58f4be790cae11c1b70fac3ee4f00da0"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4386bffeca23c4b69ad50a36211f75b35a4deb6210bdca112ac3043deb7e494a"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dfbcf1661d7146d7698da4b86e7f04814221081e9fe154183e34f4c5f5fa3bf8"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:04a1094a5aa1daa34a6b57c865b25f691848c61583fb22722a4df5699f6bf74c"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5b0ec85b9045bd49dd3a3493a5e7ddfd31c36a2a60da387c419fa04abcaecb23"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0a15b90129765b705eb2039062a6daf4d22c4e28d1a54fa260892e8c3ae6e157"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:bb8f6d7acd67a67d6fedd361ad2958ff0539445ef51cbe8cd288db4306503cd0"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd69b15374bef7e4b4440612915315cc42e8575fcda2a3d7586a0d88192d0c88"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc00f8110db6898360c53c812872662e077eaf9c75515d53ecc65d886eec209a"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83a44e8b40655d0ba565a5c3d1365d27e3e6778ae2a05b69124db9e471255c4a"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1a3604e9fbc06b788041b2a8b78f75c243021e0f512447806a6d37ee5214905d"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:92c307ae7accebd06cbae4729f0ba9fa724df5f7d91a0964b1b972a22baa482b"}, + {file = "pendulum-3.0.0.tar.gz", hash = "sha256:5d034998dea404ec31fae27af6b22cff1708f830a1ed7353be4d1019bb9f584e"}, +] + +[package.dependencies] +python-dateutil = ">=2.6" +tzdata = ">=2020.1" + +[package.extras] +test = ["time-machine (>=2.6.0)"] + [[package]] name = "pexpect" version = "4.9.0" @@ -2843,11 +3448,98 @@ nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" +[[package]] +name = "prefect" +version = "3.0.0rc17" +description = "Workflow orchestration and management." +category = "main" +optional = false +python-versions = ">=3.9" +files = [ + {file = "prefect-3.0.0rc17-py3-none-any.whl", hash = "sha256:7934edfd244863c2a4589893194c8c71ff124eef4c41c6c82f234cb54d5e93c3"}, + {file = "prefect-3.0.0rc17.tar.gz", hash = "sha256:af8cc4e679df09bcf0e99e95883d93c7739177f4396cfe529614a7f789b319e5"}, +] + +[package.dependencies] +aiosqlite = ">=0.17.0" +alembic = ">=1.7.5,<2.0.0" +anyio = ">=4.4.0,<5.0.0" +apprise = ">=1.1.0,<2.0.0" +asgi-lifespan = ">=1.0,<3.0" +asyncpg = ">=0.23" +cachetools = ">=5.3,<6.0" +click = ">=8.0,<8.2" +cloudpickle = ">=2.0,<4.0" +coolname = ">=1.0.4,<3.0.0" +croniter = ">=1.0.12,<4.0.0" +cryptography = ">=36.0.1" +dateparser = ">=1.1.1,<2.0.0" +docker = ">=4.0" +exceptiongroup = ">=1.0.0" +fastapi = ">=0.111.0,<1.0.0" +fsspec = ">=2022.5.0" +graphviz = ">=0.20.1" +griffe = ">=0.20.0,<0.48.0" +httpcore = ">=1.0.5,<2.0.0" +httpx = {version = ">=0.23,<0.23.2 || >0.23.2", extras = ["http2"]} +humanize = ">=4.9.0" +importlib-resources = ">=6.1.3,<6.2.0" +jinja2 = ">=3.0.0,<4.0.0" +jinja2-humanize-extension = ">=0.4.0" +jsonpatch = ">=1.32,<2.0" +jsonschema = ">=4.0.0,<5.0.0" +orjson = ">=3.7,<4.0" +packaging = ">=21.3,<24.3" +pathspec = ">=0.8.0" +pendulum = ">=3.0.0,<4" +prometheus-client = ">=0.20.0" +pydantic = ">=2.7,<3.0.0" +pydantic-core = ">=2.12.0,<3.0.0" +pydantic-extra-types = ">=2.8.2,<3.0.0" +pydantic-settings = "*" +python-dateutil = ">=2.8.2,<3.0.0" +python-slugify = ">=5.0,<9.0" +pytz = ">=2021.1,<2025" +pyyaml = ">=5.4.1,<7.0.0" +readchar = ">=4.0.0,<5.0.0" +rfc3339-validator = ">=0.1.4,<0.2.0" +rich = ">=11.0,<14.0" +"ruamel.yaml" = ">=0.17.0" +sniffio = ">=1.3.0,<2.0.0" +sqlalchemy = {version = ">=2.0,<3.0.0", extras = ["asyncio"]} +toml = ">=0.10.0" +typer = ">=0.12.0,<0.12.2 || >0.12.2,<0.13.0" +typing-extensions = ">=4.5.0,<5.0.0" +ujson = ">=5.8.0,<6.0.0" +uvicorn = ">=0.14.0,<0.29.0 || >0.29.0" +websockets = ">=10.4,<13.0" + +[package.extras] +aws = ["prefect-aws (>=0.5.0rc1)"] +azure = ["prefect-azure (>=0.4.0rc1)"] +bitbucket = ["prefect-bitbucket (>=0.3.0rc1)"] +dask = ["prefect-dask (>=0.3.0rc1)"] +databricks = ["prefect-databricks (>=0.3.0rc1)"] +dbt = ["prefect-dbt (>=0.6.0rc1)"] +dev = ["cairosvg", "codespell (>=2.2.6)", "ipython", "jinja2", "mkdocs", "mkdocs-gen-files", "mkdocs-material", "mkdocstrings[python]", "moto (>=5)", "mypy (>=1.9.0)", "numpy", "pillow", "pluggy (>=1.4.0)", "pre-commit", "pytest (>7,<9)", "pytest-asyncio (>=0.18.2,!=0.22.0,<0.23.0)", "pytest-benchmark", "pytest-codspeed", "pytest-cov", "pytest-env", "pytest-flakefinder", "pytest-timeout", "pytest-xdist (>=3.6.1)", "pyyaml", "redis (>=5.0.1)", "respx", "ruff", "setuptools", "types-PyYAML", "types-cachetools", "vale", "vermin", "virtualenv", "watchfiles"] +docker = ["prefect-docker (>=0.6.0rc1)"] +email = ["prefect-email (>=0.4.0rc1)"] +gcp = ["prefect-gcp (>=0.6.0rc1)"] +github = ["prefect-github (>=0.3.0rc1)"] +gitlab = ["prefect-gitlab (>=0.3.0rc1)"] +kubernetes = ["prefect-kubernetes (>=0.4.0rc1)"] +ray = ["prefect-ray (>=0.4.0rc1)"] +redis = ["redis (>=5.0.1)"] +shell = ["prefect-shell (>=0.3.0rc1)"] +slack = ["prefect-slack (>=0.3.0rc1)"] +snowflake = ["prefect-snowflake (>=0.28.0rc1)"] +sqlalchemy = ["prefect-sqlalchemy (>=0.5.0rc1)"] + [[package]] name = "prometheus-client" version = "0.20.0" description = "Python client for the Prometheus monitoring system." -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2973,7 +3665,7 @@ tests = ["pytest"] name = "pycparser" version = "2.22" description = "C parser in Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3093,6 +3785,29 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydantic-extra-types" +version = "2.9.0" +description = "Extra Pydantic types." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_extra_types-2.9.0-py3-none-any.whl", hash = "sha256:f0bb975508572ba7bf3390b7337807588463b7248587e69f43b1ad7c797530d0"}, + {file = "pydantic_extra_types-2.9.0.tar.gz", hash = "sha256:e061c01636188743bb69f368dcd391f327b8cfbfede2fe1cbb1211b06601ba3b"}, +] + +[package.dependencies] +pydantic = ">=2.5.2" + +[package.extras] +all = ["pendulum (>=3.0.0,<4.0.0)", "phonenumbers (>=8,<9)", "pycountry (>=23)", "python-ulid (>=1,<2)", "python-ulid (>=1,<3)", "pytz (>=2024.1)", "semver (>=3.0.2)", "tzdata (>=2024.1)"] +pendulum = ["pendulum (>=3.0.0,<4.0.0)"] +phonenumbers = ["phonenumbers (>=8,<9)"] +pycountry = ["pycountry (>=23)"] +python-ulid = ["python-ulid (>=1,<2)", "python-ulid (>=1,<3)"] +semver = ["semver (>=3.0.2)"] + [[package]] name = "pydantic-settings" version = "2.2.1" @@ -3329,23 +4044,41 @@ files = [ [package.extras] dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"] +[[package]] +name = "python-slugify" +version = "8.0.4" +description = "A Python slugify application that also handles Unicode" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, + {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + [[package]] name = "pytz" -version = "2020.1" +version = "2024.1" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" files = [ - {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, - {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "dev" +category = "main" optional = false python-versions = "*" files = [ @@ -3542,11 +4275,23 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "readchar" +version = "4.1.0" +description = "Library to easily read single chars and key strokes" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "readchar-4.1.0-py3-none-any.whl", hash = "sha256:d163680656b34f263fb5074023db44b999c68ff31ab394445ebfd1a2a41fe9a2"}, + {file = "readchar-4.1.0.tar.gz", hash = "sha256:6f44d1b5f0fd93bd93236eac7da39609f15df647ab9cea39f5bc7478b3344b99"}, +] + [[package]] name = "referencing" version = "0.35.1" description = "JSON Referencing + Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3558,6 +4303,95 @@ files = [ attrs = ">=22.2.0" rpds-py = ">=0.7.0" +[[package]] +name = "regex" +version = "2024.7.24" +description = "Alternative regular expression module, to replace re." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b0d3f567fafa0633aee87f08b9276c7062da9616931382993c03808bb68ce"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3426de3b91d1bc73249042742f45c2148803c111d1175b283270177fdf669024"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f273674b445bcb6e4409bf8d1be67bc4b58e8b46fd0d560055d515b8830063cd"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23acc72f0f4e1a9e6e9843d6328177ae3074b4182167e34119ec7233dfeccf53"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65fd3d2e228cae024c411c5ccdffae4c315271eee4a8b839291f84f796b34eca"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c414cbda77dbf13c3bc88b073a1a9f375c7b0cb5e115e15d4b73ec3a2fbc6f59"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf7a89eef64b5455835f5ed30254ec19bf41f7541cd94f266ab7cbd463f00c41"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19c65b00d42804e3fbea9708f0937d157e53429a39b7c61253ff15670ff62cb5"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7a5486ca56c8869070a966321d5ab416ff0f83f30e0e2da1ab48815c8d165d46"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f51f9556785e5a203713f5efd9c085b4a45aecd2a42573e2b5041881b588d1f"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a4997716674d36a82eab3e86f8fa77080a5d8d96a389a61ea1d0e3a94a582cf7"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c0abb5e4e8ce71a61d9446040c1e86d4e6d23f9097275c5bd49ed978755ff0fe"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:18300a1d78cf1290fa583cd8b7cde26ecb73e9f5916690cf9d42de569c89b1ce"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:416c0e4f56308f34cdb18c3f59849479dde5b19febdcd6e6fa4d04b6c31c9faa"}, + {file = "regex-2024.7.24-cp310-cp310-win32.whl", hash = "sha256:fb168b5924bef397b5ba13aabd8cf5df7d3d93f10218d7b925e360d436863f66"}, + {file = "regex-2024.7.24-cp310-cp310-win_amd64.whl", hash = "sha256:6b9fc7e9cc983e75e2518496ba1afc524227c163e43d706688a6bb9eca41617e"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:382281306e3adaaa7b8b9ebbb3ffb43358a7bbf585fa93821300a418bb975281"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4fdd1384619f406ad9037fe6b6eaa3de2749e2e12084abc80169e8e075377d3b"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3d974d24edb231446f708c455fd08f94c41c1ff4f04bcf06e5f36df5ef50b95a"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2ec4419a3fe6cf8a4795752596dfe0adb4aea40d3683a132bae9c30b81e8d73"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb563dd3aea54c797adf513eeec819c4213d7dbfc311874eb4fd28d10f2ff0f2"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45104baae8b9f67569f0f1dca5e1f1ed77a54ae1cd8b0b07aba89272710db61e"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:994448ee01864501912abf2bad9203bffc34158e80fe8bfb5b031f4f8e16da51"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fac296f99283ac232d8125be932c5cd7644084a30748fda013028c815ba3364"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7e37e809b9303ec3a179085415cb5f418ecf65ec98cdfe34f6a078b46ef823ee"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:01b689e887f612610c869421241e075c02f2e3d1ae93a037cb14f88ab6a8934c"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f6442f0f0ff81775eaa5b05af8a0ffa1dda36e9cf6ec1e0d3d245e8564b684ce"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:871e3ab2838fbcb4e0865a6e01233975df3a15e6fce93b6f99d75cacbd9862d1"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c918b7a1e26b4ab40409820ddccc5d49871a82329640f5005f73572d5eaa9b5e"}, + {file = "regex-2024.7.24-cp311-cp311-win32.whl", hash = "sha256:2dfbb8baf8ba2c2b9aa2807f44ed272f0913eeeba002478c4577b8d29cde215c"}, + {file = "regex-2024.7.24-cp311-cp311-win_amd64.whl", hash = "sha256:538d30cd96ed7d1416d3956f94d54e426a8daf7c14527f6e0d6d425fcb4cca52"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4ebef608553aff8deb845c7f4f1d0740ff76fa672c011cc0bacb2a00fbde86"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:74007a5b25b7a678459f06559504f1eec2f0f17bca218c9d56f6a0a12bfffdad"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7df9ea48641da022c2a3c9c641650cd09f0cd15e8908bf931ad538f5ca7919c9"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a1141a1dcc32904c47f6846b040275c6e5de0bf73f17d7a409035d55b76f289"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80c811cfcb5c331237d9bad3bea2c391114588cf4131707e84d9493064d267f9"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7214477bf9bd195894cf24005b1e7b496f46833337b5dedb7b2a6e33f66d962c"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d55588cba7553f0b6ec33130bc3e114b355570b45785cebdc9daed8c637dd440"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558a57cfc32adcf19d3f791f62b5ff564922942e389e3cfdb538a23d65a6b610"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a512eed9dfd4117110b1881ba9a59b31433caed0c4101b361f768e7bcbaf93c5"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:86b17ba823ea76256b1885652e3a141a99a5c4422f4a869189db328321b73799"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5eefee9bfe23f6df09ffb6dfb23809f4d74a78acef004aa904dc7c88b9944b05"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:731fcd76bbdbf225e2eb85b7c38da9633ad3073822f5ab32379381e8c3c12e94"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eaef80eac3b4cfbdd6de53c6e108b4c534c21ae055d1dbea2de6b3b8ff3def38"}, + {file = "regex-2024.7.24-cp312-cp312-win32.whl", hash = "sha256:185e029368d6f89f36e526764cf12bf8d6f0e3a2a7737da625a76f594bdfcbfc"}, + {file = "regex-2024.7.24-cp312-cp312-win_amd64.whl", hash = "sha256:2f1baff13cc2521bea83ab2528e7a80cbe0ebb2c6f0bfad15be7da3aed443908"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:66b4c0731a5c81921e938dcf1a88e978264e26e6ac4ec96a4d21ae0354581ae0"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:88ecc3afd7e776967fa16c80f974cb79399ee8dc6c96423321d6f7d4b881c92b"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64bd50cf16bcc54b274e20235bf8edbb64184a30e1e53873ff8d444e7ac656b2"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb462f0e346fcf41a901a126b50f8781e9a474d3927930f3490f38a6e73b6950"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a82465ebbc9b1c5c50738536fdfa7cab639a261a99b469c9d4c7dcbb2b3f1e57"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68a8f8c046c6466ac61a36b65bb2395c74451df2ffb8458492ef49900efed293"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac8e84fff5d27420f3c1e879ce9929108e873667ec87e0c8eeb413a5311adfe"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba2537ef2163db9e6ccdbeb6f6424282ae4dea43177402152c67ef869cf3978b"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:43affe33137fcd679bdae93fb25924979517e011f9dea99163f80b82eadc7e53"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:c9bb87fdf2ab2370f21e4d5636e5317775e5d51ff32ebff2cf389f71b9b13750"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:945352286a541406f99b2655c973852da7911b3f4264e010218bbc1cc73168f2"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:8bc593dcce679206b60a538c302d03c29b18e3d862609317cb560e18b66d10cf"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3f3b6ca8eae6d6c75a6cff525c8530c60e909a71a15e1b731723233331de4169"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c51edc3541e11fbe83f0c4d9412ef6c79f664a3745fab261457e84465ec9d5a8"}, + {file = "regex-2024.7.24-cp38-cp38-win32.whl", hash = "sha256:d0a07763776188b4db4c9c7fb1b8c494049f84659bb387b71c73bbc07f189e96"}, + {file = "regex-2024.7.24-cp38-cp38-win_amd64.whl", hash = "sha256:8fd5afd101dcf86a270d254364e0e8dddedebe6bd1ab9d5f732f274fa00499a5"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0ffe3f9d430cd37d8fa5632ff6fb36d5b24818c5c986893063b4e5bdb84cdf24"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25419b70ba00a16abc90ee5fce061228206173231f004437730b67ac77323f0d"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:33e2614a7ce627f0cdf2ad104797d1f68342d967de3695678c0cb84f530709f8"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d33a0021893ede5969876052796165bab6006559ab845fd7b515a30abdd990dc"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04ce29e2c5fedf296b1a1b0acc1724ba93a36fb14031f3abfb7abda2806c1535"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b16582783f44fbca6fcf46f61347340c787d7530d88b4d590a397a47583f31dd"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:836d3cc225b3e8a943d0b02633fb2f28a66e281290302a79df0e1eaa984ff7c1"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:438d9f0f4bc64e8dea78274caa5af971ceff0f8771e1a2333620969936ba10be"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:973335b1624859cb0e52f96062a28aa18f3a5fc77a96e4a3d6d76e29811a0e6e"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c5e69fd3eb0b409432b537fe3c6f44ac089c458ab6b78dcec14478422879ec5f"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fbf8c2f00904eaf63ff37718eb13acf8e178cb940520e47b2f05027f5bb34ce3"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2757ace61bc4061b69af19e4689fa4416e1a04840f33b441034202b5cd02d4"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:44fc61b99035fd9b3b9453f1713234e5a7c92a04f3577252b45feefe1b327759"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:84c312cdf839e8b579f504afcd7b65f35d60b6285d892b19adea16355e8343c9"}, + {file = "regex-2024.7.24-cp39-cp39-win32.whl", hash = "sha256:ca5b2028c2f7af4e13fb9fc29b28d0ce767c38c7facdf64f6c2cd040413055f1"}, + {file = "regex-2024.7.24-cp39-cp39-win_amd64.whl", hash = "sha256:7c479f5ae937ec9985ecaf42e2e10631551d909f203e31308c12d703922742f9"}, + {file = "regex-2024.7.24.tar.gz", hash = "sha256:9cfd009eed1a46b27c14039ad5bbc5e71b6367c5b2e6d5f5da0ea91600817506"}, +] + [[package]] name = "requests" version = "2.32.2" @@ -3580,11 +4414,30 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "requests-oauthlib" +version = "2.0.0" +description = "OAuthlib authentication support for Requests." +category = "main" +optional = false +python-versions = ">=3.4" +files = [ + {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"}, + {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"}, +] + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + [[package]] name = "rfc3339-validator" version = "0.1.4" description = "A pure python RFC3339 validator" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -3630,7 +4483,7 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "rpds-py" version = "0.18.1" description = "Python bindings to Rust's persistent data structures (rpds)" -category = "dev" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3735,6 +4588,85 @@ files = [ {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, ] +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, + {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} + +[package.extras] +docs = ["mercurial (>5.7)", "ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.8" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, + {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, + {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, +] + [[package]] name = "ruff" version = "0.2.2" @@ -4116,6 +5048,18 @@ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + [[package]] name = "threddsclient" version = "0.4.2" @@ -4151,6 +5095,18 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["pytest", "ruff"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -4242,6 +5198,124 @@ files = [ {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, ] +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +category = "main" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "tzlocal" +version = "5.2" +description = "tzinfo object for the local timezone" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, + {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, +] + +[package.dependencies] +tzdata = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] + +[[package]] +name = "ujson" +version = "5.10.0" +description = "Ultra fast JSON encoder and decoder for Python" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ujson-5.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd"}, + {file = "ujson-5.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22cffecf73391e8abd65ef5f4e4dd523162a3399d5e84faa6aebbf9583df86d6"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26b0e2d2366543c1bb4fbd457446f00b0187a2bddf93148ac2da07a53fe51569"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:caf270c6dba1be7a41125cd1e4fc7ba384bf564650beef0df2dd21a00b7f5770"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a245d59f2ffe750446292b0094244df163c3dc96b3ce152a2c837a44e7cda9d1"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:94a87f6e151c5f483d7d54ceef83b45d3a9cca7a9cb453dbdbb3f5a6f64033f5"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:29b443c4c0a113bcbb792c88bea67b675c7ca3ca80c3474784e08bba01c18d51"}, + {file = "ujson-5.10.0-cp310-cp310-win32.whl", hash = "sha256:c18610b9ccd2874950faf474692deee4223a994251bc0a083c114671b64e6518"}, + {file = "ujson-5.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:924f7318c31874d6bb44d9ee1900167ca32aa9b69389b98ecbde34c1698a250f"}, + {file = "ujson-5.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a5b366812c90e69d0f379a53648be10a5db38f9d4ad212b60af00bd4048d0f00"}, + {file = "ujson-5.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:502bf475781e8167f0f9d0e41cd32879d120a524b22358e7f205294224c71126"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b91b5d0d9d283e085e821651184a647699430705b15bf274c7896f23fe9c9d8"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:129e39af3a6d85b9c26d5577169c21d53821d8cf68e079060602e861c6e5da1b"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f77b74475c462cb8b88680471193064d3e715c7c6074b1c8c412cb526466efe9"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ec0ca8c415e81aa4123501fee7f761abf4b7f386aad348501a26940beb1860f"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab13a2a9e0b2865a6c6db9271f4b46af1c7476bfd51af1f64585e919b7c07fd4"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:57aaf98b92d72fc70886b5a0e1a1ca52c2320377360341715dd3933a18e827b1"}, + {file = "ujson-5.10.0-cp311-cp311-win32.whl", hash = "sha256:2987713a490ceb27edff77fb184ed09acdc565db700ee852823c3dc3cffe455f"}, + {file = "ujson-5.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f00ea7e00447918ee0eff2422c4add4c5752b1b60e88fcb3c067d4a21049a720"}, + {file = "ujson-5.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98ba15d8cbc481ce55695beee9f063189dce91a4b08bc1d03e7f0152cd4bbdd5"}, + {file = "ujson-5.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9d2edbf1556e4f56e50fab7d8ff993dbad7f54bac68eacdd27a8f55f433578e"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6627029ae4f52d0e1a2451768c2c37c0c814ffc04f796eb36244cf16b8e57043"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ccb77b3e40b151e20519c6ae6d89bfe3f4c14e8e210d910287f778368bb3d1"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3caf9cd64abfeb11a3b661329085c5e167abbe15256b3b68cb5d914ba7396f3"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6e32abdce572e3a8c3d02c886c704a38a1b015a1fb858004e03d20ca7cecbb21"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a65b6af4d903103ee7b6f4f5b85f1bfd0c90ba4eeac6421aae436c9988aa64a2"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:604a046d966457b6cdcacc5aa2ec5314f0e8c42bae52842c1e6fa02ea4bda42e"}, + {file = "ujson-5.10.0-cp312-cp312-win32.whl", hash = "sha256:6dea1c8b4fc921bf78a8ff00bbd2bfe166345f5536c510671bccececb187c80e"}, + {file = "ujson-5.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:38665e7d8290188b1e0d57d584eb8110951a9591363316dd41cf8686ab1d0abc"}, + {file = "ujson-5.10.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:618efd84dc1acbd6bff8eaa736bb6c074bfa8b8a98f55b61c38d4ca2c1f7f287"}, + {file = "ujson-5.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38d5d36b4aedfe81dfe251f76c0467399d575d1395a1755de391e58985ab1c2e"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67079b1f9fb29ed9a2914acf4ef6c02844b3153913eb735d4bf287ee1db6e557"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7d0e0ceeb8fe2468c70ec0c37b439dd554e2aa539a8a56365fd761edb418988"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59e02cd37bc7c44d587a0ba45347cc815fb7a5fe48de16bf05caa5f7d0d2e816"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a890b706b64e0065f02577bf6d8ca3b66c11a5e81fb75d757233a38c07a1f20"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:621e34b4632c740ecb491efc7f1fcb4f74b48ddb55e65221995e74e2d00bbff0"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9500e61fce0cfc86168b248104e954fead61f9be213087153d272e817ec7b4f"}, + {file = "ujson-5.10.0-cp313-cp313-win32.whl", hash = "sha256:4c4fc16f11ac1612f05b6f5781b384716719547e142cfd67b65d035bd85af165"}, + {file = "ujson-5.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:4573fd1695932d4f619928fd09d5d03d917274381649ade4328091ceca175539"}, + {file = "ujson-5.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a984a3131da7f07563057db1c3020b1350a3e27a8ec46ccbfbf21e5928a43050"}, + {file = "ujson-5.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73814cd1b9db6fc3270e9d8fe3b19f9f89e78ee9d71e8bd6c9a626aeaeaf16bd"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61e1591ed9376e5eddda202ec229eddc56c612b61ac6ad07f96b91460bb6c2fb"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2c75269f8205b2690db4572a4a36fe47cd1338e4368bc73a7a0e48789e2e35a"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7223f41e5bf1f919cd8d073e35b229295aa8e0f7b5de07ed1c8fddac63a6bc5d"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc2fd6b3067c0782e7002ac3b38cf48608ee6366ff176bbd02cf969c9c20fe"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:232cc85f8ee3c454c115455195a205074a56ff42608fd6b942aa4c378ac14dd7"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cc6139531f13148055d691e442e4bc6601f6dba1e6d521b1585d4788ab0bfad4"}, + {file = "ujson-5.10.0-cp38-cp38-win32.whl", hash = "sha256:e7ce306a42b6b93ca47ac4a3b96683ca554f6d35dd8adc5acfcd55096c8dfcb8"}, + {file = "ujson-5.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:e82d4bb2138ab05e18f089a83b6564fee28048771eb63cdecf4b9b549de8a2cc"}, + {file = "ujson-5.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dfef2814c6b3291c3c5f10065f745a1307d86019dbd7ea50e83504950136ed5b"}, + {file = "ujson-5.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4734ee0745d5928d0ba3a213647f1c4a74a2a28edc6d27b2d6d5bd9fa4319e27"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47ebb01bd865fdea43da56254a3930a413f0c5590372a1241514abae8aa7c76"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee5e97c2496874acbf1d3e37b521dd1f307349ed955e62d1d2f05382bc36dd5"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7490655a2272a2d0b072ef16b0b58ee462f4973a8f6bbe64917ce5e0a256f9c0"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba17799fcddaddf5c1f75a4ba3fd6441f6a4f1e9173f8a786b42450851bd74f1"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2aff2985cef314f21d0fecc56027505804bc78802c0121343874741650a4d3d1"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ad88ac75c432674d05b61184178635d44901eb749786c8eb08c102330e6e8996"}, + {file = "ujson-5.10.0-cp39-cp39-win32.whl", hash = "sha256:2544912a71da4ff8c4f7ab5606f947d7299971bdd25a45e008e467ca638d13c9"}, + {file = "ujson-5.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:3ff201d62b1b177a46f113bb43ad300b424b7847f9c5d38b1b4ad8f75d4a282a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5b6fee72fa77dc172a28f21693f64d93166534c263adb3f96c413ccc85ef6e64"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:61d0af13a9af01d9f26d2331ce49bb5ac1fb9c814964018ac8df605b5422dcb3"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecb24f0bdd899d368b715c9e6664166cf694d1e57be73f17759573a6986dd95a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbd8fd427f57a03cff3ad6574b5e299131585d9727c8c366da4624a9069ed746"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beeaf1c48e32f07d8820c705ff8e645f8afa690cca1544adba4ebfa067efdc88"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:baed37ea46d756aca2955e99525cc02d9181de67f25515c468856c38d52b5f3b"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7663960f08cd5a2bb152f5ee3992e1af7690a64c0e26d31ba7b3ff5b2ee66337"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8640fb4072d36b08e95a3a380ba65779d356b2fee8696afeb7794cf0902d0a1"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78778a3aa7aafb11e7ddca4e29f46bc5139131037ad628cc10936764282d6753"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0111b27f2d5c820e7f2dbad7d48e3338c824e7ac4d2a12da3dc6061cc39c8e6"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c66962ca7565605b355a9ed478292da628b8f18c0f2793021ca4425abf8b01e5"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ba43cc34cce49cf2d4bc76401a754a81202d8aa926d0e2b79f0ee258cb15d3a4"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac56eb983edce27e7f51d05bc8dd820586c6e6be1c5216a6809b0c668bb312b8"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44bd4b23a0e723bf8b10628288c2c7c335161d6840013d4d5de20e48551773b"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c10f4654e5326ec14a46bcdeb2b685d4ada6911050aa8baaf3501e57024b804"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0de4971a89a762398006e844ae394bd46991f7c385d7a6a3b93ba229e6dac17e"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e1402f0564a97d2a52310ae10a64d25bcef94f8dd643fcf5d310219d915484f7"}, + {file = "ujson-5.10.0.tar.gz", hash = "sha256:b3cd8f3c5d8c7738257f1018880444f7b7d9b66232c64649f562d7ba86ad4bc1"}, +] + [[package]] name = "uri-template" version = "1.3.0" @@ -4277,76 +5351,24 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.29.0" +version = "0.30.5" description = "The lightning-fast ASGI server." category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, + {file = "uvicorn-0.30.5-py3-none-any.whl", hash = "sha256:b2d86de274726e9878188fa07576c9ceeff90a839e2b6e25c917fe05f5a6c835"}, + {file = "uvicorn-0.30.5.tar.gz", hash = "sha256:ac6fdbd4425c5fd17a9fe39daf4d4d075da6fdc80f653e5894cdc2fd98752bee"}, ] [package.dependencies] click = ">=7.0" -colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} h11 = ">=0.8" -httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} -python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} -pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} -uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""} -watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} -websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] -[[package]] -name = "uvloop" -version = "0.19.0" -description = "Fast implementation of asyncio event loop on top of libuv" -category = "main" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, - {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, - {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, - {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, - {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, - {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, - {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, - {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, - {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, - {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, - {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, - {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, - {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, - {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, - {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, - {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, - {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, - {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, - {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, - {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, - {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, - {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, - {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, - {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, - {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, - {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, - {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, - {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, - {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, - {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, - {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, -] - -[package.extras] -docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] - [[package]] name = "virtualenv" version = "20.26.2" @@ -4368,94 +5390,6 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] -[[package]] -name = "watchfiles" -version = "0.22.0" -description = "Simple, modern and high performance file watching and code reload in python." -category = "main" -optional = false -python-versions = ">=3.8" -files = [ - {file = "watchfiles-0.22.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538"}, - {file = "watchfiles-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e"}, - {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1"}, - {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a"}, - {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd"}, - {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb"}, - {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171"}, - {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71"}, - {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39"}, - {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848"}, - {file = "watchfiles-0.22.0-cp310-none-win32.whl", hash = "sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797"}, - {file = "watchfiles-0.22.0-cp310-none-win_amd64.whl", hash = "sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb"}, - {file = "watchfiles-0.22.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96"}, - {file = "watchfiles-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696"}, - {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249"}, - {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550"}, - {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c"}, - {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da"}, - {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1"}, - {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f"}, - {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d"}, - {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c"}, - {file = "watchfiles-0.22.0-cp311-none-win32.whl", hash = "sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67"}, - {file = "watchfiles-0.22.0-cp311-none-win_amd64.whl", hash = "sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1"}, - {file = "watchfiles-0.22.0-cp311-none-win_arm64.whl", hash = "sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84"}, - {file = "watchfiles-0.22.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a"}, - {file = "watchfiles-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be"}, - {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2"}, - {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c"}, - {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232"}, - {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1"}, - {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6"}, - {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27"}, - {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b"}, - {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35"}, - {file = "watchfiles-0.22.0-cp312-none-win32.whl", hash = "sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e"}, - {file = "watchfiles-0.22.0-cp312-none-win_amd64.whl", hash = "sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e"}, - {file = "watchfiles-0.22.0-cp312-none-win_arm64.whl", hash = "sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea"}, - {file = "watchfiles-0.22.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d47e9ef1a94cc7a536039e46738e17cce058ac1593b2eccdede8bf72e45f372a"}, - {file = "watchfiles-0.22.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28f393c1194b6eaadcdd8f941307fc9bbd7eb567995232c830f6aef38e8a6e88"}, - {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd64f3a4db121bc161644c9e10a9acdb836853155a108c2446db2f5ae1778c3d"}, - {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2abeb79209630da981f8ebca30a2c84b4c3516a214451bfc5f106723c5f45843"}, - {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cc382083afba7918e32d5ef12321421ef43d685b9a67cc452a6e6e18920890e"}, - {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d048ad5d25b363ba1d19f92dcf29023988524bee6f9d952130b316c5802069cb"}, - {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:103622865599f8082f03af4214eaff90e2426edff5e8522c8f9e93dc17caee13"}, - {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3e1f3cf81f1f823e7874ae563457828e940d75573c8fbf0ee66818c8b6a9099"}, - {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8597b6f9dc410bdafc8bb362dac1cbc9b4684a8310e16b1ff5eee8725d13dcd6"}, - {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0b04a2cbc30e110303baa6d3ddce8ca3664bc3403be0f0ad513d1843a41c97d1"}, - {file = "watchfiles-0.22.0-cp38-none-win32.whl", hash = "sha256:b610fb5e27825b570554d01cec427b6620ce9bd21ff8ab775fc3a32f28bba63e"}, - {file = "watchfiles-0.22.0-cp38-none-win_amd64.whl", hash = "sha256:fe82d13461418ca5e5a808a9e40f79c1879351fcaeddbede094028e74d836e86"}, - {file = "watchfiles-0.22.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3973145235a38f73c61474d56ad6199124e7488822f3a4fc97c72009751ae3b0"}, - {file = "watchfiles-0.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:280a4afbc607cdfc9571b9904b03a478fc9f08bbeec382d648181c695648202f"}, - {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a0d883351a34c01bd53cfa75cd0292e3f7e268bacf2f9e33af4ecede7e21d1d"}, - {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9165bcab15f2b6d90eedc5c20a7f8a03156b3773e5fb06a790b54ccecdb73385"}, - {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc1b9b56f051209be458b87edb6856a449ad3f803315d87b2da4c93b43a6fe72"}, - {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc1fc25a1dedf2dd952909c8e5cb210791e5f2d9bc5e0e8ebc28dd42fed7562"}, - {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc92d2d2706d2b862ce0568b24987eba51e17e14b79a1abcd2edc39e48e743c8"}, - {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97b94e14b88409c58cdf4a8eaf0e67dfd3ece7e9ce7140ea6ff48b0407a593ec"}, - {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96eec15e5ea7c0b6eb5bfffe990fc7c6bd833acf7e26704eb18387fb2f5fd087"}, - {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:28324d6b28bcb8d7c1041648d7b63be07a16db5510bea923fc80b91a2a6cbed6"}, - {file = "watchfiles-0.22.0-cp39-none-win32.whl", hash = "sha256:8c3e3675e6e39dc59b8fe5c914a19d30029e36e9f99468dddffd432d8a7b1c93"}, - {file = "watchfiles-0.22.0-cp39-none-win_amd64.whl", hash = "sha256:25c817ff2a86bc3de3ed2df1703e3d24ce03479b27bb4527c57e722f8554d971"}, - {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68"}, - {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c"}, - {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab"}, - {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2"}, - {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5834e1f8b71476a26df97d121c0c0ed3549d869124ed2433e02491553cb468c2"}, - {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0bc3b2f93a140df6806c8467c7f51ed5e55a931b031b5c2d7ff6132292e803d6"}, - {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fdebb655bb1ba0122402352b0a4254812717a017d2dc49372a1d47e24073795"}, - {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c8e0aa0e8cc2a43561e0184c0513e291ca891db13a269d8d47cb9841ced7c71"}, - {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2f350cbaa4bb812314af5dab0eb8d538481e2e2279472890864547f3fe2281ed"}, - {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7a74436c415843af2a769b36bf043b6ccbc0f8d784814ba3d42fc961cdb0a9dc"}, - {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00ad0bcd399503a84cc688590cdffbe7a991691314dde5b57b3ed50a41319a31"}, - {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a44e9481afc7a5ee3291b09c419abab93b7e9c306c9ef9108cb76728ca58d2"}, - {file = "watchfiles-0.22.0.tar.gz", hash = "sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb"}, -] - -[package.dependencies] -anyio = ">=3.0.0" - [[package]] name = "wcwidth" version = "0.2.13" @@ -4714,4 +5648,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "6e9bcf6e37d0d49e1554187635dbf8d8ed5d954d9dfa58b47bd76b68d958ec79" +content-hash = "be303af7d34db3b6df2767e522714efad07763688171907fd876603b7027d746" diff --git a/pyproject.toml b/pyproject.toml index 1bab0d8e..5c10e13e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,12 +17,12 @@ threddsclient = "0.4.2" pandas = "1.5.0" requests = "^2.31.0" python-dateutil = "^2.9.0.post0" -pytz = "2020.1" +pytz = "^2024.1" httpx = "^0.27.0" anyio = "^4.3.0" -fastapi = "^0.110.0" +fastapi = "^0.112.0" pydantic-settings = "^2.2.1" -uvicorn = {extras = ["standard"], version = "^0.29.0"} +uvicorn = "^0.30.5" sqlmodel = "^0.0.16" geoalchemy2 = "^0.14.7" sqlalchemy = "^2.0.29" @@ -41,6 +41,7 @@ netcdf4 = "^1.7.1" cftime = "^1.6.4" babel = "^2.15.0" pyloess = "^0.1.0" +prefect = {version = "^3.0.0rc14", allow-prereleases = true} [tool.poetry.group.dev] diff --git a/tests/notebooks/generic.ipynb b/tests/notebooks/generic.ipynb index ac74a756..5352ac95 100644 --- a/tests/notebooks/generic.ipynb +++ b/tests/notebooks/generic.ipynb @@ -37,6 +37,7 @@ ")\n", "from arpav_ppcv.schemas import coverages\n", "from arpav_ppcv.schemas.coverages import CoverageInternal\n", + "from arpav_ppcv.schemas import observations\n", "\n", "logging.basicConfig(level=logging.DEBUG)\n", "logging.getLogger(\"httpx\").setLevel(logging.WARNING)\n", @@ -50,179 +51,147 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "c65166b7-4173-444c-be69-688ff5f6b874", "metadata": {}, "outputs": [], "source": [ - "coverage_identifier = \"tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp26-MAM\"\n", - "point_coords = \"POINT(11.5469 44.9524)\"\n", - "date_range = \"../..\"\n", - "\n", - "cov = CoverageInternal(\n", - " configuration=db.get_coverage_configuration_by_coverage_identifier(session, coverage_identifier), \n", - " identifier=coverage_identifier\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "48b441be-581b-48d6-86a4-11ea7a36b795", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['tas_seasonal_anomaly_model_ensemble_lower_uncertainty-annual-model_ensemble-tas-anomaly-rcp26-lower_bound-MAM',\n", - " 'tas_seasonal_anomaly_model_ensemble_upper_uncertainty-annual-model_ensemble-tas-anomaly-rcp26-upper_bound-MAM']" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[c.identifier for c in operations.get_related_uncertainty_coverage_configurations(session, cov)]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "82b5c65f-afe2-4b83-b3a0-54d14a5ea3e5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "id_parts=['annual', 'model_ensemble', 'tas', 'anomaly', 'rcp26', 'MAM']\n", - "about to process the found pattern_parts...\n", - "checking configuration_parameter_name='aggregation_period'...\n", - "id_part='annual'\n", - "checking configuration_parameter_name='climatological_model'...\n", - "id_part='model_ensemble'\n", - "checking configuration_parameter_name='climatological_variable'...\n", - "id_part='tas'\n", - "checking configuration_parameter_name='measure'...\n", - "id_part='anomaly'\n", - "checking configuration_parameter_name='scenario'...\n", - "id_part='rcp26'\n", - "checking configuration_parameter_name='year_period'...\n", - "id_part='MAM'\n", - "result={'aggregation_period': 'annual', 'climatological_model': 'model_ensemble', 'climatological_variable': 'tas', 'measure': 'anomaly', 'scenario': 'rcp26', 'year_period': 'MAM'}\n" - ] - }, - { - "data": { - "text/plain": [ - "{'aggregation_period': 'annual',\n", - " 'climatological_model': 'model_ensemble',\n", - " 'climatological_variable': 'tas',\n", - " 'measure': 'anomaly',\n", - " 'scenario': 'rcp26',\n", - " 'year_period': 'MAM'}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cov.configuration.retrieve_configuration_parameters(cov.identifier)" + "station = db.get_station_by_code(session, '91')" ] }, { "cell_type": "code", - "execution_count": 4, - "id": "f829643d-7e9c-40f4-b352-ea4d74e4ed2f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'{name}-{aggregation_period}-{climatological_model}-{climatological_variable}-{measure}-{scenario}-{year_period}'" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cov.configuration.coverage_id_pattern" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "5ae32788-669a-4903-8222-c694d4dacf3e", + "execution_count": 12, + "id": "1b50e512-cff5-4f30-8576-9e2ea92a2948", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp26-DJF',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp26-MAM',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp26-JJA',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp26-SON',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp45-DJF',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp45-MAM',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp45-JJA',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp45-SON',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp85-DJF',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp85-MAM',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp85-JJA',\n", - " 'tas_seasonal_anomaly_model_ensemble-annual-model_ensemble-tas-anomaly-rcp85-SON']" + "[MonthlyMeasurement(date=datetime.date(1987, 1, 1), id=UUID('0f78a845-0db1-45ef-bac8-03f8d68ff034'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-8.23, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1988, 1, 1), id=UUID('cbe5ba03-9996-44b8-b707-1b29b1fb309f'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.34, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1989, 1, 1), id=UUID('103497ee-ec72-4b1b-8992-2e1aea3270a3'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.42, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1990, 1, 1), id=UUID('761f4b69-18f7-4364-9660-88a5813d15d7'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.319, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1991, 1, 1), id=UUID('bff40fed-5a6c-493b-ba53-eda0e63fd769'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.142, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1992, 1, 1), id=UUID('8dbbc233-69c6-467c-971b-6dfbaab56977'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.258, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1993, 1, 1), id=UUID('7ef47fa6-319b-4d06-a84f-b2f56d253350'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.173, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1994, 1, 1), id=UUID('7200af2a-b69a-4d3c-ba90-bc7f90f485ab'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.869, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1995, 1, 1), id=UUID('d28b8b45-fde5-470f-ab69-4b3c5be1ffaf'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.462, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1996, 1, 1), id=UUID('c00db9a3-5c1d-40ef-b8df-f13ad686cb1b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.689, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1997, 1, 1), id=UUID('b56ca768-245d-4449-b91c-8fc2a6fc1534'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.899, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1998, 1, 1), id=UUID('9cdc48c9-415f-4dcb-b431-640f1016a9ec'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.719, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1999, 1, 1), id=UUID('5a154810-13b3-4085-854c-3d799c419b4d'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.364, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2000, 1, 1), id=UUID('f5697a14-a556-4852-9036-998bef18b9b8'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.684, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2001, 1, 1), id=UUID('38b80371-1276-43f9-80be-402e7ed5a500'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.417, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2002, 1, 1), id=UUID('7ef9ec16-6d33-4f9d-bed9-9d01d1aee217'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.836, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2003, 1, 1), id=UUID('d69f3e20-df1f-403f-a156-7e7c7d9abbfd'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.316, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2004, 1, 1), id=UUID('0952716a-32ac-4330-83f0-7843d5f1d035'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.396, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2005, 1, 1), id=UUID('25be0365-df31-435c-850e-52c86a7fe3d9'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.101, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2006, 1, 1), id=UUID('1011c8c2-4321-418f-8575-5781ee6ce622'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.783, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2007, 1, 1), id=UUID('ba8b7181-38e6-4a5b-9d67-8f68fc412d01'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.012, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2008, 1, 1), id=UUID('575070e0-c530-486e-93f4-a68ad1ddaeca'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.732, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2009, 1, 1), id=UUID('5e3d1444-82da-4c68-abe5-ba2a8235c3e1'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.439, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2010, 1, 1), id=UUID('5252e177-d5a9-4506-bb0d-0645a84356dc'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.29, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2011, 1, 1), id=UUID('b1dcff4d-821e-4244-8f82-f3323af49656'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.125, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2012, 1, 1), id=UUID('250231cd-e60a-4bef-abee-8c5d23e8d152'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.426, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2013, 1, 1), id=UUID('c9cbee38-bff2-4ebb-95cf-90c808a708d7'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.209, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2014, 1, 1), id=UUID('982e38cb-2731-4388-907a-c6fd5c12360a'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.847, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2015, 1, 1), id=UUID('7839d9bb-754a-480f-bdb9-70b17a63fe76'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.711, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2016, 1, 1), id=UUID('50f5de6f-bdda-47e4-8275-cb27b41dcc37'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.264, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2017, 1, 1), id=UUID('cd77a4d3-ac54-40cc-95ff-8c6f65e4396e'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.088, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2018, 1, 1), id=UUID('74cb0cd1-aa31-481f-80a8-f6cd15e5f139'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.445, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2019, 1, 1), id=UUID('429d51d7-4e15-4a52-841d-c401c09b2014'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.142, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2020, 1, 1), id=UUID('a6aeba0c-9bda-4cb0-b0f7-d8f8dfc96dfa'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.529, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2021, 1, 1), id=UUID('8904539a-3e35-4ca2-9898-f689a67f7731'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.025, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2022, 1, 1), id=UUID('c49f306c-d3e0-4098-bd86-80179c8067ce'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.885, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2023, 1, 1), id=UUID('9b86e4ef-407b-4235-9c45-930256ad1726'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.724, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2024, 1, 1), id=UUID('e99c0233-0c7f-4cd4-9182-e2f6a12b142f'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.711, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1987, 2, 1), id=UUID('b12da42a-f1bb-4c61-9f24-6ca83811c34a'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.191, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1988, 2, 1), id=UUID('91c90ec3-3d04-45e0-967f-58347decb673'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.257, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1989, 2, 1), id=UUID('aa56f60d-b35d-4c6b-b8ee-714957197998'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.728, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1990, 2, 1), id=UUID('54eceede-7336-42ce-8802-2d44c640e503'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.483, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1991, 2, 1), id=UUID('1ea84e16-d746-40fe-ab6c-e5bffe05193d'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.46, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1992, 2, 1), id=UUID('a1e3ab1e-27d9-4507-b1ea-2efa8a6c6241'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.505, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1993, 2, 1), id=UUID('30390ec6-acb8-44e4-af11-ce1fbd91c0fc'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-4.174, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1994, 2, 1), id=UUID('c650ee0b-2da2-468a-b758-ac1a70658c17'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.704, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1995, 2, 1), id=UUID('5e86d247-08a0-4ffb-b70f-c9186827d4eb'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.047, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1996, 2, 1), id=UUID('41af8b32-68fb-4170-8e1d-ca07a0222328'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.12, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1997, 2, 1), id=UUID('6c244bd9-facc-4a90-9df0-95f962be9983'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.522, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1998, 2, 1), id=UUID('e2e94424-9d91-4947-b60c-672553160b9b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-0.488, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1999, 2, 1), id=UUID('448df967-be0e-4943-8867-540253a8bef0'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.811, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2000, 2, 1), id=UUID('4d3cf120-0ca9-448e-8bc1-1897c7feb096'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.198, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2001, 2, 1), id=UUID('30104e41-32ee-40ce-9568-133cb849659d'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.647, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2002, 2, 1), id=UUID('7a01ba38-4f7d-4c60-aa69-d27cdab0b26f'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.02, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2003, 2, 1), id=UUID('b44ad8b8-7aaa-4d05-ae08-513e86c30d66'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.398, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2004, 2, 1), id=UUID('dc8e2010-6eee-4dbd-b1aa-c377c42a83ee'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.356, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2005, 2, 1), id=UUID('fa9c469c-448e-4afe-b3b3-e24e3df3e606'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-8.506, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2006, 2, 1), id=UUID('40b3f7ba-d835-4d4c-b32b-094c360ae7fa'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.09, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2007, 2, 1), id=UUID('032c0f4a-dd86-4e2a-94cd-bc0b53d9c0c6'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.817, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2008, 2, 1), id=UUID('1b575ebb-05a0-4b79-a7f4-5928bad72c78'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.206, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2009, 2, 1), id=UUID('8b629a67-2635-435e-bb46-d0a11149fac4'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.089, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2010, 2, 1), id=UUID('d9ee16e5-24dc-432e-a7ac-6cdcbfa8c356'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-5.43, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2011, 2, 1), id=UUID('10ab2fc0-d4ce-49f7-b900-13b8922fa563'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.327, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2012, 2, 1), id=UUID('681dc9de-9cbe-43dc-8c88-ab173a5edfba'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.829, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2013, 2, 1), id=UUID('1e4aff17-c85e-4683-a26f-3bef37fa8618'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.85, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2014, 2, 1), id=UUID('bdc566bc-a362-4ef0-a30c-b2d7f1ece2dc'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.385, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2015, 2, 1), id=UUID('86a17661-4516-427b-b780-2a01a02ee248'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.672, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2016, 2, 1), id=UUID('ff35b841-0aa6-4219-a04a-e7516f996d19'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.108, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2017, 2, 1), id=UUID('0e0b64af-548f-40e4-99bc-969c9bd171d7'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.934, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2018, 2, 1), id=UUID('d3ee9290-507f-4896-8638-af1bd4e275d9'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-7.353, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2019, 2, 1), id=UUID('bf3b915c-25fa-4033-94b2-b5bb3d23d879'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.03, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2020, 2, 1), id=UUID('527990c6-00f2-4410-a852-d24c687d97db'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.433, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2021, 2, 1), id=UUID('6138ad4b-00c2-4431-addd-510b6ff16f56'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.675, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2022, 2, 1), id=UUID('fdcf195a-f21d-425c-b423-7b530aa1a500'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.621, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2023, 2, 1), id=UUID('d4ee7b92-bbdb-4e8b-b2a6-a41b8385610b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.731, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2024, 2, 1), id=UUID('20ca569b-c3be-413e-86f5-e16a7ac00346'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.294, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1987, 3, 1), id=UUID('5dbd93e6-9b12-440c-a3c5-192023d52f64'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-6.552, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1988, 3, 1), id=UUID('12a35164-e140-4da9-a98d-f508f21ed5b7'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.824, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1989, 3, 1), id=UUID('d2e81189-b422-4dc8-be7b-a96289507627'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.527, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1990, 3, 1), id=UUID('1540a46d-080e-42f1-91c9-ba14d1ce151a'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.903, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1991, 3, 1), id=UUID('ccc1a89c-7f98-4c5c-b5b8-b37a68afd3a2'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.611, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1992, 3, 1), id=UUID('b1be00be-b5d8-4318-bb6b-672848af12b5'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.327, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1993, 3, 1), id=UUID('40401c73-a278-4fae-8e70-7be44a0c05b1'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.725, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1994, 3, 1), id=UUID('dcea512e-347f-4bcc-9605-b3234646f33d'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=2.175, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1995, 3, 1), id=UUID('271ae6f3-64cc-4237-90f3-5d0b9334e68a'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.626, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1996, 3, 1), id=UUID('a5f45d08-4f4b-4671-bd63-357d0b0ebe7b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.929, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1997, 3, 1), id=UUID('f63fce08-d43c-4ab4-9b86-db98caae46be'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=1.293, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1998, 3, 1), id=UUID('3a2c5306-5283-450b-a1d7-35dbbe74125b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.795, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(1999, 3, 1), id=UUID('ab65207d-7cd4-4ac8-ac36-c3ce35571cdf'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-0.698, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2000, 3, 1), id=UUID('87857a78-7b53-4d0a-9f65-7d55b7d28457'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-0.537, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2001, 3, 1), id=UUID('a3d59359-f202-4e2e-9841-7a0f5095c9da'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.439, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2002, 3, 1), id=UUID('9bbd7327-24c3-437d-922e-ca53ad3f5872'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.567, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2003, 3, 1), id=UUID('688a1152-08de-46d4-80a6-ece7852f380b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=1.007, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2004, 3, 1), id=UUID('c1942d73-72b8-4e74-859a-be05f195f45e'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.205, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2005, 3, 1), id=UUID('b2e0aee0-0df2-474c-a98d-da1ef82ecad5'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.307, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2006, 3, 1), id=UUID('a06f53dc-f1af-47f2-b965-f794982ee146'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-3.633, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2007, 3, 1), id=UUID('50657e6c-ffd1-4268-b56d-030326b29835'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-0.684, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2008, 3, 1), id=UUID('e342d985-b658-4f0b-b480-a22b103cd8a2'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.245, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2009, 3, 1), id=UUID('d24cd8c1-b6e5-4bc0-bbd3-5709a9cc62b1'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.051, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2010, 3, 1), id=UUID('bfd745be-13a7-43a1-89f2-e690e2a26543'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.303, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2011, 3, 1), id=UUID('756776d5-0a11-4eed-8d3c-9bf270ce315c'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-0.555, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2012, 3, 1), id=UUID('36be712f-f79f-4985-98ff-0318030e80d5'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=2.592, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2013, 3, 1), id=UUID('15407d7b-92d5-4841-9059-bf5d8628ac89'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.656, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2014, 3, 1), id=UUID('aa34a622-4fd4-46c6-a096-e3ffadf030e6'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.866, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2015, 3, 1), id=UUID('646696ad-8835-422b-bf5a-cad05138d323'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-0.489, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2016, 3, 1), id=UUID('bc6b9c8a-d2f0-4de3-81ea-65269ff62c80'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.253, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2017, 3, 1), id=UUID('ae874ab9-1838-4b71-a483-69f3bc1e9f2e'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=1.928, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2018, 3, 1), id=UUID('3925aa0c-04df-4c9a-b74f-b5b3bfe34d7b'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-2.235, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2019, 3, 1), id=UUID('27f5dc24-413b-4543-9cc6-d2ff7477f1b8'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.07, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2020, 3, 1), id=UUID('6396bde9-5c9b-4110-a158-c182b1ce0b33'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.189, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2021, 3, 1), id=UUID('e056a69c-1d1a-4eff-b658-33e9f193a3c9'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.764, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2022, 3, 1), id=UUID('bc45051d-a819-4c2b-adf1-5a8b9bf6e088'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=-1.408, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2023, 3, 1), id=UUID('2d58d4b6-3bc3-4c8f-8261-16fa3b3fe261'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.522, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35')),\n", + " MonthlyMeasurement(date=datetime.date(2024, 3, 1), id=UUID('588b9a27-3800-43cc-ac62-43a419368a91'), variable_id=UUID('32706ce0-0134-4122-91a0-9d6f237350b3'), value=0.739, station_id=UUID('8d9e6fe2-b79d-448f-bf33-b4a9d9b17e35'))]" ] }, - "execution_count": 6, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "db.generate_coverage_identifiers(cov.configuration)" + "[m for m in station.monthly_measurements if m.date.month in (1, 2, 3) and m.variable.name == \"TDd\"]" ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "366393b0-cea5-4a2b-bd3a-13316b2c85d0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "tas_annual_absolute_model_ensemble-annual-model_ensemble-tas-absolute-rcp26-year tas_annual_absolute_model_ec_earth_cclm4_8_17-annual-ec_earth_cclm_4_8_17-tas-absolute-rcp26-year\n", - "----------\n", - "tas_annual_absolute_model_ensemble-annual-model_ensemble-tas-absolute-rcp26-year tas_annual_absolute_model_ec_earth_racmo22e-annual-ec_earth_racmo22e-tas-absolute-rcp26-year\n", - "----------\n", - "tas_annual_absolute_model_ensemble-annual-model_ensemble-tas-absolute-rcp26-year tas_annual_absolute_model_ec_earth_rca4-annual-ec_earth_rca4-tas-absolute-rcp26-year\n", - "----------\n", - "tas_annual_absolute_model_ensemble-annual-model_ensemble-tas-absolute-rcp26-year tas_annual_absolute_model_hadgem2_es_racmo22e-annual-hadgem2_racmo22e-tas-absolute-rcp26-year\n", - "----------\n", - "tas_annual_absolute_model_ensemble-annual-model_ensemble-tas-absolute-rcp26-year tas_annual_absolute_model_mpi_esm_lr_remo2009-annual-mpi_esm_lr_remo2009-tas-absolute-rcp26-year\n", - "----------\n" - ] - } - ], - "source": [ - "for related_cov in operations.get_related_coverages(cov):\n", - " print(cov.identifier, related_cov.identifier)\n", - " print(\"----------\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1b50e512-cff5-4f30-8576-9e2ea92a2948", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -241,7 +210,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.8" } }, "nbformat": 4, diff --git a/tests/test_observations_harvester_app.py b/tests/test_observations_harvester_app.py deleted file mode 100644 index 5247139a..00000000 --- a/tests/test_observations_harvester_app.py +++ /dev/null @@ -1,82 +0,0 @@ -import httpx - - -def test_refresh_monthly_measurements_with_new_measurement( - httpx_mock, - cli_runner, - cli_app, - sample_variables, - sample_stations, - sample_monthly_measurements, -): - target_station = sample_stations[0] - target_variable = sample_variables[0] - execution_args = [ - "observations-harvester", - "refresh-monthly-measurements", - "--station", - str(target_station.code), - "--variable", - target_variable.name, - ] - httpx_mock.add_response( - json={ - "data": [ - { - "valore": 2.23, - "anno": 2021, - }, - ], - }, - status_code=200, - ) - result = cli_runner.invoke(cli_app, execution_args) - print(f"{result.stdout=}") - print(f"{result.stderr=}") - assert result.exit_code == 0 - - -def test_refresh_monthly_measurements_with_existing_measurement( - httpx_mock, - cli_runner, - cli_app, - sample_variables, - sample_stations, - sample_monthly_measurements, -): - target_measurement = sample_monthly_measurements[0] - target_station = target_measurement.station - target_variable = target_measurement.variable - target_year = target_measurement.date.year - target_month = target_measurement.date.month - execution_args = [ - "observations-harvester", - "refresh-monthly-measurements", - "--station", - str(target_station.code), - "--variable", - target_variable.name, - ] - - def custom_response(request: httpx.Request) -> httpx.Response: - if request.url.params["periodo"] == str(target_month): - result_response = httpx.Response( - status_code=200, - json={ - "data": [ - { - "valore": 2.23, - "anno": target_year, - }, - ], - }, - ) - else: - result_response = httpx.Response(status_code=200, json={"data": []}) - return result_response - - httpx_mock.add_callback(custom_response) - - result = cli_runner.invoke(cli_app, execution_args) - assert result.exit_code == 0 - assert "Created 0 monthly measurements" in result.stdout diff --git a/tests/test_observations_harvester_operations.py b/tests/test_observations_harvester_operations.py new file mode 100644 index 00000000..2bd37660 --- /dev/null +++ b/tests/test_observations_harvester_operations.py @@ -0,0 +1,82 @@ +import datetime as dt +import re + +import httpx +import geojson_pydantic +import pyproj +import pytest + +from arpav_ppcv.observations_harvester import operations +from arpav_ppcv.schemas import observations + + +def test_fetch_remote_stations( + httpx_mock, + arpav_db_session, + sample_real_variables, +): + httpx_mock.add_response( + url=re.compile(r"https://api.arpa.veneto.it/REST/v1/.*"), + json={ + "data": [ + { + "EPSG4258_LAT": 46.59389393, + "EPSG4258_LON": 12.51561664, + "altitude": 1342.0, + "gaussx": 1769316.0, + "gaussy": 5166067.0, + "iniziovalidita": "1992-12-11", + "statcd": 247, + "statnm": "Casamazzagno", + } + ], + }, + status_code=200, + ) + with httpx.Client() as client: + fetched = list( + operations.fetch_remote_stations( + client, + sample_real_variables[0:1], + fetch_stations_with_months=True, + fetch_stations_with_seasons=False, + fetch_stations_with_yearly_measurements=False, + ) + ) + assert list(fetched)[0]["statcd"] == 247 + + +@pytest.mark.parametrize( + "raw_station, parsed", + [ + pytest.param( + { + "EPSG4258_LAT": 46.59389393, + "EPSG4258_LON": 12.51561664, + "altitude": 1342.0, + "gaussx": 1769316.0, + "gaussy": 5166067.0, + "iniziovalidita": "1992-12-11", + "statcd": 247, + "statnm": "Casamazzagno", + }, + observations.StationCreate( + code="247", + geom=geojson_pydantic.Point( + type="Point", coordinates=(12.51561664, 46.59389393) + ), + altitude_m=1342.0, + name="Casamazzagno", + active_since=dt.date(1992, 12, 11), + ), + ) + ], +) +def test_parse_station(raw_station, parsed): + result = operations.parse_station( + raw_station, + coord_converter=pyproj.Transformer.from_crs( + pyproj.CRS("epsg:4258"), pyproj.CRS("epsg:4326"), always_xy=True + ).transform, + ) + assert result == parsed