From fea1be0ece27f5c08c9f860981df061cb868db22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Fri, 28 Jun 2024 22:20:25 +0200 Subject: [PATCH 01/21] feat(observability): add infrastructure through mlflow system metrics --- poetry.lock | 2 +- pyproject.toml | 1 + src/bikes/io/services.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1d9fbc6..d34e3c1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3613,4 +3613,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "5432c9fb5ec1419c86ebb9206b2be48ed781783b4275b8eb49f12c7500bd29eb" +content-hash = "dcfed2c72f6261692167ceae4246fa0e49410fb86c8d4d66703342aa5cf7b9a5" diff --git a/pyproject.toml b/pyproject.toml index aeee5a2..b91c7cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ omegaconf = "^2.3.0" pandas = "^2.2.2" pandera = "^0.20.1" plotly = "^5.22.0" +psutil = "^6.0.0" pyarrow = "^15.0.2" pydantic = "^2.7.4" pydantic-settings = "^2.3.4" diff --git a/src/bikes/io/services.py b/src/bikes/io/services.py index 13736d6..4ef2822 100644 --- a/src/bikes/io/services.py +++ b/src/bikes/io/services.py @@ -112,7 +112,7 @@ class RunConfig(pdt.BaseModel, strict=True, frozen=True, extra="forbid"): name: str description: str | None = None tags: dict[str, T.Any] | None = None - log_system_metrics: bool | None = None + log_system_metrics: bool | None = True # server uri tracking_uri: str = "./mlruns" From c47892ebae7197f96130bb38ec002e4c86226496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 29 Jun 2024 08:05:14 +0200 Subject: [PATCH 02/21] feat(observability): add alerting with plyer notifications --- poetry.lock | 19 ++++++++++++++++++- pyproject.toml | 1 + src/bikes/io/services.py | 37 +++++++++++++++++++++++++++++++++++++ src/bikes/jobs/base.py | 6 ++++++ src/bikes/jobs/inference.py | 3 +++ src/bikes/jobs/promotion.py | 4 ++++ src/bikes/jobs/training.py | 3 +++ src/bikes/jobs/tuning.py | 3 +++ tests/conftest.py | 9 +++++++++ tests/io/test_services.py | 9 +++++++++ 10 files changed, 93 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index d34e3c1..1b12a34 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2192,6 +2192,23 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "plyer" +version = "2.1.0" +description = "Platform-independent wrapper for platform-dependent APIs" +optional = false +python-versions = "*" +files = [ + {file = "plyer-2.1.0-py2.py3-none-any.whl", hash = "sha256:1b1772060df8b3045ed4f08231690ec8f7de30f5a004aa1724665a9074eed113"}, + {file = "plyer-2.1.0.tar.gz", hash = "sha256:65b7dfb7e11e07af37a8487eb2aa69524276ef70dad500b07228ce64736baa61"}, +] + +[package.extras] +android = ["pyjnius"] +dev = ["flake8", "mock"] +ios = ["pyobjus"] +macosx = ["pyobjus"] + [[package]] name = "pre-commit" version = "3.7.1" @@ -3613,4 +3630,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "dcfed2c72f6261692167ceae4246fa0e49410fb86c8d4d66703342aa5cf7b9a5" +content-hash = "96373f3f154c1afbf1b8cb835a227dd1b31ba98e27fd47fc99a1c80f00f81ab0" diff --git a/pyproject.toml b/pyproject.toml index b91c7cd..fdb3f93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ omegaconf = "^2.3.0" pandas = "^2.2.2" pandera = "^0.20.1" plotly = "^5.22.0" +plyer = "^2.1.0" psutil = "^6.0.0" pyarrow = "^15.0.2" pydantic = "^2.7.4" diff --git a/src/bikes/io/services.py b/src/bikes/io/services.py index 4ef2822..02d5c21 100644 --- a/src/bikes/io/services.py +++ b/src/bikes/io/services.py @@ -13,6 +13,7 @@ import mlflow import mlflow.tracking as mt import pydantic as pdt +from plyer import notification # %% SERVICES @@ -81,6 +82,42 @@ def logger(self) -> loguru.Logger: return loguru.logger +class NotificationService(Service): + """Service for sending notifications. + + Require libnotify-bin on Linux systems. + + In production, use with Slack, Discord, or emails. + + https://plyer.readthedocs.io/en/latest/api.html#plyer.facades.Notification + + Parameters: + app_name (str): name of the application. + timeout (int | None): timeout in seconds. + """ + + app_name: str = "Bikes" + timeout: int | None = None + + @T.override + def start(self) -> None: + pass + + def notify(self, title: str, message: str) -> None: + """Send a notification to the system. + + Args: + title (str): title of the notification. + message (str): message of the notification. + """ + try: + notification.notify( + title=title, message=message, app_name=self.app_name, timeout=self.timeout + ) + except NotImplementedError: + print(f"{title}: {message}") + + class MlflowService(Service): """Service for Mlflow tracking and registry. diff --git a/src/bikes/jobs/base.py b/src/bikes/jobs/base.py index 7e7406c..edf0c17 100644 --- a/src/bikes/jobs/base.py +++ b/src/bikes/jobs/base.py @@ -26,12 +26,14 @@ class Job(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): Parameters: logger_service (services.LoggerService): manage the logging system. + notification_service (services.NotificationService): manage the notification_system. mlflow_service (services.MlflowService): manage the mlflow system. """ KIND: str logger_service: services.LoggerService = services.LoggerService() + notification_service: services.NotificationService = services.NotificationService() mlflow_service: services.MlflowService = services.MlflowService() def __enter__(self) -> T.Self: @@ -43,6 +45,8 @@ def __enter__(self) -> T.Self: self.logger_service.start() logger = self.logger_service.logger() logger.debug("[START] Logger service: {}", self.logger_service) + self.notification_service.start() + logger.debug("[START] Notification service: {}", self.notification_service) logger.debug("[START] Mlflow service: {}", self.mlflow_service) self.mlflow_service.start() return self @@ -66,6 +70,8 @@ def __exit__( logger = self.logger_service.logger() logger.debug("[STOP] Mlflow service: {}", self.mlflow_service) self.mlflow_service.stop() + logger.debug("[STOP] Notification service: {}", self.notification_service) + self.notification_service.stop() logger.debug("[STOP] Logger service: {}", self.logger_service) self.logger_service.stop() return False # re-raise diff --git a/src/bikes/jobs/inference.py b/src/bikes/jobs/inference.py index 2f7cc83..aca9a9b 100644 --- a/src/bikes/jobs/inference.py +++ b/src/bikes/jobs/inference.py @@ -61,4 +61,7 @@ def run(self) -> base.Locals: # write logger.info("Write outputs: {}", self.outputs) self.outputs.write(outputs) + self.notification_service.notify( + title="Inference Job Finished", message=f"Outputs Shape: {outputs.shape}" + ) return locals() diff --git a/src/bikes/jobs/promotion.py b/src/bikes/jobs/promotion.py index 85f4891..4e3c769 100644 --- a/src/bikes/jobs/promotion.py +++ b/src/bikes/jobs/promotion.py @@ -49,4 +49,8 @@ def run(self) -> base.Locals: client.set_registered_model_alias(name=name, alias=self.alias, version=version) model_version = client.get_model_version_by_alias(name=name, alias=self.alias) logger.debug("- Model version: {}", model_version) + self.notification_service.notify( + title="Promotion Job Finished", + message=f"Version: {model_version.version} @ {self.alias}", + ) return locals() diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index b245787..6063497 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -117,4 +117,7 @@ def run(self) -> base.Locals: name=self.mlflow_service.registry_name, model_uri=model_info.model_uri ) logger.debug("- Model version: {}", model_version) + self.notification_service.notify( + title="Training Job Finished", message=f"Model version: {model_version.version}" + ) return locals() diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index a5a3091..b030dbb 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -91,4 +91,7 @@ def run(self) -> base.Locals: logger.debug("- Results: {}", results.shape) logger.debug("- Best Score: {}", best_score) logger.debug("- Best Params: {}", best_params) + self.notification_service.notify( + title="Tuning Job Finished", message=f"Best score: {best_score}" + ) return locals() diff --git a/tests/conftest.py b/tests/conftest.py index 9c8c4c9..55c4fed 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -244,6 +244,15 @@ def logger_caplog( logger.remove(handler_id) +@pytest.fixture(scope="session", autouse=True) +def notification_service() -> T.Generator[services.NotificationService, None, None]: + """Return and start the notification service.""" + service = services.NotificationService() + service.start() + yield service + service.stop() + + @pytest.fixture(scope="function", autouse=True) def mlflow_service(tmp_path: str) -> T.Generator[services.MlflowService, None, None]: """Return and start the mlflow service.""" diff --git a/tests/io/test_services.py b/tests/io/test_services.py index dca2ae7..cb83e53 100644 --- a/tests/io/test_services.py +++ b/tests/io/test_services.py @@ -21,6 +21,15 @@ def test_logger_service( assert "ERROR" in logger_caplog.messages, "Error message should be logged!" +def test_notification_service(notification_service: services.NotificationService) -> None: + # given + service = notification_service + # when + result = service.notify(title="hello", message="world") + # then + assert result is None, "Notification should be sent!" + + def test_mlflow_service(mlflow_service: services.MlflowService) -> None: # given service = mlflow_service From d6ca5a3824924666566da47cc878bb8dac6424f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 6 Jul 2024 14:01:17 +0200 Subject: [PATCH 03/21] feat(notification): add service and alerts with plyer --- poetry.lock | 19 ++++++++++++++++++- pyproject.toml | 1 + src/bikes/io/services.py | 12 +++++++----- src/bikes/jobs/base.py | 12 ++++++------ src/bikes/jobs/inference.py | 2 +- src/bikes/jobs/promotion.py | 2 +- src/bikes/jobs/training.py | 2 +- src/bikes/jobs/tuning.py | 2 +- tests/conftest.py | 9 ++++++--- tests/io/test_services.py | 28 ++++++++++++++++++++++++---- tests/jobs/test_base.py | 1 + tests/jobs/test_inference.py | 8 +++++++- tests/jobs/test_promotion.py | 8 +++++++- tests/jobs/test_training.py | 8 +++++++- tests/jobs/test_tuning.py | 8 +++++++- 15 files changed, 95 insertions(+), 27 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1b12a34..4f0dbc6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2569,6 +2569,23 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] +[[package]] +name = "pytest-mock" +version = "3.14.0" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, + {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, +] + +[package.dependencies] +pytest = ">=6.2.5" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + [[package]] name = "pytest-xdist" version = "3.6.1" @@ -3630,4 +3647,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "96373f3f154c1afbf1b8cb835a227dd1b31ba98e27fd47fc99a1c80f00f81ab0" +content-hash = "42384c2241c38a374188caa03b637026c055f46a7ebc8ed13749b19faa721ee0" diff --git a/pyproject.toml b/pyproject.toml index fdb3f93..e2fab7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ pytest-cov = "^5.0.0" pytest-xdist = "^3.6.1" pandera = { extras = ["mypy"], version = "^0.20.1" } ruff = "^0.5.0" +pytest-mock = "^3.14.0" [tool.poetry.group.commits.dependencies] commitizen = "^3.27.0" diff --git a/src/bikes/io/services.py b/src/bikes/io/services.py index 02d5c21..f5c289d 100644 --- a/src/bikes/io/services.py +++ b/src/bikes/io/services.py @@ -82,7 +82,7 @@ def logger(self) -> loguru.Logger: return loguru.logger -class NotificationService(Service): +class AlerterService(Service): """Service for sending notifications. Require libnotify-bin on Linux systems. @@ -92,10 +92,12 @@ class NotificationService(Service): https://plyer.readthedocs.io/en/latest/api.html#plyer.facades.Notification Parameters: + enable (bool): use notifications or print. app_name (str): name of the application. - timeout (int | None): timeout in seconds. + timeout (int | None): timeout in secs. """ + enable: bool = True app_name: str = "Bikes" timeout: int | None = None @@ -110,12 +112,12 @@ def notify(self, title: str, message: str) -> None: title (str): title of the notification. message (str): message of the notification. """ - try: + if self.enable: notification.notify( title=title, message=message, app_name=self.app_name, timeout=self.timeout ) - except NotImplementedError: - print(f"{title}: {message}") + else: + print(f"[{self.app_name}] {title}: {message}") class MlflowService(Service): diff --git a/src/bikes/jobs/base.py b/src/bikes/jobs/base.py index edf0c17..77c74d4 100644 --- a/src/bikes/jobs/base.py +++ b/src/bikes/jobs/base.py @@ -26,14 +26,14 @@ class Job(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): Parameters: logger_service (services.LoggerService): manage the logging system. - notification_service (services.NotificationService): manage the notification_system. + alerter_service (services.AlerterService): manage the alert system. mlflow_service (services.MlflowService): manage the mlflow system. """ KIND: str logger_service: services.LoggerService = services.LoggerService() - notification_service: services.NotificationService = services.NotificationService() + alerter_service: services.AlerterService = services.AlerterService() mlflow_service: services.MlflowService = services.MlflowService() def __enter__(self) -> T.Self: @@ -45,8 +45,8 @@ def __enter__(self) -> T.Self: self.logger_service.start() logger = self.logger_service.logger() logger.debug("[START] Logger service: {}", self.logger_service) - self.notification_service.start() - logger.debug("[START] Notification service: {}", self.notification_service) + self.alerter_service.start() + logger.debug("[START] Alerter service: {}", self.alerter_service) logger.debug("[START] Mlflow service: {}", self.mlflow_service) self.mlflow_service.start() return self @@ -70,8 +70,8 @@ def __exit__( logger = self.logger_service.logger() logger.debug("[STOP] Mlflow service: {}", self.mlflow_service) self.mlflow_service.stop() - logger.debug("[STOP] Notification service: {}", self.notification_service) - self.notification_service.stop() + logger.debug("[STOP] Alerter service: {}", self.alerter_service) + self.alerter_service.stop() logger.debug("[STOP] Logger service: {}", self.logger_service) self.logger_service.stop() return False # re-raise diff --git a/src/bikes/jobs/inference.py b/src/bikes/jobs/inference.py index aca9a9b..5a089be 100644 --- a/src/bikes/jobs/inference.py +++ b/src/bikes/jobs/inference.py @@ -61,7 +61,7 @@ def run(self) -> base.Locals: # write logger.info("Write outputs: {}", self.outputs) self.outputs.write(outputs) - self.notification_service.notify( + self.alerter_service.notify( title="Inference Job Finished", message=f"Outputs Shape: {outputs.shape}" ) return locals() diff --git a/src/bikes/jobs/promotion.py b/src/bikes/jobs/promotion.py index 4e3c769..0a9c772 100644 --- a/src/bikes/jobs/promotion.py +++ b/src/bikes/jobs/promotion.py @@ -49,7 +49,7 @@ def run(self) -> base.Locals: client.set_registered_model_alias(name=name, alias=self.alias, version=version) model_version = client.get_model_version_by_alias(name=name, alias=self.alias) logger.debug("- Model version: {}", model_version) - self.notification_service.notify( + self.alerter_service.notify( title="Promotion Job Finished", message=f"Version: {model_version.version} @ {self.alias}", ) diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index 6063497..e885a2b 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -117,7 +117,7 @@ def run(self) -> base.Locals: name=self.mlflow_service.registry_name, model_uri=model_info.model_uri ) logger.debug("- Model version: {}", model_version) - self.notification_service.notify( + self.alerter_service.notify( title="Training Job Finished", message=f"Model version: {model_version.version}" ) return locals() diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index b030dbb..6cfc4d3 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -91,7 +91,7 @@ def run(self) -> base.Locals: logger.debug("- Results: {}", results.shape) logger.debug("- Best Score: {}", best_score) logger.debug("- Best Params: {}", best_params) - self.notification_service.notify( + self.alerter_service.notify( title="Tuning Job Finished", message=f"Best score: {best_score}" ) return locals() diff --git a/tests/conftest.py b/tests/conftest.py index 55c4fed..7744a22 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -77,6 +77,9 @@ def extra_config() -> str: config = """ { "job": { + "alerter_service": { + "enable": false, + }, "mlflow_service": { "tracking_uri": "${tmp_path:}/tracking/", "registry_uri": "${tmp_path:}/registry/", @@ -245,9 +248,9 @@ def logger_caplog( @pytest.fixture(scope="session", autouse=True) -def notification_service() -> T.Generator[services.NotificationService, None, None]: - """Return and start the notification service.""" - service = services.NotificationService() +def alerter_service() -> T.Generator[services.AlerterService, None, None]: + """Return and start the alerter service.""" + service = services.AlerterService(enable=False) service.start() yield service service.stop() diff --git a/tests/io/test_services.py b/tests/io/test_services.py index cb83e53..acc684c 100644 --- a/tests/io/test_services.py +++ b/tests/io/test_services.py @@ -1,7 +1,11 @@ # %% IMPORTS + +import _pytest.capture as pc import _pytest.logging as pl import mlflow +import pytest +import pytest_mock as pm from bikes.io import services # %% SERVICES @@ -21,13 +25,29 @@ def test_logger_service( assert "ERROR" in logger_caplog.messages, "Error message should be logged!" -def test_notification_service(notification_service: services.NotificationService) -> None: +@pytest.mark.parametrize("enable", [True, False]) +def test_alerter_service( + enable: bool, mocker: pm.MockerFixture, capsys: pc.CaptureFixture[str] +) -> None: + import plyer + # given - service = notification_service + service = services.AlerterService(enable=enable) + mocker.patch("plyer.notification.notify") # when - result = service.notify(title="hello", message="world") + service.notify(title="test", message="hello") # then - assert result is None, "Notification should be sent!" + if enable: + plyer.notification.notify.assert_called_once(), "Notification method should be called!" + assert capsys.readouterr().out == "", "Notification should not be printed to stdout!" + else: + ( + plyer.notification.notify.assert_not_called(), + "Notification method should not be called!", + ) + assert ( + capsys.readouterr().out == "[Bikes] test: hello\n" + ), "Notification should be printed to stdout!" def test_mlflow_service(mlflow_service: services.MlflowService) -> None: diff --git a/tests/jobs/test_base.py b/tests/jobs/test_base.py index 2bb2648..a9f9ca9 100644 --- a/tests/jobs/test_base.py +++ b/tests/jobs/test_base.py @@ -25,5 +25,6 @@ def run(self) -> base.Locals: # - inputs assert hasattr(job, "logger_service"), "Job should have an Logger service!" assert hasattr(job, "mlflow_service"), "Job should have an Mlflow service!" + assert hasattr(job, "alerter_service"), "Job should have a alerter service!" # - outputs assert set(out) == {"self", "a", "b"}, "Run should return local variables!" diff --git a/tests/jobs/test_inference.py b/tests/jobs/test_inference.py index ef721e6..28c569b 100644 --- a/tests/jobs/test_inference.py +++ b/tests/jobs/test_inference.py @@ -1,6 +1,7 @@ # %% IMPORTS +import _pytest.capture as pc from bikes import jobs from bikes.io import datasets, registries, services @@ -9,19 +10,22 @@ def test_inference_job( mlflow_service: services.MlflowService, + alerter_service: services.AlerterService, logger_service: services.LoggerService, inputs_reader: datasets.Reader, tmp_outputs_writer: datasets.Writer, model_alias: registries.Version, loader: registries.Loader, + capsys: pc.CaptureFixture[str], ) -> None: # given assert len(model_alias.aliases) == 1, "Model should have one alias!" alias = model_alias.aliases[0] # when job = jobs.InferenceJob( - mlflow_service=mlflow_service, logger_service=logger_service, + alerter_service=alerter_service, + mlflow_service=mlflow_service, inputs=inputs_reader, outputs=tmp_outputs_writer, alias=alias, @@ -57,3 +61,5 @@ def test_inference_job( ), "Model should have a pyfunc flavor!" # - outputs assert out["outputs"].ndim == 2, "Outputs should be a dataframe!" + # - alerting service + assert "Inference Job Finished" in capsys.readouterr().out, "Alerting service should be called!" diff --git a/tests/jobs/test_promotion.py b/tests/jobs/test_promotion.py index 9b8322b..1c0d5e3 100644 --- a/tests/jobs/test_promotion.py +++ b/tests/jobs/test_promotion.py @@ -1,5 +1,6 @@ # %% IMPORTS +import _pytest.capture as pc import mlflow import pytest from bikes import jobs @@ -25,15 +26,18 @@ def test_promotion_job( version: int | None, mlflow_service: services.MlflowService, + alerter_service: services.AlerterService, logger_service: services.LoggerService, model_version: registries.Version, + capsys: pc.CaptureFixture[str], ) -> None: # given alias = "Testing" # when job = jobs.PromotionJob( - mlflow_service=mlflow_service, logger_service=logger_service, + alerter_service=alerter_service, + mlflow_service=mlflow_service, version=version, alias=alias, ) @@ -64,3 +68,5 @@ def test_promotion_job( assert out["model_version"].aliases == [ alias ], "Model version aliases should contain the given alias!" + # - alerting service + assert "Promotion Job Finished" in capsys.readouterr().out, "Alerting service should be called!" diff --git a/tests/jobs/test_training.py b/tests/jobs/test_training.py index 0c73f46..fbcbc40 100644 --- a/tests/jobs/test_training.py +++ b/tests/jobs/test_training.py @@ -1,5 +1,6 @@ # %% IMPORTS +import _pytest.capture as pc from bikes import jobs from bikes.core import metrics, models from bikes.io import datasets, registries, services @@ -10,6 +11,7 @@ def test_training_job( mlflow_service: services.MlflowService, + alerter_service: services.AlerterService, logger_service: services.LoggerService, inputs_reader: datasets.Reader, targets_reader: datasets.Reader, @@ -19,6 +21,7 @@ def test_training_job( saver: registries.Saver, signer: signers.Signer, register: registries.Register, + capsys: pc.CaptureFixture[str], ) -> None: # given run_config = mlflow_service.RunConfig( @@ -28,8 +31,9 @@ def test_training_job( client = mlflow_service.client() # when job = jobs.TrainingJob( - mlflow_service=mlflow_service, logger_service=logger_service, + alerter_service=alerter_service, + mlflow_service=mlflow_service, run_config=run_config, inputs=inputs_reader, targets=targets_reader, @@ -138,3 +142,5 @@ def test_training_job( assert ( model_version.run_id == out["run"].info.run_id ), "MLFlow model version run id should be the same!" + # - alerting service + assert "Training Job Finished" in capsys.readouterr().out, "Alerting service should be called!" diff --git a/tests/jobs/test_tuning.py b/tests/jobs/test_tuning.py index cf7e0cf..47c6018 100644 --- a/tests/jobs/test_tuning.py +++ b/tests/jobs/test_tuning.py @@ -1,5 +1,6 @@ # %% IMPORTS +import _pytest.capture as pc from bikes import jobs from bikes.core import metrics, models from bikes.io import datasets, services @@ -10,6 +11,7 @@ def test_tuning_job( mlflow_service: services.MlflowService, + alerter_service: services.AlerterService, logger_service: services.LoggerService, inputs_reader: datasets.Reader, targets_reader: datasets.Reader, @@ -17,6 +19,7 @@ def test_tuning_job( metric: metrics.Metric, time_series_splitter: splitters.Splitter, searcher: searchers.Searcher, + capsys: pc.CaptureFixture[str], ) -> None: # given run_config = mlflow_service.RunConfig( @@ -26,8 +29,9 @@ def test_tuning_job( client = mlflow_service.client() # when job = jobs.TuningJob( - mlflow_service=mlflow_service, logger_service=logger_service, + alerter_service=alerter_service, + mlflow_service=mlflow_service, run_config=run_config, inputs=inputs_reader, targets=targets_reader, @@ -79,3 +83,5 @@ def test_tuning_job( ), "Mlflow experiment name should be the same!" runs = client.search_runs(experiment_ids=experiment.experiment_id) assert len(runs) == len(out["results"]) + 1, "Mlflow should have 1 run per result + parent!" + # - alerting service + assert "Tuning Job Finished" in capsys.readouterr().out, "Alerting service should be called!" From 28b56efd6761020d9f98f9f9566012d6b07b7522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 6 Jul 2024 17:30:50 +0200 Subject: [PATCH 04/21] feat(data): add train, test, and sample data --- README.md | 8 +- confs/inference.yaml | 4 +- confs/training.yaml | 4 +- confs/tuning.yaml | 4 +- data/inputs.parquet | Bin 223410 -> 0 bytes data/targets.parquet | Bin 129662 -> 0 bytes notebooks/process.ipynb | 135 ++++++++++++++++++++-------- tests/confs/valid/1. tuning.yaml | 4 +- tests/confs/valid/2. training.yaml | 4 +- tests/confs/valid/4. inference.yaml | 4 +- tests/conftest.py | 24 +++-- tests/data/inputs.parquet | Bin 223410 -> 0 bytes tests/data/outputs.parquet | Bin 129472 -> 0 bytes tests/data/targets.parquet | Bin 129662 -> 0 bytes 14 files changed, 131 insertions(+), 60 deletions(-) delete mode 100644 data/inputs.parquet delete mode 100644 data/targets.parquet delete mode 100644 tests/data/inputs.parquet delete mode 100644 tests/data/outputs.parquet delete mode 100644 tests/data/targets.parquet diff --git a/README.md b/README.md index cfcaa27..07b0dcd 100644 --- a/README.md +++ b/README.md @@ -150,10 +150,10 @@ job: KIND: TrainingJob inputs: KIND: ParquetReader - path: data/inputs.parquet + path: data/inputs_train.parquet targets: KIND: ParquetReader - path: data/targets.parquet + path: data/targets_train.parquet ``` This config file instructs the program to start a `TrainingJob` with 2 parameters: @@ -736,10 +736,10 @@ This tag can then be associated to a reader/writer implementation in a configura ```yaml inputs: KIND: ParquetReader - path: data/inputs.parquet + path: data/inputs_train.parquet targets: KIND: ParquetReader - path: data/targets.parquet + path: data/targets_train.parquet ``` In this package, the implementation are described in `src/[package]/io/datasets.py` and selected by `KIND`. diff --git a/confs/inference.yaml b/confs/inference.yaml index 0aa6c2f..38febbc 100644 --- a/confs/inference.yaml +++ b/confs/inference.yaml @@ -2,7 +2,7 @@ job: KIND: InferenceJob inputs: KIND: ParquetReader - path: data/inputs.parquet + path: data/inputs_test.parquet outputs: KIND: ParquetWriter - path: outputs/predictions.parquet + path: outputs/predictions_test.parquet diff --git a/confs/training.yaml b/confs/training.yaml index ca80fdc..e037286 100644 --- a/confs/training.yaml +++ b/confs/training.yaml @@ -2,7 +2,7 @@ job: KIND: TrainingJob inputs: KIND: ParquetReader - path: data/inputs.parquet + path: data/inputs_train.parquet targets: KIND: ParquetReader - path: data/targets.parquet + path: data/targets_train.parquet diff --git a/confs/tuning.yaml b/confs/tuning.yaml index 920a3ec..f09fba8 100644 --- a/confs/tuning.yaml +++ b/confs/tuning.yaml @@ -2,7 +2,7 @@ job: KIND: TuningJob inputs: KIND: ParquetReader - path: data/inputs.parquet + path: data/inputs_train.parquet targets: KIND: ParquetReader - path: data/targets.parquet + path: data/targets_train.parquet diff --git a/data/inputs.parquet b/data/inputs.parquet deleted file mode 100644 index 1cdbbad284ea9b2499110700b8fb6cb99d85b6b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 223410 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�wXaBqmha+5TJk( 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�wXaBqmha+5TJk(X-LOdjKg@S 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 j6!qS#g~9XJiSPN#k|6L|;N%4UIX#==v7 diff --git a/notebooks/process.ipynb b/notebooks/process.ipynb index e13f0d5..27c0461 100644 --- a/notebooks/process.ipynb +++ b/notebooks/process.ipynb @@ -4,9 +4,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "1. **Extract** inputs data from CSV files.\n", + "1. **Extract** all data from CSV files.\n", "2. **Transform** data into inputs/targets.\n", - "3. **Load** outputs data into parquet files." + "3. **Split** inputs/targets into train/test sets.\n", + "4. **Sample** inputs/targets for the testing sets.\n", + "5. **Load** outputs inputs/targets to parquet files." ] }, { @@ -22,7 +24,8 @@ "metadata": {}, "outputs": [], "source": [ - "import pandas as pd" + "import pandas as pd\n", + "from sklearn.model_selection import train_test_split" ] }, { @@ -69,7 +72,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Load" + "# Split" ] }, { @@ -78,27 +81,58 @@ "metadata": {}, "outputs": [], "source": [ - "INPUTS_FILE = \"../data/inputs.parquet\"\n", - "TARGETS_FILE = \"../data/targets.parquet\"" + "SHUFFLE = False # time-sensitive\n", + "TEST_SIZE = 0.2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# EXTRACT" + "# Sample" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "SAMPLE_RATIO = 0.15\n", + "SAMPLE_RANDOM_STATE = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Hour" + "## Load" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "INPUTS_TRAIN_FILE = \"../data/inputs_train.parquet\"\n", + "INPUTS_TEST_FILE = \"../data/inputs_test.parquet\"\n", + "TARGETS_TRAIN_FILE = \"../data/targets_train.parquet\"\n", + "TARGETS_TEST_FILE = \"../data/targets_test.parquet\"\n", + "INPUTS_SAMPLE_FILE = \"../tests/data/inputs_sample.parquet\"\n", + "TARGETS_SAMPLE_FILE = \"../tests/data/targets_sample.parquet\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# EXTRACT" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -284,7 +318,7 @@ "5 1 0.24 0.2879 0.75 0.0 0 1 1 " ] }, - "execution_count": 5, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -302,16 +336,9 @@ "# TRANFORM" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Inputs" - ] - }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -490,7 +517,7 @@ "5 1 0.24 0.2879 0.75 0.0 0 1 " ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -501,16 +528,9 @@ "inputs.head()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Targets" - ] - }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -583,7 +603,7 @@ "5 1" ] }, - "execution_count": 7, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -598,39 +618,80 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# LOAD" + "# SPLIT" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((13903, 15), (3476, 15), (13903, 1), (3476, 1))" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inputs_train, inputs_test, targets_train, targets_test = train_test_split(\n", + " inputs, targets, test_size=TEST_SIZE, shuffle=SHUFFLE\n", + ")\n", + "inputs_train.shape, inputs_test.shape, targets_train.shape, targets_test.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Inputs" + "# SAMPLE" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "((2085, 15), (2085, 1))" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "inputs.to_parquet(INPUTS_FILE)" + "inputs_train_sample = inputs_train.sample(frac=SAMPLE_RATIO, random_state=SAMPLE_RANDOM_STATE)\n", + "targets_train_sample = targets_train.sample(frac=SAMPLE_RATIO, random_state=SAMPLE_RANDOM_STATE)\n", + "inputs_train_sample.shape, targets_train_sample.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Targets" + "# LOAD" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ - "targets.to_parquet(TARGETS_FILE)" + "inputs_train.to_parquet(INPUTS_TRAIN_FILE)\n", + "inputs_test.to_parquet(INPUTS_TEST_FILE)\n", + "targets_train.to_parquet(TARGETS_TRAIN_FILE)\n", + "targets_test.to_parquet(TARGETS_TEST_FILE)\n", + "inputs_train_sample.to_parquet(INPUTS_SAMPLE_FILE)\n", + "targets_train_sample.to_parquet(TARGETS_SAMPLE_FILE)" ] } ], @@ -650,7 +711,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.12.2" } }, "nbformat": 4, diff --git a/tests/confs/valid/1. tuning.yaml b/tests/confs/valid/1. tuning.yaml index 41b391d..b76fe0b 100644 --- a/tests/confs/valid/1. tuning.yaml +++ b/tests/confs/valid/1. tuning.yaml @@ -2,11 +2,11 @@ job: KIND: TuningJob inputs: KIND: ParquetReader - path: "${tests_path:}/data/inputs.parquet" + path: "${tests_path:}/data/inputs_sample.parquet" limit: 1500 targets: KIND: ParquetReader - path: "${tests_path:}/data/targets.parquet" + path: "${tests_path:}/data/targets_sample.parquet" limit: 1500 splitter: KIND: TimeSeriesSplitter diff --git a/tests/confs/valid/2. training.yaml b/tests/confs/valid/2. training.yaml index f1849a3..86ea35a 100644 --- a/tests/confs/valid/2. training.yaml +++ b/tests/confs/valid/2. training.yaml @@ -2,9 +2,9 @@ job: KIND: TrainingJob inputs: KIND: ParquetReader - path: "${tests_path:}/data/inputs.parquet" + path: "${tests_path:}/data/inputs_sample.parquet" limit: 1500 targets: KIND: ParquetReader - path: "${tests_path:}/data/targets.parquet" + path: "${tests_path:}/data/targets_sample.parquet" limit: 1500 diff --git a/tests/confs/valid/4. inference.yaml b/tests/confs/valid/4. inference.yaml index 5295dc6..061b7f1 100644 --- a/tests/confs/valid/4. inference.yaml +++ b/tests/confs/valid/4. inference.yaml @@ -2,8 +2,8 @@ job: KIND: InferenceJob inputs: KIND: ParquetReader - path: "${tests_path:}/data/inputs.parquet" + path: "${tests_path:}/data/inputs_sample.parquet" limit: 1500 outputs: KIND: ParquetWriter - path: "${tmp_path:}/outputs.parquet" + path: "${tmp_path:}/outputs_sample.parquet" diff --git a/tests/conftest.py b/tests/conftest.py index 7744a22..cc52fae 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -46,19 +46,19 @@ def confs_path(tests_path: str) -> str: @pytest.fixture(scope="session") def inputs_path(data_path: str) -> str: """Return the path of the inputs dataset.""" - return os.path.join(data_path, "inputs.parquet") + return os.path.join(data_path, "inputs_sample.parquet") @pytest.fixture(scope="session") def targets_path(data_path: str) -> str: """Return the path of the targets dataset.""" - return os.path.join(data_path, "targets.parquet") + return os.path.join(data_path, "targets_sample.parquet") @pytest.fixture(scope="session") def outputs_path(data_path: str) -> str: """Return the path of the outputs dataset.""" - return os.path.join(data_path, "outputs.parquet") + return os.path.join(data_path, "outputs_sample.parquet") @pytest.fixture(scope="function") @@ -96,19 +96,29 @@ def extra_config() -> str: @pytest.fixture(scope="session") def inputs_reader(inputs_path: str) -> datasets.ParquetReader: """Return a reader for the inputs dataset.""" - return datasets.ParquetReader(path=inputs_path) + return datasets.ParquetReader(path=inputs_path, limit=LIMIT) @pytest.fixture(scope="session") def targets_reader(targets_path: str) -> datasets.ParquetReader: """Return a reader for the targets dataset.""" - return datasets.ParquetReader(path=targets_path) + return datasets.ParquetReader(path=targets_path, limit=LIMIT) @pytest.fixture(scope="session") -def outputs_reader(outputs_path: str) -> datasets.ParquetReader: +def outputs_reader( + outputs_path: str, inputs_reader: datasets.ParquetReader, targets_reader: datasets.ParquetReader +) -> datasets.ParquetReader: """Return a reader for the outputs dataset.""" - return datasets.ParquetReader(path=outputs_path) + # generate outputs if it is missing + if not os.path.exists(outputs_path): + inputs = schemas.InputsSchema.check(inputs_reader.read()) + targets = schemas.TargetsSchema.check(targets_reader.read()) + model = models.BaselineSklearnModel().fit(inputs=inputs, targets=targets) + outputs = schemas.OutputsSchema.check(model.predict(inputs=inputs)) + outputs_writer = datasets.ParquetWriter(path=outputs_path) + outputs_writer.write(data=outputs) + return datasets.ParquetReader(path=outputs_path, limit=LIMIT) @pytest.fixture(scope="function") diff --git a/tests/data/inputs.parquet b/tests/data/inputs.parquet deleted file mode 100644 index 1cdbbad284ea9b2499110700b8fb6cb99d85b6b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 223410 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�wXaBqmha+5TJk( zX-LOdjKg@SFaZ-W36n7e8JLPpOv7}{z)XCJS(ptq=3p-7VLlch3k#uv7CPu*fDzfq zK`!!;j{+285sI)F#aM!+Scc_Tft6T=60F7=ti?L4M=8ES88%=eHeoZiU@Nx4gs-t3 zJFpYGP>$WGz#iE1u#Rp5r&X zz)QTsYrMhl_yccIhj;iBf8jm;#s~aE{w>|e|M_mV{Bt~dARax@3km3rKIn^n=#K$N z#6Tor5Rx$%DHwvG7zR0pV+2NG6hvcx z3ME*LHCT&vSdUVCg)(fwMr^`nY{6D+g9%?_J9c0vcA*@*QGq?!i+$LS12~97sKj9$ z!8bUHW2nM$m|?*QoWv=d#u=Q&Ih@A@e2a^?glb&I68hnr2_yKqD zBWm#z?&2Qq;{hJx5gy}bSn&kE;8#4wGd#y{c!8IAh1Yn4-|+|Dq7LuyC;q~F{EZLz zhx{K-Ape#GTmCs7JrIwc=!FFIMj!M=KlH}{Bw`?vFbK&Qj1&yPPz-|{!!ZIQF$$xR ziZKwNfD&m)$5@QRc&IP|6EO*sF$EczicCzybj-j^e2H0@4K?OqF6LoA79a}?p@9}U z=wW~n*~mdI@{o@L6k-vIuo%Tyf~8o75~DC0sTczR3Mi3=bd1F~jE4#nFcFh58B>sf zsmR1MOven&#Fv8NKPT(X?;WWMgC9|gpKurVa32rw5RdQ}Kf{VA_yxb>DW2gue!~mA#4EhU8~lzx@D_D=hd=Qb z-s5k4z&~EDjv|jBwxS5E^vh#+~EOFc)=S!@P!}zQ4awKL=b`@MhNPo z0YcFbVQ7SKM4&O6AQDZ{49y`y3$#QlM4>gJ(FQSSi*{&_4(NzZ_zbb=j4t>bUGW9t z&<#?^@c(iFz}EkBY;67ie{KKIJpk=O+Z8}t0kGWz;2b!KPpto^0L;m;6#!cSuoZw$ zwg609Y%2h^0$?iupKJk`u*y~dYz4qp06y6Qp!mvG0Bi-oRscTP0x*1=tpL~xfUN+0 zvISt!Zd(Dc6#!cS_+$$}pF_3+U@HK&0`O@T07sEHsE*~p{Pgy)%>?>?ECsU71me7~ z%>?>yo(a_XtgQfWlG~;N+ExR9f-`{}MfLxk25f5pY)b+4)IkG`$VLuwVQT>XYa4*D z7T>WFsO@*QHvpXHJrIxo+g<>+HvqQ$|2OXj5*G0j`ET))E&sOs+g1W{4t!!O0m4Fl zCjSvX+wyPAzb*ftVE+AnBmW`4+4678zb*ftUjA7L==Roj1ArIab_2k61K<<80nqiI zMxuXzh5!4()h=A*WM}IIY`uW37x?sg0Y_29qqmN>X28}A*d_#W4t!$Gz`uKgH?IGm z&A)830c>{zZL&Z!o3I&Muoc^2!q?c29oUIoD93J8U=Q|UANJz_4&o3haTrJN4UXa%s&E`;Sa1TL zWCIZSwaWGmfEV9(InZ`F@RKY6O>G^(|E3PW_H;1n=yKQ^fd3yo9juux|F-@^8z( zE&rcv{-bR9x8>iK|4%mmt!??Y<=>Y7Pd5M2w*1@jZ_EEDoBuYp{M+(x%l{{v{}@~T zZTYw5|C7ysTU-8Z`M2f&lg)oSTmEhNx8?tn&3}7a{%!fU<^Pk-e+OIsZTYw5|C7ys zM_c}F`M2f&lg)o8TmEhNx8?tn&Hrb%{M+(x%l{{v|5#i8ZTYw5|C7ysXIuVl`M2f& zlg)n@TmEhNx8?tn&Hv}N{M+(x%l{{v|E{+D+wyPA|0kROFKqd@<=>Y7Pd5K?w*1@j zZ_EEDoBwXM{M+(x%l{{s|E~XZ6aD*3`tJukORjS!9qG)5CdqA8l8IV5O-mS}}2v_>@AAO>yG z4(-ta9nlG&Ar_s{1)rlUzCawhK?++bu$6*OuoV3JFmTzUw~n@lfl>v!qX**A6TOgt z-spqA=!gCofJ6*L5(Xg|gOP$E7>Z$#V>m`&Bt~I0QZWVs6i^}!=@^S~7!MUDU?L`A zGNvE{Q;~^jn2s5ki7zn=v!TWu%*8y+#{y(wAvDlJ2R#fhA{#l#MIQ1|fI=)n5f-Bu zORyBnupBF}601;x)mVeIScml}#aAf925iJ8Y{nLB#WtAmHMV01c48OGu^ScGgT2^? z{WySwID|?Z#u0pjqd0~t9ETYeoWMz(!fBkrS)9XpT)?-uh)bx(Wn95kT*GzTz)jr3 zcc{VlxQ!oh2S1_~KjAL!;XWSVAs*o|eufoK@C$y$Q#`|S{Dv2JiC1`yH~1ZY;4SL# z4u9e=yvN`8fPcJP9Yx)3Zw6!>i|*)wc=SXsB%n9?pfCENKL#KX1CfM5NXB5KU!hnfdB=RNJBctVjRXpg$bC5Ntlc&$iP%&Vj8An24><*%))G_F$Z%o z5A(4ASy%`Sw9r8h1B}Q<4swx)d=#J%i%^8cD8>>j#WF0%3arE`lwdX1U@g{RJxcKv z%CG?&u?d^81zWKVCVY+U*nyqcg>vjh1@>Ss_F+E`;2;j65{GdF-{2^Yp$f-gh6N{Z z5~pw)XK)tha2^-%EiU2`s&N@ta23~Z9XD_jx9}Zm@I7wh2i(DrsKrmXi+i|_2Y84_ zc#NN6#S{F3U-1;r@EpJ41zzG6UgHgZ#~*l$I=sW5_zUmxH$LE>kNNLm%fF0c(H%Vy zkDlm-1oTE9^hH1P#{eW^Ad)Z$$ry|j48c$ggB-�wXaBqmha+5TJk(X-LOdjKg@S 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 j6!qS#g~9XJiSPN#k|6L|;N%4UIX#==v7 From a2b8058ed9eef8bbfe4190fc7027a5cbefe12a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 6 Jul 2024 17:31:14 +0200 Subject: [PATCH 05/21] fix(data): add parquet data --- data/inputs_test.parquet | Bin 0 -> 55720 bytes data/inputs_train.parquet | Bin 0 -> 180322 bytes data/targets_test.parquet | Bin 0 -> 28795 bytes data/targets_train.parquet | Bin 0 -> 102798 bytes tests/data/inputs_sample.parquet | Bin 0 -> 47719 bytes tests/data/outputs_sample.parquet | Bin 0 -> 13827 bytes tests/data/targets_sample.parquet | Bin 0 -> 18587 bytes 7 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/inputs_test.parquet create mode 100644 data/inputs_train.parquet create mode 100644 data/targets_test.parquet create mode 100644 data/targets_train.parquet create mode 100644 tests/data/inputs_sample.parquet create mode 100644 tests/data/outputs_sample.parquet create mode 100644 tests/data/targets_sample.parquet diff --git a/data/inputs_test.parquet b/data/inputs_test.parquet new file mode 100644 index 0000000000000000000000000000000000000000..1e407873df7f29f59ea416f415ae4bd6c558d49c GIT binary patch literal 55720 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

vdE{DKOc64KoZz2)ga(f*gFDx>-rKU& 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

  • wO;Uy+o>*M)(v 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 literal 0 HcmV?d00001 diff --git a/data/targets_test.parquet b/data/targets_test.parquet new file mode 100644 index 0000000000000000000000000000000000000000..10c3c207e07254305f517ea1da25e1ed68e851ef GIT binary patch literal 28795 zcmeF(d0dZK{P_J;nnI~ml8`1@CZ+Jf8DD=UnGH=UnHy&h`1s=}~qI9kk>{&>Rvz!V=O# zt&%E2KXK%N#CTDmWD5d)A8-PXBrSy=N_q)7(^L;9{Y{yoq@s`k@fA^l@0FQJ9INxJTPfwCznBzi^HyQJ(S%_&|O%`9q{< z(Y9bb8)*AJ<#wb+P{{etL^()cDm1VY8_|#R_>B4Vqe`3$Gu%R-WRXxTQE(lh#L3^v zT$vnkp<0APFrLv^fMSfL&s^eLs7gkCn+GM*f@vNHA!tbIe@hq9r=a~Z97YsE-~vrZ zV><4_lDdMie#8{Xq;GS!kn{-rDLF&vCb3S^PAG`@Bh+vZwUV05k)@Cpb9ITic}JNX z*YlP9FlkxRokZ;=vESzA2j;MndPahbSsg&an;nljG`iEx666;3ygV?RM>=&EvH5h-gFkSR8>pZ7m}T zre`~sCm6>OhA2$*MGnjNI)L2#>MAjPyFBMNSzpk6lP z+QeASLZ3Vf?c1ZHe2{YaIgOFGaOId7v!gM|9v^<18Ko?Ab7S}E27s%NJy}_^clRgP$Y#75>rHl zEJ!Fq@D!Oc(kY}}nZ-rK8RW+>x|OutMgF#6q%tZrk;8S)z&*~&;fO3QBZ0i&)wGNB zIhZnUb7&=p=*8Jjzg>$8>s;{hB6yz|f9qYJIuWFoQ1%q1^kG6-J?T4~*G4SI-?VQ< zx!|=Yc#S5a0cUU!ni$|-2>KSxtzd3eOSb;+*c89rljW?>*UYyC#6e#X+7d> z^1}4zMPBd`@DKKr7rc(UdAAu5FJM0BzbA%MU(iP}^_P+E;68sP?ZNfsQ=W&dTvrzP zHjcNFzXpF;a~_9Mc%z zUgm2L<&!ukko;8Ag7=r;u0>KNc!&9N50-OG@DZ*+e9KrnNekYE9@HtIOz?~!B|nd} zEn}HR+Je&)CIDUz8!JJPdwoq5_UagjrL^ToSrUFmI_C;LggqG1 zKH?voFD=>2mmEdfGiH5AOO6%gfsp3HWq8=6d4UREN`e=%9Zh)g;ULWio&L8Efk&iw z(#1xOR}cj+i&zLARKX+)Zgw=o_(%+=i^V*g&xjr5jUjk}2ws}j4B43O1q&pQ<8z67 zh}lHJ10uMzwG90VH+d`N>XMy&50d`&{h^lpMaDCkyx>Epmi`XXo*DIDaBK%IQ7(At zn$t%d^*&NRgR-%d30~Bzu?2Uz#x0y1Oj_{Z{EpYOvzGdT7nm~j?Kpocb?nJYlD|*> zG3m3^ImKesA{~VT%tt=;+BhCfT8^@f)Ys(&CRo6Nhh8wQdys$|=Qk6-r_N!b;875K z&=jzMWQnIG^CW*3<*S)APlU?1H6&OE5t1`mvx3h?*Kc1j1=Db!a>1KVutwdvWy6#S z-UC@QT}8T-bTsL$q(_ln#FMm}HX}*95goCDW4p;O$2;=fMhR@3$;VgU67kDg#{ z2Voc2w@gyn=qI87`DgjRQC>*Cz)ZfxOhdj*PhMJHOkPY`QT(RJ{~T2mAMwA{6oh8{ zf0S}?kLu7E8A0_jy%D3f35lw-3W>^jwT=*1D{2)Uqw}CuWUR6DcF}QmcH2je_e$F? zHZiz!`*%}frQ^iEPqT{?Q7?=&88xe-)nxRX79rCy+SiRuCH4AaO{EMAD@DeR9eQwK ztg-0Sc4;#??{*nWwL|T)HaZX6$Jv=3+99WIb5ls(*)?ROf?Gh<$nndg-i%cAPSO&a zuqrP^Oi4X2EkVh+;=IMgpq3GfltUY|zMHgC)IM?2#;n#IB90Hz6DMyTxS2R*n~-dh z$_{CVq^XH=Z{ih`)UF;#N!p`k9+CFGDty#(d$Rg&uZ*iIg=JldD#v4FEJs(=KDzotWxH_F z%yrt@O&2~AF?OK-x(!{^dRmn`zzNUFA zW$v%WNuEfD!Sj;CHw=Y`Wu)f+HI%kXwV>gxl+l~YslOVTUPxll0Pta$Nx{cL%+EDQB~&v<*i32SO^j#i$ewq(&{`N4E;6-mu_qp7=ey3EzG zy~fOU&QeRYntn)aq4>;W-Pf!i8@D+up3^9Iaq*gxsXOQY+$xtTs{Kp%o`o{;#^bbg z?}m@FHTWrQm%7@+L$_>=-aWpxR47Z-$zY*`uAII38tEHL##=GZ`L2H5_LkF*WR2Ul zI9ta|_=={vrK9anBb}W#W<3xZt3KekNXKExw538$TkNxST$VeFyBzU)U^UxKxAIrj z`~dR~7te?%x2GJGdy}mr8!O*4!e@f_4OhP>wHH*!X07UR3pk?tt3lw2Bj0(fZ_K{v zQT6UFjm4bAa0as(m!%GJ{x8{HJ>;|Lw$s=u#R4e@2a2b zlO*yzYj-)Pnb%90XKbG;uAOOP;kHW4t>^NpJmm{J)OQc;xcgnc{KG3sMN!U~Qwr8w zOjtc8;_2PhZrgJt#^!s<6^Is3(o>Qz$rh8>Gq+mRx29}OO~?FW*}5ag<`3*h3p`#` zYP>rAgq+Y%CmP=?trK&uvsF2GQGKGQW6>iix0)s99_#CWQ_UPdZ$d)b`i9%v?~T3V znW?0&=5#pQxADZ`dqFMlp5EKgI&yk{aMf_QmDcpw`mt8K2Si4OSji>2iAkFK7n+_` zPV_XpGBfv5s6qY%V|AlpyUe-QpNx|jBV0ArD(tHMhr+p?=HEFx9k$ZCD6+fgd|ddg zs`GIRy3I=$M)WLCoTPI?GHsGiUwZ2WIjMltlQ#Zll{rae@dy?1h_I*+lcJ)gX_^H+ z-0x*0p|)Q$C+d&%@481m$-iVjJ#znadFAILhi*kio7X9;OO@Q*vGVRaHQQ+~j-9@* zE%L78faG5hPwy{Py!d{yQoizG`52#Yg@Z9~?~3gSztMR#&3aK*g6o#|Rw36#9D6tZ zE-QLs$I7jrPIRT|e13E1U|`2ip*-J98pXRr#ujZi(fIn$crlA@)%~I>lSf#;ZIdy7 zzEfspPg==kRrQ#fD_+7O56U9!Wx zzjBX(y1}qYytcTiTYT6a7hx;)lpJgCmUqHw@k;wIcE-!O1U%fSC|0sEVV~#WLtDyT zg~hG24gWsfX5yUMF=5KdJ=f(Yjq=*=Z5I`FS3_MtEg^Es*QttIR1#(s%YNTs>a**k zd3Efrl-Qgrs`*~p9lNeqEtEyQFd%oHR|6!akoNF?!IyF z2HqT;(^U8T(eAq%BYji8WYz7JnD*d&my7ldOW!@h6P~q=*Sr6G`Lvn#5&JCNtkOF~ z@~^+Uu}1%?_?77fdPjX%&mZhP9HTxmIC0BoW#2XtwdJ+3dw&*wu_$C=`82;3rqGL|}c%~UST6V)Emm`tyw_9|Hs6X(2lI^N=CrK~;P5KkFT}w(=B~LUsG+xWY_WTo7 zb>mLU(R22DuUxs=+|nX9<;1g94kFUSt5UqW+AfGVHjFD><)pt$y z={0@yUmLtY@!5Bw9mbj7M@H&Do9CG4b$#W6Y43_Rg!im@wm)ie(ZrFO{T9C8Cz)p- z^>obZjCFA;T=<9NrWYT(g*NxJJzHX*rzLB<#V0OVVr*xZZTwcf+C9_czDUd%_gmhC z8H;p%)B-#`CclkU9os4VAa;jr^g-!uvy1YksRSt`Pt$N3;dF83PktG@M5G4Z9y*jY zsVTwW%IsAa^OC2I%JJDWDZ5NuVTsmGRdv^_M9E~?(r)Qr^5@DMj+%XS#{NC^(*6ml zJ{buj`2i!nR_r}1Atsg<*J@vqVQYQNIVWmd!mez0L*ZGDHVfl?gSVU9KVs(H=Tury zU$@3IV@8C;QTYhN@e*oF-nbq-u(e#h%rpL_!n)$K4Zlkoo43u>3dnjAtFAuaE4N^r z=v*uPPO?1?9^m%@db6i`Bneo_x|a++$^5wq2X*Zr7o}bkl_|<5&HrQ_?@G zvSZe9E`1#{wN!`Td9n0K`Ce^HR zF^ScgnpM{q{pX4A9~B%wsUMy&Wr9q{(-#sBd0xNF6PjH2!>Kb@OUxvf-mq7laqq5Q zho^^aRg%cq*jtZ1&N^f-Um_%JZ@c=O@I(!bS?8x|OvronwzYDs^gW01AvZ4j2{kp*cr+`AHP4sZS<(Bf21#3&QB|{aFMCa?OGnD zIArPk?+Cev8n%FjjT9k;2YdU2}9hracxv+`2BP zBP_!`=cn}K^leFsH6pXr2j#{~h^!mN1 zeN_^7Mb1bgL#(R5Vxjzq2)9+sC)%!Byll^ign3VYk&8)jFkDxLuQxq-ex6>|6G>#I99@a`P_%Iz2bfIrXQ=8GdW$Nlw2`oYW%nr zy7SZ8O(k~OnT~L{t8UnC@u#@#V(V*TmKCaPNweQscXYUNhlqN~h=WJ;!~Kd*|L$Tk zwc(+dNb9(T;@&TG{S6X2u%HreMA=^iAq+ono~_l0ZSsgSFcjD&1<#@e|B~JwWGJ< zhwk{QNj4{m1iJP;Pm-LFa5GoF`(|AHbBA8%F>Pkj2j;IaYJH-br+6eMApJ~Wrsmp` zW{ahfGDl8^j%vBO#>HXaL91$1#l0&hzO#R9CZjY)#`MRLjW_M~3_48}JNR&q`b7~( z%ky^>w?8+Sy5Oi%TTt^XH?H143pstF(E8=KdeNUd$o>a}Q2k?$=MZ@*kTNq?Kd_NTF` z`LEvYX)%r}{ncX8$n;r@?G2uaMEsFh>DTM+;@MtYeOYT)*1Zzxw~vpMN7&wPK7L@av$g$Vi)WAq<=~(|8Gfy=kjTKy)h5v_BRyIZ5vbf-1KRRdHdrRrb*ar5C4KsZ_7CfJ+b>G>KIVGu)UMQQ^9+&sW%l+#8HbK4ow|O*uk7S{ z;foHr-cD7s=f@mc=%6m8BR&4yfp?4JLq7@0wJw!&Tk8@S^RAI^!~rG_s)<`dyUKoU zkXtC7x2ov)xqov8cTPF-wQiOAg;^O_B<_jLe4Qd=;WbLd+Bwfo;yx5k>E(1&jhj|){ddG!teSoB?{~(+ zvv$v@zU=G2$12cZ>XXv3{t?|ydxH{`#=B3b=^vpqYph0w#N>Oj9d2QJChc4}PE%-P zM)lE?UUwA_6hsTpO4b-`&DkI4v|jkb&YbOq__;=qB-%Th&eigt+@b;fnfyS7K(Dq%{- z(_fZc(-JB*AERd0CAWJ<+l2)k*N=#tyA%IdQU9kQuRXd&x+>$X9F@bai(HsB7%SqK zmUe5xJW0p$qSex)M@;_GV7gn&$VgKo*VA@;qOONt+Aaz8qUsA;ms&)(yBPeXxlU#y>ecGChUD(h&-2k?KR5>f--@c3388@N-=ud0`>` zBTWzzBHvmqBHwyJ{v&2{thWTd_`Xh6|R#6>e~c2RtFz zo?3yG@Pc3qNwC%G3&FPy2zLEK5Q;E_BLaeL zF~JU}U{`MwqOlo*ttr8-;Z|%zEVd&Kf(=~34&qKEAQ6I1Siz4Dk|EeyOMzfZEfs>z zUBPZ?Is`kDf?d%p2zEeokc&LzqX7F*i2V@kU>-yf4xt!=9mEnGfndAuC=>14Qf$`dYncB8qoy7PGt+u;4B0?nyomGHe5hEE}{dMAlSvdf~yd0 zA6~~VxPf2MiJR!cEp+2HdT%1CQ|pPw@=T@d7XLCtl$% zyvE-cz#9zWEr#$8@9_b{_=r#Vj4${HU-2(Lf)bi{WSi)>?R8;FL?DWh5W{y6hXh7p zG{!&@QWy(q$Uqk3AP0FUU_2Bt0ZNz%WlX|kOo0lfLKWXb4bz~G>6n3;n1vspf!UaY zAE5~?Xk#vPpbI_BgFXyki1{$WPgsDTVT^?^fho*j4ht-TC9GhL#jwE=*kUQ{U=Ig4 z!U@iB!7{kQ4es!OCzfLcR>BM3@PRM6&{EY#;!64pZ2=DM7A25uM_=L~+f`9N8{|ep!`byu{xG;GU zh+-tf@EybvdM z1#kGk7k*d;f2>9T)*ujTu@37IgbfHr2tpBta6}*y8xe&~h{k5bU<_h?*k%V1H#%`ow4^pugX-G!~GLeOBc#3Cuju&`|Kk*8G;Whro z0N!8_Z!v^-c#jVl#z%a@XMDjw_=)-Id^}mq0Fo7w|U=9l`f+ehAjm5CR64+uX z>|hTEIKm0eaKSRT!VT{5fG3t?1y;ff-td7h{IClCSd9RzK_J#*9o8cV8xV{Tgdz;# zh(IJZA_|)jjm?O`7Hq{f#9}+*umkbfi3B7f3A>Pt-AKV6q+&19kd6#wA`98bK`!!; zj{@vNA@<_{4x$K$P>jPU!4Z_=D9UgQ9v?7_kNAYo_=11%75@s>|NQ^f z|3c=%1g0>9IV`XUmau{~7Q+ThV2h=&gFPJJ2q!qh1-0*SP3t9!w0_b z!z%b=H3F~(fmn-mSdSoVKrliOiZFyD0+HB=C~QJBHX{aGuoc@7i|vTR4#Z<85|D@_ z>_RejBL#bqioHlfIx>)nEMy}GxyVC43a}4_*pCA^h$0+9F%F{yM^K8RD8n(7<2WjC z0w-|_m8e2BYEX+h)Z;W7(1<29qXlPh7U$54^Jv2bwBsT=a0!=j1y^wm*YOK(;8%3w zCc1D7-MEb&+(9qyq7V1bkKb?~zvBTO;t~G9V?4oAJi~Lmz)SpzSNIFB@izwW27`Eu zA-uzTe84b1;uAjO3;w}Z{3}@hM*pqVFha}h7Fd$7E56VdpN)m zPH=_`mcbQnaEAvxu^cO~5?=6z4}9T=Rq)4Z1YivUu@>vF9zocEV1ytPVF*VABC!!s z*o0_oMhv!KE4CpP+YyHyh{sMOAQ4H}g=FkT3icosdy$58WFQk+$VLuwk%xQ~U>^#x z9|v#{ML2|F97YL_pcF?@hGQtlaa7<0PT~|QQH5&MpcZwg$7wX65lv`D3(nvy&Y>0O z(S{3X$3=AD5-#HkuHqW5;}_h(ujs^0bm11daT`6jgI?T4AMT+azu`W9#{)dXBm9BK zc!H;RhUa*Jm-rK}@E2a=Zw%lK2Jsd{c!&4+fMI;ZCw#^i{DZIfSFrwn`fvR&WG+l# z3Nx6)0*hb?D_CPOY_J5jSPDDX!vT(Pf-_vO46bm4J3QctYjNM4V9;9L~(vXe}WFiaM$U!dhkdFfFLm~F#01l!E zhfs{eD8Uhw;wZ{+4COeE3Y@@6oI)k4P>mYYq7L;qjRrKL3C(E18JxvAwBkJ4Z~^VO zhz?xBWn95kT*Gzzf*bf1ow$iE+(I{QqX&1;i@WHDfQNX5Kkyh&@D$JR z953(^f8rJX!fX7E0ldK=-eL&v@E#v9jF0$)&-j9W@D=|G*8k7{t^bA0g$Yby26I?o z5iDT^Yb=HhmcSNEVF!CSz!6Sxh6|R#6>e~c2RyMHE3gt?@P-e3;fGc5$7%#%4Fa(i z>#!a{*nnV!AQWK;M+73V5mDHLXlzCdwqPr^Ar{*ahaHH=P9z`^N!W#C>_!UqAQgL& zhIC{g6IsYc4swx)d=y|G3b7vta1cc}gkl^<367u?M^T1jD93SB-~>+M6e>}LYSf?> zb*RT_G@ubpXhsXp;4IFe73a~03uwnhbl?&$;|i|g8m{9P+`zBs#7%VJ7P@g8J-CBj z+(jSmp&!5DK7PjoJj5gXfya1)r+9|vc!8Jr6R+?WUgK{J;0*@x7DIT4_xONee8eYw z#uxm9ulQH6{*C`z{|lK56PUsb=CHsbSi%a{SPUC1fi0H84)$<>Bb?w27c7G-+~5um zcw#wLU?sfZ4IlWz53Ash)d;{E1Y#}LVLgJd0l^4CD8dkq2t;BdqOb|k*o+u#!B%WT zEVd&KI}neZNI)WzunWo9jTG!bD)u4`>BvAPvXG4&3Lq727Sj^n7n37o_!RH6#is6j32P><7SKqH#aj24{1S)4;F&Z7+%(2k4fz$IM9 z6J5|wpa=~*uw#iaDp>junewngF8IniRD;Td@tX*p4{tKs#uGfnGd#x&yu_b)g}?9`e`5e|Fo?Gp!aKaj2MpsQKH)RI;2(U& zzk>B|^56Pj$XuAf6lO4o1s1^)RB8cX+@P%drA0 z;RSE_z!!d41%IqY0M;N7Yq1XN5rhp0MhHR?hHyk65*rbPO^C*3#9#}yVjE(y9dX!! zcYjNM4V9;9L~(vXe}WFiaM$U!dh zkdFfFLm~F#01l!Ehfs{eD8Uhw;wZ{+4COeE3Y@@6oI)k4P>mYYq7L;qjRrKL3C(E1 z8JxvAwBkJ4Z~^VOhz?xBWn95kT*Gzzf*bf1ow$iE+(I{QqX&1;i@WHD zfQOReMvqLt{U)2xAO9Qq-Lt3m@&oq&k3SOhe-A1Oe)a6zKfxaf`hS;l=v3Gdod>U{T97QR_-kn@&;N0Z}{Ykq(+8o$N-s1dnu08|hv-(zA2qih+?{(qcZE zVt#gF{=s4aX<~tuV(U7^f(FEbrN0Z+{4U(?yU5`0qSC&LuKX^h^SiAB-^EIc$7zbk z+leOxizlUtCs&H6bc&}Ah^I+QWN1oc*-7LCOXQ_V6jVwSc1j!=kSLNKRjfIx#BNk+ z@Tju1QRS7RDmq7<92iw8J-S+RbgkX!`ry$GX``DeN4Ip2K07eFReDUD=9qT7F&)8U zE~kyTS~=!==a?G+cJyEG-c?Ie4GC418(`zj^-J0fuR5h(4@eD2j~&z;J7hQZeel@fw6UKm$A0M?`*mQfkc_mjmb9q7v{;C=c)Ikc zD(NvdrKR3TOUuZ}YRSmi%P54%D5lFORmmvdl$rcSMny(eRZCXQURFIsc1F7FtSVWJ zo3eA>$ZE=r)7BcNV?RzWWSoBbIK!%OMmNVTcr(seM$SY_&dgrUB1FzIUCz2n&gQ0^ z?Hf5e8F~Int&_dHONhK{y1aXpyys2%6>sFdWE6a~6#VQJ{6iE1(iH-$6xQ8T2zsLs zEHge-Ykau<_{fm)QR(BOtH#IN9KZF=_*famI4#9^d&Pth#iVq_G9fR0LP6Dp!kZHgyqQoWqg1S=RAR4G8lqH|u2f#7RB==3O9#ItWEw#q2CX(_kcD|dt_UrtxPTBUsbrt*z9%AGQky0j*B z+fV8Vnbey;sjq5M|IJDF-%NTSGx?F$V;3s%px9udV&Pj>GqQ zq2KFgd~aC&y;0Zq3kJV8mQ^#+Rx@)@vj|nQ%uutgR>nsP^=5hv|`_)1xw` zM^{ge>6*TEaC)rlj5zHX@eVT*LT4mp%t)@Dk|y6^T6QDBH3BR+OtX=W|fA{D$AHvUOlU#Yu3rZS(UOsRBQiG>+nN;=noAUKQvYU z(9-q8*})%LWi{HgHQF6CIzlxrXJ}ll*0|oKabr-UQ+9Tj_Uvwl**&4NdoyPDRnPA4 zntgw8_5;~DkF@7Jc9`=tbk6gPIWMc{yy}|sdT`Ew?2m)mKMpzk_&)T<;fx&LHyKMIZ06rQUo>ZmCerYWAOIjTl;%q>l+x0=%9v}EUM$vJ8%glQ>eYAMxdDc{nX z{8me4oVMy*Z8b-2^)T%jncA~zv^8#N&v~n@Ic~1@+_^fAbM?aJ>SxY1teIy9fuEShiCr4eEFkRP7UH2MY&s(}H-s*ad z)AO0D=jW*BAEpa*ck^ zjXJ`NE@v8DtueZO%jm{iqt0$+wrHKu%CJ}f9k9GssGkb_uu~XVBCU7a~C{z zT<|n(!Sl=oFKZUOy0zf-+XdSO#{E1v_vazUpWlc5Je>LSr<$L?-1_ZK zMV*Yr!i~kVj7QZPkLfm+8ZwraTPUluP|j(gLij?(tc6Oo3zfSUP99pQB4?tiW1{9{ zq8@HCBgzpI_6GJ<}Tspu36^pwdS7P<|~HGz2q!>bS(UwEd0YQ0BV=-Ndw-HWykEsB-1jMK49$NAvP_e+%FwaOa{oK2gKO}mp#N4U-9ESsyfHrKmtZVcIU z$}Q>AS<>yaq$hkyZ`P8&+9mznOYRRXc_3%|NXPcElkL-R+vi!fFKcaIb=$rkvK^3H zI;gXB$Z6^O@TJ39OFz{v{nEYk>(Ejmc{^cUJ5gslu?RcyY`al)c4KbaNxid^mbaJH zwU=|YSBS7z%(hpmvsb=tKlz=#ioAoWu7jGhgL;I+jBJNlbq*T09p=1q(3E%7)^*fz zcGQb-)X#P_taCKF?YQ8bqp`e`iLR5Gvy(-HlV!G(b)A#VZ717zPImIn4!X`x&dx3o z&aT~Q7IS;q)_2QdO5L* zdz^je(JJrRrt8`6?Aa0Fc{$tjYMtlx+nzVxd3MS#@6uh~?Yz7vVtH@&^1iy|{kNCj zf4BUB{EA1qD;_(qcp9-{+w<%dFY8vky1nA{yA=cSD+hH~4mq!UAF*;cd*!FPm0xbJ z{Q7RCkb;-6o|mYLmsq5ic#hYodap4(UQ+M9q!qkn^}OX=ycHt76?43m>b;eFyeGf+ zR#EU#)$>tv@llWTnUUi&tKLVW$7jxaA58^cZ9QKd7hkLB|{Va3*tn2-3di-qP``Ib1a?o4lE;~!Y>zplqW=)Hfi!s<}H)!{CyBO_Nw<*bgbUmer4dh7euu?hikdI9k+ z0SS=-NjU+@^#Lh80jci;(iGNY=&i|eS(6jFCNF1ALH(M-o;3&FuPIUpEY=GwaS1Gq z3@pnDEUyo&=m|XeKCn_@ZMELoT9>u;k!u@r);86zZRuHi_Wjycg>`Lu>)Kt`bwsYa zoU`s~{krQt>u$VX*Qv0+OK*L*%le+k^}RXk`|8*C_pHDFe*FW5phtQ^k6nVEMg~34 z33^!{^r|Q5_4}X!g$;vx8-`pqypP;4oU`Fm{e~|+8@|5ZAT&N$cwVsRvS6`|!Q#2W zqfQ5pxf3k)Ay|5Ri0r%&xn&^=8$%RxLzGU3DBlU0{2@eTe5mTYP_<>D>Kj96}+i zb0^&PL%7}e2#0wQPRk-(Hb%JSM!27j@VpbT;zNYj_(-35k$%e}{WnGi=IVKyYnN@V-?+IUcXQL}%`JB}pZ&18b$m?QyqNZ7F&!IYF6YKvJsorXPRxxD zF`eVLbj{n+y=+U*#x1?MTl!9K>A$n({)a8w9*p1mXx`Sx%eFqjGbB5zI z6?bUs@6d7Gp%=A7KW~R&!w#d~9Seqc7%Rq`=*OG6##=Z;b`>=2D(u~LV0c%NVsf#5a*1nlX;gAqUUGRuaz$_Q$>HQm#og8VyK7x{*GKJc z$lKl2u)C#q_u1jyt%@ma`YG+MDIHNMm-AAtHl$qdO}R0g(y6$oOMg$d>zLdNs$F8YQqf(#erM_%Pebt-#dN_4Jaqpo1-XYh$@1yn(=k5K} zu=h*v-mk-Zg(jp48>ET4rHO4y6VFc@)tENsZkp7`H0cTHvIgmLZs`h}(iQX5l^WBP z@1{@wn65G*L)9Qd%`HQHQ^t(^j9HBt8h111e9X|Ckg08uspFQZw<%LUKhv-=)97yI zf{&TT6S7PUvdsAVpqsKR^RuiQvuy5W*?!Ejn~?2bknQA_?XoG`H9yt1mx!gHs-9mn-lagCwM|`s6lSHTW;j0+^GEA=*HZbySZCG=EhFQ zi!;cJcgsuIl$VsBm)w|_ayKvaV_w>X{0xKqEVuleP5F8G`2~&ng?IB0e9SMJP*7}8 zP~uilx~ZTnzo5LapyF=9$&Uq<6ZTab?5lO#SHEdrL;k*|#(gb!_nrN?uXRFUn?Yf_ zTVcnh!pr%ER~rkj-z~iHv9NQ({w{<4-ERAPHtpZmo4>!Waex2a{r5lae=y;|BZC8v z-3~n6bl`dZftQU3Ufn(L`s0Ct2?qxa4i32;e81`7aQ?whjR(KnJ^1zGK_R6gVZ$O( z_ad?ABJqNvQB6f-`ii7J6-g@{k~KUe=YB{b`jBG5A*H56%6*3>e>$Y1RIF-Ptma;< z9$h@6pm9A4X;RT-#8!MHV7?zm1msmuX zSQeC6HWwU?d}yF(G`~qDy}wFT<@#6 z@u{Ly=|q>|iEj53J<%t63r_Sko#^j7asSha2TCU&8J>LXe)4Jb$>#+pUpAe5)pzps zr;`Iprv?pA4Y{9sAAM@L;MAw4Q(yW{ef@MwXkw-C{7O-eO0mtA;`=H`HCK+gS1I+m zQhH*Q?EES@k1B=DRf_wnl$xuQ?^R9yT%|IxT6KQ4nn$(z=IR;ys%JG%1n``^>NR^QiaVTpzHnKCrod-M#vt&-K9*PlwJw z9qw^Da`Wk^eW#Fy+*mZRsd#=er~Fq*jzooxz?k( zesgofzUHRp=9YWSXFoT$PHbtL-_q{U(y_Va^1ha<%`MmOwcPmJ64p8KOxOG~-5zIp zHlOL;cc!oTO#i(z_dlO`F!Ai8`Dgj#h)*}4eZKGP%jUDM?wx)8`Ru^NbA$8G4SAe< zzxmwozH^_N&waUf?(64sLdvbeMy;Zrtzt2);)SiFT3W~Sw@Q6!l~z74Yjj@D^SnaL zdBwu>N-gJ=`_E7Qa$ZH5KUCVL=Gmqm(>9~9ZB|R0Mt|F!FKwF27qpEo=y+bxi@Bg* zc)_scf>Hm41z#>0E4P~%wVQdiTg0?m7PecrwA=Kz+kR=cQ@-e6bkWK4qD#z0*TReL zEf+oeFRu7<(M!3*$Ed^4v%^28BcQM&u%%;Ne@D=lj$q|Wp+=X&JugMZT#72Z6y0(u zrvK8`FPCDKFUJ{Oj`zHr5OX=H@N#m?<&^%*sb4OqDPPGjx{~F2B`4-eUg4F3mMew* zR}Or+Qlxyf*yw7B=hf1ft7U~(%UiBi^j|&sHQA|fJ-h&1B)CYNp9^-0!~ zOeS+~-|w97oPo^4$$I|Fz5G}E`L7T1`NMqiC|{l^R2K{N^+I#6(B3b6b5J-uEPQ)Z z_->;3!(#Er_2R9);_dz7PY1=H4~xGX6@Q&5{kB-TvtIgruk^=$>Cc1G(P8PYqms^0 z9ledyms)u@b zQm5|g)~^^EetY9uxDikrYuQF9*I4f~UggX!91?~+o#8xpN&j?UKyEcr(q=5y-zOx<$31)MskfWT6Ox-1QX>% z>haSsqwDDrZT461+hAoK3<4XU7@vO7Bf|c#xW{gP`VfRPb$0C5$EVKgbmP&?So)g%O zlf0h$jbuhfikKqtOpN6)(3TWY&I|=HdW&O{h%a(Uilveis9(o83DkKhf^6aE>4kYr zRquj1i2{S!ZOFk17z5@%aPU%c&T=n`A^R8z6r4H@So(ntlXA~egKUA|KQ5<*80V;D zEUu+N;ORIO&!8;G87dx+r4jZN7fxR*~2xE=0%eeIG)DA z4$hhrIBQ1m8HB@;4wBaG;My{dUtR(=$Mb|JC?R*ivS#+BXip$XOUwLa-a#WiGwYAi z(h9$JH60br?Kgzn75LSpGpajjfZHlx?Xe~krtonJQg^*0P6WIH)aT)Ir7sREoPU60p zkIDLZ^Bu<|LvGBzo~^=?rZg8g78B%;y%;nSJj$I(VBIdryFWV2g~ym6JjZh9^nyPh z#AWTt;>3A~Zx{Rw@IC-cCKlyCIO`PvYl`7vPZ379z%!yN!=XKP zdea=~$}pmBR*Ovv35?{EX|qMcxO{C@S$0}7gaq+{Zm-@TZ(<t>59<@(8R(<-0Rkth$SL%b2lWHc z3TlcTEjhJCG$%-PK+qGoV+-~ahsJ~puur2t>JxYzkWN1-Q}NdnE_s2GBNNJxNy2?Pkp5GF-MOhT9g1PBTWH4G|Rw18-_RY@R>qJ~LP zQ2|l0#TF1-Y-w-8tfGcN#fmLBmG;_uLGhOM+TP!a-}ld#=lMKqpR><7IcM*+*4}&V zg+h|x!@{$S87#ezob?%%g)k7L-3N~%6bvGyknjkPMn-4=2EYP1fDBjw0w54j0v`ao zfIUDO5CS*>&VVDp1zZ6-KmmvV69@ppfM{SH5CzBq3E%)&11kUmAO=nY$$$so2doET zfC%6$;15s%Ja7%j0^ET$KrE0BYyc90Dc~z07gz;|0CRv33;=rpFCY#G2ZDhV;CtW- zpaoU}R=`%^G4KiC32X#9fD1q13AOns7mB1|^2xtX#z&T(auo*ZHYybM>i~yej7lCG= z8khuXXymR($WJsBNrI!hz(L@DG&0^EL!rEHViZpNgTlrm^H2zBUB0`dXy8mI?u0w;jyz!=a5`~qNTD&!>m z-ZGT?fhFKRa2Y31w4%`vG*|8NBzuLH-S_fM=TYk_70XYy;Pt`X~($0Ny|% zum>>dWhjsZnEHPc5CgaYJm3{gjVyp1gx@svB^Pi40ssjR4`=}oV3ejndO&8twI-eP z1z11_unTYiwgM&_G4*vdVA2_rPVNRw`XvK4115bs3Yhew5HQ&iA6O5x0eQdX0z@Z$Awjs|6uf|!)U zq=-h~B(N7SDFqoY18ktR)ahN{2OQihJlxW$sq*MbnpAZHtOK%v86XOD;xasQ4PXn$`EZZPAshy2Qeq)s zq%FX}C4BF655V!40EZ@eZ;)Il>!2M~AU)xpkKsArLb(q32M`DMEyKCBfE?q3%2o z1Ec`)KqasQ^*;eQaE-|UYzK}&`8yiffzJRlN5P*9-}{8W;AiwuEdrSV(qy*Iz+0%# zg6m9brv*jaVz-7Rs-xa{`po`;h9UpZ4Um)3V z?h#-P?_+vbcL3h&y?xfeIa42Y0Jmtl;Be9Rx^J@YV}MB?t^gkZX@JR|)&skMw*Ze; z0sU#xb5k2}z~0gK_G9u%`M?ffCr}8K0X=}}<4t;^1D*osflEL=@F|cDnCy#2YkuEf z7vZ_D;Ft`u51ucBvLBR9zETb4BEX~%CfgVS6u|euQD6&T(%GMZ(|{*@<6gM0AIcj5 z419k(9Gi4{7}x_Cfc*d#^rH^yHbeOdPzCISPKpKjLrgOGMIPum=luZn3rG*R)}))o zrh1?mC42;o0AUGN#Z0|6Pb!Bf|fmvrt)CfmtHU@KAyWV9bgTJWr3{QH2^q;_1{_bCFSv zvlOEmJVh>+5Ui7PF+?I$tjE}7cN%cqf>{HJmyH&aolc2%nyWilrEKL5;>N^dN?4<#13G%Hb<`2E1e8VzH$N6(blVO?jVo*(wv`v=676>Psni%w?;??# zw}4`3UNgF3Qog9B7_k}alCe0b7>fiM9uDXN>Yc;$byr{t8`$oi&mR zzYEQTY-p2&P^yBEAzT(3U*@o(*9V~zE5s7KyGQ@1U0~y42$85v7h{sh3*k=3+UEL+ z0lDHZ{?VZB0g`=z*nkM2D=-`xN*2@@RU_D~Q(YQ@O5a9XY02L2o*Vdt$~Y zp(Qgh#kAw8#g)YE^4Vd;ds$J6A#i8I5Zjqf1D2arjKc>NEXWA_cf5Y2Xtz!U8sZ_* zxO|k;T8dk#Mu#~mvRMM5QYk?&c%5+w+oYze(be;dc$!_o(@5OD0u*D%HYpZcus{(W z)V4@*meXB&mzD}&Gq<>GR80_6Nc0$fXETMceMuLFjS`5-cIHf98EHo^Mo$1WMySaA zxRjTv6^)R0G`2*z9pl7nU9<{`gqX%vi7^7XNWyWRLi+7aHfB`VpBC1rkqz%e<(4Gq z3ygPDyp*)cV^-^w+JQ(p8=$ovlavxMd?pWLUT4zL{R;@eOc9iC<{lsvX$T~aNz*H4 zrS50iYNQ;mg;^=(vyRu5BxeC)QVwW9VvoNwGhq-Ng3T@G%PD*1LA()$s zp^7SM4EUYBdMW1GR#*NG$~5(A5>sMz)BQig6~Xilx2!q7fNxPZ8me(2=xP8 z?_^VdD_aKbdUMA$HtzD4NJ>a@?QM$rEKiF^liEs8?h=|u zn+StV;vhIXhv|NEGiP*8k9F{vi1yIT=*k$jT74KhLk|rRtZg2|UQeyP<=nMg98TGe z*Y#UrmHIHEH&a}U@ov+MTGTf#j5=)c=+~O@@eVJ9}%r+=IJp>T(Ovyl9Nwm$hp3i z?xV7rYTw(he5mG^Iza8LmFeJ3Di&lMTCU`l?U?`Gn=4%lbiFGvW~Yq9EN(m(9XvvS;R)kH(Uqq>DXi&AL!d zdbTftITqwZcFgL~k%=Nyp~p~E*gN)aa*W10pi?gvjz>JJ;JYhlLs%jvQsPo7FCo!F zM0x$p)u@5uAmM02I4P;TG7LdA8-h=s@(m+NW>Gmf?aBTXp)K_ z=(QM|%>tg9O&=5CS62nKjFRF&L#PB8htNv}e%1D7;`jm7Sv_~hx2-8R#P$O&5`qE$ zEk!Key}m%+ir+^51B#7~kIe^awVkvpIscAFUbjqvhy|iON2> z7wlz-8(3jw;TbmFOt7Mn9q(FS%I?CLNj>I5i7=2M)U=?y5EpgOUaeneb%=#?SdPA* zChS#ckYJ7ip|C4NQhEq4LBa|yl$2TqEBV6&(@=%M%T*EHo3dL;E_NO2N~;(3&!TOD zWV~Vyw0$ThBS=!drs!uhe!y;PXXk+Hyx8h4iK|UF-3$(gRL!ReCX7Y{`yz_A+Qn=_EWOQ9140VHXG8@VwSJ?togNxBhsXqNXj4r}X#wi=0ZP#n zwp>`>goZip=7MX)b3|D8*NrL?$+eFk!uxsD@1A@2lu=`+>@$rO@yTp6z5JP&ut7WGy6v@#p6l2(WwHhBVO4kKqDE>xY{8?W-KC{U%j3lYRX<&O6 zhgODC<3}tsjgEJG2-lx!`2pJ50R~ZRRs$p9KC?3Xeo^%w40 zxZ^wVh=^lSq$~qDB)&iqjw=Lb>BsVYdW( z20wr`+tayNj1lOdok#-3a7d)Q<>re02N9|0^IS%_=##ctB2lEolwiCSdadZsTovBR zB3pCI4>dTAm{}G!YY?m;A43uJ8N)c68)xONgTrKj`uTDv@%LVSM8P{L+Y!DQL8+=z8`s>M=Azk<0^ho6`&23k-X zY9QMrtJN3*RY$hmD(a4LXnBrU_`b|#jNrK0k`f|AfFKl+o)^a1r>z_Du#imEgs;#H z#@NV>JcK1m73&fA_SPD&MrQty{r3^Lmp)?h7(RL z5F>97*4)GfDUAdSfvG|$Rykq|vb0^VHKR>+#YDPvB~-5Xh*?tsrk9Js+9mHz@Cw7v znez&B>PS(pX(d|k(zdxU_HLNBB0KAAYi(mkTPC6sUgeo@un2V`bE@i_2Q718o=MFR zydLB_R`b*@tEU!1*gMb`3^qr$FhJg07+;DZAX@K2j^&P17zf+2=5n8#ZMWAHk>^5LIF49q$7}YPbl`UCZt^bmy+&gKSUpu% zMeBMOz=)W+61MYLW}?#!`Kh_t3{hK2YO0Hs%>87nA5^|D_M8sMzma>99YRc?O1R)a} z*8j0o7a=Aj#kfZ-Ybcf;osxcYTyG26RZ1&m#L8IPm>a?`mQ!?VyFzak$HZw zE7a>%M++-u+fM%^-y`)1SSSny*kg_RHYR?#fDK=Js1dc?yz@od31K;WFG~a-pHSH= zk|9o=BDvra6+5_jRadDzFw8hx#u4Zhq2#c^$&IcB2M5MNTzXm?wtRFQ|1jzse2W@E zQpE_8rDd>fzno_@1pQO#{4lj3rU38!b1Jsf#j8gmW#RDXpmN`%ee4eoytv4YmcE_T zTAb85hEVLQc|;0Fff@4p_0@IeR_nJf9?E|ZGH}v~^hH}a1cBb7J#)h}jbJu12b3DHEz=k_~*3m{yFSQ9v5Eso&<%JP5V17#ch+CE{ zc8Lhl1vCxvrUHfqWvKGPl%|-Frc)cZ>k5>K7FP#z?l#;Z~ z3W;qBS%hG%$2tux{CaD8R?XS_C$iqi%f{9mmgf<%IK5ipSjr7aS-Vcoh*|w$UaIqH zpgpI$erXi-BP2aiLe6Z;e7L@Ja4wR0Ho4`*wv&-erN>sGc*vZS3Z10kB&Imf6owM3 z<)BG)`>Dliv7*BTA`&r8FUImuHC{O7nWwuJ6|l0U%Vx*ftEDmiA)Uq&Hc1Dwt;2<7 z*2P)KTXw%RL+kO21api>Jb}U###ahkkA`jDsXMj*v@+q3l33}p<^DVD z{qGjA#NBv3643snVLIu`Vu>#L&_(}K+-|jMm>__6wro7u_Jdz{hyUHcE$xoRT@7!y zS;Arum9R5F?d;ZNXK{khch=sfpKD%Ze0cT73Cn;9Bg23prK;5I!&7f;l~)!rLLEMz z7hC3J4}JA8yi2@@N631G+HUJ;{VC6ySGBQDQxPGxIoDpi<%m}Pq9M zcT`FsrfJm_=iUR`A7}ev?$<`d`Ao_7+-a-5iN^J4BrK#_kJxWMl~uFn)~k&Z>vR>q zac;CFQ8~dI7V`XK;sLvr$NW3PSN3&cBR~3{RdR+^q;7|W9#MsaI2KedJzg()rPflu zSNK}zI#<5EO)ruAgs?e!2rZQNSv3hip0AaQ>zeZ#a|h@jGuD3iN>xtw*1;@?)~B5D zI383$Tg!XFtI50iwt$;|$Nvq2v+o%n!Z5SDMtwtAq0FqC+wPx8{hD>bC6FNWrzRR&f0q0$5rQ*C-xy>NxED;d7W{RYb$SldNb<#`HACu?;YBP z2K+f+gQ3C#vlwX*v+cR5O^GzW3ras-!DRf%r1IRmbRsK>11fulcQMhSC^f!{`=K%Z z*v=i46LAio<L#hN4Ukz*4kb7Q@&RCotqXBSU44eBa|*#O{{G% z%(o2q=DC8p`QeS{ca?S3Pe;r?QHT%(Gfltgk&&LYDS7&@&_|KJl?`WChUbRd!u2TB zY7SYhD6{xBR5q3N!|uzE{r`bDQN0Tqr5Gebi5cKl1Pwj$Ek^p~Qumk)`Y`~<eO_~Sn(!IG? z_A73)`O&JrTZ0Z9rD_zIp6>qjT@= zz}lIon-AozZ>T=d(H>8>vdw}KX^&BVNBL`3XuYp7w7?;8KBYV?;J7w(kmR9N85kST zE`;%G+m6ZnkfHjMaXG)881t*ImyDXjL|={3lE-7M%0!*v)DFGWa{KI+lcz;_^NTnv zhncHkOX};B_aFBUxwF3hd23VdKWW?3_7okfUkHKd!yJwk`|4$y)s^Mqu$A9eW7(gc z{iT$a{}a!5m@LvM2zI{0y@}EkLUev*=`#>=^mg#@(c$%SjGf2GPM4o8_|u z<~D7rD$#!z1S>LL-}yKxCYp9VHsJacPs}#GG?|(e@{{$Pw$6Obq31Pcx4nI&J-zz- zDSAH=%*+)#4onkLl%7F#q=0XeYme^z&-j2fx@oEgAs{+&G5HK<>VtI+&+~6*Wh>rH z9a?rCj$e15+Fyc@QlXPlpI_dZ6v>N^^-WLwxyM8kJcV)&18MmyKkk8L_Z%w*U z@XRPoOJ_l42GyZ?|rJrMz&<@6(=sbGOy#Yb+HJAOztb5wi0iBUldOg9}3+$EzRA zS%ndBT(Oi$dsahA z_>W~!%pp4Fz3)eg<$|qLP0r+)?YGGp4?ZTpRLcF=Qfr6tj;h%bJJl;IUeNM!+LJ?D?67X3oy51I>1gHHFyyAUNj{;1%r)~es1Qz}{j+mr0f^o&ONo5ll@Kn9+z5w(^?JKd-o zpkK^lj1t`|awV(}g61L^cc-y2niY`~u})+9xg(S#OsSd6ClP7`#!;rIpx~b{?)ytL zSc>3lHD2qwHOt3f&e5wec9;5?8{N$tu@YL*tJ$&AJ!w5DYma104CYDTvFt3kVNa}= zn~s>(N}B;fD&%$~CYUNP_vO z-I-?MDb|@rBhz`g`t|Jtw!!4*ct#XjIUGM}qa>&nyP5Y|#CIi{uqo$&9c0!TBRT$8tz*=NkUJ??Lflj#gz2>&Jnf2*)s+* z-gb;fB<`8v9TDt`>|w@E5B0>medk{i?s@WHE7`h-tj17qN|nqtb0_P^*yAZXV%FZM zOgzdxrKR_qC!xGBwtUGcK44(5d0@?)viMHMt9{OiiB~&O4AvXoimb^I*sMHQ?@L+v zlP-~3!7mON_xLcEr-9~xA-Ju1twvwY2PWzYR{69YEi022V!hDp*9o*y; znKMq~K5ma^S2`EJs1bSgVX>^VR4~F76>qIP@|qY`K`|2S*-FEz{9ICBldMB~)72bKXL^{+{Xks&Cv%H_^s4=7nRjei zy>q1;q7pnuk^aSI;Y49;S-{WpD08FjpGvvw)+P}a5kWA5+_s>t^J~{$8wpv9NaL%1 z$21%l)OYBKSlCLz5-O-|DgMPq$x(MpOl`t}dyg9KdEDW(B6b{AuEy>ZRaPHZ5^>?4 z_1eLN=3T=P7oy#+OeM&OBu=iHU>TToU-`{EBg*#+ZR=P@$uF&yZn6I2aNEQ-#SkW^ zSwBkm+TFhSgT=*tCnM@>w8w<{o>>gjxeW}7T&)<+8lHM{a=mdH^DzF~^Z|?DP1AI- zBT2V_wOc3lpS14I-D~O5I$OK-ko*3NM-QB!pGdLSN4K39{^TEEsa)Cba=+Lk zOqt|eG%Cy|+Hp`tsoi;M!H;V%$gy|ApH*AM9r5~#@Fe_I&aBk59wG2mQ*WL+JZ{P? z!KaTPPeSDdcaPd&2lcnuc&Ug?~z)t_jXW>xI2FPhgVp)==Gy>(Ug^1h$HV- zEEwE6n-(+-rB+Ww@Z4s@syDrD4u?dmwm0lf-#0nMc9!c52#2G>aGbW4hM~(dehn61 zs1jG~pnq3CvWna5qvk-bVBE%PR*xy8X`mDsAJO&AwBgtlo1uO>+%``>w7B7X}HeEFK0& zk?gRG`R12~hO+6TLApdOf@O=hX~}c!9j@8EWPYNOIrUt@KIZ&1)DoSOODZ@7eXf`o zJLsRh`buGUsB3tKf6d;BM+I`t!NP?BjDVYKAb+p@db7i0U0sQ7(Lnp_gkw)yPTpDj zZ6{Ac6mVh9GmtZ#=--VnZ~-^k7*VT!6_gzFmdM9({0tRRf>;_aoM!b6s_jIr_^Fe} z*6nhwV%}4}u5=7hh_MvMhy{wPPFCM6v+vTLju-yj8s$|p+BJZN3B(A|yIDl=PNEHQ z6yLs3GQ*^--h`Fr3p|K9=yDN4`Kyq6LB))O=9--|haUg!uYglgCDU^Rtbn7|kgqp$ z?lAen=5UvFK?3WN|DF{b7yUFfS4M#Cf+6zZgBwpDsP4$3t@Dv%$3H=c*N;SfDM~N1 z%;-~y$(mOWGQ}t7TdM-@cRstPnWQJl*KOfG?I+uCMQU=XhdHT8Ndd!x+@l9^w3kPgAJIj~Bw48P zL~({4Z-~(5iDCPrw%JvqoT%cR#QP?Fq};jMBDic}b{LkW;JVh;KmXCXfm(7T_8wR@KiZVyue7=hZQX#DB9`fi5b#8e&#rtljk->*fO` z3lh{_PheJ2*{on5GM}zBg zTMYPUn8rH_r@9qZ+t;5+jGd!wf1J`{BQRUpkc$>u3LxxAOzj)7^S_vDxEpn+v-bS9 z340=IZdjLEm*iBQnjqr^1ks6m;salkETR^SL*^oA4uaPd{isu-hkDeZ zx+C7G`$6At!M@%WkFnz@^V9@t593bMk!*v6ae2(~WbBVE1J$-QqH)C9Oab8m8)N6_ z`s05QY_^$Sa$ONiDP|0~pJ>atWyTv@kg_tC7KZ8jFS;h}y%?XAmJ`=-fyl{Y@?mPi z6!&wl*DswHT}g(i$%)3VZECjV)!Vt2GJW8SOzYBPGnbT7RS!1SDnkD{w&r(QgHBYK zBf=m_rnH3p$u%VQ#ldkk?WB6Z!u#klquMPIogh&0Tyca=`CoWBw`5j&*Y;bnvt9K* z!v%BuqAW>-U6M*96}_0YHVf`j3#$E$Io6GFuL~GA`G-~A5bWmWitYTTiU-4|bCw#{ zN84OKoBstefn9OFNi4ILs$c`EvI(tJaQ96+sna1o6Y*eSk%-GA8$($lm5$6DN+t~Q zKJR^6Eoz$16y(04Cfr2rwX-;iNT(lW+hWL6`xEWYtD_VwtBe%8R$QzXl?;0}M4c|e zW~q?CSp8vJ2+_01uH(&?ZSQ6#rS4qx=>SHgHZ4cyhuk2Zg&83+)oQRlt9o~I^ zGlEb_6>|hq=eve2+|N6l?h0zD{!W@_vZoR(%VWHZ0K1C_B`Hg1FyE6!@8@o>5EV06 zZ8Zc-%0jcudc!hO!f_N%RN3-&E@ejTda-GC?YVj%Je{HNQDcZIBaumQo;G(ZcrLB< z|D20!Dr%N>MT)!xPjOTZ*EozbAGeNjKivLW9vE|f+Yd+I%HEi{czE!`Ak}3y%%;~< zXyJ5F@g{<~r8?lDZhF2m3g=%9jRngkgPql*uw%HBgKE6dH;k-L{c9}(-?Z<0v~|pXC=?CrRSc40z(QD79=sT7vta&*P&+r$lb~nwj$|7{ zE;`6%t04J=`L5aHu1aripo+GpOkE}Q!R1!%ERT(JK?>ZdI=~>2ZttAKiH`=Wy z9E-XkT%zZHrOr5hpf|9%gr8imFF~!95To0J?~eBUAw^qX&c3dci|+{Lv^AA~y zuYgIoNGUP6o=dyL2;S8GG;-zWU>!HsSJQ1~UsWwGhH$n>jV%;}gke8fXs$FX>dB3_ z2x#v!Xi%q4*tjF=d05ity)WhVt44jRac7YD$C6xL*G=qcEw7A2(DAVJuLi%4Mf>La zD=E8Vbq^E6XEjwc`)pK$rg0T|^X>IrN26Z6`l?A5?NeWUU~R-=B+fFZQ;lWxAp-=Z zS{=8?_q)WYe7_q^owp~qI09iNgEfeBFujU@>mTP{@G39V{rtgxrX-iq0Bdv$x?>vC%rl8X?DI+cNWx#B-#q%*G=x7YqY?^Nm?J1vQ( zyD1E1WC3#)N5qihN7#?G1Gn5SPCeD&nbqP7a^)E8=Mt2XeuQ4AA6$jEx0>?#Pu66m z>n0Js+GRtV4~b>1hukCUc}G;#ix_%#o=wOq1HAPc@h@B zGd)By?)e7c{M3jZqs&%Yp9u_q6;HO_QNSl+h>8}1M?_fZsMoWZI&&|=cztt9cr%u0 z#YJm|2r#X~@mEuEvi*l*dd4H$ov%?>ei@h$Eeb4DXl>rFOVgDZx1~Z~SKBS;S<}_Q z1D%R~s~pq*byDGCxFW^Ag}`?49~fOdKbHJh+}S=MrZW+UbtGjW1m*vZ)|DdZsKH?6 zn!Fsl#$u|ql(>NkvtK;NScWPfSZBTA-E1hi$f;M?Z>d#52(%LRIWUAiv3Bj}l~2XE z%hZzc6)zX}Ci`~G#Fv>_@gV$8$jZfe9j;8Obh zWSLz5+88dmS-@StAZL_P24?kmPY32)KSQA64U;_@A%yO*^Vyx`{s=z7(PO4rhPO$D z%~hfx0qcMGMsWoCeR6RW;|XVo8}!YnbkNG$G=COlDTtzfHQr;&jFnQ!y`}MYwzF>hLx* zuj(B_e(Ug&dwNuh2^0Y;9nRYEq!z#8&sj;i>+R>ylULWP#}QJfu!X{Br>Z1G`%!(Y z|E~xAj|aBQPe^ezRqH5IMotg2!|Py3!cO^+ZJ$<54z5?+)Wo@$a(v40*2~ZhB0&bp zH#q6d&6N{5B_!U<7ekCa{e2l#4waC{f)N!MidU^p^Bd)Lbe0^aG`ELO`d*b~R1rT| zhSne`79@MRB-^xD_w3qYGtKi8asKxph-tZ}U=BwlA_{4uU8U1e?*q-4h}HkddOp5t zL$XR^$?k)s90C^=+pKL$i14`4b|FFhYN3CSltR{(v6YCJY;r4QoIS#3gial0RMS41 zrfb+a9yJ;QN3TGr@ZVxMic(0YdWMM8$xNXZLHNoEFAS4wF}g$n~|y zcz68s<1|);7e_7Dar$MVP;RGA`;h;xmfdhR*fdI4vz8Brk}A zVv=~Mp17>W$v13|ERMoe%!=`zdzCOd66w_lVmm!YUU{HB|E{}BVZu$Et1-cV$EjfL zD(FMyULFTpNhAlA&!Aa8vvJ%MM$IR9`}S&W)<`VA{)!~&&j>btpO zgbb+wkQS9tA`m*`hp;EfPf2b^70$IOP19nn!w29}s6=Wf#$(BFjS@UseIZOp%L{+( z)6}So;)O6x`-L#OCOQw&jj>|>DM4c8`Uf?F8w*d#Ze^W_2DUjAh@HPj#*f~9yO*YR z*ajHxS~PH4BOyUS46a*{kByK8yuL{}C9EA{W-6q2>5nRQA)3;H5YF7Kjo02u z%vRiQDkjRlyT4=;(IvtfsNOuVuu2$icR$HWI6`ru7RRmm@3K=hC&?ElJ*J}Gv$cJ}{q)y0oKBV0BG zG_blA>$$Fh^(hXPQ?Dbq6@x8iabNt^dRtT!(1bz22E=-Xg8b|(>wKT)mZ+^S-+&ISeE;b>bnL41U)yFi-A%5mJot z?uD~5$#ie=p!5ESSr`x?tBW5dxFGO3Q`jFR{nhYX_?&NUJrZ1?yCyI1yMJvgeaO!o5xGQ|huk8FGNqs#OsyMmsN#r}SOJ>Wn^$xYJw}O zos2KhWghXnG2OkTxiZh(c!b)4cka&)3|66Vb2aH3ZMmF-TAZb;p=1BHvE9oY6Ybyzf*bre_H>nZ?#p zNW7yGIL1=yQm5;bONnfp5`2L18?%5!pm%V`JvmwiX5Iwa}?tH%ocgJ&}x_`uV^Ng_swGs4}*^yDO(cNf% z34dUr*wXz&-35Y6l~D)NfK)YxiZ^|dc$sKUFCzCxyMMU!Iw{9u-=rCb!h`t$q~GbLxl(0xxw&HO7&&I+9+Sh;wvdE~qtQFEJhM}Fzifp6combsl) zKtctcqtjSBRGuW6$%5kh$+l!iWL2{~c?}<#8Y`+UqxNLB=Q3 z{(cp1S>nY(tKCY8p0FJPZXUiYXHHSnwxMKY_QAv>JcmNqa!fO&IFf}6h%cUAcPHre zb7Q|>TUM=@LvI`pC6ZK-5O*>VtvrDK^-QPuWAs@Jv*BPop6_i+A5RnWb(?bWxKic} z_1bOeYTAEdr7oioxk!R-6Ab@dS4#Ed%=p;)@La4c?G^2EwU62Lgh6T=v=s)+$#_!t zQKjsR8dKBXXdP?Y1QgFNQ_7;gW=%Q#ykEw}Xx$Jg$O|HQOObfQcqz#Nj?K2#E`2 zJ+N-t%B)PNqHOZl_mis7VuT`4NRIF<|7xXX{#P7+Jmjn(uOAIXGcb_l3#MJBBqTa1 zvWiEX3kK6elNagC0p|dSl|e0}Td1;DZ(CC`sIgp=pZxT0HO9ARXf{4(C5Y+f?NNaBerR?P3aV!!6Q#!@tu`q%RpCrb|PH)pIeipf+W zho`qg_{;aAe)m@USekpBgFdt=72$d`5B58>qA zb&dHI*xg{>mVT<%VLAT9sf`KE+ZyLm{=MeHajH}SDI5fjsNdOR%}AWH}$@hLCXTHR8XJc#7nM#!z0p`v!@QQ|$5{Jod-=;#e_s5ZVO#W0T)`pf6%sefr2|bA z%NJoa!mpoSe0f^%cj*?VBaL({u?WIE8m?#8f$3E-+{BY>{!M-G^3;>~-%qamSyWSs zWN<_Vm!O@MY5U915+`HK|D1n$M&-CBA?ULv=?D`Gix7fcBXaXNIcb0@+Lgz^J5)C( zkS!{N88ZBCu3BQp;_xfhweDt*7X|zlz9n-pEz!)K_f9M!;`KW9iaA5&QP*AM=ayW3 zv-Rbsy0=3(vGVl~Zv_5W@ad(SbGw~Rv2VJq z6Dwr)AM_c^XyzWZPxjyB|H3+d$hZBcm>}o9rS_|nAy6*roKr^!TLi@Vqms5evEiTn zayds>+)wb_unhA(d@p}s_X*52KK0$Z-YvV>e^c7?2A@ofpxghiHoh`6-|P3WwURmF z$yEml?(I302SXOC$8DVs_#!Q<*)f9|hX}Ione4RmH~gmy(MmJVQMX z;V1QpHF)zuaok4Cu4I?onenVR$#;YN2r~u(!;OHfHrr5ntBol7L+sD;S?~5ub`0T{ z*A%=q75+7a&{O?vQ_C4-p5UxpZ9rHB53=KOl) z-ONLh!uTJQbm%!>ym8nZ8^SwwOpZ=@}j+c0_H&vu9y8yoCBOSS}A9H>v*x+%kE+rh;G zrz4DDz1l$FFN~kR_%B0?ZmroVKSklmjHna4?SGRD+mKV$5|&k}&*tjw*QHfB=e7lc zKkbJIRnpX}E)Cn1vP9*l_HViLx1#P$a`RYbdh+Q#KcsE^t9c-t@`1py4D$gugLygZ z&NYR6KK?&Rm(Lyk=BM4%7hOZET&H|S2>9v+OyIj$LZ|ke&muD0gZ2-F5LAJxiWSL1 zRLtV^>BG!Irn`#Gys~q{uzQrK1RqRQVTdqwh7GBpynDw+M$u8;rK#=^mz(IOP2zga zxB-H{u-tY`?PsUsejC5(dwcqIyu8)@n@k`4b#*BA1ITnH=J+d~opt%esNMJ!sk2jD zsJ+GCZ?;}p!BCo_57vE-QS#ZDyt{!%c|Ld3!-jvkANeokHJmlQ0#ezdQ(M!n7!N7$ zO1v)iByPF%V`ZJ<<=d`E7t|<@0Hs93Ry@&7u|Em;iojDG|0|EgF`pHMVEynAh~+5f z%G~Ny;dK=j=c;yT<9AvAL?{OP5BnQa;Z^QR4|6AwT8p=%;i^HjYQE!)+- z>!&iaU)~I@$VrB=xu|lKpZxj1JFv$#Y(HwHEIj&+t#ka6%=rj?{jwUN=Csw;oTtrU zH~Aq4uElRD`@tq*y;1Pyi0h?Xo}S=1)*R~O^kivQy2enS{^^j7^_IxZhWJ~o?jTrn z1t;soo};--=kppHk}@_^KX6TuV6G#>cnGsfG0L20o7%sz?>ZJTBFy4Pbq-gxWRL!` zchrUrFHNzT&p&(i*ma~lBnHh3J=%SD?a$lwJ^3McG72**rqb8;D(3(;HaPQ1K5g%H zm*r41D=|8384RN@CTFIm@v7&kh1)*me0E&Sg&)^G+%+1BYv$358} z{_6v);{%M(=OT0GtZ%O_l|#y#ca{N&4<_HNw zaei-SWIMW_=Os6FC;YkVjL(Z@Y$%ep4F5clMxDDEAM@R~*z0VEplbh?^cQWCg`CU~ z?4D)F(6gTHvO31SBD*8~TAMH%dfV&vblRiA;s{%8A9#2At9*xR_WVim+VGZ43-OQ; zSD#71PN=bb1cEe0{H6(~3xCTejw#N>gfOVb9=m)lHYIdXW^9QLQiWmxlhw`qPQ)4^ADr__mPk(|gp)!Xcntr?yP0 znC)K^9zXK*(9^sVFYDt^ls0D76sRd=`z0fh$j(9xwiZ6aPjc^_EqqqrRax*{F?wA* zY(?h6{|szsL?3?nQaL#qWTtr?tvh-5*7HD_wk8xSg3UYP_Jx-8w)VV?b3xLWy0b~f zu>UrF@^5|D5i>0>SC84y&i}3F+Z(?3Wh0(#C$>*{ZTU$TRykzOw1N*N#zkaqxxVix z?&$g}p7>2d${P6BO@l&1V6JGCj3V9wq?Gkv-B&+e&e;6nXAMuBDVuj+sl=Hvx;ZsN zh<62w@pjub)ZCfEpXdYaj&S^nc4RZr(>ZUEKa*DQJ z#SYv76)Ny^?)&YophH}8-c9$jV+++E0^yfAS$8d*!FEzjOZjN&c06evsX! z@+s%wvY_vHjn^-*XjozI=T>0YJatUI?NG^QNyDA=A`vgS>0tXAuMPDn^Ev!-fW++EsD zBPV3lrg2_HQ}bZ*x|q7n2)5^JaHd^-I<3LvQu_A!pT8LnvsYI>nmY2a=5p6o1#C{! zIMwx9tfP{Lq|TJGYf)56gOV+cxy$Mvs)_yZ6(_cR5`M%UTCy`FUrM2|qIIHPi{;4bK-c^0B%y_m% zMw{a|ESn!n)#lBNkF}^DmM9a0FSFZy>Xg~{#V*(bWKkLBp0knaAn%pFkJC$Lq zl;W8iOImlH9nPt{s?#On#^eKTc5}(~(=qEy*@C7yE|swR-663zMx<<8eS2Vs-XHJq zU-CJU)=~ae4ge>mX z{BlTd#oGkg(`9+q;JM)u#p#9UU7ut%NXLC1u;^#+f}8oYxW1R`P|MVU*clU2_NlYab>6Jtd@kRAt?2#ozFQ== z`KKb|CuFI@!W-nx&MbbDrLN!W+>pM6xp86_^A&0Q;T=PQB24Vi7AJHu%Ld(# z^k(ovj#a2QoZP@tcrpa%6T7d3}`>i&pdrOW*|;0q)vu+aU1;P;0qnT738j-_i@TUk3wd+m({5o zfx88vL{V4}S zTuo+>w|yuM55hgfaIWwAhP8=R8hNwe$IGvDtZFjSCfGE&A~Jap7Vm`2@~}>s`!<$NTD4+!hppbB^#;|tIkM>(g*`{olKHGE zEGRCYdb0kP;j{Y}GDjC}ocJ~`MA|jOk$I6iE)5S_#xuvwZI#zxSjn_`eO@Fjx|-Z% z$e>=d(}ILCS=dh8x=hu`-fO$pB&3|Fr7jF@OjH{U0*$Or9412H{m9w2?XmJO#h8d~ z8dq<3g5%k|$s;~RC&xHZ3lquIS0|^)!fIbkll89R zMs{4_w-!Z3=-NT1zO_Ukk{f)zqPeNIiUgT;!E*LAn*PaQpC$>oMun#?ETEh+6c`<*7Y zC?j=m*89x7(e)RO(u?1$yD3fRMN);4atT|%O-H7M-WGpL^Hwg6YDF41?Av7ig~(1{ zaXB(Hvr+$wrh9oyiO36+M{oeZd&0gFQu?t%D*JX!?$e7vZS{?2X z*Dtqu$0mK{vd3NKcYbofawe)L)+V9`i9g)l6t+{-y92j_o){l(S=i9=_QxCI|W;^v+XY5Af<%ZUFs z9Y&fk(G@W$HY5nYMdKwX2%o>b5E*;paX9gxrX@jWl=#&f9*UKL;GmFSof3bwO9_QA z2#4Ab0l!+P)P;ILf=H+jQ4kFcpdny8_kUWe#Nzc=3z%Q+UE<+aTbKm+)%N9AOPNGy z2F-y2RG7<7;gIgkr_7y?6K7z~FIFcL4+~%+m|zhsh9$5RmcepZ0V`n@ ztcEqP7S_Rf*Z^kO2%F$fuz(e8Py%+?3|n9;l)^UH4m-dBJ7E{>hCQ$s_Q8HAg9Gpv z9E3w~7>>YEaKbS-4kw@-PQocT4Ha+(&cZo34;SDfTmlzdhAVItuEBM<0XN|m+=jp5 z4phQjxCi&a4G-WUJOU3?K{eEX7aqeCcnZ(pIlO?E;DcB28s5NLcn9y{1AK%}@EN|q zSNI11z<2P&5BL{;LeQ&k|7ltmf{$xKD1<>c)P@MC19hPukRTH3Lli_q184}1AO>O~ z4jMx|G=T(Y3S>xxX3!icKm{7mfdMU`CA5MhXbo+kEifS&+Ch6rfez3SIzcLQhAz+* z(x4l3haSL!bm$4afDIhr0uT5g03nD#3=)un3ImMu7oF!x$I~c`y#f!vx5OiSP$Zf&!QfQ(!6> zVH!+_8Bho_VHV7WBA5enVICC2d{_Vr!32w7F)V?lund;N3RnrNU^T3PwXhD>!v-+J zM%V;@f(5K#gA%aAX4nE-p%k{kcGv+9*a^E}H|&AEun+b_861GW;2<1=!*B$Sf)kFx zaX10xa1u_zX{dlRa2C$NdAI-<;S#vuGF*YHa1E}*4Y&!n;5PgXcc2pP!acYTZg>C> z;SqSC3aX(7yzm&Fz*Bez&*25U1RuPD*YF13!aH~mAK)W=g3s^;zQQ;72fl+Je!#!* z6Ab|0MFj;Xe2YRuxj_DT7y~{CKnNlbg9M}?0|Mlr041nE4H=+;Oy~`Lpf6-WKj;qw zKnnw55DW$#WJ3<*f*yvzP#6ZoVFZkXQDA`4Fb2j#9*l$WFah#mBK!f9pa3Sr6qpJ| zm{NcET>$4SQfO?1TMK1_$6TI0%Q}FdTuS;Dlpv z98N$voP<+w8Y(z zcmy7(f@-J%FFb}P@D!fGb9ezS!3VG4HN1hh@DAR?2lxn|;4^%Iuka22f$!jlAMh{y zME;*QM*iP54&)!>!2>=BKnNlbg9M}?0|Mlr041nE4H=+;Oy~`Lpf6-WKj;qwKnnw5 z5DW$#WJ3<*f*yvzP#6ZoVFZkXQDA`4Fb2j#9*l$WFah#mBK!f9pa3Sr6qpJ|m{NcET>$4SQfO?1TMK1_$6TI0%Q}FdTuS;Dlpv98N$v zoP<+w8Y(zcmy7( zf@-J%FFb}P@D!fGb9ezS!3VG4HN1hh@DAR?2lxn|;4^%Iuka22f$!jlAMh{yME|{c0ReJQfD%-oh78a^CiI3r&=<0xAM}R-poM`j2nK@= zvLOd@K@US4+~%+m|zhsh9$5RmcepZ0V`n@tcEqP7S_Rf*Z^kO2%F$fuz(e8 zPy%+?3|n9;l)^UH4m-dBJ7E{>hCQ$s_Q8HAg9Gpv9E3w~7>>YEaKbS-4kw@-PQocT z4Ha+(&cZo34;SDfTmlzdhAVItuEBM<0XN|m+=jp54phQjxCi&a4G-WUJOU3?K{eEX z7aqeCcnZ(pIlO?E;DcB28s5NLcn9y{1AK%}@EN|qSNI11z<2P&5BL{;BL8<=A^%ma z0{O>y@PH2j5P}HAAOR`JfB-otKnW^PLk4Id6M91*=nGlU5BkFZ(853%1cN~b*^mRd zpobwa6o$cY7y%<;6c}JMjDfL`2jgHoOn`it2!FsND1gZ@1*U=#ronWW0fjIVX2EPI zf;li3=0P#chXt?@Ot1(R!xC5u%V0UIfR(TcR>K-t3+rG#YydNCgiY`#SilN4C;>Zc zhApraN?{vphaKR6ov;gb!yecR`(Qtm!2$RS4#FWg3`gK7IN=x^hZ9f^C*c&Fh6*?X zXW<;2hYN5KE`bX!!xgv+*WfzbfSYg&Zo}Vj2P)w%+=Khzh6nHv9)Sm{pc-nx3yK-t3+rG#YydNCgiY`#SilN4C;>ZchApra zN?{vphaKR6ov;gb!yecR`(Qtm!2$RS4#FWg3`gK7IN=x^hZ9f^C*c&Fh6*?XXW<;2 zhYN5KE`bX!!xgv+*WfzbfSYg&Zo}Vj2P)w%+=Khzh6nHv9)Sm{pc-nx3yK-t3+rG#YydNCgiY`#SilN4C;>ZchApraN?{vp zhaKR6ov;gb!yecR`(Qtm!2$RS4#FWg3`gK7IN=x^hZ9f^C*c&Fh6*?XXW<;2hYN5K zE`bX!!xgv+*WfzbfSYg&Zo}Vj2P)w%+=Khzh6nHv9)Sm{pc-nx3yy@PH2j5P}HA zAOR`JfB-otKnW^PLk4Id6M91*=nGlU5BkFZ(853%1cN~b*^mRdpobwa6o$cY7y%<; z6c}JMjDfL`2jgHoOn`it2!FsND1gZ@1*U=#ronWW0fjIVX2EPIf;li3=0P#chXt?@ zOt1(R!xC5u%V0UIfR(TcR>K-t3+rG#YydNCgiY`#SilN4C;>ZchApraN?{vphaKR6 zov;gb!yecR`(Qtm!2$RS4#FWg3`gK7IN=x^hZ9f^C*c&Fh6*?XXW<;2hYN5KE`bX! z!xgv+*WfzbfSYg&Zo}Vj2P)w%+=Khzh6nHv9)Sm{pc-nx3y5|Dxn z2#|vUl%N7NWPk=Tp*Qq_zK{j|pg#-%EewP~Fc@@@4LOhtdKdyjVHgaD5ik-)fdNLt z7#ItAFb>AU1jvVp@CQtS0+CNssDLwY7S6$WxBwU761d0 z{ZIx6;4e4`hu|u>{Z z!Y#NBf5RQ9gu8GL?t>d1z(aTh9;kw9r~xlLh9~e8p22f?0WZM^ui!Pjfw%Au-opp@ z2%q3He1Wg<4gP`e;D;aZFZ{$0g$}A0R|h-s@mUDef=~#9aHtItPzUNlJs?3O)Q2dD zh6d0O8bJ)iLL4-PcxVC%&=km!2+g25P=E?FpaTP1Kuc%^NzfYFKwDr!GPHyCkOCc` zBXojP=nP$;E2Kd;=ng%A1?kWedI1|azy%)gK>$J!VT8o>BtO?!VIypUKfwZ4ut5pfVKZ!jtxyWvU_0yp2keAhup9Qk zUf2iwp$rbdUvLl(!C^Q8N5Kil;5eLsaySX6;51ag88{2);5=M_i*N~Ca2c+^Rk#M% z;Rf7tI|1Y#SUX02q(|O#ui@0WdD}A&~$7nfYHg zEHpSW?tEmR00as^;2HqO!0$EzST+_DfOTU7`48kjkpJH>|MMq>21h0Q=R&>~-hL>A zK{(Wg2&e;fp&pPR66!+~L_-5;2#p{HVj&J1Lp(Hr1ZWCmNQ7q494J5q8qk3OEubZ| zf+T1SZJ;eMAsO01dq{x}&=ER8Ds+Y}&=u048+3;rz=Cw>3B7;~9NKX4-ME4BmU-G@NnNudA7R-nL602~*AodEx1cLL!_pl;^^1po(m;8DQ9 zZs6bWNubc6g#SJU9GCzE9tEC_I#>jAU@pvqVhBtC{>M%Lnzg=zoj@J#1TFw@ob!MW z0uX`-#2^7F$bbMjC_o7+P(uc2AQO5+ALt8N&=2~<0MNof7zBes2icGVxuAz3FcgNt za2Nq2VH6l(G>n0d1=SyG#0N?n)0zlvf!0F$s0I+^G5Bl#f%70%Xf+;~^!GXCzU@j1t3;bTC;J=-L zsgJ*e1||c6$v|K=0LQ>@HW~PD1)wGTr}!v-+JM%V;@f(5K#gA%aAX4nE-p%k{kcGv+9*a^E}H|&AE zun+b_861GW;2<1=!*B$Sf)kFxaX10xa1u_zZ#e;AY#Sc90>C#va62$?JMgzG04)MD zfd4}?fWY&BsG}<(Fah}g&5s5O4Qd(4e<1&X=YfCQ3xHOE{0H(M$p3Gf|D-_v1Njf+ z|F_M5>p=bk`48m(x6OZ>K>h>y59I&1&41fK{sZ|Bh>y|84W19LRql z|AGAfw)t-t$bTUJf&Blr`EMV{e<1&X{QtK3PYL8dkpDpbf7|?b2;@JI|3LnK+x&M7 zmN*{C5iEKal@G{(sy2rv~yL$bTUJzis|I2l5}te<1(AZT`Ci^8f!K|13q9 z|F%$8{$H=LL9x~Tkl5G$5N7PAyTP&1vEi}dL>7xx|y z{+Kd26d&Oq2(CXPh#f=;A_axAgLOgVpa^z|C5RbBV%PEnv4W!6p_E`ED25%T3)Tk3 zv%@XHh9EM#wkOyaL}5ozLQFvnb{$=aIVg!;*An6gVzTRbLYzSQO+Dex;5;^&Qri`r&ra0U zb_W-*n^|i6f{pCvp4$H4LN)E|gHneGS;=mp ztD_BB%Wi3@V+b*`TY2gjLoDnhN?lWko!wej*BnyHZeywI2yw96dg?ku_OO|hdajT% zcCxOXJLC|%ou!^H#K~^&spk(VXQxm|q*@j14muLK)_HbE3yE3F#qQ)Gv1(mor&1z` zTDRDpb&=XymFzB-NJA|*yQ?SCSj)psqtrLm^0K?>>YHmlV|TaIchvH+dwA+QYrSQ& zC{eCjAKB@;D0i)|?4Fh=UoAhomnX_!D~Q9UM3X{8IUHRyIW&U9wL~*RNgSRhniU$& z;ZqtAp)nkRu7Nf*o+Gq0FocphB2NQjD1{@YG&F@WI1*h$b7&GrYH8>QWpZSmhR)Cw z4nb+;3Qgt6b&cGiX&i;6kuQ|RQF#*k7N?IT))1!U^!3CV!*rZ1N}MT7&*`U&Glvc5^tZ%0!VH`No;YV% z9!E=Q>*C4b#he^VJTu(H$@Rpu z!k2RNlqN*@O3n~n6K(if&QMDeL%5kU%+tgeZs824B$&eOoDsSNb9gCdq$R--?%<5_ zBsjzOa14~DuJAI>XkAlx_#w_1OH*IClQY)S)E{2X$)k`-wJSK|bYybv^PKS(GPAae zGr>b<)xO5brz8@!Z*eB-61BA}Ie%CZ4Yl2zNuESwZ4ak_(#%xb%bBceX0H8=GsV)( zQQOCv>S^Yz{gz{-GEj#a-f|`y<%gr4$CK4xhVB#~{}c zbC+8f%sK>jg@?haqvEclv>@taa#!hEXzOHgS6f;b>S(!ZJS~iMblkO+mZmy-?mAsd zbDiPb^_G^7ItK0rPfKT=Jg%A2%2g+yyHVH5U8jJ%$3`kZYkNk?Iz4 zt-2&~-D0lIlEkcQ;+A-lSap|j?UdF;-Id(Uy4KpdYq?u2tqpa}+^wG0#<~`6DW#36 zuARG0*T!78l)K&1#!=V7-Qj8DthE#vOgwRP7$#NB0S>#OVJ?)J3x*DdGn zp)g7HD!6-fOme;R+2we_4_Z_1xTpo@8S^ z5BCtIovEIedsx@bT<;n8h^3vQo{xLf)6QA%E!RnD@2dBadra5fUGFRRxTU?Xo}YWd z)81b%h*wTYA(29PCv_=gQUvdmC51^M@lJbESfprP1*HQ)is7BnbOOGqNSsQ#N=J_baawZcrHpO7b%r@S=Y%;O5yJ>1>SD@hT}@Op$utU0oM*^=K7_)7nbgh`VQVpPj_eiJv<+!hpT=W@0G5H zyZ#~GYfBGbeJAgYr-#3OIqxlnMT)B6z0E>yLFJmF8T>lgTyu01zpj<*h-UKZRdJosDSQ%@ z=Za3{M`rWf(P{kpR-P}K#gD4u`J>tVXeyu7fX{D`%_lby^BY?E%mxI%Q5B!nK*f)t z3Wx@o{Mc-Pwm}v@&MGi8(DEBs35*SN{CKL+)IiT~k}Whh7|u_y3LOm${H9exXM;RG znJRKM$mb_!i`)$g_|2>$Ujrk*d6mfDppZ|Yib)NN_|$AMxnVJ%W)(9Vn)vi8F{|NH zK7%SD8m{EG$d+guuI0D1N(>Fn{8m*GV?zr+i7GWUwDVhMOU(^S`E9IHM?(j{ZI#s7 za1WnJmAM+0@sqP?W{6iLnps|mCWC;oS#A^NR2A^9kK~>qx1ZZR)X2c#qU%_ zuo_+Cr&8raqg(vW*>Y{8N`4os+|bC)?^-1{HuCV(s0vdfFTY#1!rbT?zq?i8XyoJf zs8To^z2&p0N>`(g{Pb+4yU|yEPpi_`$j|RprSvxn60oT%QcS3TldU4hL29WLl^?c<0w z2nJO3amMBewA8+?*nGjj?7r^U0>L0_Utg?IFu1C(KekYyqh^ufiUir&S>(84L5?+x z8D|pYR%Nl`mJ0OLeni|#!I12J+PJlXq1JweIJ00_RX<~#MKGM&-xOyTjL7b9jw=<6 zwDxzzIRvAs`a9$H2n^H#uDCM6=_{b zl&U8+;R}~#>&Z>T!sS*yvk4(wQKe@!Q3+R4hY(FNg{!iMXq#jSS6hb|nrMYr!dl@L>j*=F zS-7=ogfYP)ETxV#CD?`AvPYT|N`>34BOM72;f|`2&V)Te2X&Myp-i|ldz3rjkZ_lE zlrO<4++8)wpHME`Lp6|^RtWcI8^}%13-?(K%%(2k{wf2j=`~>)bu`iRmheFKXl>I< z;a}F#hNf=e!K%^5rXJxT>KIc~ukdj87<1ES!Xwr(j;220(W)`drf-E#>R4CPkHTZw zW8F=^3XfaI`kMNMC#uH!n+A!>sd*%FsOV&N9+?~=I%Umcl1ZY|Re3COw5WnQjv&W~ z&Sa0%lH)~Zt>X-2vglmZI3t-NI!_&MA~Qr6vd5drNurC^@eVRmbg62*lbj-QQ75>_ zsiMo-6Wru9(G}|iADJb(S~bB>W{a*-^GS(((e>@>z*0(Jksk zA~92RJA0xwF-!Efb)q3rE4ouP(U_j>!%w{H0O;rJ_ z*;0|0I+7JY1L$7GmGdMb&9E(UGzMAin&>-=!JEPqnShW zvTBO6*&dOPI@Q&zO!O*ys=L`C(QE5eUo)rZP1RI?vvSc}s*%*ZLi8@%NN#>!^xkS@ zHg}0WR2f;#uZccVrxDF>i9Tgd(>AXZeYQ?BGR82EBpWzXGrA{|B_lmw{Pd7Jz zCi=%Z-O=19`d&5N+5D}@Po3dv{!#QJdxpFDSJA)L8NTLz(a)+G{^mjAAX*`b5-JYP zDI`-O#38mqCWR!fRb9xUM2kadGYLwJI4ozTmJ%-xx6L$A$l}`7GmR9AID$6IL}7^Q zDGDJIj3#WY(nlV%drtBYB*rD6tcK0#Y4Zjm!zOIs^$X`64LnZ>QD=NoAjaT0BT ziDnnK&RJllm5STg7C2}Qaog$zPTC$ZleW-BD-$Q@EOgTjiQCy0`e;sZ`|5>$TDdrd zW+Krm#2s=>Wcqn=N1KUBcZoYyn^^Q~;#Arqf__WfIcJfUUMcQkTV$ZS#a*ix8R;Hz z8f~$O?iF{-S!||16L+^QcF=v|9@UGT^tWObZHbHiQJkK$#7+My?rB@%qx;3Zs+aib zK@v7?DTxs(;p8kOGa@8h+fpWjB;i#rWig^9eA+UC5hD@gEYmXLB|_UW1A{CPRWCC# zC=xMkxrxD$NOG2&8A%eUZMlQNl*p==I~gewg0{lNNR`NQR=62y5`}GrkHL~Ct5^6L zY>A4tlGK7PQRl2Aw-8G*Y%7^92#Kb8C98!>l1W=dw8)h7&RL~xktOM4TV-gWmGrG% zWo)67WYJceTIePHa#ovL443q`t#-69NCs4|cDBfqXlZL)E%GG;bJn<96i5cy*7#Z& zC4;Ni_*)c8bhNdkmPL~6oVDbZ#gZJ`T4qa=B)57ktL0LOp0Z@eB?N47Tzhp-BpZ-=s(n6YrloTqRnPVX*MM!7aEX*X5bau6cl@u*4 zqFITg80nlGt2QZKI@e}3B$1`_s;$N(inN$!GbJ&k^K)$Gq$KGAo6V8LlrF5cIg?VP zCR&LrDOI{Cr^KCnC$|<$m)q>j)`WCLwVl;k zC0$9|Otj9FuFBc0ZJi}uZQE>Ut(C5+-fV2Gldh$0F}2o9*X3+6w;nECZ`?oo)6=9kd;;Hf7SCIXm2K4oP>}cKF&jrMs(l_}i3A_s|@qwiVL7ISz8$ z^U{4b2eYk9y1&}NYI{vuM%ziWy(K-6vs2r)Qu>!|r=hJ|da!z@v8_jXh_=hr)+;@n zv&-D}ne>Qlm!qvudbE0%v+Y}{leXK{_M`Mz&Te51yy{pm{n9;Hd+FpVgBRi9`SIdl-owe;XFv+rW)q9OhitIdX zpNYwkUC7yIW+url+V(k^OxdOCeNJYI%thPpVy4P2=j?Yg(_~j{`+ZE7>}vIXKa(xH zMk^yF^JUj_%E-xL*$rD6GntUxtS)0Et7Nxm2Z-cM+3lPI+T<+R-?jsWWUcH@^#NnD zPF6|#%ap8_-Oc&SoIG51&-Rxi*&w@L{g*R2Pv)i_bS3A@9^@Q!Cl|;b+79}Xjj~78 z2mQ%~G7s$#sa=t*D(4WnU9qg%c8J-|B&(@D#A>%x=A|7b+O3p5&N-}Yw^sJVcG%F) zEPGmg*x1e@dqz8AYG;={&pBdlS1Nm9JK|{PkiD!v;%v7^=A#{TwJVdo$~o$8cS!cy zcGTC-DSK0W)ZeaL_Lk-(wXcx9%W;z1pO?M2IhpNUvJcfxR{I&(WFKkAi1xQ+pK^|A z+gHjy+m0F9yJcUhj~Uy0WM65=P3^t1Z#l=!?Vrj1u^o4`_sPCjA9uEYEA!J%xY~b| z{m41tZvR#GukD1dyrI5D`Q#C#8fE!MWw+ln5fEq@0;TB5Ku?vr?joQ2I$C zC58ygJ*iEJC&Eik8dAta?V6Lu6bcbRKV?c`5Os1-nNyO8x+SL^DNLeX%_(O}3PGZu zcBP~ek-4YcDQQIglGDBv77}Vm9=od{L?L_O`i{_4{M4OU}j*bqZ zZOuhz$2|m-e#zCbj7ZMCdcfNA#$<;_UR6V9~F-I(;P4bFaEPeI5+4O6q)KEDm_Zm4h zLe4F@#!My2c{SHqsnK#i{W_5vBNyae*QUnHg(cSwsbsmR=DIPJA{Wzdm{J*XN$w4E zYLZ-9a>J3zl*?*vI8#&P1pTHfHB~Opz3EO(lPgMY`chePWz9{0DqF6i-y(J9%hkEJ z$eqRVjFMZ-&V*c3bBonkCC{YaCOT)zd*|NPcFvObDYd2%iNj;nLNd|>V!cjp56pprYj&PMs*nmhi^g>oIe zlGLS0o}F7s?ouqzDXC<3G0AglDp_5Y%JuZSM3BRA0RySkLgN9W#mcR3^kT%JdFle$*O$K|@oU1yw^k1ugEySn5PYTT@@*W~&12SnFf@`B~N|bjEX;Np8C5LDlGJ8r0zuuYwk00_hN;u`5yz*?xI|GZXJXiD1$f79E)8Cs|4CRH~ z_hwd-@?yz*2aBn^RP)}+N>RG#A6%?d<>lNDZdRJ|O34Qwi>16;^TE$zE3eT%lG6Fg z>$xAv>0;%Ll8?-ELV2_1BP(5{yhZ;+q-QE`=YGMGN$X4mGsZ1 zbiML!?q_rQaOJ&{&yIA1@_x-{XL_E}P5jK5NB{2XS*CoI``z91kn(lOcVADZ z@=eWmf6p1^%C~essaJ*aU9O+p>%8)PiJ#farTkFiXZ50;5t5W&7 z1CO8#~9@+rU9{Oj!XR_UkzboKhE{E_?9 z-RrCJ-;$rcUVi1znxFn&L8>4|P$WB46|4_RWJjn%>_N$FlB$+BD4iXx3S|V#*)ggx zeeghbyeixtJeo~b)%FHYV^dTSjF3fahN_M}WFtFCRo5P}lg(7s^M)K_r>IDbT9?_W zsz`mU2kbOeeS57}Y?dm@Tk8j#t%_!ZMsoP72KvxMj#$;u9-7P{RE@l$=^T|Rh7l&` zWU6BIVFNi?syKVtXpUCZ*c&#Dqf^B*!WVJ$swVpIjhx}C1bg^SjzQJb8-9$Fry?_I zU*_bi67{toa0*n-?6qHUjH>3|+CMmjDheYal3S#r>LU`l#VVRTBAIJa(Y+Dr+@&f8 zqmG=rQq@9VXCQa2s-?ZoXs%h+%3Eg|*P=>d)Lq22t6J;pZseA#+Su#v*Xq z_o$eRdY8Fns$_k=2i!xdcJ_L&xK34jZ@nMfa#ae06v?YlbvwoC zBsI?)oz9O|^BE1~{1~-B-(Vm=UM;jY7|kcEMcxL}_!PC6(Qpx;p_b?yZsaGarS^t9 z`AoIU+wd4aMNKdoUFN5%<@!bs_-Sf|z0oT^ORe-a`oU+bRg9QO0bi}w$0Q2G>I{2K zvVc%)yfNtll{%9VD;H#{d+TEd3bNFF?6IQ-T6JG<>@EkvEhO7JA z<8}%R>H*%kV}d-jmeKgKAYVOD-}r%`Kt0Ib_?5t@9_(%WLr|#JG2$bIMe1yQe4?;e zonwzr7Mj$#-uQIkQnjAZL@r#Z9-?nDP`Fk-)ZS#Y(5xQjZ8A-0Q4eP%EE3w)BlHOy zg{A6|_Jo~6hkBGZ;h1ob+Q4XfSy-kXt#A53IOC9djJ@eAp;JB9+w_O9T%E@tM~W)c zVIm}RFVi%A)?y_9rubVd<_Di_CO%+XT^isLip+Nq<(NGJW zqnJTkBxYpH*V8tNlQI_AX*F>y+Ui9x?CPR&@Pr#}#tMn}fO0qIm+gps5XfxJ$ zTTGMaGS)I$E|Tao*6CYrlnl>UZ*RF%V#wIwZFx+RmtkhKx-7}h*r;#yKvIyg$=>Rf z#F+7?x780xVTOf~6e%srust?$uFcqD zZ#`OS&e-a0JxyxKC}p%+B(-O3)3@0uEzQ_&Z?jYC$k^d+b4Mj6Doyq^u%iub!DGJD;)7&P9T7XWsGFG>{iAB zeeytAWyW9jDxb$ea$#-Z~sc>&p6?2|3em}DQBca5}}%t`jkW>LUYQVl1z{^r@blZM6{-Y z(LqkcXwK+63?$+;XYCzE6J*UfZ-;3FMRT6faS_4LT+nyiNF-@4+B@zfn3_x8j>m`; zjf>IgGLfpetnc)INYh-gcX~yzG*`Wyeh_TUHAZTroUggAPfe7IH8(u zS7~lBI?Lsmn%nx$1LawozwMnz%e9(2-pt297Uwf}tO26i(x7QD4P-ajIcBCpa zGk6F)Q5BIHvYDN%B4yTk%uZKDXNI=m$W<|!VM90rRq>hOn>nLZ%!n4; zMJh&Sogv(fs-(=io4Gqx%*=X^xyMu~|EsrqkBg#w9KKIQMFmJjMFmL4VL3`gMFogT ziUtenp3kS*o!P_e8Bt+DMMZ@L6%`d0RQ3!DDk>^0sHmv0prTR%QgK+0Qc+O>-j{w4 z_xJn!o`0U#^SbZx1<1@bGuO<{_}}L(&OK;lM|up-16tXa9*gtTubfPe!z~(GIiH@0 z^9oAxSeJx*9ZK?BmyCNupA@++1^4DqQvAAfoOjUIsq1jKx1g`->qxk_^$i*bQLYf{&j;DVqv^!25< zVEr1&`Z8R|(3K_I$T81Hy!KiagoqB zed`-=QTlHt*Eiyp4t+Dfz6BQ@l;W|W755R8;L48wPN(LD<3#gSamsZ21N!?n^zkX2S&Tt08RDhG|?} zP+G@^8C*P+*0*66m!MCZ+%Sh*Hk3BM!3CcflDNhczWCKc>#}hH_~fAVg}6Zc8fbkv4ufB-UtfcZz<)Ee zz6lqNPYK%4fs4VXLL2&Uv3RV0!z3;apEk5%9+!wu55jrilkn>xoF6_Jzg~}v#HZjl z4B_JO>3CcaJ{6C{;~_j9Pr?)QcnO|{Cl2AW@hm(kh){^<;mHu891r6udO{6ejHeC} zn(#6_Er{5GSK;Xpu@9e#XXuHO_$)kgh&YeW#j}D)9)vtR8zT7;^6?x!DUwit=MItL z3B`C`5IL1lf`=e7oluJB>&X&A8D20%&L&ji;UG#Op$d;clyX9j2`|)BY6#VM(GaDH zP=^->Q9B6rcnL)9BQ)SqJ#~`Mh?fpg=Ls!%SrE;G*ov1!G(Tb+UZJN&65H|0AzD1K z3$F^IrxLsIYKTrJ_TV%0bP2H+zj273O&q{y1~CeWgZNDlqnzl(Z`Lzvh!glNLyRWk zG(Ibc*+HDaXG6?B;w)aHXHF95@Hs=wd7=v;H;CmyawTkqSbiio!ZtlClH^Xe&*KFJadZJDU_h$PeNak^%|4Ax=37L)fF|)Q} zLUoX+gHlhZfkb_j27*m5nxr%mYKKJglomo=kl2ITN;n0H{itn((|U0vwViNgNE}b? zBGd;-QmNg9vyg;N?IE1gOC;1@!ucUdHg$l|5QG*|2MHG-w4CZBT-2jA)Ct0+A+(7) zO=t{~c2H*sO^~#YI!mzYrIXY-Li3Pxp6Wtu36goxT#1(8rx70xsk7-UVoy*;A)QD37Ro56!^H3O88vh<@%y2S zCc2E+8?>>5t|In98~f;)#D4w8NqQFX(a^?udMl|*OI=0ZjlaTMBI&M* zFTJLQIYIn;NYlieCe8)rbTDU#^H5G7bC$TE&zWS-5uXg@%rjj`F2T7TELYNV{9Hel z8|isNZY0Z{^ulm%Jj;vZ8oV`?%?cp71#c^41(IIj zZ!2eENUs{U)vzK+uMKZ&VnvhOgSU6EVn`nR?R~6RlBZ$&BrA@zXn6ZPE0N?Coaez# zBE8Pf^J6EI-Z11vvQtQJ4(G+Q(@EaJJ5t#=(p&r;bT*0fwqb{aO(VTCyd#^yXl-#Qm|pSgi}Te8Qz`E zsU%^7_Y`ufNTK{aQp@iE@ z`h2)Bn>#>?4b~QN2T5P>wdGtV=}UvQhC4y}YFOLEohHQv7j1$li5E>y2|m!liy^1-5A^Y3 z$ymdINnRW|ZTP@EFOi%cT;c&Gk=OA{{Gep=dP7MhltSJxToMnZlX1ZZQz0A~&p$|q zNMwTHpai0kiNgo8Ar_ewe5erOk;(i+mwNE?$ZUS8A3vYWF_cE~3&`Bz(s+I`nHPK{m0v=J_($mc zoKiC1a74l{BMXL)Wb-S@aPZMWeia$vA1&vb$U?)>8h$ldG<>v)Uq==PAM4=PlO_CP zef$P8YB)B@ZzM~HkInO2$g8tvPeNYSvg!5FX$qxg3D6{-DEYt zoG$1gXBf&Qf?o2*;qq+3068;QS11@HZ{q991y1s2gRVv}LEbW~YZ6S8vw|x+1T*Ap zenp>PmaH*UObX`6Il~q60vAedaHR+AO4-V<^n=|f+YFVFusdb@aAiE~Mac_3o(g+Y zcJPnWVIRs)!*L1hOW8GiJR1(68>%9a6v~0&s(2)wQWC6B zMR1gZd_5f@Q4SgO5`;!MJgm<~Sd`LWLm|SW9N`Op(F@%E@6Lrw zmQeJ3GhJ9pF&NAeVHw3ZY|a)|QcS^?LSYrf%(s*aO%#j4QX{OUScff5!a7QIu(d;2 zPpRQs`-BY?o54CMY^2ll)B(*4^b=S6u;U})J8dNsE!o1Q_c)m$BVis^}#i% zqHfArehppJLpf)tk%)RJ=Z9;uMFW(EU|XSRkaB@UF~@iP)EVWB63IIDpy~e7aB^NWIBFT`tB@Zy8S4h$E=Chfg<& zqp9t|XF9|&)DHfcK5;D7VK_4>j-z%CpP3gYQoDldJtRrgJN$Y-Niy}Wp*~WQLcKR! zA1_I#b_btLmEfrN`Df`867_-MtVBYiJ{&%qEn!i6g3lF7c+_wC=gK88^*h748i|f&~M@y;0h6@t3j5;!WAselvI)g73qE*yU{>5_CL>)6+ ztU;@(rw{h8nBCvBtt zVrYz%wo`u{Zj6_9QD=giQl;J0-}p^*X%F>xLz6_>OZ{WGDO)-~oej1ZN(ZTb^6lkP zC-pCby+%4g{d?HnB%P+t1vhs{XQ=c1=052xb-~a)DV?J}8E&4Jy3kxgT0CT~wC4mZ zelj=O^Tw7)nLF);k(PLw7tJ-~a;nUm_M+f2UFJi3$#_{J^QFB!ayeTTKywSZQYZ_g zy&||$F2m4XHD0NaMbKUwxzZ$yrn!e)?U2RLJOo$!WU(|)kws(B2$rjhCm>yhE;~%5k)}1lQ)7lZr;# z(vjQqiWXXQNV|u!mG+UK-A~y@``FkXscffxGSVKe?4relbfhY~X`c!@=*k}2XT}bR zvX}PxNJqAEfEF9#C{zy8z7ROdl}_51Mn{cug7(#jqe(eUiwo)OP|nce1)Y7$Sz3az zb5c1+TQ<@;uXLd&hIDzTTPZiwj zQ^nG;#(R^hIC|R1y?Iq4Jw2q`L!CrlC+PN5C)3v(yCc;p^bI53@#=IsF64fy8b`+q z?$gyII>C5fqNdS_Blok_EIKLVL7|#QCkq~wt6@6D_@G8Drc*~AG^u5DTFAo=wTey` zJnU0v(iz5wljG8<2 zp+kai=^3STzVTa0Mj2f&@@;lTB^?g=t}vsDjtIUh&oI%2#_wt}s_CMU@0v2|=;Dy? zJ2L9&62bR<84YyQ`2A!?BV9W3{d`6XT^7>ov9Xmd7xemVY@;iTy^$N+>B^Db_>En3 zRY+gz#%{V=&`00cL(eewNjCPUf{=Zrj>-{``~4H@vrbY*N64ESZbF}4{8A~W3? z+eZfCGrbsjAwQ&MdNXziexPUiFm@V$kYxHYc8&ayof*K$5Bae$Gmx=c@MC!p&GGiEpf}i>_V;NfGPm`H(jG~dB<}(u+#UX1XdlQRM8ZunCiN`o1 z7%txgGmaXEYc`1)$3}*mHpv)eAtN1|RE%=LNZ+PRhR!%LxhacLF)}j0DVI?h;`G>@ z$2cx<`fbi~gHy1EYjyU5t7c;6tMpHMJF!X{^`sPxG!8j_}T*fetjAn1HWSBz6 z3O83V%!0A<%_fG$I99W{nqeIoYua4Ls16zL*j&%35sde3ZeZAqO&?|w{$bk3MT1WdKl-7laejHjPoOt z*;@t}4Ixv7TLu{y1XJZ(oQ#XcshTYlj7uX^OBua1=GBqu_$)7GYsk;3S>DWRf}iPGKFsUJ zpCwto%o`&=XJ-X4+d_UR%nD@Q6#P=2g<;+@{!)__!Mr{4OH)=fvpwY3j;t7Fhv3(~ ztXQVQ`0Hd=9J6!e*ZHhOW>?6JM|KkPj$p<;-YH57R>qOv@w4%&PC?5 zGk+bKi_hs|&VG($;gxW92b@g#>F$&mGvC#;-Blr zdfwy`mFv!W!ReBa>&0@#JcrHoX1xeM$H?_zy<~b0&Gluy?0im>8^ChIJg?0SWW54E zugk@-UNt>$%Z*^Y=6v3s8_jaZyx_=2yuln$GgZyolY3W4#5x$k<9^y={6C-AZG<<9t!GmBsSG zyrkXAW4#N%q}vL!-ZQ;q+bU+g?|jL=RmSqgyzJPjV)?-@_ixQ)`I}yz+M2~$?0k7) zYc4AQNG1-B!j5 zalWG2R>{I(Ue#`^Vuix5>b99!VWwAY+p1aN&R6Z*>R1t&*BsmGS&{H-{o5K?QKr|X zwl%VrI$vAZ*20R$xO;AIWqky@`)_Y!eQa`%+TPCk#Oa=}y^9rt@xX5HW_=2KFt+!w zJ~Mfs+k07`J3Tbp2UxKfPwn3vniYpx= zHT*gw&xgIr^g5d7%Uy^`M-qD-?CrlJnZ4fR9knBcy}{|7up^y~ z!@Pyvfn($0w-`G}Y=Y@6bO()1biSq8!D5pzZ)c#|e^(n@Ve*aI z)y`HreG_(du~is9?5=LM8unxC>S1S?{Lo#!?2S%8&8`7L1ZS^vi9J7>Q-Jx3D)lB zagM;jy4^76s43XCTg*A;47TrFwIULfzJCma`g-q?v;#4?87Ix=yDlr(( zJ$antFvfpRKIeo96Sb#+bJB@P*i+1@!h~Y?lyLNLC}U44$6yLY_mpvr&QQ&sN{$H= zrrlG;F~ecHJtmID6lU8~&9OSe?0f1s)tGR{o_bCV9NxdDfnzg;Pwi>s)H=f#_Ox*7 zFcF@6TRErT2>-opoYSU=sJ-o+GtP*FyB3$YZVM*bv%r;m8IJZZaN}MvMMo95bFVt16AHYzt(cFn1>W3i@JEaSAMSP2M`(dB z_lEN$O+f&+4fCd#Be*{Px=dDxen7O zQw4F{PUj~J1&Q1)OpIq?688=q<6oG}y=#hzDoo+tbH*eTrgOV7pJEGf-23pSj6xFk zf$3AUkj8!J{8UrO;`U%Z(-!i$-@>2i3SsVdrq67JV($0O&+LUcGHx&Cb4Q_y+XsK% zUzo}5H+?=;n8khM{CuG>mpg!o_0;BZe}H5CwfWp1O|enh0`5=F*aU4ccM$UhR$Iay zg1=yBOS!|QFHmh6cf|RHMq9~sV!qUBtGJ`^mpZM9J7)UQrmg0VJHNDR>$nq`uN>NX z?j-zGzqWxpW%_DL+sJ+F{Axkl!kxy%c^0*De}?1yi`uxqnBt;}+PS|v;}VLxxHFh| zY*9D&H#nYA)WiMV6pt45a{q9~Yl;TAvzP>J(IEFvI6+tBk|8^$Wi>A4A zm}QQl8SXs1tiNcMyI@*2RW!$a;#{^+eYq0xEctOY-#{N=Xuz3x-zl;|$x<<3Vl7|UhtKDD4 z3q{uI_M3QN=C!u{)x7Z0wf6mWyok_m9Q*5ek;pgw`x|&s=5MCpqKagXsYJG z053Kat35Et`vSr04mf#Vnz6P66TGiRvGxPgytvRb$AKAMJd)ObV3wC)PMbO~$6Gd< zws61&N(@c+EOCXFBkBGnZqN#IdQ^!!v~n~(p~MSH3SEaS@rJ%e)-g(apjGB|Xo)Yh zdUTzpBmhbdU9T+(gw`PIbtM>Rt$DqzBm(+obiKVK8cGS>;3$cKQjrb)C9x3JykV*& z4oVx{uuzf+rHA4?4<L|f}PzKRLiH?IRh>j5Z4`xCPGjZx* z7Q`GSE*#8-SfM1(LwOJzA^9K5hd5?Z)S&{1J4#A8R1EP#$=E|B5QLB!he{#7nT#GP zg9M{w&7n#N4y9-hRY3?s(H$~DLNmp7s2UQDQtXH7AaN+wai|`WAk_Xt4G?OkP9185 zq@&b@LoJXjl;(N36_O(~|HEyN!c2=g+zu&6X$gnBAXO+Gd$=1?BXq{$9w@_1M-TTx z8%ODy!vj!eC_{UA5ZZ(=bcdbLW;4Tfcmmoo%CH}vhO$DLj>9uhHp1*bJPT>e%&Eh3 zP|hfG;jjxoHdN1Wu>4Ei_}k2^s8Vm0Ka$MfZ{|fEN#P$Dd{d}Ud$fvgMufVfCceciv>mPHTStZVqjmi1P?6(kJ--GK^&f5E z+svY=qmBI9QPIND7Jgl**z;H`{}dwjKi0-SZ5BrzYv-RC6(=0);@5{tu*bUjXAueG zSP%c4S%Mzx<)0swXpRl=8$wa-u|fU?1l1jL@-LcE+p!7$rBT#=Y?|K~Ds>#2;Wr`D z{$sOzyIDGQY>wYNDqT3{B4`Pfd6u~fE+aDkGB?2$vn;C2U2t_&mQdy;XbqKP%e)2G z5ILjFM{wONN6UN#H%8@}vH(F_s6ty7D7c9zbY&R9EwjQ_79qGjs<4+u3)(}KjYV% z1osg&qnspoU{<5$G{M7BwWd6WCFlvw(3bNA-y#{ha#--4Im1>i7JNUNVK0{ndP6rl z%2k3sWMhAMrl8-vajHB^@Mv`7LV2!WAT-lcmnZlE$@JId3w|_bM(GL!KaFN4=!yk{ zp_{O}62TC%iJ>bM44XHhx-!AY=q8P>Qs4~TtkqQsMv=`rok=ie-fYuV3&uw`+jVt< ziO?+$UA}(fVXl9r8~nT_H>%Pd zeqk&(q0$R>4cm&X^oCy)Ze>*Zz%N<0qLsez%VS$Ll>x9@*fwotApDAOo30WAziQcL ztBinO8{1~DjE3FAwmT|gU=QK;{>oU`)3SZ4G7erewtb;85%vnp^E{pezb?%4Kb{P~ zVaba+o&vu)mX~lm9rg~}fjy3c-xBU%94EnVTXvwwY4AH^J2b~xuus@d?QtIbu5hRB zI1ImM*=aj2hTk9CX+JK5eZzJ+j;mll;jaGUnXtcQ*VOSWc=6b-h2yz!Kv=%#i9GlN zVZQ%~e0Yf^Kk7sQ{NY%B!ii!yFl;yWL)Ot z6&xzuqdQ@O!z_DjC#vD_u|4(^b#O%3UdM@gI8wN`|3m{EW!XD*q7hy?ws+w~3mhF* z;CZqY{zzEhf3gk!*isO6vK{_ptRUfJ7aS8-h&|a2e=00woa})=vlOByd*RQ=3N4d+uXl*Aa;IGEC_LI|aTv(Cgv452tvcggvRppMX94k(!@Sg$MepViBz6z*JQn zk~Vf=p(+tc4=eH1Cn4*ECI0$kWWA*%N}qyk7%NH8rz5zqgIGNd!3z&E^f@GiU^$5D zX$W!bphnL^NMVPxdLBX+9@6Pygkm{l(~A-6*de=KhS0(eJM=1qETk$LIF`~VLjl4aD@`yIBfPL9SVIW{36C%gr3l}01T~Z) zg0UkSLnQ)-9n~7D5JY%XXD}f`%Tb%58WD{hwHxXXao913p&pS4kM$cG5Y%#P%Fu{N z$Br!+S`b-SnWwQ8kqgWGjctg+QWj-wN0eh_3C1o&6;_Tlb|Y$GIm6h4WLU~kV=uCC ztXyLpKr+L0TH_$HNvP8qoyca3&SsoIwv6fQ#%UxgtioZOL9&Gv{l-~DW2u-j&LKHt z6$?feVQyHZr^!{gRaoh7auaT|R7RQHh1!b@W|yLDRF7*^}B&Ip@?wf)vvq1{qD zWt|f?kJT<%T|_Nmb)MC(qRYZM|7thU6-!-IwY%u*SY1N3m#8)D6t>!1bWM1QQSBqT zZaIZk`-*OiozheXh}yzVYpVlAH-)El)fmw&%V}G6gy{CzX?u0Fs6FhAqdG>^Aw1Jx z9V>EJ&P-Lui8{y5EL10oy29!`Ym!8Fg!TS4$)dZK`ly-|(Y>+ygqoamQFqu`YzLLlQl(oJDJBqK9K=H8m_zPuMwa4Nvr~@SLs&7JX+qXR8s5z8^bhuaSv*!_GTu zRH8oN`Tm+rQNQK z2)pF4)r%&Dm-=lDqAAOzDO;oH@z|vWTZ?EqtkJW!RrIs4(Z9A$^oyl2ssVt# zZI@^!tO;A&E&5H^#Hj5N{cdSOYkNh1j5TR$2Sl@Bc5UsT=ue?tSL+o0WwG08Cq#db z+3mH{qPehUN9~MgUfA4UJ1bhSG*8veiJpu#FVwn-UBX*D>s-apiCX;Y+{DjYTcYaR z#V?GvB-D9{UBfS9>%7G;iY_zie8ewVFQaw7;+MxSYw7~TZsAw7b%EknL|1fm81bvt zE4I1_@oVE(>~+y%_wcKZx)`yC=xTpmtk~0fb*e5-ylDLDLS3TRE4$X#3@%!V~?Wbg7-|!obQ!25a=tlpkOtHW9#?+}S@#66t3#W3$0pV?) zr}M-gh}!&5=ZlwE+oDbvh(8=}OE_ID4h+AEJzXLW65V8+E)@q`Z=$Em#3AE1HK!}Z znDATL(^cY7(JkF+lQ_(J%XYe296o-_e!5N^5q{fox?UV9y4`=eK^$ehJ$1TKymb8b z!s!-qba=bxnO5;fqIUl?ZQ_ru?NMji#h;9~C!FaL$Aoua&vc7F6?HJq^oT#RcA#f^ z#h;INXwD3XW5XTVGlSwUL=N2;di;*2K0uNjepg!`C|M)AtE`k{>LVoIjNi4_M@v$|?>XvYB&ni% z{q?aDto7bheVin1{N6%+q9i@M+w*LaWSywn|7=dOWWBXJ>THT+!+3YX*>njm{66+9 zPJ$QRXPhNT2-f@PS(=16eqVEzB_V}B(4OT<$f5_jv#^9>ePBB)mQcqZ*w4x&wD5AjOE}h^sB;Ap?s!kaxnc<~ z{9Ej~5(y;wmT|6B!nb~lo-30G#=q5^tCYau-)YZPNf6O@x^pIp(E6S2T(v|r{+<0? zokSe|z2jWHL?ZgW|6GFvwSGT!u2CW#|9;_Ii$oUQ>v_IaA{X`gpKp^Wti4g^+a=2J z-h}gA5> zRD(OZeS9FH!3)g`{{h?JjqVWrz-aJ6cUpfy8+_4S<3DH`0?_>MAGHmE=x))Ex&{oo z$NHnKAp+ey{-eDi8Z8L_$=*0M>hN*L#d@?xG~R!)0kv7jr!F?4wd3Op7hBM}@CnaL zt>`Jyg#V>B^t5#%>QXy;W_%*yQWshuK8d~5jh+=vGA{L?=d6?HrC#*>_@w620NM~f zrM)zWUJy;`E;-SQ)+yVi3G~wVl>O2)+8F-WacKr^5h7;kEbrpq0Qru7cRL- zTf(P38(pQBMbrL`Zqh5(>8M6`>DBS+ghnrEYxvLDMsMjg(a(%VAL(`L&uF8s^v3wl zn#KTWTlg>9#z5&!(J#72jP#cE7h7Y5^!E5K_Qq&wd-$)8#u#ab=-2+nSgFJM>r`W$ zv~&E|g~psjX;=7+XH$~&j%dceDOq~gIuq5DBE2_0lhBkd?GFD9+k}(e7yZU)B1s=u ze?yyS(ud=}X_{Elp77tbO+4whqTh8*u=G3Y@3tnf^!xGO?M*UiZ}=aMCY7{L^hbYF zrnKMs$5d06^wIbq3r)Gwf$&*Rd!FS?PlH$yD>4^vU>>g=QBSa6lKexXPXryDV;TlL6gxX^XoIK%UE5 zykx-aOl$F$y(oT;+2SJu5~sAqR|e3{oR$C?@HLBC0%fm=pRZ`a$bgzz+Y%uIKxT7G zvmk5Ah3+T4H5DxP06aCj*$}la@poa4Q#GPLjPYc3pfqSq3!9rI%A=0G?cS zIb8;f$+XKj*<0clnU_g2AV*3s(_{dN%(={x0S~h1GEerd_@#==unZ`VwU@;*06I2b zmdSwK*m+qc^Ao@P=yIkEh>VXfXUTxQ_~de~3^0p}uH?x+5W6kDk}m^z;?gSxGTAOqZ9(bYj2ko79AI%NRStGzlQ172S9 z)oB@^@j9>0$bf?P=<2KtfOn6t&dC66_vEUJ94K~+T3zJ;tXtgbCI>d%(pGmlVCa^$ zddYz}m)7bn2e=%w)kh8-Icck}9FTE2tpReN!xgm#$^isd(Tb4+^R2cuLJoMh=GJIA zklZ?3W8?sBd(@f}D+fT^oTYNoV4(zX`*9+u;`C4|pSPn$5 zwCg2ufOj#km&$?DCB0rI2P9X{^-4L=w~DS;$pN%gaor>brdI9sYB}Juny=T%ft1yG zy0T8A|ZLSL7EiGg;^X{am%CtB24YAY6ZYwns3!9fb-IMt6otf z4u5p3K>_rZ$F~|40BU)1t3?4!mPNN)6{o}zi*L6nfV8socDn+gD$8znDS)4ncDq{v zs1)Yy9tBWQq_=w&06@vPJ)i*ANzv^=1z=4oZaWn~FsZ#gp#WG(^X+K`a7j9E&nSRE z^62)g0$?MLZ_g=!EAr&FixLnbi`re4Knq#i?xqAV$kKLqB``piwR!o#DEOeMe^ z9(QCZf!pw;BUcHChDDA%CD0faJMxtPURdfVPy%CNnWI<OOh>5_APG`O znG$#iIgUytpbv^1RZ5^7R5(mZ02o0aMWFs8<4!;E|(23Gji(jz%SL z2A()tlz+`Iimyt{iDuVC1~Xzcg`t67XPHv zMFk4@MP05c5W6q#a#Mk>eQB4w3MA~yy1Z1NR!{5lR)H{`+2x}G4Z5_;R|RtOoUQ;B zD9ekw0#zU)ujs<4Krdd~6`=xYcym{@3RK{oT`?*Ud_U@nRe`qqaaWuQWZX}>5>=qs zUUVl(1>)?*cal}0!(MtPMFo=UWp~n5psr54gHwT!nt6w$0?oAa4owB}=$tz&6)2&L z?(kF~dak$wt3cmedq=DSC3Eu~nF>V9op)3!&?i5-lc@qJ^5Z*MDo`Cixs$5`f$^fd zc`DEnFTR_v0@?7=y9Fvx2rs)^tO7A`+T9Wr=zf`ZOI0B8mEJ8=ftokxZlwx@yG3`a zRG`tVxNA~@9JlsvwF;EC&3EfmAhPYeTdx8=?W4O5Dv-`TzT2n*mF$zdEh-SiF1pvM z0`2SKdu=L^xh}oet^!5tvU^=B5U-})>sEnIm3gm61(H&b1D#ZKDp*wwA)<`0?cLIUTV-$s1ToYC#pekxafY88nlIr z?kgYKvl&V3YCVfz*1~FRBgGx2%&WavXsX<~^@xY`8 zHCgS0YBdPQnjh4uK_k}rpk57futyIX)S&!&{Gd?{BCjV8TGXKDTJ*404brW}58KqB z(pvhkT@8Y)We>a5puI|a*sTVc74u<_8WdI1hrMbLPvtxuP=ijY=;5FmBvBO)ooWz2 z)jph1gU+e>;j|hgO`Q*C)SzB^^l(-ULZ!zK=hUD{dh*aE1LQ}GdR#L=X|%YD%IUhn$6jG#&t8&$pa{M$g$e>=C$>+PwZUI}(sUJ34Q zeg6Lo$p3D{TdqL$f8GUr^8!CyT);`K}jm*STGu zp88$icO!zeSD*jiQ+qn_pVQhi^ZeU8uRb3<_EE4Km{ZdW;OJoa@Bbv=f39`;pL6=Z zclB@YX?*kPg$294J!5e9b^(*|c}d1bd2FT64=-$4f}lJolgX8e)e=;>=r3`EspF&M!|ATf{m-|PNyc&2KT?CHQIY82s0dC(Ft z8dXbVoBq8)$`L|b)zkG7NX6!{RctVP%Mu6$!x2>QbYDDfRb=dv?Ck$Nng5=}67cCf zJ-~lW<6kTPAM-#^)n_sPa~A(z{U4KfdU4qiU@rf>uz%l_|8c5+-7T=;|L5tRU7`YF ztE7r&w?T|>6l}$&r*}cNiLFpbH$I(v2Bc6TQuOKCk3Nlxj{0~BnCHJv{T~}Yjsky{ zWV`sdFJHetjriq1o_?Q}mzO?WVg)OgFJHb6d_7&hS-w1G`3k}ERm+zPmah~%Teo7x ze{J9RbmiCo-oE15{@{18JUhy>?Q51V-?$v?2Yx;~2>AJIC-9vNzE*4`6F(J^NvX@1 zr+p2Et@wP6M69N)Cd80F#%6Gm2`UbniliYcI8WDeKUoiR&~*rD!$!dx$v?M?zmRbx z>&4J&!sazXset&265&WzsVE!Pe70uwryp@vZ&a>XxmLm^5|orxU#Q8%kHk;MaZrMi zvl1K!T>*prVeUs?L_?$%&$g{W32HVGn?YHPM^aWUN5EJWH(AW*C5tycJMPN08Dxn} zO#WouKeiJI(PZL!n78`tr*j3@Kv0uE{zAkieu_Rl*BUVazaEK>S%ZG`#edEHpVtO$ zTKn&Lf$LK9R<8Mfo%4Te`{#Yb{^y)z;NEfH<7zR&m8{wXJ^hSVuH6U`S8d`-zWC(XwV@O- z7sbjrAIChKV=4}>PF)$ZX$=al4~+fC^9Jslgs_SGu{eYC^q4ExY)TQXQKuqnzj*q5 zK6_NZe)haRd!D1y!Ta&_abCCP*^|Bc*`R;DDo>wcuwwPUpHHA7{d4@&*9R=%Ao!;T z1@BYx)As=^>z=+8|5(0W`RpXm4)S#9zZURLEMFl6pXqY&VuD}5{u`gZNB>;F5&yNg x_yow<3b`6mMRH}b$Y=jB1pM>G5BSGF3GYVux`6+C#>M6Dmt0)Zm#_cme*womC$#_o literal 0 HcmV?d00001 diff --git a/tests/data/inputs_sample.parquet b/tests/data/inputs_sample.parquet new file mode 100644 index 0000000000000000000000000000000000000000..8ba44d01f137398d52747380a615f7aded10b300 GIT binary patch literal 47719 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 literal 0 HcmV?d00001 diff --git a/tests/data/targets_sample.parquet b/tests/data/targets_sample.parquet new file mode 100644 index 0000000000000000000000000000000000000000..da17dfd6501ae2f14c73fbf58bc6e77c383ab75e GIT binary patch literal 18587 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 m%8HueYN}AJrmT)Z`0KACHh}L Date: Wed, 10 Jul 2024 21:50:18 +0200 Subject: [PATCH 06/21] feat(explanations): add explainability features and tooling --- confs/explanations.yaml | 12 + data/model_explanations.parquet | Bin 0 -> 2604 bytes data/samples_explanations.parquet | Bin 0 -> 24084 bytes notebooks/explain.ipynb | 4576 ++++++++++++++++++++++++ poetry.lock | 150 +- pyproject.toml | 1 + src/bikes/core/models.py | 50 + src/bikes/core/schemas.py | 28 + src/bikes/jobs/__init__.py | 5 +- src/bikes/jobs/explanations.py | 78 + src/bikes/jobs/inference.py | 4 +- tasks/dags.py | 1 + tests/confs/valid/5. explanations.yaml | 12 + tests/conftest.py | 37 + tests/core/test_models.py | 36 +- tests/core/test_schemas.py | 24 +- tests/jobs/test_explanations.py | 73 + 17 files changed, 5077 insertions(+), 10 deletions(-) create mode 100644 confs/explanations.yaml create mode 100644 data/model_explanations.parquet create mode 100644 data/samples_explanations.parquet create mode 100644 notebooks/explain.ipynb create mode 100644 src/bikes/jobs/explanations.py create mode 100644 tests/confs/valid/5. explanations.yaml create mode 100644 tests/jobs/test_explanations.py diff --git a/confs/explanations.yaml b/confs/explanations.yaml new file mode 100644 index 0000000..7f3f6f4 --- /dev/null +++ b/confs/explanations.yaml @@ -0,0 +1,12 @@ +job: + KIND: ExplanationsJob + inputs_samples: + KIND: ParquetReader + path: data/inputs_test.parquet + limit: 100 + model_explanations: + KIND: ParquetWriter + path: outputs/model_explanations.parquet + samples_explanations: + KIND: ParquetWriter + path: outputs/samples_explanations.parquet diff --git a/data/model_explanations.parquet b/data/model_explanations.parquet new file mode 100644 index 0000000000000000000000000000000000000000..8747a66d399bb3341f5c440ed051e3207b3ed94a GIT binary patch literal 2604 zcmcImOKclO7@njiu^=kxV_iFqDr-fp9^BNAq|}=}wCmW;x^~*QjbDJQec9e*cXru_ z-E9=92apgFH-u1us^x-^DmWl6oVaiS33}jwdgu+r0i+%|^3U2y?b234(2aI>{{Nr( zAKyRUIG5Q|D^W2D9YpAdeR2pPBnghvF)URQG`rQZ6~Q)eD=E$)lp;eK zhQQ(+*F}lGA~;>evQ?**oWsXpfdxYvhUnsc@Pu7mIq)FpS+mSRG^1mudp?GOUF#4N zL*cHWsj}dmKZ3%2McIPs#9s?-^h)2bwp839CX8ksMK=#HuOlQ(Q0QfbLNi@grn2#i5>AYKoegKaEc8CrRuU<5}U*lgoo_kJKk&j7_{S z9esy=H*@0i?{012#@FvN{Hafu@7}+C?vMCS%j#G6mn9}}_TkZ+%YSl*FFX!QI6$=F z0Pzz-Cq|@a!th&go(c|Ocv00&!*T>H4UqVDGW7jq?EZA@ zWX7K>{(R>R5C#rgzISElcic@|RW!LZt{ddlay*m7qg|{@hCE2Y)lF~DV2GQF
    K z#Svt|5n%Z?tzcLVTqb)ruI5jkp?5}-8P9?q@`^YaOJ&sXpYkDa?ZhFiVU6^oBmB>x zpZ$Mu6}G`%SRm?l3GL8%-50!SV<+rYBgI(I@VDv9bWQWWZ6ZQ>#%v2?XcO7 zuj9Bed!HzCd-lS5b|Ay(d-3f&%l28=2VdU_eEm%@HsIy@joQ*yqh4m&>>1e4y~^vF z+bmQU>#4P#xLS2YTvjisoTzw3OMtcfrqSVXu`BAb#;g4fuP=4Q+6GzU%C&2DDa)!- zy3&>KI_TK`Q0_@t{xrXmTN=vRK+b3CSBQ^cEG=V-dPP$T)$1fqEp4l!o_Cs8U~ge5 zDHi%RpDpS_t!g*(8MjeOYGj>=tG1X0KbV8OAa*j7Q0km-<8jp$YHPh_VM8UcVXY&r zYHfK{>-&DQ#a=@X4zmdE&M=E4IxsZq2 zo|>B}*14X9D}d?R)AQ4twwTH%%Gdd);j4>&6Xc8x z&-Gec)~lYB(t0BCndQCGChwNjV#cQg%lS+Jez0tL6G(UlCb<n{g+%A82^%6|Dz4I{K;x9$vs3}-) jx{7mBGR>3z#S7b!Vks>N8qSy;4B3?yA5Jj=K z>`sWi)9k%>v2g9>-vyN-SNY!WllRA)O=joJnP<*<_UxIH&2_^)jMZe-*2=4u%8yVx zCZ)zwVX+p=)Gv~{Y%vTwxJwxuh4isCSEplxy2xY7k*D}84;o-r%0Ae$o;ujpLH)5a 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 WtfwZ6^`HI6vejp?-01%w{Qm\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    featureimportance
    18numericals__casual0.579146
    10numericals__hr0.250726
    13numericals__workingday0.078542
    8numericals__yr0.038600
    9numericals__mnth0.012079
    \n", + "" + ], + "text/plain": [ + " feature importance\n", + "18 numericals__casual 0.579146\n", + "10 numericals__hr 0.250726\n", + "13 numericals__workingday 0.078542\n", + "8 numericals__yr 0.038600\n", + "9 numericals__mnth 0.012079" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_explanations = (\n", + " pd.read_parquet(MODEL_EXPLANATIONS)\n", + " .sort_values('importance', ascending=False)\n", + ")\n", + "print(model_explanations.shape)\n", + "model_explanations.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(100, 19)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    categoricals__season_1categoricals__season_2categoricals__season_3categoricals__season_4categoricals__weathersit_1categoricals__weathersit_2categoricals__weathersit_3categoricals__weathersit_4numericals__yrnumericals__mnthnumericals__hrnumericals__holidaynumericals__weekdaynumericals__workingdaynumericals__tempnumericals__atempnumericals__humnumericals__windspeednumericals__casual
    00.169155-0.124650-0.203503-0.758982-1.474484-1.0763490.8019560.00051331.4951342.905728-74.036369-0.019947-7.11896818.6407952.6138961.898717-1.322058-0.210363147.338089
    10.142295-0.242301-0.061819-0.650959-1.001739-0.5237190.8241410.00050132.2514922.752874-68.468292-0.037579-4.27233519.7231661.8124521.4621430.3695320.374412117.786423
    20.168699-0.173419-0.054359-0.723623-1.554552-1.0339790.7629420.00053432.2454303.195950-82.5151670.009938-2.85652919.8243031.4989752.0467801.5594382.603706127.694664
    30.253636-0.791483-0.218226-0.6126110.4995810.0397980.7789880.00051830.9053542.808645-70.1802220.097680-6.69985719.2064724.4686947.614378-0.7768831.582501180.403839
    40.130902-0.788029-0.395371-0.614574-1.5584090.111731-3.9279000.00090447.1910676.631704-4.3152430.029141-0.15762029.4014264.7042894.135256-3.7745230.583940202.349609
    \n", + "
    " + ], + "text/plain": [ + " categoricals__season_1 categoricals__season_2 categoricals__season_3 \\\n", + "0 0.169155 -0.124650 -0.203503 \n", + "1 0.142295 -0.242301 -0.061819 \n", + "2 0.168699 -0.173419 -0.054359 \n", + "3 0.253636 -0.791483 -0.218226 \n", + "4 0.130902 -0.788029 -0.395371 \n", + "\n", + " categoricals__season_4 categoricals__weathersit_1 \\\n", + "0 -0.758982 -1.474484 \n", + "1 -0.650959 -1.001739 \n", + "2 -0.723623 -1.554552 \n", + "3 -0.612611 0.499581 \n", + "4 -0.614574 -1.558409 \n", + "\n", + " categoricals__weathersit_2 categoricals__weathersit_3 \\\n", + "0 -1.076349 0.801956 \n", + "1 -0.523719 0.824141 \n", + "2 -1.033979 0.762942 \n", + "3 0.039798 0.778988 \n", + "4 0.111731 -3.927900 \n", + "\n", + " categoricals__weathersit_4 numericals__yr numericals__mnth \\\n", + "0 0.000513 31.495134 2.905728 \n", + "1 0.000501 32.251492 2.752874 \n", + "2 0.000534 32.245430 3.195950 \n", + "3 0.000518 30.905354 2.808645 \n", + "4 0.000904 47.191067 6.631704 \n", + "\n", + " numericals__hr numericals__holiday numericals__weekday \\\n", + "0 -74.036369 -0.019947 -7.118968 \n", + "1 -68.468292 -0.037579 -4.272335 \n", + "2 -82.515167 0.009938 -2.856529 \n", + "3 -70.180222 0.097680 -6.699857 \n", + "4 -4.315243 0.029141 -0.157620 \n", + "\n", + " numericals__workingday numericals__temp numericals__atemp \\\n", + "0 18.640795 2.613896 1.898717 \n", + "1 19.723166 1.812452 1.462143 \n", + "2 19.824303 1.498975 2.046780 \n", + "3 19.206472 4.468694 7.614378 \n", + "4 29.401426 4.704289 4.135256 \n", + "\n", + " numericals__hum numericals__windspeed numericals__casual \n", + "0 -1.322058 -0.210363 147.338089 \n", + "1 0.369532 0.374412 117.786423 \n", + "2 1.559438 2.603706 127.694664 \n", + "3 -0.776883 1.582501 180.403839 \n", + "4 -3.774523 0.583940 202.349609 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "samples_explanations = pd.read_parquet(SAMPLES_EXPLANATIONS)\n", + "print(samples_explanations.shape)\n", + "samples_explanations.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ".values =\n", + " categoricals__season_1 categoricals__season_2 categoricals__season_3 \\\n", + "0 0.169155 -0.124650 -0.203503 \n", + "1 0.142295 -0.242301 -0.061819 \n", + "2 0.168699 -0.173419 -0.054359 \n", + "3 0.253636 -0.791483 -0.218226 \n", + "4 0.130902 -0.788029 -0.395371 \n", + ".. ... ... ... \n", + "95 0.032898 0.004389 -0.022684 \n", + "96 -0.039833 -0.035329 -0.022280 \n", + "97 -0.029910 -0.054200 -0.015400 \n", + "98 0.002795 -0.055408 -0.033671 \n", + "99 0.001024 -0.061020 -0.034896 \n", + "\n", + " categoricals__season_4 categoricals__weathersit_1 \\\n", + "0 -0.758982 -1.474484 \n", + "1 -0.650959 -1.001739 \n", + "2 -0.723623 -1.554552 \n", + "3 -0.612611 0.499581 \n", + "4 -0.614574 -1.558409 \n", + ".. ... ... \n", + "95 -0.615178 0.264237 \n", + "96 -0.627357 0.463110 \n", + "97 -0.607787 0.455338 \n", + "98 -0.623416 0.560994 \n", + "99 -0.625861 0.542756 \n", + "\n", + " categoricals__weathersit_2 categoricals__weathersit_3 \\\n", + "0 -1.076349 0.801956 \n", + "1 -0.523719 0.824141 \n", + "2 -1.033979 0.762942 \n", + "3 0.039798 0.778988 \n", + "4 0.111731 -3.927900 \n", + ".. ... ... \n", + "95 -0.054727 0.568837 \n", + "96 -0.015223 0.565861 \n", + "97 0.003094 0.551169 \n", + "98 0.020387 0.537736 \n", + "99 0.013132 0.532625 \n", + "\n", + " categoricals__weathersit_4 numericals__yr numericals__mnth \\\n", + "0 0.000513 31.495134 2.905728 \n", + "1 0.000501 32.251492 2.752874 \n", + "2 0.000534 32.245430 3.195950 \n", + "3 0.000518 30.905354 2.808645 \n", + "4 0.000904 47.191067 6.631704 \n", + ".. ... ... ... \n", + "95 0.000399 40.124039 6.724072 \n", + "96 0.000403 35.804981 20.436369 \n", + "97 0.000411 32.999043 26.067795 \n", + "98 0.000392 32.314198 23.293106 \n", + "99 0.000388 32.588284 24.576950 \n", + "\n", + " numericals__hr numericals__holiday numericals__weekday \\\n", + "0 -74.036369 -0.019947 -7.118968 \n", + "1 -68.468292 -0.037579 -4.272335 \n", + "2 -82.515167 0.009938 -2.856529 \n", + "3 -70.180222 0.097680 -6.699857 \n", + "4 -4.315243 0.029141 -0.157620 \n", + ".. ... ... ... \n", + "95 -3.901324 0.138933 0.979801 \n", + "96 4.877304 -0.027108 2.595324 \n", + "97 5.580533 -0.012089 2.779204 \n", + "98 1.114409 0.254242 2.357220 \n", + "99 1.200160 0.254306 2.411582 \n", + "\n", + " numericals__workingday numericals__temp numericals__atemp \\\n", + "0 18.640795 2.613896 1.898717 \n", + "1 19.723166 1.812452 1.462143 \n", + "2 19.824303 1.498975 2.046780 \n", + "3 19.206472 4.468694 7.614378 \n", + "4 29.401426 4.704289 4.135256 \n", + ".. ... ... ... \n", + "95 -21.420794 -1.613000 -4.774735 \n", + "96 -20.015820 -0.422287 -6.170654 \n", + "97 -19.195932 -3.357377 -8.327322 \n", + "98 -18.854221 -0.914422 -15.955507 \n", + "99 -19.075937 -1.693157 -12.839770 \n", + "\n", + " numericals__hum numericals__windspeed numericals__casual \n", + "0 -1.322058 -0.210363 147.338089 \n", + "1 0.369532 0.374412 117.786423 \n", + "2 1.559438 2.603706 127.694664 \n", + "3 -0.776883 1.582501 180.403839 \n", + "4 -3.774523 0.583940 202.349609 \n", + ".. ... ... ... \n", + "95 -2.793116 1.410505 319.295746 \n", + "96 -1.366720 -0.086119 363.113678 \n", + "97 1.297852 0.499207 374.674683 \n", + "98 1.504436 -0.023106 381.828125 \n", + "99 3.381457 -0.181553 378.957825 \n", + "\n", + "[100 rows x 19 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "shap_values = shap.Explanation(samples_explanations, feature_names=samples_explanations.columns.to_list())\n", + "shap_values.feature_names\n", + "shap_values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# EXPLANATIONS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "hovertemplate": "feature=%{x}
    importance=%{y}", + "legendgroup": "", + "marker": { + "color": "#636efa", + "pattern": { + "shape": "" + } + }, + "name": "", + "offsetgroup": "", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": [ + "numericals__casual", + "numericals__hr", + "numericals__workingday", + "numericals__yr", + "numericals__mnth", + "numericals__hum", + "numericals__atemp", + "numericals__temp", + "numericals__weekday", + "numericals__windspeed", + "categoricals__weathersit_3", + "categoricals__season_4", + "categoricals__season_1", + "numericals__holiday", + "categoricals__weathersit_1", + "categoricals__weathersit_2", + "categoricals__season_2", + "categoricals__season_3", + "categoricals__weathersit_4" + ], + "xaxis": "x", + "y": [ + 0.5791462063789368, + 0.2507259249687195, + 0.0785420835018158, + 0.038599804043769836, + 0.0120792705565691, + 0.008070561103522778, + 0.006674219388514757, + 0.006322493776679039, + 0.00494948448613286, + 0.004703037440776825, + 0.0028446626383811235, + 0.002690249355509877, + 0.0013275929959490895, + 0.0011345595121383667, + 0.0009102495387196541, + 0.0005809680442325771, + 0.0005128193879500031, + 0.00018277487833984196, + 0.0000030518597213813337 + ], + "yaxis": "y" + } + ], + "layout": { + "barmode": "relative", + "legend": { + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Feature Importances" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "feature" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "importance" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.bar(model_explanations, x='feature', y='importance', title='Feature Importances')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Samples" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "coloraxis": "coloraxis", + "hovertemplate": "x: %{x}
    y: %{y}
    color: %{z}", + "name": "0", + "type": "heatmap", + "x": [ + "categoricals__season_1", + "categoricals__season_2", + "categoricals__season_3", + "categoricals__season_4", + "categoricals__weathersit_1", + "categoricals__weathersit_2", + "categoricals__weathersit_3", + "categoricals__weathersit_4", + "numericals__yr", + "numericals__mnth", + "numericals__hr", + "numericals__holiday", + "numericals__weekday", + "numericals__workingday", + "numericals__temp", + "numericals__atemp", + "numericals__hum", + "numericals__windspeed", + "numericals__casual" + ], + "xaxis": "x", + "y": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99 + ], + "yaxis": "y", + "z": [ + [ + 0.169154554605484, + -0.12465005367994308, + -0.20350304245948792, + -0.7589821815490723, + -1.4744840860366821, + -1.0763494968414307, + 0.8019556403160095, + 0.0005125635070726275, + 31.495134353637695, + 2.905728340148926, + -74.03636932373047, + -0.01994742453098297, + -7.118968486785889, + 18.64079475402832, + 2.613896131515503, + 1.898716688156128, + -1.322058081626892, + -0.21036271750926971, + 147.3380889892578 + ], + [ + 0.14229492843151093, + -0.24230052530765533, + -0.06181931495666504, + -0.6509594321250916, + -1.0017391443252563, + -0.523719310760498, + 0.8241411447525024, + 0.0005005813436582685, + 32.25149154663086, + 2.7528738975524902, + -68.46829223632812, + -0.037578750401735306, + -4.272334575653076, + 19.72316551208496, + 1.8124518394470215, + 1.4621434211730957, + 0.3695316016674042, + 0.37441232800483704, + 117.78642272949219 + ], + [ + 0.16869859397411346, + -0.17341940104961395, + -0.054359059780836105, + -0.7236232757568359, + -1.5545519590377808, + -1.0339789390563965, + 0.762941837310791, + 0.0005341940559446812, + 32.24542999267578, + 3.1959495544433594, + -82.51516723632812, + 0.009938172064721584, + -2.8565289974212646, + 19.824302673339844, + 1.4989748001098633, + 2.0467801094055176, + 1.55943763256073, + 2.603705883026123, + 127.69466400146484 + ], + [ + 0.25363633036613464, + -0.7914834022521973, + -0.2182263433933258, + -0.6126111149787903, + 0.4995812475681305, + 0.03979773819446564, + 0.7789877653121948, + 0.0005178267601877451, + 30.905353546142578, + 2.808645009994507, + -70.18022155761719, + 0.09768002480268478, + -6.699856758117676, + 19.206472396850586, + 4.46869421005249, + 7.614377975463867, + -0.7768831253051758, + 1.5825011730194092, + 180.40383911132812 + ], + [ + 0.13090188801288605, + -0.7880292534828186, + -0.3953709006309509, + -0.6145736575126648, + -1.5584088563919067, + 0.11173088103532791, + -3.9278995990753174, + 0.0009037204436026514, + 47.19106674194336, + 6.631704330444336, + -4.315243244171143, + 0.029140517115592957, + -0.1576196849346161, + 29.401426315307617, + 4.704289436340332, + 4.135255813598633, + -3.7745230197906494, + 0.583940327167511, + 202.349609375 + ], + [ + 0.09980977326631546, + -0.1289137452840805, + 0.04262050241231918, + -1.0114322900772095, + -1.5444451570510864, + -0.3063795566558838, + 1.2926396131515503, + 0.007032076362520456, + 77.94355010986328, + 5.943662643432617, + 176.00094604492188, + 0.0029676654376089573, + 4.077856063842773, + 77.48359680175781, + 2.1760151386260986, + -4.81910514831543, + -3.676065444946289, + 0.42632120847702026, + 252.67762756347656 + ], + [ + 0.17066802084445953, + -0.2959515154361725, + -0.11001028120517731, + -1.0064359903335571, + -1.6547470092773438, + -0.7146743535995483, + 1.3593095541000366, + 0.006959938909858465, + 67.61687469482422, + 7.270330429077148, + 177.5045623779297, + -0.15282031893730164, + 6.387446403503418, + 96.7355728149414, + 2.823650360107422, + -3.538238763809204, + -3.534722089767456, + 1.1455564498901367, + 236.20997619628906 + ], + [ + 0.21100318431854248, + -0.5323825478553772, + -0.11136386543512344, + -0.7844051122665405, + -3.295231342315674, + -4.226391315460205, + 1.0265041589736938, + 0.006217549089342356, + 52.71641540527344, + 5.100271701812744, + 64.47308349609375, + -0.13248220086097717, + 6.663832187652588, + 58.35783386230469, + 3.418996572494507, + 2.1445350646972656, + -2.514310836791992, + 1.3115136623382568, + 195.78465270996094 + ], + [ + 0.15828295052051544, + -0.10273899137973785, + -0.23303288221359253, + -0.7537844181060791, + -1.0537359714508057, + -0.3776755928993225, + 0.923829197883606, + 0.0001359017041977495, + 39.298519134521484, + 1.023025631904602, + -0.3841829001903534, + -0.09258145093917847, + 3.8694167137145996, + 46.602294921875, + 3.19360613822937, + 3.103475332260132, + -3.797464370727539, + -1.9199837446212769, + 138.60589599609375 + ], + [ + 0.15737031400203705, + 0.0520184300839901, + -0.4065300226211548, + -0.6695138812065125, + -0.9999762773513794, + -0.3622300326824188, + 0.7322946190834045, + 0.0005345836980268359, + 41.25462341308594, + 0.020151332020759583, + -39.13706970214844, + -0.08169162273406982, + 4.318027496337891, + 40.69746780395508, + 2.7966856956481934, + 2.3097407817840576, + -4.547541618347168, + -1.7421387434005737, + 140.1410675048828 + ], + [ + 0.2103569209575653, + -0.6580501794815063, + -0.018581287935376167, + -0.5772673487663269, + 0.5382667779922485, + 0.07692182064056396, + 0.7319211959838867, + 0.0004881093336734921, + 36.82917022705078, + 2.3916404247283936, + -56.327823638916016, + -0.10369519889354706, + -3.7037088871002197, + 17.519577026367188, + 3.3487110137939453, + 4.850150108337402, + -1.7671900987625122, + 0.2815130054950714, + 62.255897521972656 + ], + [ + 0.23457731306552887, + -0.3182263970375061, + -0.03401074558496475, + -0.5962135195732117, + 0.6905218958854675, + 0.0343155562877655, + 0.6870012283325195, + 0.0006443400052376091, + 21.72657585144043, + 2.088026762008667, + -64.06810760498047, + -0.028121035546064377, + -2.425230026245117, + 10.60973072052002, + 1.6931196451187134, + 1.4571316242218018, + -2.226402521133423, + 0.7569981217384338, + -37.61403274536133 + ], + [ + 0.1959066241979599, + -0.18706031143665314, + -0.02977874130010605, + -0.5241200923919678, + 0.7009141445159912, + 0.07782352715730667, + 0.6562888622283936, + 0.0007873308495618403, + 18.619783401489258, + 1.6802222728729248, + -87.85552978515625, + 0.008099825121462345, + -2.5846824645996094, + 2.4992663860321045, + 1.3333842754364014, + 1.8203318119049072, + -3.4116618633270264, + 0.13050484657287598, + -54.8721809387207 + ], + [ + 0.22012750804424286, + -0.1243598610162735, + 0.04713971167802811, + -0.4951706528663635, + 0.5279565453529358, + 0.006826077122241259, + 1.2234665155410767, + 0.0020947991870343685, + 16.840295791625977, + 1.5345487594604492, + -78.14442443847656, + 0.06610047072172165, + -0.40369319915771484, + 6.414614200592041, + 1.874184489250183, + 1.5743393898010254, + -1.5664819478988647, + 0.8207980394363403, + -93.91680145263672 + ], + [ + 0.23642316460609436, + -0.07295327633619308, + 0.02021026983857155, + -0.46774348616600037, + 0.5260272026062012, + -0.0433531254529953, + 1.3350751399993896, + 0.0008117177058011293, + 16.031938552856445, + 1.671962857246399, + -78.07720947265625, + 0.022589685395359993, + -0.31112754344940186, + 7.640243053436279, + 1.160016655921936, + 1.7891626358032227, + -2.236783981323242, + 0.45728132128715515, + -104.49085235595703 + ], + [ + 0.24079622328281403, + -0.04550537094473839, + 0.10600541532039642, + -0.4731599688529968, + 0.5193852782249451, + -0.02344142273068428, + 1.3347171545028687, + 0.000648858433123678, + 15.789037704467773, + 1.5652916431427002, + -80.2547836303711, + -0.0102729182690382, + -0.08482003957033157, + 8.450746536254883, + 1.0162487030029297, + 1.6323434114456177, + -2.069530487060547, + 0.407787561416626, + -104.59845733642578 + ], + [ + 0.2427425980567932, + -0.0384024940431118, + 0.10925472527742386, + -0.4685764014720917, + 0.6121373176574707, + -0.010323641821742058, + 1.344220519065857, + 0.000648858433123678, + 17.439502716064453, + 1.6917942762374878, + -73.54963684082031, + -0.021768908947706223, + -0.015513437800109386, + 10.325225830078125, + 0.9995515942573547, + 1.6338378190994263, + -1.988153100013733, + 0.34100043773651123, + -114.72674560546875 + ], + [ + 0.19245152175426483, + -0.08253858983516693, + -0.0036932018119841814, + -0.47749078273773193, + -0.778639554977417, + -0.12267234921455383, + 1.2741750478744507, + 0.0017355340532958508, + 19.329111099243164, + 1.9788233041763306, + -49.32539367675781, + -0.014683695510029793, + 0.3591795265674591, + 14.508062362670898, + 1.2764817476272583, + 1.9689347743988037, + -3.1787121295928955, + -0.0871240571141243, + -117.06720733642578 + ], + [ + 0.26470598578453064, + -0.20068220794200897, + 0.04700566455721855, + -0.5295122861862183, + -2.3159399032592773, + -0.5527059435844421, + 1.4427541494369507, + 0.002121501136571169, + 23.01054573059082, + 4.577113151550293, + 4.840754985809326, + -0.04685033857822418, + 1.0733647346496582, + 24.8539981842041, + 2.3293471336364746, + 2.876255512237549, + -2.0436370372772217, + 0.4947572350502014, + -95.24009704589844 + ], + [ + 0.6009383797645569, + -0.53944331407547, + 0.07307998836040497, + -0.5650307536125183, + -1.6178886890411377, + -1.9659442901611328, + 1.523211121559143, + 0.0005157730774953961, + 55.051509857177734, + 11.02030086517334, + 134.98486328125, + -0.21013426780700684, + 1.3449642658233643, + 48.54542541503906, + 4.885603427886963, + 7.470324516296387, + -3.7808265686035156, + -0.40304115414619446, + 21.054868698120117 + ], + [ + 1.0368555784225464, + -4.67413330078125, + -0.0035402767825871706, + -0.6122829914093018, + -1.3186876773834229, + -0.3487352132797241, + 2.466224431991577, + 0.0005312719731591642, + 84.37887573242188, + 6.363649368286133, + 223.41319274902344, + -0.32166752219200134, + 1.1088142395019531, + 57.85630798339844, + -3.1717469692230225, + 0.9009676575660706, + 1.3160041570663452, + 1.3381297588348389, + 127.35955047607422 + ], + [ + 0.12387402355670929, + 0.07819881290197372, + -0.009967210702598095, + -0.7128632664680481, + -0.6675121784210205, + 0.03523243963718414, + 1.462039589881897, + 0.0005336896283552051, + 54.256168365478516, + 2.884908437728882, + 24.965435028076172, + -0.05086776614189148, + 1.2107491493225098, + 28.869901657104492, + -0.03788652643561363, + 0.46800532937049866, + 0.19632861018180847, + 1.7283220291137695, + 36.397701263427734 + ], + [ + 0.15390318632125854, + -0.24831996858119965, + -0.005272223148494959, + -0.5715996026992798, + -0.8208709955215454, + -0.1594245284795761, + 0.7970048189163208, + 0.0005079301190562546, + 31.991912841796875, + 2.542576551437378, + -94.4873275756836, + -0.09413846582174301, + -1.5950297117233276, + 12.353922843933105, + 3.599046468734741, + 2.71368408203125, + 1.3042409420013428, + 0.17937436699867249, + 94.56910705566406 + ], + [ + 0.12881344556808472, + -0.23975999653339386, + -0.11960572004318237, + -0.7206676602363586, + -1.1241790056228638, + -0.6253287196159363, + 0.7455617189407349, + 0.0005503954016603529, + 27.759973526000977, + 2.76396107673645, + -93.7419662475586, + 0.02968677505850792, + -0.7746119499206543, + 19.718368530273438, + 2.5528836250305176, + 1.075609564781189, + 0.22086085379123688, + 2.4454987049102783, + 129.79888916015625 + ], + [ + 0.12905992567539215, + -0.2558153569698334, + -0.021835684776306152, + -0.5680426955223083, + -1.2032192945480347, + -0.269516259431839, + 0.8631099462509155, + 0.0005503954016603529, + 41.81741714477539, + 3.8032913208007812, + -56.884029388427734, + -0.1119290143251419, + 0.18008644878864288, + 14.842578887939453, + 3.691838026046753, + 2.833195447921753, + 0.746959924697876, + 2.0351486206054688, + 112.8614273071289 + ], + [ + 0.25078874826431274, + -0.7432373762130737, + 0.15399301052093506, + -0.5888906717300415, + -0.9327319860458374, + -0.34541767835617065, + 0.8261586427688599, + 0.0005503954016603529, + 31.770305633544922, + 2.8528950214385986, + -65.05724334716797, + 0.10114981979131699, + -4.877957344055176, + 19.00931167602539, + 4.283749580383301, + 7.261184215545654, + -0.10680069774389267, + 1.2539360523223877, + 181.61904907226562 + ], + [ + 0.16916249692440033, + -0.3376086950302124, + -0.017634164541959763, + -0.5719799995422363, + -0.8471976518630981, + -0.2293485701084137, + 0.8150206208229065, + 0.00047357301809825003, + 37.48652648925781, + 3.877255439758301, + -68.99298858642578, + -0.11778315156698227, + -0.25162991881370544, + 13.409579277038574, + 3.3177073001861572, + 2.5264971256256104, + 0.631689190864563, + -0.2489928901195526, + 105.84652709960938 + ], + [ + 0.2764410376548767, + -0.5664715766906738, + -0.22968539595603943, + -0.572463870048523, + -0.6430850028991699, + 0.0533578097820282, + 0.785500168800354, + 0.00045881280675530434, + 33.81791687011719, + 2.6530468463897705, + -68.8091812133789, + 0.40473902225494385, + -5.343265533447266, + 16.448652267456055, + 5.755948543548584, + 8.034867286682129, + 1.9738346338272095, + 0.8543528914451599, + 193.16583251953125 + ], + [ + 0.19928956031799316, + -0.7926640510559082, + -0.33886241912841797, + -0.6365681886672974, + -1.6411441564559937, + -0.41482436656951904, + 0.953245222568512, + 0.0018760856473818421, + 48.95395278930664, + 6.103858470916748, + -5.4297051429748535, + 0.1609586477279663, + 0.6505838632583618, + 23.07547950744629, + 5.43159818649292, + 4.431673526763916, + 0.35956060886383057, + 0.3377896845340729, + 203.73019409179688 + ], + [ + 0.12561261653900146, + -0.31200775504112244, + -0.12821342051029205, + -0.9878201484680176, + -1.5346041917800903, + -0.7124462723731995, + 1.3390915393829346, + 0.0067122639156877995, + 68.63040924072266, + 8.366534233093262, + 181.4793243408203, + -0.048752136528491974, + 5.048268795013428, + 87.0127944946289, + 3.649786949157715, + -1.8663026094436646, + -1.0483384132385254, + 0.7698644399642944, + 246.24838256835938 + ], + [ + 0.14318406581878662, + -0.16817134618759155, + 0.044656164944171906, + -1.000720500946045, + -1.4363611936569214, + -0.39889147877693176, + 1.3321622610092163, + 0.006973070092499256, + 69.49068450927734, + 6.908123016357422, + 178.58457946777344, + 0.028811536729335785, + 6.33791971206665, + 78.09114837646484, + 2.4604194164276123, + -5.162672996520996, + -1.9589805603027344, + 1.2794933319091797, + 250.82594299316406 + ], + [ + 0.25990957021713257, + -0.45059436559677124, + 0.06157448887825012, + -0.7794139385223389, + 0.6918620467185974, + 0.44951292872428894, + 1.0499746799468994, + 0.005841830279678106, + 56.292964935302734, + 5.9671502113342285, + 66.78968811035156, + 0.03751257807016373, + 8.603753089904785, + 47.94328689575195, + 3.6040074825286865, + 1.6773055791854858, + -2.9190239906311035, + -1.7982277870178223, + 209.1162109375 + ], + [ + 0.15738365054130554, + -0.1990543156862259, + -0.21096879243850708, + -0.7437237501144409, + 0.5962345600128174, + 0.12838692963123322, + 0.9325858354568481, + 0.00018758232181426138, + 41.38226318359375, + 1.345165729522705, + -2.0313286781311035, + -0.07635390013456345, + 5.108170986175537, + 47.13261795043945, + 3.0720739364624023, + 3.1783692836761475, + -3.6837525367736816, + 0.8788055777549744, + 142.00624084472656 + ], + [ + 0.17235073447227478, + 0.01019226387143135, + -0.35296082496643066, + -0.6621893048286438, + 0.5560445189476013, + 0.11236726492643356, + 0.7399334907531738, + 0.0004884038353338838, + 41.968544006347656, + 0.2141100913286209, + -38.599220275878906, + -0.06284061074256897, + 5.414779186248779, + 39.87111282348633, + 3.059467315673828, + 2.390272378921509, + -3.2591283321380615, + -3.486874580383301, + 138.43185424804688 + ], + [ + 0.23794770240783691, + -0.4900645613670349, + -0.011707608588039875, + -0.6704952716827393, + 0.5372632741928101, + 0.051002152264118195, + 0.7467884421348572, + 0.0004856945888604969, + 40.592533111572266, + 2.753553867340088, + -42.574153900146484, + -0.07540760189294815, + 3.0798721313476562, + 20.167428970336914, + 3.7870593070983887, + 4.918464660644531, + -0.7026727199554443, + 1.1029096841812134, + 51.432491302490234 + ], + [ + 0.2759004533290863, + -0.5924070477485657, + 0.020931249484419823, + -0.5460458993911743, + 0.6820108890533447, + 0.09886196255683899, + 0.7167019248008728, + 0.0005002596299163997, + 21.094329833984375, + 2.4871826171875, + -60.72250747680664, + -0.03376798704266548, + 1.3835946321487427, + 10.921226501464844, + 1.651340365409851, + 1.753352403640747, + -1.0688366889953613, + 0.4954444169998169, + -39.085052490234375 + ], + [ + 0.2188735157251358, + -0.3142482340335846, + -0.014533264562487602, + -0.5839090347290039, + 0.518755316734314, + 0.000005135694664204493, + 0.6131640672683716, + 0.0006211507134139538, + 20.23552703857422, + 2.1691536903381348, + -94.65522003173828, + 0.03900580108165741, + 3.6193885803222656, + 2.670538902282715, + 1.6299409866333008, + 1.5473499298095703, + -0.8562081456184387, + 0.4622454047203064, + -39.50715255737305 + ], + [ + 0.198481485247612, + -0.07439839094877243, + 0.06274367868900299, + -0.5037127137184143, + 0.5450150966644287, + 0.04884336516261101, + 1.023443341255188, + 0.0030024913139641285, + 16.98451042175293, + 1.5871094465255737, + -81.69155883789062, + 0.050032585859298706, + 2.0760021209716797, + 5.364504337310791, + 1.3132153749465942, + 1.8380100727081299, + -1.8052141666412354, + 0.11141256988048553, + -87.30631256103516 + ], + [ + 0.2194717824459076, + -0.11921803653240204, + 0.019222011789679527, + -0.47156256437301636, + 0.5185927748680115, + 0.005403690971434116, + 1.1428186893463135, + 0.0012586560333147645, + 16.242998123168945, + 1.5087487697601318, + -79.564453125, + 0.027658730745315552, + 0.8004121780395508, + 7.296459674835205, + 1.0413297414779663, + 1.63692045211792, + -2.1477887630462646, + 0.16242094337940216, + -102.68614196777344 + ], + [ + 0.24611498415470123, + -0.05045967549085617, + 0.09174752235412598, + -0.46277180314064026, + 0.5304945111274719, + -0.012623950839042664, + 1.2979978322982788, + 0.000569057185202837, + 15.881168365478516, + 1.5359578132629395, + -79.95002746582031, + -0.00878177210688591, + 0.9832655191421509, + 8.446954727172852, + 0.997465968132019, + 1.639317512512207, + -1.9241515398025513, + 0.2967201769351959, + -105.7148666381836 + ], + [ + 0.23592261970043182, + -0.056163568049669266, + 0.04964485019445419, + -0.4659730792045593, + -0.7095680236816406, + 0.048651017248630524, + 1.2980189323425293, + 0.0007347611244767904, + 16.73440933227539, + 1.762690544128418, + -70.92251586914062, + -0.032373104244470596, + 1.05104398727417, + 10.196749687194824, + 1.0973315238952637, + 1.7885221242904663, + -2.9193472862243652, + 0.2187758833169937, + -115.69583129882812 + ], + [ + 0.15151800215244293, + -0.09102077037096024, + 0.014796901494264603, + -0.4803575873374939, + -0.7396679520606995, + -0.0007302318117581308, + 1.1593388319015503, + 0.0025926027446985245, + 20.630054473876953, + 1.8797599077224731, + -52.01689910888672, + -0.03619256988167763, + 1.1444971561431885, + 15.103338241577148, + 1.2100002765655518, + 1.3989856243133545, + -3.14176082611084, + 0.16095776855945587, + -110.93091583251953 + ], + [ + 0.3331563174724579, + -0.5375060439109802, + 0.07809200137853622, + -0.5034290552139282, + 1.7812379598617554, + 0.2593395709991455, + 1.1528451442718506, + 0.0026077369693666697, + 27.796009063720703, + 6.520780563354492, + 10.290216445922852, + -0.047430116683244705, + 1.8525245189666748, + 26.498050689697266, + 2.599048137664795, + 2.684617519378662, + -1.538456916809082, + 0.2234235405921936, + -85.03682708740234 + ], + [ + 0.6148445010185242, + -0.5458109974861145, + 0.07436816394329071, + -0.5558772683143616, + -1.6022089719772339, + -1.8660619258880615, + 1.4260317087173462, + 0.0005109156481921673, + 55.66039276123047, + 10.748068809509277, + 133.65122985839844, + -0.20039774477481842, + 2.7093417644500732, + 47.711605072021484, + 4.897413730621338, + 7.3790411949157715, + -3.70729398727417, + -0.4770473539829254, + 20.235145568847656 + ], + [ + 1.219691514968872, + -3.930114984512329, + -0.05820227786898613, + -0.7105394601821899, + 1.1356737613677979, + 0.3353612422943115, + 2.251840114593506, + 0.00047251631622202694, + 85.90479278564453, + 6.80287504196167, + 229.81942749023438, + -0.07705919444561005, + 2.6597917079925537, + 64.78392791748047, + -2.5225374698638916, + 1.3843309879302979, + 1.1906018257141113, + -0.05136825144290924, + 86.52433013916016 + ], + [ + 0.20475554466247559, + -0.21365594863891602, + -0.00399854127317667, + -0.5768263339996338, + 0.4638493061065674, + -0.025749268010258675, + 1.2562960386276245, + 0.00046094285789877176, + 65.2007827758789, + 3.486802816390991, + 11.989641189575195, + -0.14037208259105682, + 1.885317325592041, + 18.04607582092285, + 2.0254745483398438, + 2.0944604873657227, + -0.48780372738838196, + 0.42370009422302246, + 81.5890884399414 + ], + [ + 0.10137239098548889, + -0.37388700246810913, + -0.020501015707850456, + -0.6074191927909851, + 0.4287753403186798, + 0.115017831325531, + 0.7555304169654846, + 0.00048564354074187577, + 29.506513595581055, + 2.9056577682495117, + -94.57997131347656, + 0.03204174339771271, + 3.9000699520111084, + 19.290468215942383, + 1.8547735214233398, + 1.6670939922332764, + 0.32219696044921875, + -0.3370084762573242, + 123.68209075927734 + ], + [ + 0.18710395693778992, + -0.19680142402648926, + -0.32244470715522766, + -0.5688077807426453, + 0.4720882475376129, + 0.0397401861846447, + 0.7683758735656738, + 0.0005462547997012734, + 31.28867530822754, + 3.731929063796997, + -90.71562957763672, + -0.03494120389223099, + 0.08460897952318192, + 17.6873836517334, + 3.125368118286133, + 3.4693655967712402, + 2.5074703693389893, + 2.282147169113159, + 160.0921173095703 + ], + [ + 0.1529584527015686, + -0.0030397260561585426, + -0.1533682495355606, + -0.709664523601532, + 0.893938422203064, + 0.5760723352432251, + 0.8047239184379578, + 0.0004966786364093423, + 36.98611068725586, + 3.146008014678955, + -71.38362121582031, + 0.018817907199263573, + 3.2452728748321533, + 19.201480865478516, + 2.6668121814727783, + 1.8272329568862915, + 3.000004291534424, + 0.04630224406719208, + 150.34600830078125 + ], + [ + 0.12564659118652344, + -0.10856067389249802, + -0.13760994374752045, + -0.6819873452186584, + 0.985526442527771, + 0.5328243970870972, + 0.8184333443641663, + 0.0004991660825908184, + 36.06460952758789, + 2.3818607330322266, + -67.15582275390625, + 0.06724181771278381, + 4.003010272979736, + 20.30370330810547, + 1.7372372150421143, + 0.7887271046638489, + 3.711036205291748, + -0.16165831685066223, + 140.82354736328125 + ], + [ + 0.2156868875026703, + -0.21970093250274658, + -0.17157238721847534, + -0.582151472568512, + 0.7571473121643066, + 0.34388917684555054, + 0.8021156191825867, + 0.0004671056231018156, + 35.37557601928711, + 3.965250015258789, + -80.08492279052734, + -0.020001837983727455, + -0.5407283902168274, + 18.760866165161133, + 2.503405809402466, + 1.832324504852295, + 2.6140968799591064, + -0.19020792841911316, + 150.99533081054688 + ], + [ + 0.1412637084722519, + -0.30071574449539185, + -0.022506190463900566, + -0.5232022404670715, + 0.5742732882499695, + 0.07827191799879074, + 0.8163344860076904, + 0.0004601764085236937, + 40.39252471923828, + 3.7928383350372314, + -66.60188293457031, + -0.05314407870173454, + 1.8710877895355225, + 12.72307300567627, + 2.8527181148529053, + 2.524333953857422, + 2.7482614517211914, + 0.30411258339881897, + 106.4751968383789 + ], + [ + 0.21904438734054565, + -0.9796338081359863, + -0.20808185636997223, + -0.6725241541862488, + 0.76905757188797, + 0.1507904976606369, + 0.9582247138023376, + 0.0018147160299122334, + 51.486236572265625, + 8.145078659057617, + 2.00826358795166, + -0.02299480140209198, + 1.78370201587677, + 28.655366897583008, + 3.6398465633392334, + 3.2651970386505127, + 3.6815109252929688, + 0.6304918527603149, + 186.10191345214844 + ], + [ + 0.14291352033615112, + -0.4092702567577362, + -0.016462016850709915, + -1.0074352025985718, + 0.7507007122039795, + 0.0233329888433218, + 1.2622381448745728, + 0.00662043783813715, + 76.708984375, + 9.956892013549805, + 188.7099609375, + -0.10155251622200012, + 3.933154344558716, + 78.10543823242188, + 4.067844390869141, + -2.402595281600952, + 6.157655715942383, + 0.5734622478485107, + 253.45640563964844 + ], + [ + 0.020308295264840126, + -0.12989488244056702, + 0.012950842268764973, + -1.0508146286010742, + -1.8382384777069092, + -0.18744176626205444, + 1.3021883964538574, + 0.007097089663147926, + 64.22801971435547, + 5.043331623077393, + 185.12010192871094, + -0.11849214881658554, + 5.452884197235107, + 99.28350067138672, + 6.566226959228516, + 2.2203423976898193, + 3.2472586631774902, + -0.5647582411766052, + 199.72872924804688 + ], + [ + 0.3228916525840759, + -0.3939247727394104, + -0.07691303640604019, + -0.835760772228241, + 0.7163823246955872, + 0.5999462008476257, + 1.0237541198730469, + 0.005271204747259617, + 60.66386795043945, + 6.487387657165527, + 80.66358947753906, + -0.23649781942367554, + 6.688722610473633, + 65.82988739013672, + 4.051763534545898, + 1.3767602443695068, + 1.2283387184143066, + -1.5445997714996338, + 189.17742919921875 + ], + [ + 0.22933758795261383, + -0.5853457450866699, + -0.40808942914009094, + -0.7420495748519897, + 0.5262842774391174, + 0.12272506207227707, + 0.8630633354187012, + 0.0002305197558598593, + 45.97563552856445, + 1.6473886966705322, + 0.2738247513771057, + -0.25354090332984924, + 5.018074989318848, + 49.321250915527344, + 4.49329948425293, + 3.769881010055542, + 0.5061792135238647, + 2.4303884506225586, + 171.16476440429688 + ], + [ + 0.10595784336328506, + -0.3034239709377289, + 0.004209194332361221, + -0.5913828015327454, + -0.6290345191955566, + -0.1300378441810608, + 0.795529842376709, + 0.0004703139129560441, + 38.556922912597656, + 2.611149787902832, + -29.965702056884766, + -0.2867933511734009, + 3.7744107246398926, + 19.35792350769043, + 4.308314323425293, + 5.401734352111816, + -1.5967721939086914, + 1.1559562683105469, + 80.67886352539062 + ], + [ + 0.18422643840312958, + -0.61520916223526, + 0.00014860428927931935, + -0.5726089477539062, + -0.8390034437179565, + -0.28560081124305725, + 0.7249773144721985, + 0.00046326289884746075, + 36.372188568115234, + 2.6457676887512207, + -49.63511276245117, + -0.1284542679786682, + 2.8439812660217285, + 17.921478271484375, + 4.430426597595215, + 5.805295467376709, + -0.828450620174408, + -0.8559787273406982, + 57.3697624206543 + ], + [ + 0.3403075337409973, + -0.49216631054878235, + 0.03154202178120613, + -0.5617940425872803, + 0.6211637854576111, + 0.0806439071893692, + 0.7029438614845276, + 0.0005348918493837118, + 21.42361831665039, + 2.2635087966918945, + -63.300052642822266, + -0.04405362904071808, + 5.08213472366333, + 11.197439193725586, + 1.9858449697494507, + 2.1883108615875244, + -1.1526974439620972, + 1.0649752616882324, + -30.624439239501953 + ], + [ + 0.25372663140296936, + -0.320645272731781, + -0.07507364451885223, + -0.5897619724273682, + 0.5589356422424316, + 0.04340376704931259, + 0.5946183800697327, + 0.0006588282412849367, + 20.094369888305664, + 1.8859014511108398, + -93.14723205566406, + 0.04088236391544342, + 4.745431900024414, + 3.4518299102783203, + 2.009272336959839, + 2.3444361686706543, + 0.32627999782562256, + -0.770842432975769, + -38.7278938293457 + ], + [ + 0.21943247318267822, + -0.12726733088493347, + 0.037228118628263474, + -0.534363865852356, + 0.5164883732795715, + 0.03384561836719513, + 0.8946473002433777, + 0.002717023016884923, + 17.320478439331055, + 1.5989444255828857, + -83.35277557373047, + 0.04878876730799675, + 2.4009861946105957, + 5.762009620666504, + 1.32908034324646, + 1.8349647521972656, + -0.21863609552383423, + -0.023395920172333717, + -84.03746795654297 + ], + [ + 0.20040203630924225, + -0.11559498310089111, + 0.06417270004749298, + -0.5235376954078674, + 0.4606982469558716, + -0.03526902571320534, + 0.9255168437957764, + 0.0023979234974831343, + 16.93575096130371, + 1.9022513628005981, + -88.30435943603516, + 0.0501277782022953, + 0.9381177425384521, + 5.077188014984131, + 1.1604444980621338, + 1.5118155479431152, + -1.317555546760559, + 0.08588874340057373, + -85.24915313720703 + ], + [ + 0.18269747495651245, + -0.07605229318141937, + 0.07173091173171997, + -0.4844357669353485, + -0.5732073783874512, + 0.007844681851565838, + 1.12010657787323, + 0.0014891471946612, + 16.58222198486328, + 1.64606511592865, + -83.35057067871094, + -0.01078686024993658, + 0.7091659903526306, + 8.082894325256348, + 1.1329712867736816, + 1.1000499725341797, + -1.6158696413040161, + -0.04177570715546608, + -96.3712387084961 + ], + [ + 0.1609257012605667, + -0.05698171257972717, + 0.04584861919283867, + -0.43657249212265015, + -0.9378309845924377, + -0.03391912952065468, + -4.230218887329102, + 0.0004189460596535355, + 16.555925369262695, + 1.4549293518066406, + -62.00870895385742, + -0.03154341131448746, + 0.8709114193916321, + 9.55553913116455, + 0.9311321973800659, + 1.621904730796814, + -2.1065187454223633, + -0.09628447890281677, + -117.97828674316406 + ], + [ + 0.08872067928314209, + -0.08316853642463684, + 0.0016095149330794811, + -0.45677241683006287, + -0.7193160057067871, + -0.004891686141490936, + -4.217394828796387, + 0.0008948497707024217, + 19.923673629760742, + 1.6255260705947876, + -43.96807098388672, + -0.023817621171474457, + 0.6935403347015381, + 14.397486686706543, + 1.1161388158798218, + 1.7200865745544434, + -2.053905487060547, + -0.18823200464248657, + -113.9238052368164 + ], + [ + 0.0777093768119812, + 0.013259045779705048, + 0.03686278313398361, + -0.5079013109207153, + -2.0132761001586914, + 0.0010254626395180821, + -6.094466209411621, + 0.000774412474129349, + 20.7618408203125, + 3.0023746490478516, + 0.21572139859199524, + -0.04260637238621712, + -0.36693641543388367, + 19.99711799621582, + 1.3040275573730469, + 1.5885565280914307, + -3.245990514755249, + -1.6222633123397827, + -111.28253173828125 + ], + [ + 1.3190847635269165, + -0.5746856927871704, + 0.17855508625507355, + -0.4402800500392914, + -0.9835253357887268, + -0.10344929993152618, + -23.086894989013672, + 0.0010899447370320559, + 33.84690856933594, + 6.115768909454346, + 89.60429382324219, + -0.07197070121765137, + 7.1410698890686035, + 31.115278244018555, + -0.05915360897779465, + 0.12214836478233337, + -7.519678592681885, + 0.6514346599578857, + -114.10769653320312 + ], + [ + 1.2231159210205078, + -0.9607287645339966, + 0.11360731720924377, + -0.8973789811134338, + -3.622178554534912, + -0.04175031557679176, + -31.327651977539062, + 0.00081804976798594, + 55.58741760253906, + 7.034365653991699, + 180.90435791015625, + -0.1258937418460846, + 5.686140060424805, + 43.01454544067383, + -2.399845838546753, + -6.53320837020874, + -8.385109901428223, + -0.6005556583404541, + -81.34176635742188 + ], + [ + 0.1511291116476059, + -0.14357897639274597, + -0.040454570204019547, + -0.6771087646484375, + -0.9349943995475769, + -0.18844249844551086, + 1.8697611093521118, + 0.0005906057194806635, + 48.79141616821289, + 3.4771835803985596, + 64.20134735107422, + -0.07858435064554214, + 1.188006043434143, + 29.33063316345215, + 2.216262102127075, + 2.483311891555786, + -2.1261587142944336, + 1.5241737365722656, + -3.6361958980560303 + ], + [ + 0.08736417442560196, + -0.08311426639556885, + -0.01806890033185482, + -0.624649703502655, + 0.6050037741661072, + -0.02681633271276951, + 1.0923813581466675, + 0.0006138867465779185, + 32.609310150146484, + 1.8777395486831665, + -67.16415405273438, + -0.06076953560113907, + 1.5194796323776245, + 12.951915740966797, + 3.7513234615325928, + 1.5240014791488647, + -8.173264503479004, + 0.45639482140541077, + 18.55360984802246 + ], + [ + 0.04419853538274765, + -0.4252106249332428, + -0.06638911366462708, + -0.5873331427574158, + -0.6901756525039673, + 0.05158567801117897, + -3.1602203845977783, + 0.00033470726339146495, + 27.93245506286621, + 2.6492807865142822, + -81.19194030761719, + 0.005892109125852585, + 2.6808066368103027, + 19.46100425720215, + 1.354649305343628, + 2.2994210720062256, + -3.287984609603882, + -0.13685253262519836, + 129.00477600097656 + ], + [ + 0.11973437666893005, + -0.10793077945709229, + -0.10786595940589905, + -0.6045520305633545, + -1.2147974967956543, + -0.9284350872039795, + 0.7844049334526062, + 0.00048030438483692706, + 32.625423431396484, + 2.515143632888794, + -56.58749771118164, + 0.0021387909073382616, + 4.255259990692139, + 19.609878540039062, + 2.299473524093628, + 2.23740553855896, + -1.2034484148025513, + 0.1916126310825348, + 136.5943603515625 + ], + [ + 0.1082364097237587, + -0.21223677694797516, + -0.05490153655409813, + -0.545283854007721, + -1.429426908493042, + -0.3627423346042633, + 0.8043985962867737, + 0.0004843123606406152, + 34.36043167114258, + 2.9854509830474854, + -57.13039016723633, + -0.08268441259860992, + 3.9013848304748535, + 18.15716552734375, + 3.1370790004730225, + 2.550403594970703, + -0.14497748017311096, + 0.07626056671142578, + 119.68839263916016 + ], + [ + 0.12623703479766846, + -0.09981473535299301, + -0.022092686966061592, + -0.6123619675636292, + 0.6960574984550476, + 0.17629790306091309, + 0.7644410729408264, + 0.0004500673967413604, + 31.243064880371094, + 2.7847800254821777, + -71.42472076416016, + 0.029871594160795212, + 1.6017038822174072, + 18.788877487182617, + 1.5603853464126587, + 2.075836181640625, + -0.5787506103515625, + -0.8384397029876709, + 123.85447692871094 + ], + [ + 0.30559927225112915, + -0.6843422055244446, + -0.5509061217308044, + -0.5843949317932129, + 0.49212977290153503, + 0.05200646445155144, + 0.7462283372879028, + 0.0004433387366589159, + 36.03656768798828, + 1.8012105226516724, + -52.44881057739258, + 0.08841561526060104, + 4.25314474105835, + 18.274324417114258, + 6.6279802322387695, + 9.095296859741211, + 1.1217288970947266, + -1.7296305894851685, + 186.48130798339844 + ], + [ + 0.19026543200016022, + -0.9811125993728638, + -0.24197007715702057, + -0.6790480017662048, + 0.826160728931427, + 0.1361076533794403, + 0.9567856788635254, + 0.0017447572899982333, + 44.38533020019531, + 6.729168891906738, + 8.35029125213623, + -0.008922005072236061, + -0.3479408025741577, + 27.414697647094727, + 4.110133647918701, + 3.7592267990112305, + -2.021366596221924, + -0.2974810302257538, + 183.8362274169922 + ], + [ + 0.11138199269771576, + -0.21216361224651337, + -0.07062851637601852, + -1.0341061353683472, + 0.7042338252067566, + -0.03752940893173218, + 1.26123046875, + 0.006767518352717161, + 65.3997802734375, + 5.077115058898926, + 168.5412139892578, + -0.07065502554178238, + -21.741933822631836, + 66.58692932128906, + 3.9180402755737305, + -2.6938364505767822, + -0.8006421327590942, + 0.15820886194705963, + 232.139892578125 + ], + [ + 0.11156803369522095, + -0.14972706139087677, + -0.03701518103480339, + -1.0750479698181152, + 0.7851226925849915, + 0.05880920961499214, + 1.2723593711853027, + 0.006968651432543993, + 71.91404724121094, + 5.302643775939941, + 160.10682678222656, + -0.32071197032928467, + -27.322114944458008, + 81.18883514404297, + 3.3621318340301514, + -2.1586947441101074, + -3.7938132286071777, + -0.14915278553962708, + 197.42027282714844 + ], + [ + 0.204599067568779, + -0.2461235225200653, + -0.21333153545856476, + -0.7938452959060669, + 0.4815913140773773, + 0.1256493330001831, + 1.0464138984680176, + 0.00518224760890007, + 49.97133255004883, + 4.894437789916992, + 53.68952941894531, + -0.19911928474903107, + -23.529586791992188, + 55.32871627807617, + 3.3635354042053223, + 1.538684368133545, + -2.1115994453430176, + -0.26926857233047485, + 174.94149780273438 + ], + [ + 0.284850537776947, + -0.7224855422973633, + -0.10599470883607864, + -0.7012123465538025, + 0.6031214594841003, + 0.1194339394569397, + 1.062707781791687, + 0.0002201393072027713, + 47.41392517089844, + 3.0333330631256104, + 15.15195083618164, + -0.16700708866119385, + -11.840907096862793, + 22.97865104675293, + 4.272884368896484, + 3.205537796020508, + 1.213819980621338, + 0.24470829963684082, + 102.32076263427734 + ], + [ + 0.08558260649442673, + -0.26781657338142395, + -0.03651169314980507, + -0.6109598875045776, + 0.4114564061164856, + 0.024791114032268524, + 0.7712389230728149, + 0.00045804245746694505, + 41.705875396728516, + 2.4311540126800537, + -35.981204986572266, + -0.18467994034290314, + -3.1382734775543213, + 16.870887756347656, + 4.5229268074035645, + 4.405489921569824, + -2.3479084968566895, + 0.03791113942861557, + 82.2328872680664 + ], + [ + 0.18889480829238892, + -0.7775468826293945, + -0.034241363406181335, + -0.4900377690792084, + 0.4668247401714325, + 0.03599352017045021, + 0.6572790741920471, + 0.0004563787078950554, + 38.646183013916016, + 2.2688169479370117, + -59.59256362915039, + -0.18536728620529175, + 0.9315031170845032, + 13.838233947753906, + 4.0595269203186035, + 5.059770107269287, + -1.8184020519256592, + 0.10285140573978424, + 80.02012634277344 + ], + [ + 0.11466164141893387, + -0.16193976998329163, + -0.050843071192502975, + -0.5839547514915466, + 0.4238177239894867, + 0.0644395723938942, + 0.6787403225898743, + 0.0004557965148705989, + 29.917152404785156, + 1.2996795177459717, + -81.47754669189453, + -0.07345428317785263, + 2.0325613021850586, + 13.935806274414062, + 0.7567772269248962, + 1.9554189443588257, + -1.8155736923217773, + -0.9485164284706116, + 40.475616455078125 + ], + [ + -0.3174290060997009, + 0.3310340642929077, + -0.12958554923534393, + -1.3448700904846191, + 0.5881621837615967, + -0.004714091308414936, + 0.5277523994445801, + 0.001710362615995109, + 25.41599464416504, + 1.3539729118347168, + -50.08005142211914, + -0.3727305829524994, + 3.743600845336914, + -26.54120445251465, + -1.3080363273620605, + 1.7957813739776611, + -2.2712464332580566, + 0.7923770546913147, + 41.63277816772461 + ], + [ + -0.19238382577896118, + 0.16576017439365387, + -0.06331092119216919, + -0.877108633518219, + 0.5804239511489868, + 0.02127970941364765, + 0.5031863451004028, + 0.002146092476323247, + 22.907079696655273, + 2.157161235809326, + -53.333221435546875, + -0.15660357475280762, + 4.341437339782715, + -30.90949821472168, + -1.8963706493377686, + 0.18700070679187775, + -1.8457233905792236, + 0.1540101170539856, + 31.643033981323242 + ], + [ + 0.04668380692601204, + 0.046534158289432526, + 0.20892439782619476, + -0.6090874671936035, + -0.5739677548408508, + 0.020424511283636093, + -2.284179449081421, + 0.0005521719576790929, + 15.208908081054688, + 0.8874129056930542, + -55.6029167175293, + 0.15441690385341644, + 1.6044375896453857, + -19.737382888793945, + 0.18790587782859802, + 0.5347346067428589, + -1.110144853591919, + -0.07951051741838455, + -30.715444564819336 + ], + [ + 0.0704040378332138, + 0.00306660495698452, + 0.005788542330265045, + -0.5281633138656616, + -0.3896014392375946, + -0.051410697400569916, + -2.4512624740600586, + 0.0005640322342514992, + 14.02071762084961, + 0.9111858606338501, + -42.93519592285156, + 0.022168485447764397, + 1.2551944255828857, + -14.146629333496094, + 0.7183982133865356, + 1.0827301740646362, + -1.948799967765808, + 0.03619908541440964, + -95.28205108642578 + ], + [ + 0.07861907035112381, + -0.041344404220581055, + -0.00439880695194006, + -0.5452210307121277, + 0.32789313793182373, + -0.01280132308602333, + 0.6400336027145386, + 0.0008225631900131702, + 14.963103294372559, + 1.159946084022522, + -51.35942840576172, + -0.10364393144845963, + 1.2107940912246704, + -22.75741958618164, + 0.4763311743736267, + 0.853819727897644, + -1.950206995010376, + 0.16697914898395538, + -95.26329803466797 + ], + [ + 0.13270977139472961, + -0.01503751054406166, + 0.03497190773487091, + -0.5262167453765869, + 0.37883010506629944, + 0.0026681271847337484, + 0.6798986196517944, + 0.0008393845055252314, + 14.390527725219727, + 1.1559127569198608, + -34.342041015625, + -0.2232520431280136, + 0.9509322047233582, + -32.627685546875, + 0.7535831928253174, + 1.1008868217468262, + -2.6093475818634033, + 0.02177518419921398, + -103.45665740966797 + ], + [ + 0.15651755034923553, + -0.15258224308490753, + 0.03707513585686684, + -0.5549656748771667, + -0.8716737031936646, + -0.17876099050045013, + 0.5893511772155762, + 0.0012780610704794526, + 16.52436065673828, + 1.6463030576705933, + -15.422141075134277, + -0.3689005374908447, + 1.9884896278381348, + -55.493408203125, + 0.8239267468452454, + 0.7360613942146301, + -2.750591278076172, + -0.06881178915500641, + -82.84323120117188 + ], + [ + 0.4447348117828369, + -0.4231981933116913, + -0.02228293940424919, + -0.7803685665130615, + 0.7693158984184265, + 0.3406188488006592, + 1.031157374382019, + 0.0005409898003563285, + 26.59900665283203, + 4.324277877807617, + 44.66126251220703, + -0.6762575507164001, + 4.063052177429199, + -120.94087219238281, + 2.1688156127929688, + 2.7925262451171875, + -2.3223366737365723, + 0.47057315707206726, + -57.06726837158203 + ], + [ + 0.3455011546611786, + -0.34853312373161316, + -0.07679200172424316, + -0.7773706316947937, + 0.8298165798187256, + 0.1192348450422287, + 1.2219772338867188, + 0.0004078227502759546, + 40.303794860839844, + 3.6706557273864746, + 87.4390869140625, + -0.5022661089897156, + 5.4427337646484375, + -179.41114807128906, + -2.2335124015808105, + 0.38430309295654297, + -3.290996789932251, + 0.5145955681800842, + 37.80179977416992 + ], + [ + -0.9017656445503235, + 0.4451572299003601, + 0.06388839334249496, + -0.7944748997688293, + 0.6035032272338867, + -0.0905015766620636, + 0.7729612588882446, + 0.00041011886787600815, + 37.274715423583984, + 1.159719467163086, + 14.937543869018555, + -2.050440788269043, + 3.1982452869415283, + -70.25680541992188, + -1.3633711338043213, + 0.7603104114532471, + -5.101544380187988, + -0.42048677802085876, + 83.18323516845703 + ], + [ + 0.11393378674983978, + 0.11304812133312225, + -0.16461777687072754, + -0.7269461154937744, + 0.16770629584789276, + -0.1017497181892395, + 0.5087674260139465, + 0.0004202720010653138, + 27.24408531188965, + 1.5593397617340088, + -28.239973068237305, + 0.4899006187915802, + 1.0886896848678589, + -24.55528450012207, + 2.7483482360839844, + 2.03686785697937, + -0.42894095182418823, + 1.3455692529678345, + 204.861572265625 + ], + [ + 0.03289812058210373, + 0.00438904482871294, + -0.02268366888165474, + -0.6151777505874634, + 0.26423653960227966, + -0.05472677946090698, + 0.5688372254371643, + 0.00039869867032393813, + 40.12403869628906, + 6.724072456359863, + -3.9013240337371826, + 0.13893280923366547, + 0.9798011779785156, + -21.420793533325195, + -1.6129995584487915, + -4.774735450744629, + -2.7931156158447266, + 1.4105048179626465, + 319.2957458496094 + ], + [ + -0.03983254358172417, + -0.03532906994223595, + -0.022279951721429825, + -0.627357006072998, + 0.4631103277206421, + -0.015223309397697449, + 0.5658614635467529, + 0.00040272370097227395, + 35.80498123168945, + 20.436368942260742, + 4.8773040771484375, + -0.02710779756307602, + 2.5953235626220703, + -20.015819549560547, + -0.4222872853279114, + -6.170653820037842, + -1.3667196035385132, + -0.08611901849508286, + 363.1136779785156 + ], + [ + -0.029909580945968628, + -0.054200202226638794, + -0.015400067903101444, + -0.6077865958213806, + 0.45533764362335205, + 0.003094450104981661, + 0.5511691570281982, + 0.00041140950634144247, + 32.99904251098633, + 26.067794799804688, + 5.580532550811768, + -0.01208861917257309, + 2.7792036533355713, + -19.195932388305664, + -3.357377052307129, + -8.327322006225586, + 1.2978521585464478, + 0.4992067217826843, + 374.6746826171875 + ], + [ + 0.002795484848320484, + -0.0554082915186882, + -0.033671021461486816, + -0.6234163641929626, + 0.560994029045105, + 0.020386941730976105, + 0.5377357006072998, + 0.00039178752922452986, + 32.3141975402832, + 23.293106079101562, + 1.1144087314605713, + 0.2542417645454407, + 2.357220411300659, + -18.85422134399414, + -0.9144224524497986, + -15.955507278442383, + 1.5044362545013428, + -0.023106178268790245, + 381.828125 + ], + [ + 0.0010237160604447126, + -0.06102044880390167, + -0.034895896911621094, + -0.625860869884491, + 0.5427557229995728, + 0.013131984509527683, + 0.5326250195503235, + 0.0003884797915816307, + 32.58828353881836, + 24.576950073242188, + 1.2001595497131348, + 0.25430577993392944, + 2.411581516265869, + -19.075937271118164, + -1.6931570768356323, + -12.839770317077637, + 3.3814566135406494, + -0.1815534234046936, + 378.95782470703125 + ] + ] + } + ], + "layout": { + "coloraxis": { + "colorscale": [ + [ + 0, + "rgb(0,0,255)" + ], + [ + 1, + "rgb(255,0,0)" + ] + ] + }, + "height": 700, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Sample Explanations" + }, + "xaxis": { + "anchor": "y", + "constrain": "domain", + "domain": [ + 0, + 1 + ], + "scaleanchor": "y" + }, + "yaxis": { + "anchor": "x", + "autorange": "reversed", + "constrain": "domain", + "domain": [ + 0, + 1 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.imshow(samples_explanations, height=700, color_continuous_scale='Bluered', title=\"Sample Explanations\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/poetry.lock b/poetry.lock index 4f0dbc6..8a33e78 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1376,6 +1376,36 @@ files = [ {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, ] +[[package]] +name = "llvmlite" +version = "0.43.0" +description = "lightweight wrapper around basic LLVM functionality" +optional = false +python-versions = ">=3.9" +files = [ + {file = "llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761"}, + {file = "llvmlite-0.43.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4fd101f571a31acb1559ae1af30f30b1dc4b3186669f92ad780e17c81e91bc"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d434ec7e2ce3cc8f452d1cd9a28591745de022f931d67be688a737320dfcead"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6912a87782acdff6eb8bf01675ed01d60ca1f2551f8176a300a886f09e836a6a"}, + {file = "llvmlite-0.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f0e4bf2fd2d9a75a3534111e8ebeb08eda2f33e9bdd6dfa13282afacdde0ed"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8d0618cb9bfe40ac38a9633f2493d4d4e9fcc2f438d39a4e854f39cc0f5f98"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0a9a1a39d4bf3517f2af9d23d479b4175ead205c592ceeb8b89af48a327ea57"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1da416ab53e4f7f3bc8d4eeba36d801cc1894b9fbfbf2022b29b6bad34a7df2"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977525a1e5f4059316b183fb4fd34fa858c9eade31f165427a3977c95e3ee749"}, + {file = "llvmlite-0.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5bd550001d26450bd90777736c69d68c487d17bf371438f975229b2b8241a91"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f99b600aa7f65235a5a05d0b9a9f31150c390f31261f2a0ba678e26823ec38f7"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:35d80d61d0cda2d767f72de99450766250560399edc309da16937b93d3b676e7"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eccce86bba940bae0d8d48ed925f21dbb813519169246e2ab292b5092aba121f"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6509e1507ca0760787a199d19439cc887bfd82226f5af746d6977bd9f66844"}, + {file = "llvmlite-0.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7a2872ee80dcf6b5dbdc838763d26554c2a18aa833d31a2635bff16aafefb9c9"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cd2a7376f7b3367019b664c21f0c61766219faa3b03731113ead75107f3b66c"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18e9953c748b105668487b7c81a3e97b046d8abf95c4ddc0cd3c94f4e4651ae8"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74937acd22dc11b33946b67dca7680e6d103d6e90eeaaaf932603bec6fe7b03a"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9efc739cc6ed760f795806f67889923f7274276f0eb45092a1473e40d9b867"}, + {file = "llvmlite-0.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:47e147cdda9037f94b399bf03bfd8a6b6b1f2f90be94a454e3386f006455a9b4"}, + {file = "llvmlite-0.43.0.tar.gz", hash = "sha256:ae2b5b5c3ef67354824fb75517c8db5fbe93bc02cd9671f3c62271626bc041d5"}, +] + [[package]] name = "loguru" version = "0.7.2" @@ -1766,6 +1796,40 @@ files = [ {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] +[[package]] +name = "numba" +version = "0.60.0" +description = "compiling Python code using LLVM" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651"}, + {file = "numba-0.60.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:159e618ef213fba758837f9837fb402bbe65326e60ba0633dbe6c7f274d42c1b"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1527dc578b95c7c4ff248792ec33d097ba6bef9eda466c948b68dfc995c25781"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe0b28abb8d70f8160798f4de9d486143200f34458d34c4a214114e445d7124e"}, + {file = "numba-0.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:19407ced081d7e2e4b8d8c36aa57b7452e0283871c296e12d798852bc7d7f198"}, + {file = "numba-0.60.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a17b70fc9e380ee29c42717e8cc0bfaa5556c416d94f9aa96ba13acb41bdece8"}, + {file = "numba-0.60.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fb02b344a2a80efa6f677aa5c40cd5dd452e1b35f8d1c2af0dfd9ada9978e4b"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f4fde652ea604ea3c86508a3fb31556a6157b2c76c8b51b1d45eb40c8598703"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4142d7ac0210cc86432b818338a2bc368dc773a2f5cf1e32ff7c5b378bd63ee8"}, + {file = "numba-0.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:cac02c041e9b5bc8cf8f2034ff6f0dbafccd1ae9590dc146b3a02a45e53af4e2"}, + {file = "numba-0.60.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7da4098db31182fc5ffe4bc42c6f24cd7d1cb8a14b59fd755bfee32e34b8404"}, + {file = "numba-0.60.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38d6ea4c1f56417076ecf8fc327c831ae793282e0ff51080c5094cb726507b1c"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:62908d29fb6a3229c242e981ca27e32a6e606cc253fc9e8faeb0e48760de241e"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0ebaa91538e996f708f1ab30ef4d3ddc344b64b5227b67a57aa74f401bb68b9d"}, + {file = "numba-0.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:f75262e8fe7fa96db1dca93d53a194a38c46da28b112b8a4aca168f0df860347"}, + {file = "numba-0.60.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:01ef4cd7d83abe087d644eaa3d95831b777aa21d441a23703d649e06b8e06b74"}, + {file = "numba-0.60.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:819a3dfd4630d95fd574036f99e47212a1af41cbcb019bf8afac63ff56834449"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b983bd6ad82fe868493012487f34eae8bf7dd94654951404114f23c3466d34b"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c151748cd269ddeab66334bd754817ffc0cabd9433acb0f551697e5151917d25"}, + {file = "numba-0.60.0-cp39-cp39-win_amd64.whl", hash = "sha256:3031547a015710140e8c87226b4cfe927cac199835e5bf7d4fe5cb64e814e3ab"}, + {file = "numba-0.60.0.tar.gz", hash = "sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16"}, +] + +[package.dependencies] +llvmlite = "==0.43.*" +numpy = ">=1.22,<2.1" + [[package]] name = "numpy" version = "1.26.4" @@ -3147,6 +3211,59 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "shap" +version = "0.46.0" +description = "A unified approach to explain the output of any machine learning model." +optional = false +python-versions = ">=3.9" +files = [ + {file = "shap-0.46.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:905b2d7a0262ef820785a7c0e3c7f24c9d281e6f934edb65cbe811fe0e971187"}, + {file = "shap-0.46.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bccbb30ffbf8b9ed53e476d0c1319fdfcbeac455fe9df277fb0d570d92790e80"}, + {file = "shap-0.46.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9633d3d7174acc01455538169ca6e6344f570530384548631aeadcf7bfdaaaea"}, + {file = "shap-0.46.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6097eb2ab7e8c194254bac3e462266490fbdd43bfe35a1014e9ee21c4ef10ee"}, + {file = "shap-0.46.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0cf7c6e3f056cf3bfd16bcfd5744d0cc25b851555b1e750a3ab889b3077d2d05"}, + {file = "shap-0.46.0-cp310-cp310-win_amd64.whl", hash = "sha256:949bd7fa40371c3f1885a30ae0611dd481bf4ac90066ff726c73cb5bb393032b"}, + {file = "shap-0.46.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f18217c98f39fd485d541f6aab0b860b3be74b69b21d4faf11959e3fcba765c5"}, + {file = "shap-0.46.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5bbdae4489577c6fce1cfe2d9d8f3d5b96d69284d29645fe651f78f6e965aeb4"}, + {file = "shap-0.46.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13d36dc58d1e8c010feb4e7da71c77d23626a52d12d16b02869e793b11be4695"}, + {file = "shap-0.46.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70e06fdfdf53d5fb932c82f4529397552b262e0ccce734f5226fb1e1eab2bc3e"}, + {file = "shap-0.46.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:943f0806fa00b4fafb174f172a73d88de2d8600e6d69c2e2bff833f00e6c4c21"}, + {file = "shap-0.46.0-cp311-cp311-win_amd64.whl", hash = "sha256:c972a2efdc9fc00d543efaa55805eca947b8c418d065962d967824c2d5d295d0"}, + {file = "shap-0.46.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a9cc9be191562bea1a782baff912854d267c6f4831bbf454d8d7bb7df7ddb214"}, + {file = "shap-0.46.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab1fecfb43604605be17e26ae12bde4406c451c46b54b980d9570cec03fbc239"}, + {file = "shap-0.46.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b216adf2a17b0e0694f17965ac29354ca8c4f27ac3c66f68bf6fc4cb2aa28207"}, + {file = "shap-0.46.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6e5dc5257b747a784f7a9b3acb64216a9011f01734f3c96b27fe5e15ae5f99f"}, + {file = "shap-0.46.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1230bf973463041dfa15734f290fbf3ab9c6e4e8222339c76f68fc355b940d80"}, + {file = "shap-0.46.0-cp312-cp312-win_amd64.whl", hash = "sha256:0cbbf996537b2a42d3bc7f2a13492988822ee1bfd7220700989408dfb9e1c5ad"}, + {file = "shap-0.46.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c7d0c53a8cbefb2260ce28a98fa866c1a287770981f95c40a54f9d1082cbb31"}, + {file = "shap-0.46.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0726f8c63f09dde586c9859ad315641f5a080e9aecf123a0cabc336b61703d66"}, + {file = "shap-0.46.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99edc28daac4cbb98cd9f02febf4e9fbc6b9e3d24519c22ed59a98c68c47336c"}, + {file = "shap-0.46.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85a6ff9c9e15abd9a332360cff8d105165a600466167d6274dab468a050d005a"}, + {file = "shap-0.46.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9f9f9727839e2459dfa4b4fbc190224e87f7b4b2a29f0e2a438500215921192b"}, + {file = "shap-0.46.0-cp39-cp39-win_amd64.whl", hash = "sha256:b169b485a69f7d32e32fa64ad77be00129436c4455b9d0997b21b553f0becc8c"}, + {file = "shap-0.46.0.tar.gz", hash = "sha256:bdaa5b098be5a958348015e940f6fd264339b5db1e651f9898a3117be95b05a0"}, +] + +[package.dependencies] +cloudpickle = "*" +numba = "*" +numpy = "*" +packaging = ">20.9" +pandas = "*" +scikit-learn = "*" +scipy = "*" +slicer = "0.0.8" +tqdm = ">=4.27.0" + +[package.extras] +docs = ["ipython", "matplotlib", "myst-parser (==2.0.0)", "nbsphinx (==0.9.3)", "numpydoc", "requests", "sphinx (==7.2.6)", "sphinx-github-changelog (==1.2.1)", "sphinx-rtd-theme (==2.0.0)"] +others = ["lime"] +plots = ["ipython", "matplotlib"] +test = ["catboost", "gpboost", "lightgbm", "ngboost", "opencv-python", "protobuf (==3.20.3)", "pyod", "pyspark", "pytest", "pytest-cov", "pytest-mpl", "sentencepiece", "tensorflow", "tf-keras", "torch", "torch (==2.2.0)", "torchvision", "transformers", "xgboost"] +test-core = ["pytest", "pytest-cov", "pytest-mpl"] +test-notebooks = ["datasets", "jupyter", "keras", "nbconvert", "nbformat", "nlp", "transformers"] + [[package]] name = "six" version = "1.16.0" @@ -3158,6 +3275,17 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "slicer" +version = "0.0.8" +description = "A small package for big slicing." +optional = false +python-versions = ">=3.6" +files = [ + {file = "slicer-0.0.8-py3-none-any.whl", hash = "sha256:6c206258543aecd010d497dc2eca9d2805860a0b3758673903456b7df7934dc3"}, + {file = "slicer-0.0.8.tar.gz", hash = "sha256:2e7553af73f0c0c2d355f4afcc3ecf97c6f2156fcf4593955c3f56cf6c4d6eb7"}, +] + [[package]] name = "smmap" version = "5.0.1" @@ -3375,6 +3503,26 @@ files = [ {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, ] +[[package]] +name = "tqdm" +version = "4.66.4" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"}, + {file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "traitlets" version = "5.14.3" @@ -3647,4 +3795,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "42384c2241c38a374188caa03b637026c055f46a7ebc8ed13749b19faa721ee0" +content-hash = "ec9aafc1b37547d8180d3f9e9e6f592aceff4852915f1821e9b3762a0ee459dc" diff --git a/pyproject.toml b/pyproject.toml index e2fab7b..9be366a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ pyarrow = "^15.0.2" pydantic = "^2.7.4" pydantic-settings = "^2.3.4" scikit-learn = "^1.5.0" +shap = "^0.46.0" [tool.poetry.group.checks.dependencies] bandit = "^1.7.9" diff --git a/src/bikes/core/models.py b/src/bikes/core/models.py index 462fe10..dac1acc 100644 --- a/src/bikes/core/models.py +++ b/src/bikes/core/models.py @@ -6,6 +6,7 @@ import typing as T import pydantic as pdt +import shap from sklearn import compose, ensemble, pipeline, preprocessing from bikes.core import schemas @@ -77,6 +78,28 @@ def predict(self, inputs: schemas.Inputs) -> schemas.Outputs: schemas.Outputs: model prediction outputs. """ + def explain_model(self) -> schemas.FeatureImportances: + """Explain the internal model structure. + + Raises: + NotImplementedError: method not implemented. + + Returns: + schemas.FeatureImportances: feature importances. + """ + raise NotImplementedError() + + def explain_samples(self, inputs: schemas.Inputs) -> schemas.SHAPValues: + """Explain model outputs on input samples. + + Raises: + NotImplementedError: method not implemented. + + Returns: + schemas.SHAPValues: SHAP values. + """ + raise NotImplementedError() + def get_internal_model(self) -> T.Any: """Return the internal model in the object. @@ -161,6 +184,33 @@ def predict(self, inputs: schemas.Inputs) -> schemas.Outputs: ) return outputs + @T.override + def explain_model(self) -> schemas.FeatureImportances: + model = self.get_internal_model() + regressor = model.named_steps["regressor"] + transformer = model.named_steps["transformer"] + column_names = transformer.get_feature_names_out() + feature_importances = schemas.FeatureImportances( + data={ + "feature": column_names, + "importance": regressor.feature_importances_, + } + ) + return feature_importances + + @T.override + def explain_samples(self, inputs: schemas.Inputs) -> schemas.SHAPValues: + model = self.get_internal_model() + regressor = model.named_steps["regressor"] + transformer = model.named_steps["transformer"] + transformed = transformer.transform(X=inputs) + explainer = shap.TreeExplainer(model=regressor) + shap_values = schemas.SHAPValues( + data=explainer.shap_values(X=transformed), + columns=transformer.get_feature_names_out(), + ) + return shap_values + @T.override def get_internal_model(self) -> pipeline.Pipeline: model = self._pipeline diff --git a/src/bikes/core/schemas.py b/src/bikes/core/schemas.py index 988954f..b21128e 100644 --- a/src/bikes/core/schemas.py +++ b/src/bikes/core/schemas.py @@ -90,3 +90,31 @@ class OutputsSchema(Schema): Outputs = papd.DataFrame[OutputsSchema] + + +class SHAPValuesSchema(Schema): + """Schema for the project shap values.""" + + class Config: + """Default configurations this schema. + + Parameters: + dtype (str): dataframe default data type. + strict (bool): ensure the data type is correct. + """ + + dtype: str = "float32" + strict: bool = False + + +SHAPValues = papd.DataFrame[SHAPValuesSchema] + + +class FeatureImportancesSchema(Schema): + """Schema for the project feature importances.""" + + feature: papd.Series[padt.String] = pa.Field() + importance: papd.Series[padt.Float32] = pa.Field() + + +FeatureImportances = papd.DataFrame[FeatureImportancesSchema] diff --git a/src/bikes/jobs/__init__.py b/src/bikes/jobs/__init__.py index dd76e7d..55e8786 100644 --- a/src/bikes/jobs/__init__.py +++ b/src/bikes/jobs/__init__.py @@ -2,6 +2,7 @@ # %% IMPORTS +from bikes.jobs.explanations import ExplanationsJob from bikes.jobs.inference import InferenceJob from bikes.jobs.promotion import PromotionJob from bikes.jobs.training import TrainingJob @@ -9,8 +10,8 @@ # %% TYPES -JobKind = TuningJob | TrainingJob | PromotionJob | InferenceJob +JobKind = TuningJob | TrainingJob | PromotionJob | InferenceJob | ExplanationsJob # %% EXPORTS -__all__ = ["TuningJob", "TrainingJob", "PromotionJob", "InferenceJob", "JobKind"] +__all__ = ["TuningJob", "TrainingJob", "PromotionJob", "InferenceJob", "ExplanationsJob", "JobKind"] diff --git a/src/bikes/jobs/explanations.py b/src/bikes/jobs/explanations.py new file mode 100644 index 0000000..f7561cf --- /dev/null +++ b/src/bikes/jobs/explanations.py @@ -0,0 +1,78 @@ +"""Define a job for explaining the model structure and decisions.""" + +# %% IMPORTS + +import typing as T + +import pydantic as pdt + +from bikes.core import schemas +from bikes.io import datasets, registries +from bikes.jobs import base + +# %% JOBS + + +class ExplanationsJob(base.Job): + """Generate explanations for the model and a data sample. + + Parameters: + inputs_samples (datasets.ReaderKind): reader for the samples data. + model_explanations (datasets.WriterKind): writer for model explanation. + samples_explanations (datasets.WriterKind): writer for samples explanation. + alias (str): alias tag for the model. Defaults to "Champion". + loader (registries.LoaderKind): loader system for the model. + """ + + KIND: T.Literal["ExplanationsJob"] = "ExplanationsJob" + + # Samples + inputs_samples: datasets.ReaderKind = pdt.Field(..., discriminator="KIND") + # Explanations + model_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") + samples_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") + # Model + alias: str = "Champion" + # Loader + loader: registries.LoaderKind = pdt.Field(registries.CustomLoader(), discriminator="KIND") + + @T.override + def run(self) -> base.Locals: + # services + logger = self.logger_service.logger() + logger.info("With logger: {}", logger) + # inputs + logger.info("Read samples: {}", self.inputs_samples) + inputs_samples = self.inputs_samples.read() # unchecked! + inputs_samples = schemas.InputsSchema.check(inputs_samples) + logger.debug("- Inputs samples shape: {}", inputs_samples.shape) + # model + logger.info("With model: {}", self.mlflow_service.registry_name) + model_uri = registries.uri_for_model_alias( + name=self.mlflow_service.registry_name, alias=self.alias + ) + logger.debug("- Model URI: {}", model_uri) + # loader + logger.info("Load model: {}", self.loader) + model = self.loader.load(uri=model_uri).model.unwrap_python_model().model + logger.debug("- Model: {}", model) + # explanations + # - model + logger.info("Explain model: {}", model) + model_explanations = model.explain_model() + logger.debug("- Model explanations shape: {}", model_explanations.shape) + # - samples + logger.info("Explain samples: {}", len(inputs_samples)) + samples_explanations = model.explain_samples(inputs=inputs_samples) + logger.debug("- Samples explanations shape: {}", samples_explanations.shape) + # write + # - model + logger.info("Write model explanations: {}", self.model_explanations) + self.model_explanations.write(data=model_explanations) + # - samples + logger.info("Write samples explanations: {}", self.samples_explanations) + self.samples_explanations.write(data=samples_explanations) + self.alerter_service.notify( + title="Explanations Job Finished", message=f"Features Count: {len(model_explanations)}" + ) + return locals() diff --git a/src/bikes/jobs/inference.py b/src/bikes/jobs/inference.py index 5a089be..b922879 100644 --- a/src/bikes/jobs/inference.py +++ b/src/bikes/jobs/inference.py @@ -18,7 +18,7 @@ class InferenceJob(base.Job): Parameters: inputs (datasets.ReaderKind): reader for the inputs data. - outputs (datasets.WriterKind ): writer for the outputs data. + outputs (datasets.WriterKind): writer for the outputs data. alias (str): alias tag for the model. Defaults to "Champion". loader (registries.LoaderKind): loader system for the model. """ @@ -60,7 +60,7 @@ def run(self) -> base.Locals: logger.debug("- Outputs shape: {}", outputs.shape) # write logger.info("Write outputs: {}", self.outputs) - self.outputs.write(outputs) + self.outputs.write(data=outputs) self.alerter_service.notify( title="Inference Job Finished", message=f"Outputs Shape: {outputs.shape}" ) diff --git a/tasks/dags.py b/tasks/dags.py index 83cdbeb..00f1765 100644 --- a/tasks/dags.py +++ b/tasks/dags.py @@ -20,6 +20,7 @@ def job(ctx: Context, name: str) -> None: call(job, name="training"), # type: ignore[arg-type] call(job, name="promotion"), # type: ignore[arg-type] call(job, name="inference"), # type: ignore[arg-type] + call(job, name="explanations"), # type: ignore[arg-type] ], default=True, ) diff --git a/tests/confs/valid/5. explanations.yaml b/tests/confs/valid/5. explanations.yaml new file mode 100644 index 0000000..c72cee7 --- /dev/null +++ b/tests/confs/valid/5. explanations.yaml @@ -0,0 +1,12 @@ +job: + KIND: ExplanationsJob + inputs_samples: + KIND: ParquetReader + path: "${tests_path:}/data/inputs_sample.parquet" + limit: 100 + model_explanations: + KIND: ParquetWriter + path: "${tmp_path:}/model_explanations.parquet" + samples_explanations: + KIND: ParquetWriter + path: "${tmp_path:}/samples_explanations.parquet" diff --git a/tests/conftest.py b/tests/conftest.py index cc52fae..b46019e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -67,6 +67,18 @@ def tmp_outputs_path(tmp_path: str) -> str: return os.path.join(tmp_path, "outputs.parquet") +@pytest.fixture(scope="function") +def tmp_model_explanations_path(tmp_path: str) -> str: + """Return a tmp path for the model explanations dataset.""" + return os.path.join(tmp_path, "model_explanations.parquet") + + +@pytest.fixture(scope="function") +def tmp_samples_explanations_path(tmp_path: str) -> str: + """Return a tmp path for the samples explanations dataset.""" + return os.path.join(tmp_path, "samples_explanations.parquet") + + # %% - Configs @@ -99,6 +111,12 @@ def inputs_reader(inputs_path: str) -> datasets.ParquetReader: return datasets.ParquetReader(path=inputs_path, limit=LIMIT) +@pytest.fixture(scope="session") +def inputs_samples_reader(inputs_path: str) -> datasets.ParquetReader: + """Return a reader for the inputs samples dataset.""" + return datasets.ParquetReader(path=inputs_path, limit=100) + + @pytest.fixture(scope="session") def targets_reader(targets_path: str) -> datasets.ParquetReader: """Return a reader for the targets dataset.""" @@ -127,6 +145,18 @@ def tmp_outputs_writer(tmp_outputs_path: str) -> datasets.ParquetWriter: return datasets.ParquetWriter(path=tmp_outputs_path) +@pytest.fixture(scope="function") +def tmp_model_explanations_writer(tmp_model_explanations_path: str) -> datasets.ParquetWriter: + """Return a writer for the tmp model explanations dataset.""" + return datasets.ParquetWriter(path=tmp_model_explanations_path) + + +@pytest.fixture(scope="function") +def tmp_samples_explanations_writer(tmp_samples_explanations_path: str) -> datasets.ParquetWriter: + """Return a writer for the tmp samples explanations dataset.""" + return datasets.ParquetWriter(path=tmp_samples_explanations_path) + + # %% - Dataframes @@ -137,6 +167,13 @@ def inputs(inputs_reader: datasets.ParquetReader) -> schemas.Inputs: return schemas.InputsSchema.check(data) +@pytest.fixture(scope="session") +def inputs_samples(inputs_samples_reader: datasets.ParquetReader) -> schemas.Inputs: + """Return the inputs samples data.""" + data = inputs_samples_reader.read() + return schemas.InputsSchema.check(data) + + @pytest.fixture(scope="session") def targets(targets_reader: datasets.ParquetReader) -> schemas.Targets: """Return the targets data.""" diff --git a/tests/core/test_models.py b/tests/core/test_models.py index fa7d04c..f8f3e0e 100644 --- a/tests/core/test_models.py +++ b/tests/core/test_models.py @@ -8,7 +8,7 @@ # %% MODELS -def test_model() -> None: +def test_model(inputs_samples: schemas.Inputs) -> None: # given class MyModel(models.Model): KIND: T.Literal["MyModel"] = "MyModel" @@ -29,7 +29,11 @@ def predict(self, inputs: schemas.Inputs) -> schemas.Outputs: model = MyModel(a=10) params_init = model.get_params() params_set_params = model.set_params(b=20).get_params() - with pytest.raises(NotImplementedError) as error: + with pytest.raises(NotImplementedError) as explain_model_error: + model.explain_model() + with pytest.raises(NotImplementedError) as explain_samples_error: + model.explain_samples(inputs=inputs_samples) + with pytest.raises(NotImplementedError) as get_internal_model_error: model.get_internal_model() # then assert params_init == {"a": 10, "b": 2}, "Model should have the given params after init!" @@ -37,7 +41,15 @@ def predict(self, inputs: schemas.Inputs) -> schemas.Outputs: "a": 10, "b": 20, }, "Model should have the given params after set_params!" - assert isinstance(error.value, NotImplementedError), "Model should raise NotImplementedError!" + assert isinstance( + explain_model_error.value, NotImplementedError + ), "Model should raise NotImplementedError for explain_model_error()!" + assert isinstance( + explain_samples_error.value, NotImplementedError + ), "Model should raise NotImplementedError for explain_samples_error()!" + assert isinstance( + get_internal_model_error.value, NotImplementedError + ), "Model should raise NotImplementedError for get_internal_model_error()!" def test_baseline_sklearn_model( @@ -52,10 +64,26 @@ def test_baseline_sklearn_model( model.get_internal_model() model.fit(inputs=inputs_train, targets=targets_train) outputs = model.predict(inputs=inputs_test) + shap_values = model.explain_samples(inputs=inputs_test) + feature_importances = model.explain_model() # then assert not_fitted_error.match( "Model is not fitted yet!" ), "Model should raise an error when not fitted!" - assert outputs.ndim == 2, "Outputs should be a dataframe!" + # - model assert model.get_params() == params, "Model should have the given params!" assert model.get_internal_model() is not None, "Internal model should be fitted!" + # - outputs + assert outputs.ndim == 2, "Outputs should be a dataframe!" + # - shap values + assert len(shap_values.index) == len( + inputs_test.index + ), "SHAP values should be the same length as inputs!" + assert len(shap_values.columns) >= len( + inputs_test.columns + ), "SHAP values should have more features than inputs!" + # - feature importances + assert feature_importances["importance"].sum() == 1.0, "Importance values should sum to 1.0!" + assert len(feature_importances["feature"]) >= len( + inputs_train.columns + ), "Importance features should have more features than inputs!" diff --git a/tests/core/test_schemas.py b/tests/core/test_schemas.py index 7102286..d06653e 100644 --- a/tests/core/test_schemas.py +++ b/tests/core/test_schemas.py @@ -1,6 +1,6 @@ # %% IMPORTS -from bikes.core import schemas +from bikes.core import models, schemas from bikes.io import datasets # %% SCHEMAS @@ -31,3 +31,25 @@ def test_outputs_schema(outputs_reader: datasets.Reader) -> None: data = outputs_reader.read() # then assert schema.check(data) is not None, "Outputs data should be valid!" + + +def test_shap_values_schema( + model: models.Model, + train_test_sets: tuple[schemas.Inputs, schemas.Targets, schemas.Inputs, schemas.Targets], +) -> None: + # given + schema = schemas.SHAPValuesSchema + _, _, inputs_test, _ = train_test_sets + # when + data = model.explain_samples(inputs=inputs_test) + # then + assert schema.check(data) is not None, "SHAP values data should be valid!" + + +def test_feature_importances_schema(model: models.Model) -> None: + # given + schema = schemas.FeatureImportancesSchema + # when + data = model.explain_model() + # then + assert schema.check(data) is not None, "Feature importance data should be valid!" diff --git a/tests/jobs/test_explanations.py b/tests/jobs/test_explanations.py new file mode 100644 index 0000000..0a970ae --- /dev/null +++ b/tests/jobs/test_explanations.py @@ -0,0 +1,73 @@ +# %% IMPORTS + + +import _pytest.capture as pc +from bikes import jobs +from bikes.core import models +from bikes.io import datasets, registries, services + +# %% JOBS + + +def test_explanations_job( + mlflow_service: services.MlflowService, + alerter_service: services.AlerterService, + logger_service: services.LoggerService, + inputs_samples_reader: datasets.Reader, + tmp_model_explanations_writer: datasets.Writer, + tmp_samples_explanations_writer: datasets.Writer, + model_alias: registries.Version, + loader: registries.Loader, + capsys: pc.CaptureFixture[str], +) -> None: + # given + assert len(model_alias.aliases) == 1, "Model should have one alias!" + alias = model_alias.aliases[0] + # when + job = jobs.ExplanationsJob( + logger_service=logger_service, + alerter_service=alerter_service, + mlflow_service=mlflow_service, + inputs_samples=inputs_samples_reader, + model_explanations=tmp_model_explanations_writer, + samples_explanations=tmp_samples_explanations_writer, + alias=alias, + loader=loader, + ) + with job as runner: + out = runner.run() + # then + # - vars + assert set(out) == { + "self", + "logger", + "inputs_samples", + "model_uri", + "model", + "model_explanations", + "samples_explanations", + } + # - inputs + assert out["inputs_samples"].ndim == 2, "Inputs samples should be a dataframe!" + # - model uri + assert alias in out["model_uri"], "Model URI should contain the model alias!" + assert ( + mlflow_service.registry_name in out["model_uri"] + ), "Model URI should contain the registry name!" + # - model + assert isinstance(out["model"], models.Model), "Model should be an instance of a project Model!" + # - model explanations + assert len(out["model_explanations"].index) >= len( + out["inputs_samples"].columns + ), "Model explanations should have at least as many columns as inputs samples!" + # - samples explanations + assert len(out["samples_explanations"].index) == len( + out["inputs_samples"].index + ), "Samples explanations should have the same number of rows as inputs samples!" + assert len(out["samples_explanations"].columns) >= len( + out["inputs_samples"].columns + ), "Samples explanations should have at least as many columns as inputs samples!" + # - alerting service + assert ( + "Explanations Job Finished" in capsys.readouterr().out + ), "Alerting service should be called!" From 28321fff5dc65eade694070e9fce6640c115d574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Fri, 12 Jul 2024 22:27:58 +0200 Subject: [PATCH 07/21] feat(lineage): add lineage features through mlflow data api --- confs/explanations.yaml | 4 +-- notebooks/explain.ipynb | 13 +++++---- poetry.lock | 13 ++++++++- pyproject.toml | 1 + src/bikes/io/datasets.py | 37 ++++++++++++++++++++++++++ src/bikes/io/services.py | 2 +- src/bikes/jobs/explanations.py | 14 +++++----- src/bikes/jobs/inference.py | 1 + src/bikes/jobs/promotion.py | 1 + src/bikes/jobs/training.py | 11 ++++++++ src/bikes/jobs/tuning.py | 10 +++++++ tests/confs/valid/5. explanations.yaml | 4 +-- tests/conftest.py | 8 +++--- tests/io/test_datasets.py | 9 +++++++ tests/jobs/test_explanations.py | 8 +++--- tests/jobs/test_training.py | 20 +++++++++++--- tests/jobs/test_tuning.py | 20 +++++++++++--- 17 files changed, 142 insertions(+), 34 deletions(-) diff --git a/confs/explanations.yaml b/confs/explanations.yaml index 7f3f6f4..12d8474 100644 --- a/confs/explanations.yaml +++ b/confs/explanations.yaml @@ -4,9 +4,9 @@ job: KIND: ParquetReader path: data/inputs_test.parquet limit: 100 - model_explanations: + models_explanations: KIND: ParquetWriter - path: outputs/model_explanations.parquet + path: outputs/models_explanations.parquet samples_explanations: KIND: ParquetWriter path: outputs/samples_explanations.parquet diff --git a/notebooks/explain.ipynb b/notebooks/explain.ipynb index 1dcb015..f683f78 100644 --- a/notebooks/explain.ipynb +++ b/notebooks/explain.ipynb @@ -47,7 +47,7 @@ "metadata": {}, "outputs": [], "source": [ - "MODEL_EXPLANATIONS = '../data/model_explanations.parquet'\n", + "MODELS_EXPLANATIONS = '../data/models_explanations.parquet'\n", "SAMPLES_EXPLANATIONS = '../data/samples_explanations.parquet'" ] }, @@ -140,12 +140,11 @@ } ], "source": [ - "model_explanations = (\n", - " pd.read_parquet(MODEL_EXPLANATIONS)\n", - " .sort_values('importance', ascending=False)\n", + "models_explanations = pd.read_parquet(MODELS_EXPLANATIONS).sort_values(\n", + " \"importance\", ascending=False\n", ")\n", - "print(model_explanations.shape)\n", - "model_explanations.head()" + "print(models_explanations.shape)\n", + "models_explanations.head()" ] }, { @@ -1433,7 +1432,7 @@ } ], "source": [ - "px.bar(model_explanations, x='feature', y='importance', title='Feature Importances')" + "px.bar(models_explanations, x='feature', y='importance', title='Feature Importances')" ] }, { diff --git a/poetry.lock b/poetry.lock index 8a33e78..1b8e674 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2581,6 +2581,17 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pynvml" +version = "11.5.0" +description = "Python Bindings for the NVIDIA Management Library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pynvml-11.5.0-py3-none-any.whl", hash = "sha256:5cce014ac01b098d08f06178f86c37be409b80b2e903a5a03ce15eed60f55e25"}, + {file = "pynvml-11.5.0.tar.gz", hash = "sha256:d027b21b95b1088b9fc278117f9f61b7c67f8e33a787e9f83f735f0f71ac32d0"}, +] + [[package]] name = "pyparsing" version = "3.1.2" @@ -3795,4 +3806,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "ec9aafc1b37547d8180d3f9e9e6f592aceff4852915f1821e9b3762a0ee459dc" +content-hash = "928bd41b7a25a26c44a30f30e369e77e3ab666471faf765b32ad51bb7562f4b5" diff --git a/pyproject.toml b/pyproject.toml index 9be366a..9187ed2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ psutil = "^6.0.0" pyarrow = "^15.0.2" pydantic = "^2.7.4" pydantic-settings = "^2.3.4" +pynvml = "^11.5.0" scikit-learn = "^1.5.0" shap = "^0.46.0" diff --git a/src/bikes/io/datasets.py b/src/bikes/io/datasets.py index 4d9aeb4..623f69b 100644 --- a/src/bikes/io/datasets.py +++ b/src/bikes/io/datasets.py @@ -5,9 +5,14 @@ import abc import typing as T +import mlflow.data.pandas_dataset as lineage import pandas as pd import pydantic as pdt +# %% TYPINGS + +Lineage: T.TypeAlias = lineage.PandasDataset + # %% READERS @@ -33,6 +38,26 @@ def read(self) -> pd.DataFrame: pd.DataFrame: dataframe representation. """ + @abc.abstractmethod + def lineage( + self, + name: str, + data: pd.DataFrame, + targets: str | None = None, + predictions: str | None = None, + ) -> Lineage: + """Generate lineage information. + + Args: + name (str): dataset name. + data (pd.DataFrame): reader dataframe. + targets (str | None): name of the target column. + predictions (str | None): name of the prediction column. + + Returns: + Lineage: lineage information. + """ + class ParquetReader(Reader): """Read a dataframe from a parquet file. @@ -53,6 +78,18 @@ def read(self) -> pd.DataFrame: data = data.head(self.limit) return data + @T.override + def lineage( + self, + name: str, + data: pd.DataFrame, + targets: str | None = None, + predictions: str | None = None, + ) -> Lineage: + return lineage.from_pandas( + df=data, name=name, source=self.path, targets=targets, predictions=predictions + ) + ReaderKind = ParquetReader diff --git a/src/bikes/io/services.py b/src/bikes/io/services.py index f5c289d..7785433 100644 --- a/src/bikes/io/services.py +++ b/src/bikes/io/services.py @@ -184,7 +184,7 @@ def start(self) -> None: exclusive=self.autolog_exclusive, log_input_examples=self.autolog_log_input_examples, log_model_signatures=self.autolog_log_model_signatures, - log_models=self.autolog_log_models, + log_datasets=self.autolog_log_datasets, silent=self.autolog_silent, ) diff --git a/src/bikes/jobs/explanations.py b/src/bikes/jobs/explanations.py index f7561cf..7bff2ed 100644 --- a/src/bikes/jobs/explanations.py +++ b/src/bikes/jobs/explanations.py @@ -18,7 +18,7 @@ class ExplanationsJob(base.Job): Parameters: inputs_samples (datasets.ReaderKind): reader for the samples data. - model_explanations (datasets.WriterKind): writer for model explanation. + models_explanations (datasets.WriterKind): writer for model explanation. samples_explanations (datasets.WriterKind): writer for samples explanation. alias (str): alias tag for the model. Defaults to "Champion". loader (registries.LoaderKind): loader system for the model. @@ -29,7 +29,7 @@ class ExplanationsJob(base.Job): # Samples inputs_samples: datasets.ReaderKind = pdt.Field(..., discriminator="KIND") # Explanations - model_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") + models_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") samples_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") # Model alias: str = "Champion" @@ -59,20 +59,20 @@ def run(self) -> base.Locals: # explanations # - model logger.info("Explain model: {}", model) - model_explanations = model.explain_model() - logger.debug("- Model explanations shape: {}", model_explanations.shape) + models_explanations = model.explain_model() + logger.debug("- Model explanations shape: {}", models_explanations.shape) # - samples logger.info("Explain samples: {}", len(inputs_samples)) samples_explanations = model.explain_samples(inputs=inputs_samples) logger.debug("- Samples explanations shape: {}", samples_explanations.shape) # write # - model - logger.info("Write model explanations: {}", self.model_explanations) - self.model_explanations.write(data=model_explanations) + logger.info("Write model explanations: {}", self.models_explanations) + self.models_explanations.write(data=models_explanations) # - samples logger.info("Write samples explanations: {}", self.samples_explanations) self.samples_explanations.write(data=samples_explanations) self.alerter_service.notify( - title="Explanations Job Finished", message=f"Features Count: {len(model_explanations)}" + title="Explanations Job Finished", message=f"Features Count: {len(models_explanations)}" ) return locals() diff --git a/src/bikes/jobs/inference.py b/src/bikes/jobs/inference.py index b922879..673910e 100644 --- a/src/bikes/jobs/inference.py +++ b/src/bikes/jobs/inference.py @@ -61,6 +61,7 @@ def run(self) -> base.Locals: # write logger.info("Write outputs: {}", self.outputs) self.outputs.write(data=outputs) + # alerter self.alerter_service.notify( title="Inference Job Finished", message=f"Outputs Shape: {outputs.shape}" ) diff --git a/src/bikes/jobs/promotion.py b/src/bikes/jobs/promotion.py index 0a9c772..38a9dd1 100644 --- a/src/bikes/jobs/promotion.py +++ b/src/bikes/jobs/promotion.py @@ -49,6 +49,7 @@ def run(self) -> base.Locals: client.set_registered_model_alias(name=name, alias=self.alias, version=version) model_version = client.get_model_version_by_alias(name=name, alias=self.alias) logger.debug("- Model version: {}", model_version) + # alerter self.alerter_service.notify( title="Promotion Job Finished", message=f"Version: {model_version.version} @ {self.alias}", diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index e885a2b..22d8c57 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -4,6 +4,7 @@ import typing as T +import mlflow import pydantic as pdt from bikes.core import metrics as metrics_ @@ -61,6 +62,7 @@ def run(self) -> base.Locals: logger.info("With logger: {}", logger) # - mlflow client = self.mlflow_service.client() + logger.info("With client: {}", client) with self.mlflow_service.run_context(run_config=self.run_config) as run: logger.info("With mlflow run id: {}", run.info.run_id) # data @@ -69,11 +71,19 @@ def run(self) -> base.Locals: inputs_ = self.inputs.read() # unchecked! inputs = schemas.InputsSchema.check(inputs_) logger.debug("- Inputs shape: {}", inputs.shape) + inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") + mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) + logger.debug("- Inputs lineage: {}", inputs_lineage) # - targets logger.info("Read targets: {}", self.targets) targets_ = self.targets.read() # unchecked! targets = schemas.TargetsSchema.check(targets_) logger.debug("- Targets shape: {}", targets.shape) + targets_lineage = self.targets.lineage( + data=targets, name="targets", targets=schemas.TargetsSchema.cnt + ) + mlflow.log_input(dataset=targets_lineage, context=self.run_config.name) + logger.debug("- Targets lineage: {}", targets_lineage) # splitter logger.info("With splitter: {}", self.splitter) # - index @@ -117,6 +127,7 @@ def run(self) -> base.Locals: name=self.mlflow_service.registry_name, model_uri=model_info.model_uri ) logger.debug("- Model version: {}", model_version) + # alerter self.alerter_service.notify( title="Training Job Finished", message=f"Model version: {model_version.version}" ) diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index 6cfc4d3..230b0bc 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -4,6 +4,7 @@ import typing as T +import mlflow import pydantic as pdt from bikes.core import metrics, models, schemas @@ -68,11 +69,19 @@ def run(self) -> base.Locals: inputs_ = self.inputs.read() # unchecked! inputs = schemas.InputsSchema.check(inputs_) logger.debug("- Inputs shape: {}", inputs.shape) + inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") + mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) + logger.debug("- Inputs lineage: {}", inputs_lineage) # - targets logger.info("Read targets: {}", self.targets) targets_ = self.targets.read() # unchecked! targets = schemas.TargetsSchema.check(targets_) logger.debug("- Targets shape: {}", targets.shape) + targets_lineage = self.targets.lineage( + data=targets, name="targets", targets=schemas.TargetsSchema.cnt + ) + mlflow.log_input(dataset=targets_lineage, context=self.run_config.name) + logger.debug("- Targets lineage: {}", targets_lineage) # model logger.info("With model: {}", self.model) # metric @@ -91,6 +100,7 @@ def run(self) -> base.Locals: logger.debug("- Results: {}", results.shape) logger.debug("- Best Score: {}", best_score) logger.debug("- Best Params: {}", best_params) + # alerter self.alerter_service.notify( title="Tuning Job Finished", message=f"Best score: {best_score}" ) diff --git a/tests/confs/valid/5. explanations.yaml b/tests/confs/valid/5. explanations.yaml index c72cee7..8f4721c 100644 --- a/tests/confs/valid/5. explanations.yaml +++ b/tests/confs/valid/5. explanations.yaml @@ -4,9 +4,9 @@ job: KIND: ParquetReader path: "${tests_path:}/data/inputs_sample.parquet" limit: 100 - model_explanations: + models_explanations: KIND: ParquetWriter - path: "${tmp_path:}/model_explanations.parquet" + path: "${tmp_path:}/models_explanations.parquet" samples_explanations: KIND: ParquetWriter path: "${tmp_path:}/samples_explanations.parquet" diff --git a/tests/conftest.py b/tests/conftest.py index b46019e..e999b74 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -68,9 +68,9 @@ def tmp_outputs_path(tmp_path: str) -> str: @pytest.fixture(scope="function") -def tmp_model_explanations_path(tmp_path: str) -> str: +def tmp_models_explanations_path(tmp_path: str) -> str: """Return a tmp path for the model explanations dataset.""" - return os.path.join(tmp_path, "model_explanations.parquet") + return os.path.join(tmp_path, "models_explanations.parquet") @pytest.fixture(scope="function") @@ -146,9 +146,9 @@ def tmp_outputs_writer(tmp_outputs_path: str) -> datasets.ParquetWriter: @pytest.fixture(scope="function") -def tmp_model_explanations_writer(tmp_model_explanations_path: str) -> datasets.ParquetWriter: +def tmp_models_explanations_writer(tmp_models_explanations_path: str) -> datasets.ParquetWriter: """Return a writer for the tmp model explanations dataset.""" - return datasets.ParquetWriter(path=tmp_model_explanations_path) + return datasets.ParquetWriter(path=tmp_models_explanations_path) @pytest.fixture(scope="function") diff --git a/tests/io/test_datasets.py b/tests/io/test_datasets.py index 0f4004d..e6ecc04 100644 --- a/tests/io/test_datasets.py +++ b/tests/io/test_datasets.py @@ -15,10 +15,19 @@ def test_parquet_reader(limit: int | None, inputs_path: str) -> None: reader = datasets.ParquetReader(path=inputs_path, limit=limit) # when data = reader.read() + lineage = reader.lineage(name="inputs", data=data) # then assert data.ndim == 2, "Data should be a dataframe!" if limit is not None: assert len(data) == limit, "Data should have the limit size!" + assert lineage.name == "inputs", "Lineage name should be inputs!" + assert lineage.source.uri == inputs_path, "Lineage source uri should be the inputs path!" + assert set(lineage.schema.input_names()) == set( + data.columns + ), "Lineage schema names should be the data columns!" + assert lineage.profile["num_rows"] == len( + data + ), "Lineage profile should contain the data row count!" # %% WRITERS diff --git a/tests/jobs/test_explanations.py b/tests/jobs/test_explanations.py index 0a970ae..9d064cb 100644 --- a/tests/jobs/test_explanations.py +++ b/tests/jobs/test_explanations.py @@ -14,7 +14,7 @@ def test_explanations_job( alerter_service: services.AlerterService, logger_service: services.LoggerService, inputs_samples_reader: datasets.Reader, - tmp_model_explanations_writer: datasets.Writer, + tmp_models_explanations_writer: datasets.Writer, tmp_samples_explanations_writer: datasets.Writer, model_alias: registries.Version, loader: registries.Loader, @@ -29,7 +29,7 @@ def test_explanations_job( alerter_service=alerter_service, mlflow_service=mlflow_service, inputs_samples=inputs_samples_reader, - model_explanations=tmp_model_explanations_writer, + models_explanations=tmp_models_explanations_writer, samples_explanations=tmp_samples_explanations_writer, alias=alias, loader=loader, @@ -44,7 +44,7 @@ def test_explanations_job( "inputs_samples", "model_uri", "model", - "model_explanations", + "models_explanations", "samples_explanations", } # - inputs @@ -57,7 +57,7 @@ def test_explanations_job( # - model assert isinstance(out["model"], models.Model), "Model should be an instance of a project Model!" # - model explanations - assert len(out["model_explanations"].index) >= len( + assert len(out["models_explanations"].index) >= len( out["inputs_samples"].columns ), "Model explanations should have at least as many columns as inputs samples!" # - samples explanations diff --git a/tests/jobs/test_training.py b/tests/jobs/test_training.py index fbcbc40..d83327e 100644 --- a/tests/jobs/test_training.py +++ b/tests/jobs/test_training.py @@ -2,7 +2,7 @@ import _pytest.capture as pc from bikes import jobs -from bikes.core import metrics, models +from bikes.core import metrics, models, schemas from bikes.io import datasets, registries, services from bikes.utils import signers, splitters @@ -13,8 +13,8 @@ def test_training_job( mlflow_service: services.MlflowService, alerter_service: services.AlerterService, logger_service: services.LoggerService, - inputs_reader: datasets.Reader, - targets_reader: datasets.Reader, + inputs_reader: datasets.ParquetReader, + targets_reader: datasets.ParquetReader, model: models.Model, metric: metrics.Metric, train_test_splitter: splitters.Splitter, @@ -55,8 +55,10 @@ def test_training_job( "run", "inputs", "inputs_", + "inputs_lineage", "targets", "targets_", + "targets_lineage", "train_index", "test_index", "inputs_test", @@ -82,6 +84,18 @@ def test_training_job( # - data assert out["inputs"].ndim == out["inputs_"].ndim == 2, "Inputs should be a dataframe!" assert out["targets"].ndim == out["targets_"].ndim == 2, "Targets should be a dataframe!" + # - lineage + assert out["inputs_lineage"].name == "inputs", "Inputs lineage name should be inputs!" + assert ( + out["inputs_lineage"].source.uri == inputs_reader.path + ), "Inputs lineage source should be the inputs reader path!" + assert out["targets_lineage"].name == "targets", "Targets lineage name should be targets!" + assert ( + out["targets_lineage"].source.uri == targets_reader.path + ), "Targets lineage source should be the targets reader path!" + assert ( + out["targets_lineage"].targets == schemas.TargetsSchema.cnt + ), "Targets lineage target should be cnt!" # - splitter assert len(out["inputs_train"]) + len(out["inputs_test"]) == len( out["inputs"] diff --git a/tests/jobs/test_tuning.py b/tests/jobs/test_tuning.py index 47c6018..ffbe0e4 100644 --- a/tests/jobs/test_tuning.py +++ b/tests/jobs/test_tuning.py @@ -2,7 +2,7 @@ import _pytest.capture as pc from bikes import jobs -from bikes.core import metrics, models +from bikes.core import metrics, models, schemas from bikes.io import datasets, services from bikes.utils import searchers, splitters @@ -13,8 +13,8 @@ def test_tuning_job( mlflow_service: services.MlflowService, alerter_service: services.AlerterService, logger_service: services.LoggerService, - inputs_reader: datasets.Reader, - targets_reader: datasets.Reader, + inputs_reader: datasets.ParquetReader, + targets_reader: datasets.ParquetReader, model: models.Model, metric: metrics.Metric, time_series_splitter: splitters.Splitter, @@ -50,8 +50,10 @@ def test_tuning_job( "run", "inputs", "inputs_", + "inputs_lineage", "targets", "targets_", + "targets_lineage", "results", "best_params", "best_score", @@ -66,6 +68,18 @@ def test_tuning_job( # - data assert out["inputs"].ndim == out["inputs_"].ndim == 2, "Inputs should be a dataframe!" assert out["targets"].ndim == out["inputs_"].ndim == 2, "Targets should be a dataframe!" + # - lineage + assert out["inputs_lineage"].name == "inputs", "Inputs lineage name should be inputs!" + assert ( + out["inputs_lineage"].source.uri == inputs_reader.path + ), "Inputs lineage source should be the inputs reader path!" + assert out["targets_lineage"].name == "targets", "Targets lineage name should be targets!" + assert ( + out["targets_lineage"].source.uri == targets_reader.path + ), "Targets lineage source should be the targets reader path!" + assert ( + out["targets_lineage"].targets == schemas.TargetsSchema.cnt + ), "Targets lineage target should be cnt!" # - results assert out["results"].ndim == 2, "Results should be a dataframe!" # - best score From 32d77a6e23086ca4ed840c2eedc2938dd4b83c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Fri, 12 Jul 2024 22:34:37 +0200 Subject: [PATCH 08/21] fix(data): fix models explanations name --- ...anations.parquet => models_explanations.parquet} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename data/{model_explanations.parquet => models_explanations.parquet} (100%) diff --git a/data/model_explanations.parquet b/data/models_explanations.parquet similarity index 100% rename from data/model_explanations.parquet rename to data/models_explanations.parquet From 82744bbe11ad6c07d12e97cfe538f1175817afc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 13 Jul 2024 07:42:45 +0200 Subject: [PATCH 09/21] fix(paths): fix path for explanation job --- data/models_explanations.parquet | Bin 2604 -> 0 bytes data/samples_explanations.parquet | Bin 24084 -> 0 bytes notebooks/explain.ipynb | 5 +++-- src/bikes/jobs/explanations.py | 9 +++++---- src/bikes/jobs/training.py | 9 ++++++--- src/bikes/jobs/tuning.py | 9 ++++++--- 6 files changed, 20 insertions(+), 12 deletions(-) delete mode 100644 data/models_explanations.parquet delete mode 100644 data/samples_explanations.parquet diff --git a/data/models_explanations.parquet b/data/models_explanations.parquet deleted file mode 100644 index 8747a66d399bb3341f5c440ed051e3207b3ed94a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2604 zcmcImOKclO7@njiu^=kxV_iFqDr-fp9^BNAq|}=}wCmW;x^~*QjbDJQec9e*cXru_ z-E9=92apgFH-u1us^x-^DmWl6oVaiS33}jwdgu+r0i+%|^3U2y?b234(2aI>{{Nr( zAKyRUIG5Q|D^W2D9YpAdeR2pPBnghvF)URQG`rQZ6~Q)eD=E$)lp;eK zhQQ(+*F}lGA~;>evQ?**oWsXpfdxYvhUnsc@Pu7mIq)FpS+mSRG^1mudp?GOUF#4N zL*cHWsj}dmKZ3%2McIPs#9s?-^h)2bwp839CX8ksMK=#HuOlQ(Q0QfbLNi@grn2#i5>AYKoegKaEc8CrRuU<5}U*lgoo_kJKk&j7_{S z9esy=H*@0i?{012#@FvN{Hafu@7}+C?vMCS%j#G6mn9}}_TkZ+%YSl*FFX!QI6$=F z0Pzz-Cq|@a!th&go(c|Ocv00&!*T>H4UqVDGW7jq?EZA@ zWX7K>{(R>R5C#rgzISElcic@|RW!LZt{ddlay*m7qg|{@hCE2Y)lF~DV2GQF
    K z#Svt|5n%Z?tzcLVTqb)ruI5jkp?5}-8P9?q@`^YaOJ&sXpYkDa?ZhFiVU6^oBmB>x zpZ$Mu6}G`%SRm?l3GL8%-50!SV<+rYBgI(I@VDv9bWQWWZ6ZQ>#%v2?XcO7 zuj9Bed!HzCd-lS5b|Ay(d-3f&%l28=2VdU_eEm%@HsIy@joQ*yqh4m&>>1e4y~^vF z+bmQU>#4P#xLS2YTvjisoTzw3OMtcfrqSVXu`BAb#;g4fuP=4Q+6GzU%C&2DDa)!- zy3&>KI_TK`Q0_@t{xrXmTN=vRK+b3CSBQ^cEG=V-dPP$T)$1fqEp4l!o_Cs8U~ge5 zDHi%RpDpS_t!g*(8MjeOYGj>=tG1X0KbV8OAa*j7Q0km-<8jp$YHPh_VM8UcVXY&r zYHfK{>-&DQ#a=@X4zmdE&M=E4IxsZq2 zo|>B}*14X9D}d?R)AQ4twwTH%%Gdd);j4>&6Xc8x z&-Gec)~lYB(t0BCndQCGChwNjV#cQg%lS+Jez0tL6G(UlCb<n{g+%A82^%6|Dz4I{K;x9$vs3}-) jx{7mBGR>3z#S7b!Vks>N8qSy;4B3?yA5Jj=K z>`sWi)9k%>v2g9>-vyN-SNY!WllRA)O=joJnP<*<_UxIH&2_^)jMZe-*2=4u%8yVx zCZ)zwVX+p=)Gv~{Y%vTwxJwxuh4isCSEplxy2xY7k*D}84;o-r%0Ae$o;ujpLH)5a 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 WtfwZ6^`HI6vejp?-01%w{Qm base.Locals: model = self.loader.load(uri=model_uri).model.unwrap_python_model().model logger.debug("- Model: {}", model) # explanations - # - model + # - models logger.info("Explain model: {}", model) models_explanations = model.explain_model() - logger.debug("- Model explanations shape: {}", models_explanations.shape) + logger.debug("- Models explanations shape: {}", models_explanations.shape) # - samples logger.info("Explain samples: {}", len(inputs_samples)) samples_explanations = model.explain_samples(inputs=inputs_samples) logger.debug("- Samples explanations shape: {}", samples_explanations.shape) # write # - model - logger.info("Write model explanations: {}", self.models_explanations) + logger.info("Write models explanations: {}", self.models_explanations) self.models_explanations.write(data=models_explanations) # - samples logger.info("Write samples explanations: {}", self.samples_explanations) self.samples_explanations.write(data=samples_explanations) + # alerter self.alerter_service.notify( title="Explanations Job Finished", message=f"Features Count: {len(models_explanations)}" ) diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index 22d8c57..f88e799 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -71,14 +71,17 @@ def run(self) -> base.Locals: inputs_ = self.inputs.read() # unchecked! inputs = schemas.InputsSchema.check(inputs_) logger.debug("- Inputs shape: {}", inputs.shape) - inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") - mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) - logger.debug("- Inputs lineage: {}", inputs_lineage) # - targets logger.info("Read targets: {}", self.targets) targets_ = self.targets.read() # unchecked! targets = schemas.TargetsSchema.check(targets_) logger.debug("- Targets shape: {}", targets.shape) + # lineage + # - inputs + inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") + mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) + logger.debug("- Inputs lineage: {}", inputs_lineage) + # - targets targets_lineage = self.targets.lineage( data=targets, name="targets", targets=schemas.TargetsSchema.cnt ) diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index 230b0bc..82c4b06 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -69,14 +69,17 @@ def run(self) -> base.Locals: inputs_ = self.inputs.read() # unchecked! inputs = schemas.InputsSchema.check(inputs_) logger.debug("- Inputs shape: {}", inputs.shape) - inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") - mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) - logger.debug("- Inputs lineage: {}", inputs_lineage) # - targets logger.info("Read targets: {}", self.targets) targets_ = self.targets.read() # unchecked! targets = schemas.TargetsSchema.check(targets_) logger.debug("- Targets shape: {}", targets.shape) + # lineage + # - inputs + inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") + mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) + logger.debug("- Inputs lineage: {}", inputs_lineage) + # - targets targets_lineage = self.targets.lineage( data=targets, name="targets", targets=schemas.TargetsSchema.cnt ) From 05be890d64c4ab0d6233133f9d48363292255651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 13 Jul 2024 09:32:18 +0200 Subject: [PATCH 10/21] fix(mlflow): remove input examples following the addition of lineage --- poetry.lock | 936 ++++++++++++++++++------------------ src/bikes/io/datasets.py | 7 +- src/bikes/io/registries.py | 15 +- src/bikes/jobs/training.py | 4 +- tests/conftest.py | 2 +- tests/io/test_datasets.py | 3 + tests/io/test_registries.py | 4 +- 7 files changed, 495 insertions(+), 476 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1b8e674..8745cc0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -164,13 +164,13 @@ files = [ [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -489,63 +489,63 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.5.4" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, - {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, - {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, - {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, - {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, - {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, - {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, - {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, - {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, - {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, - {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, - {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, - {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, - {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.extras] @@ -762,53 +762,53 @@ dotenv = ["python-dotenv"] [[package]] name = "fonttools" -version = "4.53.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, - {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, - {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, - {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, - {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, - {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, - {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, - {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, - {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, - {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, - {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, - {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, - {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, - {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, ] [package.extras] @@ -996,13 +996,13 @@ tornado = ["tornado (>=0.2)"] [[package]] name = "identify" -version = "2.5.36" +version = "2.6.0" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, - {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, + {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, + {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, ] [package.extras] @@ -1062,13 +1062,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.29.4" +version = "6.29.5" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, - {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, ] [package.dependencies] @@ -1188,13 +1188,13 @@ files = [ [[package]] name = "jsonschema" -version = "4.22.0" +version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, - {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, ] [package.dependencies] @@ -1205,7 +1205,7 @@ rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] [[package]] name = "jsonschema-specifications" @@ -1553,40 +1553,40 @@ files = [ [[package]] name = "matplotlib" -version = "3.9.0" +version = "3.9.1" description = "Python plotting package" optional = false python-versions = ">=3.9" files = [ - {file = "matplotlib-3.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56"}, - {file = "matplotlib-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d"}, - {file = "matplotlib-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4"}, - {file = "matplotlib-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb"}, - {file = "matplotlib-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674"}, - {file = "matplotlib-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db"}, - {file = "matplotlib-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7"}, - {file = "matplotlib-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89"}, - {file = "matplotlib-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b"}, - {file = "matplotlib-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e"}, - {file = "matplotlib-3.9.0.tar.gz", hash = "sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, + {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, + {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, + {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, + {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, + {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, + {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, + {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, + {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, + {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, ] [package.dependencies] @@ -1630,13 +1630,13 @@ files = [ [[package]] name = "mlflow" -version = "2.14.1" +version = "2.14.3" description = "MLflow is an open source platform for the complete machine learning lifecycle" optional = false python-versions = ">=3.8" files = [ - {file = "mlflow-2.14.1-py3-none-any.whl", hash = "sha256:0bda38f94468d69a169415b1d751078f1083ddb44646f50854d387bcb6d0b9ec"}, - {file = "mlflow-2.14.1.tar.gz", hash = "sha256:1258ade134b9fbb15b1b0f22b0e9f98b5ff6f5f57575c10adfb255b9331fc587"}, + {file = "mlflow-2.14.3-py3-none-any.whl", hash = "sha256:2de915346c8e34a9d13efbd6469551980923619274db57fd2253621a2c666e18"}, + {file = "mlflow-2.14.3.tar.gz", hash = "sha256:292cae4b83574a0cb223117e224caa6798933078af0233719c2b612bea645617"}, ] [package.dependencies] @@ -2126,84 +2126,95 @@ ptyprocess = ">=0.5" [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -2440,109 +2451,122 @@ files = [ [[package]] name = "pydantic" -version = "2.7.4" +version = "2.8.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, - {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.18.4" -typing-extensions = ">=4.6.1" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] [package.extras] email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.4" +version = "2.20.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"}, - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"}, - {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"}, - {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"}, - {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"}, - {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"}, - {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"}, - {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"}, - {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"}, - {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"}, - {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"}, - {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"}, - {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"}, - {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"}, - {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, ] [package.dependencies] @@ -2987,167 +3011,167 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.18.1" +version = "0.19.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, - {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, - {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, - {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, - {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, - {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, - {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, - {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, - {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, - {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, - {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, - {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, - {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"}, + {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"}, + {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"}, + {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"}, + {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"}, + {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"}, + {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"}, + {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"}, + {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"}, + {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"}, + {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"}, + {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"}, ] [[package]] name = "ruff" -version = "0.5.0" +version = "0.5.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"}, - {file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"}, - {file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"}, - {file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"}, - {file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"}, - {file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"}, - {file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"}, + {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, + {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, + {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, + {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, + {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, + {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, + {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, ] [[package]] name = "scikit-learn" -version = "1.5.0" +version = "1.5.1" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.9" files = [ - {file = "scikit_learn-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12e40ac48555e6b551f0a0a5743cc94cc5a765c9513fe708e01f0aa001da2801"}, - {file = "scikit_learn-1.5.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f405c4dae288f5f6553b10c4ac9ea7754d5180ec11e296464adb5d6ac68b6ef5"}, - {file = "scikit_learn-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df8ccabbf583315f13160a4bb06037bde99ea7d8211a69787a6b7c5d4ebb6fc3"}, - {file = "scikit_learn-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c75ea812cd83b1385bbfa94ae971f0d80adb338a9523f6bbcb5e0b0381151d4"}, - {file = "scikit_learn-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:a90c5da84829a0b9b4bf00daf62754b2be741e66b5946911f5bdfaa869fcedd6"}, - {file = "scikit_learn-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a65af2d8a6cce4e163a7951a4cfbfa7fceb2d5c013a4b593686c7f16445cf9d"}, - {file = "scikit_learn-1.5.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:4c0c56c3005f2ec1db3787aeaabefa96256580678cec783986836fc64f8ff622"}, - {file = "scikit_learn-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f77547165c00625551e5c250cefa3f03f2fc92c5e18668abd90bfc4be2e0bff"}, - {file = "scikit_learn-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:118a8d229a41158c9f90093e46b3737120a165181a1b58c03461447aa4657415"}, - {file = "scikit_learn-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:a03b09f9f7f09ffe8c5efffe2e9de1196c696d811be6798ad5eddf323c6f4d40"}, - {file = "scikit_learn-1.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:460806030c666addee1f074788b3978329a5bfdc9b7d63e7aad3f6d45c67a210"}, - {file = "scikit_learn-1.5.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:1b94d6440603752b27842eda97f6395f570941857456c606eb1d638efdb38184"}, - {file = "scikit_learn-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d82c2e573f0f2f2f0be897e7a31fcf4e73869247738ab8c3ce7245549af58ab8"}, - {file = "scikit_learn-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3a10e1d9e834e84d05e468ec501a356226338778769317ee0b84043c0d8fb06"}, - {file = "scikit_learn-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:855fc5fa8ed9e4f08291203af3d3e5fbdc4737bd617a371559aaa2088166046e"}, - {file = "scikit_learn-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:40fb7d4a9a2db07e6e0cae4dc7bdbb8fada17043bac24104d8165e10e4cff1a2"}, - {file = "scikit_learn-1.5.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:47132440050b1c5beb95f8ba0b2402bbd9057ce96ec0ba86f2f445dd4f34df67"}, - {file = "scikit_learn-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174beb56e3e881c90424e21f576fa69c4ffcf5174632a79ab4461c4c960315ac"}, - {file = "scikit_learn-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261fe334ca48f09ed64b8fae13f9b46cc43ac5f580c4a605cbb0a517456c8f71"}, - {file = "scikit_learn-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:057b991ac64b3e75c9c04b5f9395eaf19a6179244c089afdebaad98264bff37c"}, - {file = "scikit_learn-1.5.0.tar.gz", hash = "sha256:789e3db01c750ed6d496fa2db7d50637857b451e57bcae863bff707c1247bef7"}, + {file = "scikit_learn-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:781586c414f8cc58e71da4f3d7af311e0505a683e112f2f62919e3019abd3745"}, + {file = "scikit_learn-1.5.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5b213bc29cc30a89a3130393b0e39c847a15d769d6e59539cd86b75d276b1a7"}, + {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff4ba34c2abff5ec59c803ed1d97d61b036f659a17f55be102679e88f926fac"}, + {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:161808750c267b77b4a9603cf9c93579c7a74ba8486b1336034c2f1579546d21"}, + {file = "scikit_learn-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:10e49170691514a94bb2e03787aa921b82dbc507a4ea1f20fd95557862c98dc1"}, + {file = "scikit_learn-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:154297ee43c0b83af12464adeab378dee2d0a700ccd03979e2b821e7dd7cc1c2"}, + {file = "scikit_learn-1.5.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b5e865e9bd59396220de49cb4a57b17016256637c61b4c5cc81aaf16bc123bbe"}, + {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:909144d50f367a513cee6090873ae582dba019cb3fca063b38054fa42704c3a4"}, + {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689b6f74b2c880276e365fe84fe4f1befd6a774f016339c65655eaff12e10cbf"}, + {file = "scikit_learn-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:9a07f90846313a7639af6a019d849ff72baadfa4c74c778821ae0fad07b7275b"}, + {file = "scikit_learn-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5944ce1faada31c55fb2ba20a5346b88e36811aab504ccafb9f0339e9f780395"}, + {file = "scikit_learn-1.5.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0828673c5b520e879f2af6a9e99eee0eefea69a2188be1ca68a6121b809055c1"}, + {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508907e5f81390e16d754e8815f7497e52139162fd69c4fdbd2dfa5d6cc88915"}, + {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97625f217c5c0c5d0505fa2af28ae424bd37949bb2f16ace3ff5f2f81fb4498b"}, + {file = "scikit_learn-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:da3f404e9e284d2b0a157e1b56b6566a34eb2798205cba35a211df3296ab7a74"}, + {file = "scikit_learn-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:88e0672c7ac21eb149d409c74cc29f1d611d5158175846e7a9c2427bd12b3956"}, + {file = "scikit_learn-1.5.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:7b073a27797a283187a4ef4ee149959defc350b46cbf63a84d8514fe16b69855"}, + {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b59e3e62d2be870e5c74af4e793293753565c7383ae82943b83383fdcf5cc5c1"}, + {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd8d3a19d4bd6dc5a7d4f358c8c3a60934dc058f363c34c0ac1e9e12a31421d"}, + {file = "scikit_learn-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:5f57428de0c900a98389c4a433d4a3cf89de979b3aa24d1c1d251802aa15e44d"}, + {file = "scikit_learn-1.5.1.tar.gz", hash = "sha256:0ea5d40c0e3951df445721927448755d3fe1d80833b0b7308ebff5d2a45e6414"}, ] [package.dependencies] @@ -3158,8 +3182,8 @@ threadpoolctl = ">=3.1.0" [package.extras] benchmark = ["matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "pandas (>=1.1.5)"] -build = ["cython (>=3.0.10)", "meson-python (>=0.15.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.15.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +build = ["cython (>=3.0.10)", "meson-python (>=0.16.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pydata-sphinx-theme (>=0.15.3)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=7.3.7)", "sphinx-copybutton (>=0.5.2)", "sphinx-design (>=0.5.0)", "sphinx-gallery (>=0.16.0)", "sphinx-prompt (>=1.4.0)", "sphinx-remove-toctrees (>=1.0.0.post1)", "sphinxcontrib-sass (>=0.3.4)", "sphinxext-opengraph (>=0.9.1)"] examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoolctl (>=3.1.0)"] maintenance = ["conda-lock (==2.5.6)"] @@ -3209,18 +3233,18 @@ test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "me [[package]] name = "setuptools" -version = "70.1.1" +version = "70.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, - {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, + {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, + {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shap" @@ -3445,13 +3469,13 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] name = "tenacity" -version = "8.4.2" +version = "8.5.0" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, - {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, ] [package.extras] @@ -3485,13 +3509,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.5" +version = "0.13.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, - {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, + {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, + {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, ] [[package]] diff --git a/src/bikes/io/datasets.py b/src/bikes/io/datasets.py index 623f69b..4447a1f 100644 --- a/src/bikes/io/datasets.py +++ b/src/bikes/io/datasets.py @@ -69,11 +69,13 @@ class ParquetReader(Reader): KIND: T.Literal["ParquetReader"] = "ParquetReader" path: str + engine: T.Literal["auto", "pyarrow", "fastparquet"] = "pyarrow" + dtype_backend: str = "pyarrow" @T.override def read(self) -> pd.DataFrame: # can't limit rows at read time - data = pd.read_parquet(self.path) + data = pd.read_parquet(self.path, engine=self.engine, dtype_backend=self.dtype_backend) if self.limit is not None: data = data.head(self.limit) return data @@ -124,10 +126,11 @@ class ParquetWriter(Writer): KIND: T.Literal["ParquetWriter"] = "ParquetWriter" path: str + engine: T.Literal["auto", "pyarrow", "fastparquet"] = "pyarrow" @T.override def write(self, data: pd.DataFrame) -> None: - pd.DataFrame.to_parquet(data, self.path) + data.to_parquet(path=self.path, engine=self.engine) WriterKind = ParquetWriter diff --git a/src/bikes/io/registries.py b/src/bikes/io/registries.py index 06d686f..0a4f21c 100644 --- a/src/bikes/io/registries.py +++ b/src/bikes/io/registries.py @@ -65,15 +65,12 @@ class Saver(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): path: str = "model" @abc.abstractmethod - def save( - self, model: models.Model, signature: signers.Signature, input_example: schemas.Inputs - ) -> Info: + def save(self, model: models.Model, signature: signers.Signature) -> Info: """Save a model in the model registry. Args: model (models.Model): project model to save. signature (signers.Signature): model signature. - input_example (schemas.Inputs): sample of inputs. Returns: Info: model saving information. @@ -121,15 +118,12 @@ def predict( return self.model.predict(inputs=model_input) @T.override - def save( - self, model: models.Model, signature: signers.Signature, input_example: schemas.Inputs - ) -> Info: + def save(self, model: models.Model, signature: signers.Signature) -> Info: adapter = CustomSaver.Adapter(model=model) return mlflow.pyfunc.log_model( python_model=adapter, signature=signature, artifact_path=self.path, - input_example=input_example, ) @@ -151,13 +145,10 @@ def save( self, model: models.Model, signature: signers.Signature, - input_example: schemas.Inputs | None = None, ) -> mlflow.entities.model_registry.ModelVersion: builtin_model = model.get_internal_model() module = getattr(mlflow, self.flavor) - return module.log_model( - builtin_model, artifact_path=self.path, signature=signature, input_example=input_example - ) + return module.log_model(builtin_model, artifact_path=self.path, signature=signature) SaverKind = CustomSaver | BuiltinSaver diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index f88e799..da26c15 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -120,9 +120,7 @@ def run(self) -> base.Locals: logger.debug("- Model signature: {}", model_signature.to_dict()) # saver logger.info("Save model: {}", self.saver) - model_info = self.saver.save( - model=self.model, signature=model_signature, input_example=inputs - ) + model_info = self.saver.save(model=self.model, signature=model_signature) logger.debug("- Model URI: {}", model_info.model_uri) # register logger.info("Register model: {}", self.registry) diff --git a/tests/conftest.py b/tests/conftest.py index e999b74..bd9d2ec 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -389,7 +389,7 @@ def model_version( """Save and register the default model version.""" run_config = mlflow_service.RunConfig(name="Custom-Run") with mlflow_service.run_context(run_config=run_config): - info = saver.save(model=model, signature=signature, input_example=inputs) + info = saver.save(model=model, signature=signature) version = register.register(name=mlflow_service.registry_name, model_uri=info.model_uri) return version diff --git a/tests/io/test_datasets.py b/tests/io/test_datasets.py index e6ecc04..dc0a61f 100644 --- a/tests/io/test_datasets.py +++ b/tests/io/test_datasets.py @@ -20,6 +20,8 @@ def test_parquet_reader(limit: int | None, inputs_path: str) -> None: assert data.ndim == 2, "Data should be a dataframe!" if limit is not None: assert len(data) == limit, "Data should have the limit size!" + assert reader.engine == "pyarrow", "Engine should be pyarrow!" + assert reader.dtype_backend == "pyarrow", "Dtype backend should be pyarrow!" assert lineage.name == "inputs", "Lineage name should be inputs!" assert lineage.source.uri == inputs_path, "Lineage source uri should be the inputs path!" assert set(lineage.schema.input_names()) == set( @@ -40,3 +42,4 @@ def test_parquet_writer(targets: schemas.Targets, tmp_outputs_path: str) -> None writer.write(data=targets) # then assert os.path.exists(tmp_outputs_path), "Data should be written!" + assert writer.engine == "pyarrow", "Engine should be pyarrow!" diff --git a/tests/io/test_registries.py b/tests/io/test_registries.py index e05ef18..293bc4e 100644 --- a/tests/io/test_registries.py +++ b/tests/io/test_registries.py @@ -46,7 +46,7 @@ def test_custom_pipeline( run_config = mlflow_service.RunConfig(name="Custom-Run") # when with mlflow_service.run_context(run_config=run_config) as run: - info = saver.save(model=model, signature=signature, input_example=inputs) + info = saver.save(model=model, signature=signature) version = register.register(name=name, model_uri=info.model_uri) model_uri = registries.uri_for_model_version(name=name, version=version.version) adapter = loader.load(uri=model_uri) @@ -95,7 +95,7 @@ def test_builtin_pipeline( run_config = mlflow_service.RunConfig(name="Builtin-Run") # when with mlflow_service.run_context(run_config=run_config) as run: - info = saver.save(model=model, signature=signature, input_example=inputs) + info = saver.save(model=model, signature=signature) version = register.register(name=name, model_uri=info.model_uri) model_uri = registries.uri_for_model_version(name=name, version=version.version) adapter = loader.load(uri=model_uri) From 25b7b1ca2979499280bff83db523806be7f32295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 13 Jul 2024 10:41:53 +0200 Subject: [PATCH 11/21] Revert "fix(mlflow): remove input examples following the addition of lineage" This reverts commit 05be890d64c4ab0d6233133f9d48363292255651. --- poetry.lock | 936 ++++++++++++++++++------------------ src/bikes/io/datasets.py | 7 +- src/bikes/io/registries.py | 15 +- src/bikes/jobs/training.py | 4 +- tests/conftest.py | 2 +- tests/io/test_datasets.py | 3 - tests/io/test_registries.py | 4 +- 7 files changed, 476 insertions(+), 495 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8745cc0..1b8e674 100644 --- a/poetry.lock +++ b/poetry.lock @@ -164,13 +164,13 @@ files = [ [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] [[package]] @@ -489,63 +489,63 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.6.0" +version = "7.5.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, - {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, - {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, - {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, - {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, - {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, - {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, - {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, - {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, - {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, - {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, - {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, - {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, - {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, + {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, + {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, + {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, + {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, + {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, + {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, + {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, + {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, + {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, + {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, + {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, + {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.extras] @@ -762,53 +762,53 @@ dotenv = ["python-dotenv"] [[package]] name = "fonttools" -version = "4.53.1" +version = "4.53.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, - {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, - {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, - {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, - {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, - {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, - {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, - {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, - {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, - {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, - {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, - {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, - {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, - {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, - {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, - {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, - {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, - {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, - {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, - {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, - {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, - {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, - {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, - {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, - {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, - {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, - {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, - {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, - {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, - {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, - {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, - {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, - {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, - {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, - {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, - {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, - {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, - {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, - {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, - {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, - {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, - {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, + {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, + {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, + {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, + {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, + {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, + {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, + {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, + {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, + {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, + {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, + {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, + {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, + {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, + {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, + {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, + {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, + {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, + {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, + {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, + {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, + {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, + {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, + {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, + {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, + {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, + {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, + {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, + {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, + {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, + {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, + {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, + {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, + {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, + {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, + {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, + {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, + {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, + {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, + {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, + {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, + {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, + {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, ] [package.extras] @@ -996,13 +996,13 @@ tornado = ["tornado (>=0.2)"] [[package]] name = "identify" -version = "2.6.0" +version = "2.5.36" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, - {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, + {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, + {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, ] [package.extras] @@ -1062,13 +1062,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.29.5" +version = "6.29.4" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, - {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, + {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, + {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, ] [package.dependencies] @@ -1188,13 +1188,13 @@ files = [ [[package]] name = "jsonschema" -version = "4.23.0" +version = "4.22.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, - {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, ] [package.dependencies] @@ -1205,7 +1205,7 @@ rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "jsonschema-specifications" @@ -1553,40 +1553,40 @@ files = [ [[package]] name = "matplotlib" -version = "3.9.1" +version = "3.9.0" description = "Python plotting package" optional = false python-versions = ">=3.9" files = [ - {file = "matplotlib-3.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb"}, - {file = "matplotlib-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842"}, - {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, - {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, - {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, - {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, - {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, - {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, - {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, - {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, - {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, - {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, - {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, - {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, - {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, - {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, - {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, - {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, - {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, - {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, - {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, - {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, - {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, - {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, - {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, - {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, - {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, - {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, - {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, + {file = "matplotlib-3.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56"}, + {file = "matplotlib-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b"}, + {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"}, + {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d"}, + {file = "matplotlib-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4"}, + {file = "matplotlib-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463"}, + {file = "matplotlib-3.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38"}, + {file = "matplotlib-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152"}, + {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85"}, + {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb"}, + {file = "matplotlib-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674"}, + {file = "matplotlib-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be"}, + {file = "matplotlib-3.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382"}, + {file = "matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84"}, + {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5"}, + {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db"}, + {file = "matplotlib-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7"}, + {file = "matplotlib-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf"}, + {file = "matplotlib-3.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956"}, + {file = "matplotlib-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a"}, + {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321"}, + {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89"}, + {file = "matplotlib-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b"}, + {file = "matplotlib-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd"}, + {file = "matplotlib-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e"}, + {file = "matplotlib-3.9.0.tar.gz", hash = "sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a"}, ] [package.dependencies] @@ -1630,13 +1630,13 @@ files = [ [[package]] name = "mlflow" -version = "2.14.3" +version = "2.14.1" description = "MLflow is an open source platform for the complete machine learning lifecycle" optional = false python-versions = ">=3.8" files = [ - {file = "mlflow-2.14.3-py3-none-any.whl", hash = "sha256:2de915346c8e34a9d13efbd6469551980923619274db57fd2253621a2c666e18"}, - {file = "mlflow-2.14.3.tar.gz", hash = "sha256:292cae4b83574a0cb223117e224caa6798933078af0233719c2b612bea645617"}, + {file = "mlflow-2.14.1-py3-none-any.whl", hash = "sha256:0bda38f94468d69a169415b1d751078f1083ddb44646f50854d387bcb6d0b9ec"}, + {file = "mlflow-2.14.1.tar.gz", hash = "sha256:1258ade134b9fbb15b1b0f22b0e9f98b5ff6f5f57575c10adfb255b9331fc587"}, ] [package.dependencies] @@ -2126,95 +2126,84 @@ ptyprocess = ">=0.5" [[package]] name = "pillow" -version = "10.4.0" +version = "10.3.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] + {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, + {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, + {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, + {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, + {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, + {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, + {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, + {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, + {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, + {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, + {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, + {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, + {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, + {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, + {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, + {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, + {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -2451,122 +2440,109 @@ files = [ [[package]] name = "pydantic" -version = "2.8.2" +version = "2.7.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, + {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, + {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" -typing-extensions = [ - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, -] +pydantic-core = "2.18.4" +typing-extensions = ">=4.6.1" [package.extras] email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.20.1" +version = "2.18.4" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, + {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"}, + {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"}, + {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"}, + {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"}, + {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"}, + {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"}, + {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"}, + {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"}, + {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"}, + {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"}, + {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"}, + {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"}, + {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"}, + {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"}, + {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"}, + {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"}, + {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"}, + {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"}, + {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"}, + {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"}, + {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"}, + {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"}, + {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"}, + {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"}, + {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"}, + {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"}, + {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"}, + {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"}, + {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"}, + {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"}, + {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"}, + {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"}, + {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"}, + {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"}, + {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"}, + {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"}, + {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"}, + {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"}, + {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"}, + {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"}, + {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"}, + {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"}, + {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"}, + {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"}, + {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"}, + {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"}, + {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"}, + {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"}, + {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"}, + {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"}, + {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"}, + {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"}, + {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"}, + {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"}, + {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"}, + {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"}, + {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"}, + {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"}, + {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"}, + {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"}, + {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"}, + {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"}, + {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"}, + {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"}, + {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"}, ] [package.dependencies] @@ -3011,167 +2987,167 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.19.0" +version = "0.18.1" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"}, - {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"}, - {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"}, - {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"}, - {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"}, - {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"}, - {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"}, - {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"}, - {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"}, - {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"}, - {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"}, - {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"}, - {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"}, - {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"}, - {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"}, - {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"}, - {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"}, - {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"}, - {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"}, - {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"}, - {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"}, - {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"}, - {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"}, - {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"}, - {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"}, - {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"}, - {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"}, - {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"}, - {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"}, - {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"}, - {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"}, - {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"}, - {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"}, - {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"}, - {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"}, - {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"}, - {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"}, - {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"}, - {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"}, - {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"}, - {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"}, - {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"}, - {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"}, - {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"}, - {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"}, - {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"}, - {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"}, - {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"}, - {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"}, - {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"}, - {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"}, - {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"}, - {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"}, - {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"}, - {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"}, - {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"}, - {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"}, - {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"}, - {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"}, - {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"}, - {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"}, - {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"}, - {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"}, - {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"}, - {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"}, - {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"}, - {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"}, - {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"}, - {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, + {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, + {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, + {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, + {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, + {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, + {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, + {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, + {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, + {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, + {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, + {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, ] [[package]] name = "ruff" -version = "0.5.1" +version = "0.5.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, - {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, - {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, - {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, - {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, - {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, - {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, + {file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"}, + {file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"}, + {file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"}, + {file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"}, + {file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"}, + {file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"}, + {file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"}, ] [[package]] name = "scikit-learn" -version = "1.5.1" +version = "1.5.0" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.9" files = [ - {file = "scikit_learn-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:781586c414f8cc58e71da4f3d7af311e0505a683e112f2f62919e3019abd3745"}, - {file = "scikit_learn-1.5.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5b213bc29cc30a89a3130393b0e39c847a15d769d6e59539cd86b75d276b1a7"}, - {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff4ba34c2abff5ec59c803ed1d97d61b036f659a17f55be102679e88f926fac"}, - {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:161808750c267b77b4a9603cf9c93579c7a74ba8486b1336034c2f1579546d21"}, - {file = "scikit_learn-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:10e49170691514a94bb2e03787aa921b82dbc507a4ea1f20fd95557862c98dc1"}, - {file = "scikit_learn-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:154297ee43c0b83af12464adeab378dee2d0a700ccd03979e2b821e7dd7cc1c2"}, - {file = "scikit_learn-1.5.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b5e865e9bd59396220de49cb4a57b17016256637c61b4c5cc81aaf16bc123bbe"}, - {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:909144d50f367a513cee6090873ae582dba019cb3fca063b38054fa42704c3a4"}, - {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689b6f74b2c880276e365fe84fe4f1befd6a774f016339c65655eaff12e10cbf"}, - {file = "scikit_learn-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:9a07f90846313a7639af6a019d849ff72baadfa4c74c778821ae0fad07b7275b"}, - {file = "scikit_learn-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5944ce1faada31c55fb2ba20a5346b88e36811aab504ccafb9f0339e9f780395"}, - {file = "scikit_learn-1.5.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0828673c5b520e879f2af6a9e99eee0eefea69a2188be1ca68a6121b809055c1"}, - {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508907e5f81390e16d754e8815f7497e52139162fd69c4fdbd2dfa5d6cc88915"}, - {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97625f217c5c0c5d0505fa2af28ae424bd37949bb2f16ace3ff5f2f81fb4498b"}, - {file = "scikit_learn-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:da3f404e9e284d2b0a157e1b56b6566a34eb2798205cba35a211df3296ab7a74"}, - {file = "scikit_learn-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:88e0672c7ac21eb149d409c74cc29f1d611d5158175846e7a9c2427bd12b3956"}, - {file = "scikit_learn-1.5.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:7b073a27797a283187a4ef4ee149959defc350b46cbf63a84d8514fe16b69855"}, - {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b59e3e62d2be870e5c74af4e793293753565c7383ae82943b83383fdcf5cc5c1"}, - {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd8d3a19d4bd6dc5a7d4f358c8c3a60934dc058f363c34c0ac1e9e12a31421d"}, - {file = "scikit_learn-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:5f57428de0c900a98389c4a433d4a3cf89de979b3aa24d1c1d251802aa15e44d"}, - {file = "scikit_learn-1.5.1.tar.gz", hash = "sha256:0ea5d40c0e3951df445721927448755d3fe1d80833b0b7308ebff5d2a45e6414"}, + {file = "scikit_learn-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12e40ac48555e6b551f0a0a5743cc94cc5a765c9513fe708e01f0aa001da2801"}, + {file = "scikit_learn-1.5.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f405c4dae288f5f6553b10c4ac9ea7754d5180ec11e296464adb5d6ac68b6ef5"}, + {file = "scikit_learn-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df8ccabbf583315f13160a4bb06037bde99ea7d8211a69787a6b7c5d4ebb6fc3"}, + {file = "scikit_learn-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c75ea812cd83b1385bbfa94ae971f0d80adb338a9523f6bbcb5e0b0381151d4"}, + {file = "scikit_learn-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:a90c5da84829a0b9b4bf00daf62754b2be741e66b5946911f5bdfaa869fcedd6"}, + {file = "scikit_learn-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a65af2d8a6cce4e163a7951a4cfbfa7fceb2d5c013a4b593686c7f16445cf9d"}, + {file = "scikit_learn-1.5.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:4c0c56c3005f2ec1db3787aeaabefa96256580678cec783986836fc64f8ff622"}, + {file = "scikit_learn-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f77547165c00625551e5c250cefa3f03f2fc92c5e18668abd90bfc4be2e0bff"}, + {file = "scikit_learn-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:118a8d229a41158c9f90093e46b3737120a165181a1b58c03461447aa4657415"}, + {file = "scikit_learn-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:a03b09f9f7f09ffe8c5efffe2e9de1196c696d811be6798ad5eddf323c6f4d40"}, + {file = "scikit_learn-1.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:460806030c666addee1f074788b3978329a5bfdc9b7d63e7aad3f6d45c67a210"}, + {file = "scikit_learn-1.5.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:1b94d6440603752b27842eda97f6395f570941857456c606eb1d638efdb38184"}, + {file = "scikit_learn-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d82c2e573f0f2f2f0be897e7a31fcf4e73869247738ab8c3ce7245549af58ab8"}, + {file = "scikit_learn-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3a10e1d9e834e84d05e468ec501a356226338778769317ee0b84043c0d8fb06"}, + {file = "scikit_learn-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:855fc5fa8ed9e4f08291203af3d3e5fbdc4737bd617a371559aaa2088166046e"}, + {file = "scikit_learn-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:40fb7d4a9a2db07e6e0cae4dc7bdbb8fada17043bac24104d8165e10e4cff1a2"}, + {file = "scikit_learn-1.5.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:47132440050b1c5beb95f8ba0b2402bbd9057ce96ec0ba86f2f445dd4f34df67"}, + {file = "scikit_learn-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174beb56e3e881c90424e21f576fa69c4ffcf5174632a79ab4461c4c960315ac"}, + {file = "scikit_learn-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261fe334ca48f09ed64b8fae13f9b46cc43ac5f580c4a605cbb0a517456c8f71"}, + {file = "scikit_learn-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:057b991ac64b3e75c9c04b5f9395eaf19a6179244c089afdebaad98264bff37c"}, + {file = "scikit_learn-1.5.0.tar.gz", hash = "sha256:789e3db01c750ed6d496fa2db7d50637857b451e57bcae863bff707c1247bef7"}, ] [package.dependencies] @@ -3182,8 +3158,8 @@ threadpoolctl = ">=3.1.0" [package.extras] benchmark = ["matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "pandas (>=1.1.5)"] -build = ["cython (>=3.0.10)", "meson-python (>=0.16.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pydata-sphinx-theme (>=0.15.3)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=7.3.7)", "sphinx-copybutton (>=0.5.2)", "sphinx-design (>=0.5.0)", "sphinx-gallery (>=0.16.0)", "sphinx-prompt (>=1.4.0)", "sphinx-remove-toctrees (>=1.0.0.post1)", "sphinxcontrib-sass (>=0.3.4)", "sphinxext-opengraph (>=0.9.1)"] +build = ["cython (>=3.0.10)", "meson-python (>=0.15.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.15.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoolctl (>=3.1.0)"] maintenance = ["conda-lock (==2.5.6)"] @@ -3233,18 +3209,18 @@ test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "me [[package]] name = "setuptools" -version = "70.3.0" +version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, - {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, ] [package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shap" @@ -3469,13 +3445,13 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] name = "tenacity" -version = "8.5.0" +version = "8.4.2" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, + {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, + {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, ] [package.extras] @@ -3509,13 +3485,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.13.0" +version = "0.12.5" description = "Style preserving TOML library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, - {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, ] [[package]] diff --git a/src/bikes/io/datasets.py b/src/bikes/io/datasets.py index 4447a1f..623f69b 100644 --- a/src/bikes/io/datasets.py +++ b/src/bikes/io/datasets.py @@ -69,13 +69,11 @@ class ParquetReader(Reader): KIND: T.Literal["ParquetReader"] = "ParquetReader" path: str - engine: T.Literal["auto", "pyarrow", "fastparquet"] = "pyarrow" - dtype_backend: str = "pyarrow" @T.override def read(self) -> pd.DataFrame: # can't limit rows at read time - data = pd.read_parquet(self.path, engine=self.engine, dtype_backend=self.dtype_backend) + data = pd.read_parquet(self.path) if self.limit is not None: data = data.head(self.limit) return data @@ -126,11 +124,10 @@ class ParquetWriter(Writer): KIND: T.Literal["ParquetWriter"] = "ParquetWriter" path: str - engine: T.Literal["auto", "pyarrow", "fastparquet"] = "pyarrow" @T.override def write(self, data: pd.DataFrame) -> None: - data.to_parquet(path=self.path, engine=self.engine) + pd.DataFrame.to_parquet(data, self.path) WriterKind = ParquetWriter diff --git a/src/bikes/io/registries.py b/src/bikes/io/registries.py index 0a4f21c..06d686f 100644 --- a/src/bikes/io/registries.py +++ b/src/bikes/io/registries.py @@ -65,12 +65,15 @@ class Saver(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): path: str = "model" @abc.abstractmethod - def save(self, model: models.Model, signature: signers.Signature) -> Info: + def save( + self, model: models.Model, signature: signers.Signature, input_example: schemas.Inputs + ) -> Info: """Save a model in the model registry. Args: model (models.Model): project model to save. signature (signers.Signature): model signature. + input_example (schemas.Inputs): sample of inputs. Returns: Info: model saving information. @@ -118,12 +121,15 @@ def predict( return self.model.predict(inputs=model_input) @T.override - def save(self, model: models.Model, signature: signers.Signature) -> Info: + def save( + self, model: models.Model, signature: signers.Signature, input_example: schemas.Inputs + ) -> Info: adapter = CustomSaver.Adapter(model=model) return mlflow.pyfunc.log_model( python_model=adapter, signature=signature, artifact_path=self.path, + input_example=input_example, ) @@ -145,10 +151,13 @@ def save( self, model: models.Model, signature: signers.Signature, + input_example: schemas.Inputs | None = None, ) -> mlflow.entities.model_registry.ModelVersion: builtin_model = model.get_internal_model() module = getattr(mlflow, self.flavor) - return module.log_model(builtin_model, artifact_path=self.path, signature=signature) + return module.log_model( + builtin_model, artifact_path=self.path, signature=signature, input_example=input_example + ) SaverKind = CustomSaver | BuiltinSaver diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index da26c15..f88e799 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -120,7 +120,9 @@ def run(self) -> base.Locals: logger.debug("- Model signature: {}", model_signature.to_dict()) # saver logger.info("Save model: {}", self.saver) - model_info = self.saver.save(model=self.model, signature=model_signature) + model_info = self.saver.save( + model=self.model, signature=model_signature, input_example=inputs + ) logger.debug("- Model URI: {}", model_info.model_uri) # register logger.info("Register model: {}", self.registry) diff --git a/tests/conftest.py b/tests/conftest.py index bd9d2ec..e999b74 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -389,7 +389,7 @@ def model_version( """Save and register the default model version.""" run_config = mlflow_service.RunConfig(name="Custom-Run") with mlflow_service.run_context(run_config=run_config): - info = saver.save(model=model, signature=signature) + info = saver.save(model=model, signature=signature, input_example=inputs) version = register.register(name=mlflow_service.registry_name, model_uri=info.model_uri) return version diff --git a/tests/io/test_datasets.py b/tests/io/test_datasets.py index dc0a61f..e6ecc04 100644 --- a/tests/io/test_datasets.py +++ b/tests/io/test_datasets.py @@ -20,8 +20,6 @@ def test_parquet_reader(limit: int | None, inputs_path: str) -> None: assert data.ndim == 2, "Data should be a dataframe!" if limit is not None: assert len(data) == limit, "Data should have the limit size!" - assert reader.engine == "pyarrow", "Engine should be pyarrow!" - assert reader.dtype_backend == "pyarrow", "Dtype backend should be pyarrow!" assert lineage.name == "inputs", "Lineage name should be inputs!" assert lineage.source.uri == inputs_path, "Lineage source uri should be the inputs path!" assert set(lineage.schema.input_names()) == set( @@ -42,4 +40,3 @@ def test_parquet_writer(targets: schemas.Targets, tmp_outputs_path: str) -> None writer.write(data=targets) # then assert os.path.exists(tmp_outputs_path), "Data should be written!" - assert writer.engine == "pyarrow", "Engine should be pyarrow!" diff --git a/tests/io/test_registries.py b/tests/io/test_registries.py index 293bc4e..e05ef18 100644 --- a/tests/io/test_registries.py +++ b/tests/io/test_registries.py @@ -46,7 +46,7 @@ def test_custom_pipeline( run_config = mlflow_service.RunConfig(name="Custom-Run") # when with mlflow_service.run_context(run_config=run_config) as run: - info = saver.save(model=model, signature=signature) + info = saver.save(model=model, signature=signature, input_example=inputs) version = register.register(name=name, model_uri=info.model_uri) model_uri = registries.uri_for_model_version(name=name, version=version.version) adapter = loader.load(uri=model_uri) @@ -95,7 +95,7 @@ def test_builtin_pipeline( run_config = mlflow_service.RunConfig(name="Builtin-Run") # when with mlflow_service.run_context(run_config=run_config) as run: - info = saver.save(model=model, signature=signature) + info = saver.save(model=model, signature=signature, input_example=inputs) version = register.register(name=name, model_uri=info.model_uri) model_uri = registries.uri_for_model_version(name=name, version=version.version) adapter = loader.load(uri=model_uri) From 8a7a8f1cd020835295c1d8034473303cde106333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 13 Jul 2024 11:49:08 +0200 Subject: [PATCH 12/21] fix(warnings): improve styles and remove warnings --- poetry.lock | 945 ++++++++++++++++---------------- pyproject.toml | 4 +- src/bikes/core/schemas.py | 6 +- src/bikes/io/registries.py | 2 +- src/bikes/io/services.py | 2 +- src/bikes/jobs/base.py | 14 +- src/bikes/jobs/explanations.py | 4 +- src/bikes/jobs/inference.py | 4 +- src/bikes/jobs/promotion.py | 6 +- src/bikes/jobs/training.py | 6 +- src/bikes/jobs/tuning.py | 7 +- src/bikes/scripts.py | 9 + tests/conftest.py | 6 +- tests/io/test_services.py | 4 +- tests/jobs/test_base.py | 2 +- tests/jobs/test_explanations.py | 4 +- tests/jobs/test_inference.py | 4 +- tests/jobs/test_promotion.py | 4 +- tests/jobs/test_training.py | 4 +- tests/jobs/test_tuning.py | 4 +- 20 files changed, 535 insertions(+), 506 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1b8e674..89767c1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -164,13 +164,13 @@ files = [ [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -489,63 +489,63 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.5.4" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, - {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, - {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, - {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, - {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, - {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, - {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, - {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, - {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, - {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, - {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, - {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, - {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, - {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.extras] @@ -762,53 +762,53 @@ dotenv = ["python-dotenv"] [[package]] name = "fonttools" -version = "4.53.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, - {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, - {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, - {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, - {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, - {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, - {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, - {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, - {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, - {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, - {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, - {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, - {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, - {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, ] [package.extras] @@ -996,13 +996,13 @@ tornado = ["tornado (>=0.2)"] [[package]] name = "identify" -version = "2.5.36" +version = "2.6.0" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, - {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, + {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, + {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, ] [package.extras] @@ -1062,13 +1062,13 @@ files = [ [[package]] name = "ipykernel" -version = "6.29.4" +version = "6.29.5" description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, - {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, ] [package.dependencies] @@ -1188,13 +1188,13 @@ files = [ [[package]] name = "jsonschema" -version = "4.22.0" +version = "4.23.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, - {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, ] [package.dependencies] @@ -1205,7 +1205,7 @@ rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] [[package]] name = "jsonschema-specifications" @@ -1553,40 +1553,40 @@ files = [ [[package]] name = "matplotlib" -version = "3.9.0" +version = "3.9.1" description = "Python plotting package" optional = false python-versions = ">=3.9" files = [ - {file = "matplotlib-3.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56"}, - {file = "matplotlib-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"}, - {file = "matplotlib-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d"}, - {file = "matplotlib-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4"}, - {file = "matplotlib-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38"}, - {file = "matplotlib-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85"}, - {file = "matplotlib-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb"}, - {file = "matplotlib-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674"}, - {file = "matplotlib-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382"}, - {file = "matplotlib-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5"}, - {file = "matplotlib-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db"}, - {file = "matplotlib-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7"}, - {file = "matplotlib-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956"}, - {file = "matplotlib-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321"}, - {file = "matplotlib-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89"}, - {file = "matplotlib-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b"}, - {file = "matplotlib-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd"}, - {file = "matplotlib-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e"}, - {file = "matplotlib-3.9.0.tar.gz", hash = "sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, + {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, + {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, + {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, + {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, + {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, + {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, + {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, + {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, + {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, ] [package.dependencies] @@ -1630,13 +1630,13 @@ files = [ [[package]] name = "mlflow" -version = "2.14.1" +version = "2.14.3" description = "MLflow is an open source platform for the complete machine learning lifecycle" optional = false python-versions = ">=3.8" files = [ - {file = "mlflow-2.14.1-py3-none-any.whl", hash = "sha256:0bda38f94468d69a169415b1d751078f1083ddb44646f50854d387bcb6d0b9ec"}, - {file = "mlflow-2.14.1.tar.gz", hash = "sha256:1258ade134b9fbb15b1b0f22b0e9f98b5ff6f5f57575c10adfb255b9331fc587"}, + {file = "mlflow-2.14.3-py3-none-any.whl", hash = "sha256:2de915346c8e34a9d13efbd6469551980923619274db57fd2253621a2c666e18"}, + {file = "mlflow-2.14.3.tar.gz", hash = "sha256:292cae4b83574a0cb223117e224caa6798933078af0233719c2b612bea645617"}, ] [package.dependencies] @@ -2126,84 +2126,95 @@ ptyprocess = ">=0.5" [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -2440,109 +2451,122 @@ files = [ [[package]] name = "pydantic" -version = "2.7.4" +version = "2.8.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, - {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.18.4" -typing-extensions = ">=4.6.1" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] [package.extras] email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.4" +version = "2.20.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"}, - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"}, - {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"}, - {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"}, - {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"}, - {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"}, - {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"}, - {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"}, - {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"}, - {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"}, - {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"}, - {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"}, - {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"}, - {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"}, - {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, ] [package.dependencies] @@ -2987,183 +3011,180 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.18.1" +version = "0.19.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, - {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, - {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, - {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, - {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, - {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, - {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, - {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, - {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, - {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, - {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, - {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, - {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"}, + {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"}, + {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"}, + {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"}, + {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"}, + {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"}, + {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"}, + {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"}, + {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"}, + {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"}, + {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"}, + {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"}, ] [[package]] name = "ruff" -version = "0.5.0" +version = "0.5.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"}, - {file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"}, - {file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"}, - {file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"}, - {file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"}, - {file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"}, - {file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"}, + {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, + {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, + {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, + {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, + {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, + {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, + {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, ] [[package]] name = "scikit-learn" -version = "1.5.0" +version = "1.4.2" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.9" files = [ - {file = "scikit_learn-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12e40ac48555e6b551f0a0a5743cc94cc5a765c9513fe708e01f0aa001da2801"}, - {file = "scikit_learn-1.5.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f405c4dae288f5f6553b10c4ac9ea7754d5180ec11e296464adb5d6ac68b6ef5"}, - {file = "scikit_learn-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df8ccabbf583315f13160a4bb06037bde99ea7d8211a69787a6b7c5d4ebb6fc3"}, - {file = "scikit_learn-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c75ea812cd83b1385bbfa94ae971f0d80adb338a9523f6bbcb5e0b0381151d4"}, - {file = "scikit_learn-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:a90c5da84829a0b9b4bf00daf62754b2be741e66b5946911f5bdfaa869fcedd6"}, - {file = "scikit_learn-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a65af2d8a6cce4e163a7951a4cfbfa7fceb2d5c013a4b593686c7f16445cf9d"}, - {file = "scikit_learn-1.5.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:4c0c56c3005f2ec1db3787aeaabefa96256580678cec783986836fc64f8ff622"}, - {file = "scikit_learn-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f77547165c00625551e5c250cefa3f03f2fc92c5e18668abd90bfc4be2e0bff"}, - {file = "scikit_learn-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:118a8d229a41158c9f90093e46b3737120a165181a1b58c03461447aa4657415"}, - {file = "scikit_learn-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:a03b09f9f7f09ffe8c5efffe2e9de1196c696d811be6798ad5eddf323c6f4d40"}, - {file = "scikit_learn-1.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:460806030c666addee1f074788b3978329a5bfdc9b7d63e7aad3f6d45c67a210"}, - {file = "scikit_learn-1.5.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:1b94d6440603752b27842eda97f6395f570941857456c606eb1d638efdb38184"}, - {file = "scikit_learn-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d82c2e573f0f2f2f0be897e7a31fcf4e73869247738ab8c3ce7245549af58ab8"}, - {file = "scikit_learn-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3a10e1d9e834e84d05e468ec501a356226338778769317ee0b84043c0d8fb06"}, - {file = "scikit_learn-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:855fc5fa8ed9e4f08291203af3d3e5fbdc4737bd617a371559aaa2088166046e"}, - {file = "scikit_learn-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:40fb7d4a9a2db07e6e0cae4dc7bdbb8fada17043bac24104d8165e10e4cff1a2"}, - {file = "scikit_learn-1.5.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:47132440050b1c5beb95f8ba0b2402bbd9057ce96ec0ba86f2f445dd4f34df67"}, - {file = "scikit_learn-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174beb56e3e881c90424e21f576fa69c4ffcf5174632a79ab4461c4c960315ac"}, - {file = "scikit_learn-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261fe334ca48f09ed64b8fae13f9b46cc43ac5f580c4a605cbb0a517456c8f71"}, - {file = "scikit_learn-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:057b991ac64b3e75c9c04b5f9395eaf19a6179244c089afdebaad98264bff37c"}, - {file = "scikit_learn-1.5.0.tar.gz", hash = "sha256:789e3db01c750ed6d496fa2db7d50637857b451e57bcae863bff707c1247bef7"}, + {file = "scikit-learn-1.4.2.tar.gz", hash = "sha256:daa1c471d95bad080c6e44b4946c9390a4842adc3082572c20e4f8884e39e959"}, + {file = "scikit_learn-1.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8539a41b3d6d1af82eb629f9c57f37428ff1481c1e34dddb3b9d7af8ede67ac5"}, + {file = "scikit_learn-1.4.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:68b8404841f944a4a1459b07198fa2edd41a82f189b44f3e1d55c104dbc2e40c"}, + {file = "scikit_learn-1.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81bf5d8bbe87643103334032dd82f7419bc8c8d02a763643a6b9a5c7288c5054"}, + {file = "scikit_learn-1.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36f0ea5d0f693cb247a073d21a4123bdf4172e470e6d163c12b74cbb1536cf38"}, + {file = "scikit_learn-1.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:87440e2e188c87db80ea4023440923dccbd56fbc2d557b18ced00fef79da0727"}, + {file = "scikit_learn-1.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:45dee87ac5309bb82e3ea633955030df9bbcb8d2cdb30383c6cd483691c546cc"}, + {file = "scikit_learn-1.4.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1d0b25d9c651fd050555aadd57431b53d4cf664e749069da77f3d52c5ad14b3b"}, + {file = "scikit_learn-1.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0203c368058ab92efc6168a1507d388d41469c873e96ec220ca8e74079bf62e"}, + {file = "scikit_learn-1.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44c62f2b124848a28fd695db5bc4da019287abf390bfce602ddc8aa1ec186aae"}, + {file = "scikit_learn-1.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:5cd7b524115499b18b63f0c96f4224eb885564937a0b3477531b2b63ce331904"}, + {file = "scikit_learn-1.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:90378e1747949f90c8f385898fff35d73193dfcaec3dd75d6b542f90c4e89755"}, + {file = "scikit_learn-1.4.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ff4effe5a1d4e8fed260a83a163f7dbf4f6087b54528d8880bab1d1377bd78be"}, + {file = "scikit_learn-1.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:671e2f0c3f2c15409dae4f282a3a619601fa824d2c820e5b608d9d775f91780c"}, + {file = "scikit_learn-1.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d36d0bc983336bbc1be22f9b686b50c964f593c8a9a913a792442af9bf4f5e68"}, + {file = "scikit_learn-1.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:d762070980c17ba3e9a4a1e043ba0518ce4c55152032f1af0ca6f39b376b5928"}, + {file = "scikit_learn-1.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9993d5e78a8148b1d0fdf5b15ed92452af5581734129998c26f481c46586d68"}, + {file = "scikit_learn-1.4.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:426d258fddac674fdf33f3cb2d54d26f49406e2599dbf9a32b4d1696091d4256"}, + {file = "scikit_learn-1.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5460a1a5b043ae5ae4596b3126a4ec33ccba1b51e7ca2c5d36dac2169f62ab1d"}, + {file = "scikit_learn-1.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49d64ef6cb8c093d883e5a36c4766548d974898d378e395ba41a806d0e824db8"}, + {file = "scikit_learn-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:c97a50b05c194be9146d61fe87dbf8eac62b203d9e87a3ccc6ae9aed2dfaf361"}, ] [package.dependencies] joblib = ">=1.2.0" numpy = ">=1.19.5" scipy = ">=1.6.0" -threadpoolctl = ">=3.1.0" +threadpoolctl = ">=2.0.0" [package.extras] -benchmark = ["matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "pandas (>=1.1.5)"] -build = ["cython (>=3.0.10)", "meson-python (>=0.15.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.15.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +benchmark = ["matplotlib (>=3.3.4)", "memory-profiler (>=0.57.0)", "pandas (>=1.1.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.15.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] -install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoolctl (>=3.1.0)"] -maintenance = ["conda-lock (==2.5.6)"] -tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.2.1)", "scikit-image (>=0.17.2)"] +tests = ["black (>=23.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.19.12)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.17.2)"] [[package]] name = "scipy" @@ -3209,18 +3230,18 @@ test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "me [[package]] name = "setuptools" -version = "70.1.1" +version = "70.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, - {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, + {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, + {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shap" @@ -3445,13 +3466,13 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] name = "tenacity" -version = "8.4.2" +version = "8.5.0" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"}, - {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"}, + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, ] [package.extras] @@ -3485,13 +3506,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.5" +version = "0.13.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, - {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, + {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, + {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, ] [[package]] @@ -3806,4 +3827,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "928bd41b7a25a26c44a30f30e369e77e3ab666471faf765b32ad51bb7562f4b5" +content-hash = "af49d976e486109834116d313106521513707aba2831087db962144ffeefb1da" diff --git a/pyproject.toml b/pyproject.toml index 9187ed2..e664e50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ bikes = 'bikes.scripts:main' python = "^3.12" loguru = "^0.7.2" matplotlib = "^3.9.0" -mlflow = "^2.14.1" +mlflow = "^2.14.3" numpy = "^1.26.4" omegaconf = "^2.3.0" pandas = "^2.2.2" @@ -37,7 +37,7 @@ pyarrow = "^15.0.2" pydantic = "^2.7.4" pydantic-settings = "^2.3.4" pynvml = "^11.5.0" -scikit-learn = "^1.5.0" +scikit-learn = "1.4.2" shap = "^0.46.0" [tool.poetry.group.checks.dependencies] diff --git a/src/bikes/core/schemas.py b/src/bikes/core/schemas.py index b21128e..244434c 100644 --- a/src/bikes/core/schemas.py +++ b/src/bikes/core/schemas.py @@ -51,7 +51,7 @@ def check(cls: T.Type[TSchema], data: pd.DataFrame) -> papd.DataFrame[TSchema]: class InputsSchema(Schema): """Schema for the project inputs.""" - instant: papd.Index[padt.UInt32] = pa.Field(ge=0, check_name=True) + instant: papd.Index[padt.UInt32] = pa.Field(ge=0) dteday: papd.Series[padt.DateTime] = pa.Field() season: papd.Series[padt.UInt8] = pa.Field(isin=[1, 2, 3, 4]) yr: papd.Series[padt.UInt8] = pa.Field(ge=0, le=1) @@ -75,7 +75,7 @@ class InputsSchema(Schema): class TargetsSchema(Schema): """Schema for the project target.""" - instant: papd.Index[padt.UInt32] = pa.Field(ge=0, check_name=True) + instant: papd.Index[padt.UInt32] = pa.Field(ge=0) cnt: papd.Series[padt.UInt32] = pa.Field(ge=0) @@ -85,7 +85,7 @@ class TargetsSchema(Schema): class OutputsSchema(Schema): """Schema for the project output.""" - instant: papd.Index[padt.UInt32] = pa.Field(ge=0, check_name=True) + instant: papd.Index[padt.UInt32] = pa.Field(ge=0) prediction: papd.Series[padt.UInt32] = pa.Field(ge=0) diff --git a/src/bikes/io/registries.py b/src/bikes/io/registries.py index 06d686f..407f002 100644 --- a/src/bikes/io/registries.py +++ b/src/bikes/io/registries.py @@ -113,7 +113,7 @@ def predict( Args: context (mlflow.pyfunc.PythonModelContext): mlflow context. model_input (schemas.Inputs): inputs for the mlflow model. - params(dict[str, T.Any] | None): additional parameters. + params (dict[str, T.Any] | None): additional parameters. Returns: schemas.Outputs: validated outputs of the project model. diff --git a/src/bikes/io/services.py b/src/bikes/io/services.py index 7785433..d821c35 100644 --- a/src/bikes/io/services.py +++ b/src/bikes/io/services.py @@ -82,7 +82,7 @@ def logger(self) -> loguru.Logger: return loguru.logger -class AlerterService(Service): +class AlertsService(Service): """Service for sending notifications. Require libnotify-bin on Linux systems. diff --git a/src/bikes/jobs/base.py b/src/bikes/jobs/base.py index 77c74d4..e2105f9 100644 --- a/src/bikes/jobs/base.py +++ b/src/bikes/jobs/base.py @@ -25,15 +25,15 @@ class Job(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): e.g., to define common services like logger Parameters: - logger_service (services.LoggerService): manage the logging system. - alerter_service (services.AlerterService): manage the alert system. + logger_service (services.LoggerService): manage the logger system. + alerts_service (services.AlertsService): manage the alerts system. mlflow_service (services.MlflowService): manage the mlflow system. """ KIND: str logger_service: services.LoggerService = services.LoggerService() - alerter_service: services.AlerterService = services.AlerterService() + alerts_service: services.AlertsService = services.AlertsService() mlflow_service: services.MlflowService = services.MlflowService() def __enter__(self) -> T.Self: @@ -45,8 +45,8 @@ def __enter__(self) -> T.Self: self.logger_service.start() logger = self.logger_service.logger() logger.debug("[START] Logger service: {}", self.logger_service) - self.alerter_service.start() - logger.debug("[START] Alerter service: {}", self.alerter_service) + logger.debug("[START] Alerts service: {}", self.alerts_service) + self.alerts_service.start() logger.debug("[START] Mlflow service: {}", self.mlflow_service) self.mlflow_service.start() return self @@ -70,8 +70,8 @@ def __exit__( logger = self.logger_service.logger() logger.debug("[STOP] Mlflow service: {}", self.mlflow_service) self.mlflow_service.stop() - logger.debug("[STOP] Alerter service: {}", self.alerter_service) - self.alerter_service.stop() + logger.debug("[STOP] Alerts service: {}", self.alerts_service) + self.alerts_service.stop() logger.debug("[STOP] Logger service: {}", self.logger_service) self.logger_service.stop() return False # re-raise diff --git a/src/bikes/jobs/explanations.py b/src/bikes/jobs/explanations.py index e10f7e8..58a3a09 100644 --- a/src/bikes/jobs/explanations.py +++ b/src/bikes/jobs/explanations.py @@ -72,8 +72,8 @@ def run(self) -> base.Locals: # - samples logger.info("Write samples explanations: {}", self.samples_explanations) self.samples_explanations.write(data=samples_explanations) - # alerter - self.alerter_service.notify( + # notify + self.alerts_service.notify( title="Explanations Job Finished", message=f"Features Count: {len(models_explanations)}" ) return locals() diff --git a/src/bikes/jobs/inference.py b/src/bikes/jobs/inference.py index 673910e..152a6fe 100644 --- a/src/bikes/jobs/inference.py +++ b/src/bikes/jobs/inference.py @@ -61,8 +61,8 @@ def run(self) -> base.Locals: # write logger.info("Write outputs: {}", self.outputs) self.outputs.write(data=outputs) - # alerter - self.alerter_service.notify( + # notify + self.alerts_service.notify( title="Inference Job Finished", message=f"Outputs Shape: {outputs.shape}" ) return locals() diff --git a/src/bikes/jobs/promotion.py b/src/bikes/jobs/promotion.py index 38a9dd1..2bc3a95 100644 --- a/src/bikes/jobs/promotion.py +++ b/src/bikes/jobs/promotion.py @@ -32,8 +32,8 @@ def run(self) -> base.Locals: logger.info("With logger: {}", logger) # - mlflow client = self.mlflow_service.client() + logger.info("With client: {}", client) name = self.mlflow_service.registry_name - logger.info("With mlflow model name: {}", name) # version if self.version is None: # use the latest model version version = client.search_model_versions( @@ -49,8 +49,8 @@ def run(self) -> base.Locals: client.set_registered_model_alias(name=name, alias=self.alias, version=version) model_version = client.get_model_version_by_alias(name=name, alias=self.alias) logger.debug("- Model version: {}", model_version) - # alerter - self.alerter_service.notify( + # notify + self.alerts_service.notify( title="Promotion Job Finished", message=f"Version: {model_version.version} @ {self.alias}", ) diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index f88e799..024c163 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -64,7 +64,7 @@ def run(self) -> base.Locals: client = self.mlflow_service.client() logger.info("With client: {}", client) with self.mlflow_service.run_context(run_config=self.run_config) as run: - logger.info("With mlflow run id: {}", run.info.run_id) + logger.info("With run context: {}", run) # data # - inputs logger.info("Read inputs: {}", self.inputs) @@ -130,8 +130,8 @@ def run(self) -> base.Locals: name=self.mlflow_service.registry_name, model_uri=model_info.model_uri ) logger.debug("- Model version: {}", model_version) - # alerter - self.alerter_service.notify( + # notify + self.alerts_service.notify( title="Training Job Finished", message=f"Model version: {model_version.version}" ) return locals() diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index 82c4b06..58c1599 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -60,9 +60,8 @@ def run(self) -> base.Locals: # - logger logger = self.logger_service.logger() logger.info("With logger: {}", logger) - # - mlflow with self.mlflow_service.run_context(run_config=self.run_config) as run: - logger.info("With mlflow run id: {}", run.info.run_id) + logger.info("With run context: {}", run) # data # - inputs logger.info("Read inputs: {}", self.inputs) @@ -103,8 +102,8 @@ def run(self) -> base.Locals: logger.debug("- Results: {}", results.shape) logger.debug("- Best Score: {}", best_score) logger.debug("- Best Params: {}", best_params) - # alerter - self.alerter_service.notify( + # notify + self.alerts_service.notify( title="Tuning Job Finished", message=f"Best score: {best_score}" ) return locals() diff --git a/src/bikes/scripts.py b/src/bikes/scripts.py index eb56f1b..2dc1e55 100644 --- a/src/bikes/scripts.py +++ b/src/bikes/scripts.py @@ -1,5 +1,14 @@ """Scripts for the CLI application.""" +# ruff: noqa: E402 + +# %% WARNINGS + +import warnings + +# disable annoying mlflow warnings +warnings.filterwarnings(action="ignore", category=UserWarning) + # %% IMPORTS import argparse diff --git a/tests/conftest.py b/tests/conftest.py index e999b74..5daa9d0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -89,7 +89,7 @@ def extra_config() -> str: config = """ { "job": { - "alerter_service": { + "alerts_service": { "enable": false, }, "mlflow_service": { @@ -295,9 +295,9 @@ def logger_caplog( @pytest.fixture(scope="session", autouse=True) -def alerter_service() -> T.Generator[services.AlerterService, None, None]: +def alerts_service() -> T.Generator[services.AlertsService, None, None]: """Return and start the alerter service.""" - service = services.AlerterService(enable=False) + service = services.AlertsService(enable=False) service.start() yield service service.stop() diff --git a/tests/io/test_services.py b/tests/io/test_services.py index acc684c..abb0a1b 100644 --- a/tests/io/test_services.py +++ b/tests/io/test_services.py @@ -26,13 +26,13 @@ def test_logger_service( @pytest.mark.parametrize("enable", [True, False]) -def test_alerter_service( +def test_alerts_service( enable: bool, mocker: pm.MockerFixture, capsys: pc.CaptureFixture[str] ) -> None: import plyer # given - service = services.AlerterService(enable=enable) + service = services.AlertsService(enable=enable) mocker.patch("plyer.notification.notify") # when service.notify(title="test", message="hello") diff --git a/tests/jobs/test_base.py b/tests/jobs/test_base.py index a9f9ca9..1b37fde 100644 --- a/tests/jobs/test_base.py +++ b/tests/jobs/test_base.py @@ -25,6 +25,6 @@ def run(self) -> base.Locals: # - inputs assert hasattr(job, "logger_service"), "Job should have an Logger service!" assert hasattr(job, "mlflow_service"), "Job should have an Mlflow service!" - assert hasattr(job, "alerter_service"), "Job should have a alerter service!" + assert hasattr(job, "alerts_service"), "Job should have a alerter service!" # - outputs assert set(out) == {"self", "a", "b"}, "Run should return local variables!" diff --git a/tests/jobs/test_explanations.py b/tests/jobs/test_explanations.py index 9d064cb..a051bb0 100644 --- a/tests/jobs/test_explanations.py +++ b/tests/jobs/test_explanations.py @@ -11,7 +11,7 @@ def test_explanations_job( mlflow_service: services.MlflowService, - alerter_service: services.AlerterService, + alerts_service: services.AlertsService, logger_service: services.LoggerService, inputs_samples_reader: datasets.Reader, tmp_models_explanations_writer: datasets.Writer, @@ -26,7 +26,7 @@ def test_explanations_job( # when job = jobs.ExplanationsJob( logger_service=logger_service, - alerter_service=alerter_service, + alerts_service=alerts_service, mlflow_service=mlflow_service, inputs_samples=inputs_samples_reader, models_explanations=tmp_models_explanations_writer, diff --git a/tests/jobs/test_inference.py b/tests/jobs/test_inference.py index 28c569b..c4411fb 100644 --- a/tests/jobs/test_inference.py +++ b/tests/jobs/test_inference.py @@ -10,7 +10,7 @@ def test_inference_job( mlflow_service: services.MlflowService, - alerter_service: services.AlerterService, + alerts_service: services.AlertsService, logger_service: services.LoggerService, inputs_reader: datasets.Reader, tmp_outputs_writer: datasets.Writer, @@ -24,7 +24,7 @@ def test_inference_job( # when job = jobs.InferenceJob( logger_service=logger_service, - alerter_service=alerter_service, + alerts_service=alerts_service, mlflow_service=mlflow_service, inputs=inputs_reader, outputs=tmp_outputs_writer, diff --git a/tests/jobs/test_promotion.py b/tests/jobs/test_promotion.py index 1c0d5e3..0c3b81f 100644 --- a/tests/jobs/test_promotion.py +++ b/tests/jobs/test_promotion.py @@ -26,7 +26,7 @@ def test_promotion_job( version: int | None, mlflow_service: services.MlflowService, - alerter_service: services.AlerterService, + alerts_service: services.AlertsService, logger_service: services.LoggerService, model_version: registries.Version, capsys: pc.CaptureFixture[str], @@ -36,7 +36,7 @@ def test_promotion_job( # when job = jobs.PromotionJob( logger_service=logger_service, - alerter_service=alerter_service, + alerts_service=alerts_service, mlflow_service=mlflow_service, version=version, alias=alias, diff --git a/tests/jobs/test_training.py b/tests/jobs/test_training.py index d83327e..902c605 100644 --- a/tests/jobs/test_training.py +++ b/tests/jobs/test_training.py @@ -11,7 +11,7 @@ def test_training_job( mlflow_service: services.MlflowService, - alerter_service: services.AlerterService, + alerts_service: services.AlertsService, logger_service: services.LoggerService, inputs_reader: datasets.ParquetReader, targets_reader: datasets.ParquetReader, @@ -32,7 +32,7 @@ def test_training_job( # when job = jobs.TrainingJob( logger_service=logger_service, - alerter_service=alerter_service, + alerts_service=alerts_service, mlflow_service=mlflow_service, run_config=run_config, inputs=inputs_reader, diff --git a/tests/jobs/test_tuning.py b/tests/jobs/test_tuning.py index ffbe0e4..7263d64 100644 --- a/tests/jobs/test_tuning.py +++ b/tests/jobs/test_tuning.py @@ -11,7 +11,7 @@ def test_tuning_job( mlflow_service: services.MlflowService, - alerter_service: services.AlerterService, + alerts_service: services.AlertsService, logger_service: services.LoggerService, inputs_reader: datasets.ParquetReader, targets_reader: datasets.ParquetReader, @@ -30,7 +30,7 @@ def test_tuning_job( # when job = jobs.TuningJob( logger_service=logger_service, - alerter_service=alerter_service, + alerts_service=alerts_service, mlflow_service=mlflow_service, run_config=run_config, inputs=inputs_reader, From 7ec2d29b85c51e15068d4f475bfea5e682c3155b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Tue, 16 Jul 2024 21:06:56 +0200 Subject: [PATCH 13/21] fix(loading): use version or alias for loading models --- src/bikes/io/registries.py | 8 ++++++++ src/bikes/jobs/explanations.py | 12 ++++++------ src/bikes/jobs/inference.py | 10 +++++----- src/bikes/jobs/training.py | 2 +- src/bikes/jobs/tuning.py | 2 +- tests/io/test_registries.py | 17 +++++++++++++++++ tests/jobs/test_explanations.py | 14 +++++++++----- tests/jobs/test_inference.py | 14 +++++++++----- 8 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/bikes/io/registries.py b/src/bikes/io/registries.py index 407f002..83a8e21 100644 --- a/src/bikes/io/registries.py +++ b/src/bikes/io/registries.py @@ -47,6 +47,14 @@ def uri_for_model_version(name: str, version: str) -> str: return f"models:/{name}/{version}" +def uri_for_model_alias_or_version(name: str, alias_or_version: str | int) -> str: + """Create a model URi from a model name and an alias or version.""" + if isinstance(alias_or_version, int): + return uri_for_model_version(name=name, version=str(alias_or_version)) + else: + return uri_for_model_alias(name=name, alias=alias_or_version) + + # %% SAVERS diff --git a/src/bikes/jobs/explanations.py b/src/bikes/jobs/explanations.py index 58a3a09..3983a9d 100644 --- a/src/bikes/jobs/explanations.py +++ b/src/bikes/jobs/explanations.py @@ -14,14 +14,14 @@ class ExplanationsJob(base.Job): - """Generate explanations for the model and a data sample. + """Generate explanations from the model and a data sample. Parameters: inputs_samples (datasets.ReaderKind): reader for the samples data. models_explanations (datasets.WriterKind): writer for models explanation. samples_explanations (datasets.WriterKind): writer for samples explanation. - alias (str): alias tag for the model. Defaults to "Champion". - loader (registries.LoaderKind): loader system for the model. + alias_or_version (str | int): alias or version for the model. + loader (registries.LoaderKind): registry loader for the model. """ KIND: T.Literal["ExplanationsJob"] = "ExplanationsJob" @@ -32,7 +32,7 @@ class ExplanationsJob(base.Job): models_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") samples_explanations: datasets.WriterKind = pdt.Field(..., discriminator="KIND") # Model - alias: str = "Champion" + alias_or_version: str | int = "Champion" # Loader loader: registries.LoaderKind = pdt.Field(registries.CustomLoader(), discriminator="KIND") @@ -48,8 +48,8 @@ def run(self) -> base.Locals: logger.debug("- Inputs samples shape: {}", inputs_samples.shape) # model logger.info("With model: {}", self.mlflow_service.registry_name) - model_uri = registries.uri_for_model_alias( - name=self.mlflow_service.registry_name, alias=self.alias + model_uri = registries.uri_for_model_alias_or_version( + name=self.mlflow_service.registry_name, alias_or_version=self.alias_or_version ) logger.debug("- Model URI: {}", model_uri) # loader diff --git a/src/bikes/jobs/inference.py b/src/bikes/jobs/inference.py index 152a6fe..aba3eae 100644 --- a/src/bikes/jobs/inference.py +++ b/src/bikes/jobs/inference.py @@ -19,8 +19,8 @@ class InferenceJob(base.Job): Parameters: inputs (datasets.ReaderKind): reader for the inputs data. outputs (datasets.WriterKind): writer for the outputs data. - alias (str): alias tag for the model. Defaults to "Champion". - loader (registries.LoaderKind): loader system for the model. + alias_or_version (str | int): alias or version for the model. + loader (registries.LoaderKind): registry loader for the model. """ KIND: T.Literal["InferenceJob"] = "InferenceJob" @@ -30,7 +30,7 @@ class InferenceJob(base.Job): # Outputs outputs: datasets.WriterKind = pdt.Field(..., discriminator="KIND") # Model - alias: str = "Champion" + alias_or_version: str | int = "Champion" # Loader loader: registries.LoaderKind = pdt.Field(registries.CustomLoader(), discriminator="KIND") @@ -46,8 +46,8 @@ def run(self) -> base.Locals: logger.debug("- Inputs shape: {}", inputs.shape) # model logger.info("With model: {}", self.mlflow_service.registry_name) - model_uri = registries.uri_for_model_alias( - name=self.mlflow_service.registry_name, alias=self.alias + model_uri = registries.uri_for_model_alias_or_version( + name=self.mlflow_service.registry_name, alias_or_version=self.alias_or_version ) logger.debug("- Model URI: {}", model_uri) # loader diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index 024c163..54a82fd 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -64,7 +64,7 @@ def run(self) -> base.Locals: client = self.mlflow_service.client() logger.info("With client: {}", client) with self.mlflow_service.run_context(run_config=self.run_config) as run: - logger.info("With run context: {}", run) + logger.info("With run context: {}", run.info) # data # - inputs logger.info("Read inputs: {}", self.inputs) diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index 58c1599..1125c67 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -61,7 +61,7 @@ def run(self) -> base.Locals: logger = self.logger_service.logger() logger.info("With logger: {}", logger) with self.mlflow_service.run_context(run_config=self.run_config) as run: - logger.info("With run context: {}", run) + logger.info("With run context: {}", run.info) # data # - inputs logger.info("Read inputs: {}", self.inputs) diff --git a/tests/io/test_registries.py b/tests/io/test_registries.py index e05ef18..4dfb8ac 100644 --- a/tests/io/test_registries.py +++ b/tests/io/test_registries.py @@ -27,6 +27,23 @@ def test_uri_for_model_version() -> None: assert uri == f"models:/{name}/{version}", "The model URI should be valid!" +def test_uri_for_model_alias_or_version() -> None: + # given + name = "testing" + alias = "Champion" + version = 1 + # when + alias_uri = registries.uri_for_model_alias_or_version(name=name, alias_or_version=alias) + version_uri = registries.uri_for_model_alias_or_version(name=name, alias_or_version=version) + # then + assert alias_uri == registries.uri_for_model_alias( + name=name, alias=alias + ), "The alias URI should be valid!" + assert version_uri == registries.uri_for_model_version( + name=name, version=version + ), "The version URI should be valid!" + + # %% SAVERS/LOADERS/REGISTERS diff --git a/tests/jobs/test_explanations.py b/tests/jobs/test_explanations.py index a051bb0..4285bdc 100644 --- a/tests/jobs/test_explanations.py +++ b/tests/jobs/test_explanations.py @@ -1,7 +1,7 @@ # %% IMPORTS - import _pytest.capture as pc +import pytest from bikes import jobs from bikes.core import models from bikes.io import datasets, registries, services @@ -9,7 +9,9 @@ # %% JOBS +@pytest.mark.parametrize("alias_or_version", [1, "Promotion"]) def test_explanations_job( + alias_or_version: str | int, mlflow_service: services.MlflowService, alerts_service: services.AlertsService, logger_service: services.LoggerService, @@ -21,8 +23,10 @@ def test_explanations_job( capsys: pc.CaptureFixture[str], ) -> None: # given - assert len(model_alias.aliases) == 1, "Model should have one alias!" - alias = model_alias.aliases[0] + if isinstance(alias_or_version, int): + assert alias_or_version == model_alias.version, "Model version should be the same!" + else: + assert alias_or_version == model_alias.aliases[0], "Model alias should be the same!" # when job = jobs.ExplanationsJob( logger_service=logger_service, @@ -31,7 +35,7 @@ def test_explanations_job( inputs_samples=inputs_samples_reader, models_explanations=tmp_models_explanations_writer, samples_explanations=tmp_samples_explanations_writer, - alias=alias, + alias_or_version=alias_or_version, loader=loader, ) with job as runner: @@ -50,7 +54,7 @@ def test_explanations_job( # - inputs assert out["inputs_samples"].ndim == 2, "Inputs samples should be a dataframe!" # - model uri - assert alias in out["model_uri"], "Model URI should contain the model alias!" + assert str(alias_or_version) in out["model_uri"], "Model URI should contain the model alias!" assert ( mlflow_service.registry_name in out["model_uri"] ), "Model URI should contain the registry name!" diff --git a/tests/jobs/test_inference.py b/tests/jobs/test_inference.py index c4411fb..0f8808e 100644 --- a/tests/jobs/test_inference.py +++ b/tests/jobs/test_inference.py @@ -1,14 +1,16 @@ # %% IMPORTS - import _pytest.capture as pc +import pytest from bikes import jobs from bikes.io import datasets, registries, services # %% JOBS +@pytest.mark.parametrize("alias_or_version", [1, "Promotion"]) def test_inference_job( + alias_or_version: str | int, mlflow_service: services.MlflowService, alerts_service: services.AlertsService, logger_service: services.LoggerService, @@ -19,8 +21,10 @@ def test_inference_job( capsys: pc.CaptureFixture[str], ) -> None: # given - assert len(model_alias.aliases) == 1, "Model should have one alias!" - alias = model_alias.aliases[0] + if isinstance(alias_or_version, int): + assert alias_or_version == model_alias.version, "Model version should be the same!" + else: + assert alias_or_version == model_alias.aliases[0], "Model alias should be the same!" # when job = jobs.InferenceJob( logger_service=logger_service, @@ -28,7 +32,7 @@ def test_inference_job( mlflow_service=mlflow_service, inputs=inputs_reader, outputs=tmp_outputs_writer, - alias=alias, + alias_or_version=alias_or_version, loader=loader, ) with job as runner: @@ -47,7 +51,7 @@ def test_inference_job( # - inputs assert out["inputs"].ndim == out["inputs_"].ndim == 2, "Inputs should be a dataframe!" # - model uri - assert alias in out["model_uri"], "Model URI should contain the model alias!" + assert str(alias_or_version) in out["model_uri"], "Model URI should contain the model alias!" assert ( mlflow_service.registry_name in out["model_uri"] ), "Model URI should contain the registry name!" From f72aa93baaa33ccc715b1c37aede9e62bbe79aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 20 Jul 2024 07:37:40 +0200 Subject: [PATCH 14/21] feat(monitoring): add mlflow.evaluate API --- src/bikes/core/metrics.py | 72 +++++++++++++++++++++++++- src/bikes/io/registries.py | 6 +-- src/bikes/jobs/__init__.py | 13 ++++- src/bikes/jobs/training.py | 8 +-- src/bikes/jobs/tuning.py | 6 ++- tasks/dags.py | 1 + tests/confs/valid/1. tuning.yaml | 14 ----- tests/confs/valid/2. training.yaml | 10 ---- tests/confs/valid/3. promotion.yaml | 2 - tests/confs/valid/4. inference.yaml | 9 ---- tests/confs/valid/5. explanations.yaml | 12 ----- tests/core/test_metrics.py | 41 +++++++++++++-- tests/io/test_registries.py | 2 +- 13 files changed, 134 insertions(+), 62 deletions(-) delete mode 100644 tests/confs/valid/1. tuning.yaml delete mode 100644 tests/confs/valid/2. training.yaml delete mode 100644 tests/confs/valid/3. promotion.yaml delete mode 100644 tests/confs/valid/4. inference.yaml delete mode 100644 tests/confs/valid/5. explanations.yaml diff --git a/src/bikes/core/metrics.py b/src/bikes/core/metrics.py index 6eaf13c..37b64b5 100644 --- a/src/bikes/core/metrics.py +++ b/src/bikes/core/metrics.py @@ -2,14 +2,26 @@ # %% IMPORTS +from __future__ import annotations + import abc import typing as T +import mlflow +import pandas as pd import pydantic as pdt from sklearn import metrics from bikes.core import models, schemas +# %% TYPINGS + +MlflowMetric: T.TypeAlias = mlflow.metrics.MetricValue +MlflowThreshold: T.TypeAlias = mlflow.models.MetricThreshold +MlflowModelValidationFailedException: T.TypeAlias = ( + mlflow.models.evaluation.validation.ModelValidationFailedException +) + # %% METRICS @@ -21,11 +33,13 @@ class Metric(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): Parameters: name (str): name of the metric for the reporting. + greater_is_better (bool): maximize or minimize result. """ KIND: str name: str + greater_is_better: bool @abc.abstractmethod def score(self, targets: schemas.Targets, outputs: schemas.Outputs) -> float: @@ -42,7 +56,7 @@ def score(self, targets: schemas.Targets, outputs: schemas.Outputs) -> float: def scorer( self, model: models.Model, inputs: schemas.Inputs, targets: schemas.Targets ) -> float: - """Score the model outputs against targets. + """Score model outputs against targets. Args: model (models.Model): model to evaluate. @@ -56,6 +70,37 @@ def scorer( score = self.score(targets=targets, outputs=outputs) return score + def to_mlflow(self) -> MlflowMetric: + """Convert the metric to an Mlflow metric. + + Returns: + MlflowMetric: the Mlflow metric. + """ + + def eval_fn(predictions: pd.Series[int], targets: pd.Series[int]) -> MlflowMetric: + """Evaluation function associated with the mlflow metric. + + Args: + predictions (pd.Series): model predictions. + targets (pd.Series | None): model targets. + + Returns: + MlflowMetric: the mlflow metric. + """ + score_targets = schemas.Targets( + {schemas.TargetsSchema.cnt: targets}, index=targets.index + ) + score_outputs = schemas.Outputs( + {schemas.OutputsSchema.prediction: predictions}, index=predictions.index + ) + sign = 1 if self.greater_is_better else -1 # reverse the effect + score = self.score(targets=score_targets, outputs=score_outputs) + return MlflowMetric(aggregate_results={self.name: score * sign}) + + return mlflow.metrics.make_metric( + eval_fn=eval_fn, name=self.name, greater_is_better=self.greater_is_better + ) + class SklearnMetric(Metric): """Compute metrics with sklearn. @@ -81,3 +126,28 @@ def score(self, targets: schemas.Targets, outputs: schemas.Outputs) -> float: MetricKind = SklearnMetric + +# %% THRESHOLDS + + +class Threshold(abc.ABC, pdt.BaseModel, strict=True, frozen=True, extra="forbid"): + """A project threshold for a metric. + + Use thresholds to monitor model performances. + e.g., to trigger an alert when a threshold is met. + + Parameters: + threshold (int | float): absolute threshold value. + greater_is_better (bool): maximize or minimize result. + """ + + threshold: int | float + greater_is_better: bool + + def to_mlflow(self) -> MlflowThreshold: + """Convert the threshold to an mlflow threshold. + + Returns: + MlflowThreshold: the mlflow threshold. + """ + return MlflowThreshold(threshold=self.threshold, greater_is_better=self.greater_is_better) diff --git a/src/bikes/io/registries.py b/src/bikes/io/registries.py index 83a8e21..f4bd672 100644 --- a/src/bikes/io/registries.py +++ b/src/bikes/io/registries.py @@ -34,12 +34,12 @@ def uri_for_model_alias(name: str, alias: str) -> str: return f"models:/{name}@{alias}" -def uri_for_model_version(name: str, version: str) -> str: +def uri_for_model_version(name: str, version: int) -> str: """Create a model URI from a model name and a version. Args: name (str): name of the mlflow registered model. - version (str): version of the registered model. + version (int): version of the registered model. Returns: str: model URI as "models:/name/version." @@ -50,7 +50,7 @@ def uri_for_model_version(name: str, version: str) -> str: def uri_for_model_alias_or_version(name: str, alias_or_version: str | int) -> str: """Create a model URi from a model name and an alias or version.""" if isinstance(alias_or_version, int): - return uri_for_model_version(name=name, version=str(alias_or_version)) + return uri_for_model_version(name=name, version=alias_or_version) else: return uri_for_model_alias(name=name, alias=alias_or_version) diff --git a/src/bikes/jobs/__init__.py b/src/bikes/jobs/__init__.py index 55e8786..9b7d2d1 100644 --- a/src/bikes/jobs/__init__.py +++ b/src/bikes/jobs/__init__.py @@ -2,6 +2,7 @@ # %% IMPORTS +from bikes.jobs.evaluations import EvaluationsJob from bikes.jobs.explanations import ExplanationsJob from bikes.jobs.inference import InferenceJob from bikes.jobs.promotion import PromotionJob @@ -10,8 +11,16 @@ # %% TYPES -JobKind = TuningJob | TrainingJob | PromotionJob | InferenceJob | ExplanationsJob +JobKind = TuningJob | TrainingJob | PromotionJob | InferenceJob | EvaluationsJob | ExplanationsJob # %% EXPORTS -__all__ = ["TuningJob", "TrainingJob", "PromotionJob", "InferenceJob", "ExplanationsJob", "JobKind"] +__all__ = [ + "TuningJob", + "TrainingJob", + "PromotionJob", + "InferenceJob", + "EvaluationsJob", + "ExplanationsJob", + "JobKind", +] diff --git a/src/bikes/jobs/training.py b/src/bikes/jobs/training.py index 54a82fd..571d291 100644 --- a/src/bikes/jobs/training.py +++ b/src/bikes/jobs/training.py @@ -62,7 +62,7 @@ def run(self) -> base.Locals: logger.info("With logger: {}", logger) # - mlflow client = self.mlflow_service.client() - logger.info("With client: {}", client) + logger.info("With client: {}", client.tracking_uri) with self.mlflow_service.run_context(run_config=self.run_config) as run: logger.info("With run context: {}", run.info) # data @@ -78,15 +78,17 @@ def run(self) -> base.Locals: logger.debug("- Targets shape: {}", targets.shape) # lineage # - inputs + logger.info("Log lineage: inputs") inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) - logger.debug("- Inputs lineage: {}", inputs_lineage) + logger.debug("- Inputs lineage: {}", inputs_lineage.to_dict()) # - targets + logger.info("Log lineage: targets") targets_lineage = self.targets.lineage( data=targets, name="targets", targets=schemas.TargetsSchema.cnt ) mlflow.log_input(dataset=targets_lineage, context=self.run_config.name) - logger.debug("- Targets lineage: {}", targets_lineage) + logger.debug("- Targets lineage: {}", targets_lineage.to_dict()) # splitter logger.info("With splitter: {}", self.splitter) # - index diff --git a/src/bikes/jobs/tuning.py b/src/bikes/jobs/tuning.py index 1125c67..ed0df86 100644 --- a/src/bikes/jobs/tuning.py +++ b/src/bikes/jobs/tuning.py @@ -75,15 +75,17 @@ def run(self) -> base.Locals: logger.debug("- Targets shape: {}", targets.shape) # lineage # - inputs + logger.info("Log lineage: inputs") inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) - logger.debug("- Inputs lineage: {}", inputs_lineage) + logger.debug("- Inputs lineage: {}", inputs_lineage.to_dict()) # - targets + logger.info("Log lineage: targets") targets_lineage = self.targets.lineage( data=targets, name="targets", targets=schemas.TargetsSchema.cnt ) mlflow.log_input(dataset=targets_lineage, context=self.run_config.name) - logger.debug("- Targets lineage: {}", targets_lineage) + logger.debug("- Targets lineage: {}", targets_lineage.to_dict()) # model logger.info("With model: {}", self.model) # metric diff --git a/tasks/dags.py b/tasks/dags.py index 00f1765..0f51cfa 100644 --- a/tasks/dags.py +++ b/tasks/dags.py @@ -20,6 +20,7 @@ def job(ctx: Context, name: str) -> None: call(job, name="training"), # type: ignore[arg-type] call(job, name="promotion"), # type: ignore[arg-type] call(job, name="inference"), # type: ignore[arg-type] + call(job, name="evaluations"), # type: ignore[arg-type] call(job, name="explanations"), # type: ignore[arg-type] ], default=True, diff --git a/tests/confs/valid/1. tuning.yaml b/tests/confs/valid/1. tuning.yaml deleted file mode 100644 index b76fe0b..0000000 --- a/tests/confs/valid/1. tuning.yaml +++ /dev/null @@ -1,14 +0,0 @@ -job: - KIND: TuningJob - inputs: - KIND: ParquetReader - path: "${tests_path:}/data/inputs_sample.parquet" - limit: 1500 - targets: - KIND: ParquetReader - path: "${tests_path:}/data/targets_sample.parquet" - limit: 1500 - splitter: - KIND: TimeSeriesSplitter - n_splits: 3 - test_size: 167 # 1 week diff --git a/tests/confs/valid/2. training.yaml b/tests/confs/valid/2. training.yaml deleted file mode 100644 index 86ea35a..0000000 --- a/tests/confs/valid/2. training.yaml +++ /dev/null @@ -1,10 +0,0 @@ -job: - KIND: TrainingJob - inputs: - KIND: ParquetReader - path: "${tests_path:}/data/inputs_sample.parquet" - limit: 1500 - targets: - KIND: ParquetReader - path: "${tests_path:}/data/targets_sample.parquet" - limit: 1500 diff --git a/tests/confs/valid/3. promotion.yaml b/tests/confs/valid/3. promotion.yaml deleted file mode 100644 index 0f5feec..0000000 --- a/tests/confs/valid/3. promotion.yaml +++ /dev/null @@ -1,2 +0,0 @@ -job: - KIND: PromotionJob diff --git a/tests/confs/valid/4. inference.yaml b/tests/confs/valid/4. inference.yaml deleted file mode 100644 index 061b7f1..0000000 --- a/tests/confs/valid/4. inference.yaml +++ /dev/null @@ -1,9 +0,0 @@ -job: - KIND: InferenceJob - inputs: - KIND: ParquetReader - path: "${tests_path:}/data/inputs_sample.parquet" - limit: 1500 - outputs: - KIND: ParquetWriter - path: "${tmp_path:}/outputs_sample.parquet" diff --git a/tests/confs/valid/5. explanations.yaml b/tests/confs/valid/5. explanations.yaml deleted file mode 100644 index 8f4721c..0000000 --- a/tests/confs/valid/5. explanations.yaml +++ /dev/null @@ -1,12 +0,0 @@ -job: - KIND: ExplanationsJob - inputs_samples: - KIND: ParquetReader - path: "${tests_path:}/data/inputs_sample.parquet" - limit: 100 - models_explanations: - KIND: ParquetWriter - path: "${tmp_path:}/models_explanations.parquet" - samples_explanations: - KIND: ParquetWriter - path: "${tmp_path:}/samples_explanations.parquet" diff --git a/tests/core/test_metrics.py b/tests/core/test_metrics.py index f6114e6..c8a286c 100644 --- a/tests/core/test_metrics.py +++ b/tests/core/test_metrics.py @@ -1,6 +1,7 @@ # %% IMPORTS - +import mlflow +import pandas as pd import pytest from bikes.core import metrics, models, schemas @@ -25,10 +26,44 @@ def test_sklearn_metric( ) -> None: # given low, high = interval + data = pd.concat([targets, outputs], axis="columns") metric = metrics.SklearnMetric(name=name, greater_is_better=greater_is_better) # when score = metric.score(targets=targets, outputs=outputs) scorer = metric.scorer(model=model, inputs=inputs, targets=targets) + mlflow_metric = metric.to_mlflow() + mlflow_results = mlflow.evaluate( + data=data, + predictions=schemas.OutputsSchema.prediction, + targets=schemas.TargetsSchema.cnt, + extra_metrics=[mlflow_metric], + ) + # then + # - score + assert low <= score <= high, "Score should be in the expected interval!" + # - scorer + assert low <= scorer <= high, "Scorer should be in the expected interval!" + # - mlflow metric + assert mlflow_metric.name == metric.name, "Mlflow metric name should be the same!" + assert ( + mlflow_metric.greater_is_better == metric.greater_is_better + ), "Mlflow metric greater is better should be the same!" + # - mlflow results + assert mlflow_results.metrics == { + metric.name: score * (1 if greater_is_better else -1) + }, "Mlflow results metrics should have the same name and score!" + + +# %% THRESHOLDS + + +def test_threshold() -> None: + # given + threshold = metrics.Threshold(threshold=10, greater_is_better=True) + # when + mlflow_threshold = threshold.to_mlflow() # then - assert low <= score <= high, "Score is not in the expected interval!" - assert low <= scorer <= high, "Scorer is not in the expected interval!" + assert mlflow_threshold.threshold == threshold.threshold, "Threshold should be the same!" + assert ( + mlflow_threshold.greater_is_better == threshold.greater_is_better + ), "Greater is better should be the same!" diff --git a/tests/io/test_registries.py b/tests/io/test_registries.py index 4dfb8ac..29cb4a7 100644 --- a/tests/io/test_registries.py +++ b/tests/io/test_registries.py @@ -20,7 +20,7 @@ def test_uri_for_model_alias() -> None: def test_uri_for_model_version() -> None: # given name = "testing" - version = "1" + version = 1 # when uri = registries.uri_for_model_version(name=name, version=version) # then From 50ee7202afcbac4516be893b3c96c5434a5fd05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 20 Jul 2024 07:38:14 +0200 Subject: [PATCH 15/21] fix(evaluation): add evaluation files --- confs/evaluations.yaml | 8 ++ src/bikes/jobs/evaluations.py | 129 ++++++++++++++++++++ tests/confs/valid/0. tuning.yaml | 14 +++ tests/confs/valid/1. training.yaml | 10 ++ tests/confs/valid/2. promotion.yaml | 2 + tests/confs/valid/3. inference.yaml | 9 ++ tests/confs/valid/5. evaluations.yaml | 10 ++ tests/confs/valid/6. explanations.yaml | 12 ++ tests/jobs/test_evaluations.py | 158 +++++++++++++++++++++++++ 9 files changed, 352 insertions(+) create mode 100644 confs/evaluations.yaml create mode 100644 src/bikes/jobs/evaluations.py create mode 100644 tests/confs/valid/0. tuning.yaml create mode 100644 tests/confs/valid/1. training.yaml create mode 100644 tests/confs/valid/2. promotion.yaml create mode 100644 tests/confs/valid/3. inference.yaml create mode 100644 tests/confs/valid/5. evaluations.yaml create mode 100644 tests/confs/valid/6. explanations.yaml create mode 100644 tests/jobs/test_evaluations.py diff --git a/confs/evaluations.yaml b/confs/evaluations.yaml new file mode 100644 index 0000000..40bee1f --- /dev/null +++ b/confs/evaluations.yaml @@ -0,0 +1,8 @@ +job: + KIND: EvaluationsJob + inputs: + KIND: ParquetReader + path: data/inputs_train.parquet + targets: + KIND: ParquetReader + path: data/targets_train.parquet diff --git a/src/bikes/jobs/evaluations.py b/src/bikes/jobs/evaluations.py new file mode 100644 index 0000000..93cbf0c --- /dev/null +++ b/src/bikes/jobs/evaluations.py @@ -0,0 +1,129 @@ +"""Define a job for evaluating registered models with data.""" + +# %% IMPORTS + +import typing as T + +import mlflow +import pandas as pd +import pydantic as pdt + +from bikes.core import metrics as metrics_ +from bikes.core import schemas +from bikes.io import datasets, registries, services +from bikes.jobs import base + +# %% JOBS + + +class EvaluationsJob(base.Job): + """Generate evaluations from a registered model and a dataset. + + Parameters: + run_config (services.MlflowService.RunConfig): mlflow run config. + inputs (datasets.ReaderKind): reader for the inputs data. + targets (datasets.ReaderKind): reader for the targets data. + model_type (str): model type (e.g. "regressor", "classifier"). + alias_or_version (str | int): alias or version for the model. + metrics (metrics_.MetricKind): metrics for the reporting. + evaluators (list[str]): list of evaluators to use. + thresholds (dict[str, metrics_.Threshold] | None): metric thresholds. + """ + + KIND: T.Literal["EvaluationsJob"] = "EvaluationsJob" + + # Run + run_config: services.MlflowService.RunConfig = services.MlflowService.RunConfig( + name="Evaluations" + ) + # Data + inputs: datasets.ReaderKind = pdt.Field(..., discriminator="KIND") + targets: datasets.ReaderKind = pdt.Field(..., discriminator="KIND") + # Model + model_type: str = "regressor" + alias_or_version: str | int = "Champion" + # Metrics + metrics: list[metrics_.MetricKind] = pdt.Field([metrics_.SklearnMetric()], discriminator="KIND") + # Evaluators + evaluators: list[str] = ["default"] + # Thresholds + thresholds: dict[str, metrics_.Threshold] = { + "r2_score": metrics_.Threshold(threshold=0.5, greater_is_better=True) + } + + @T.override + def run(self) -> base.Locals: + # services + logger = self.logger_service.logger() + logger.info("With logger: {}", logger) + # - mlflow + client = self.mlflow_service.client() + logger.info("With client: {}", client.tracking_uri) + with self.mlflow_service.run_context(run_config=self.run_config) as run: + logger.info("With run context: {}", run.info) + # data + # - inputs + logger.info("Read inputs: {}", self.inputs) + inputs_ = self.inputs.read() # unchecked! + inputs = schemas.InputsSchema.check(inputs_) + logger.debug("- Inputs shape: {}", inputs.shape) + # - targets + logger.info("Read targets: {}", self.targets) + targets_ = self.targets.read() # unchecked! + targets = schemas.TargetsSchema.check(targets_) + logger.debug("- Targets shape: {}", targets.shape) + # lineage + # - inputs + logger.info("Log lineage: inputs") + inputs_lineage = self.inputs.lineage(data=inputs, name="inputs") + mlflow.log_input(dataset=inputs_lineage, context=self.run_config.name) + logger.debug("- Inputs lineage: {}", inputs_lineage.to_dict()) + # - targets + logger.info("Log lineage: targets") + targets_lineage = self.targets.lineage( + data=targets, name="targets", targets=schemas.TargetsSchema.cnt + ) + mlflow.log_input(dataset=targets_lineage, context=self.run_config.name) + logger.debug("- Targets lineage: {}", targets_lineage.to_dict()) + # dataset + logger.info("Create dataset: inputs & targets") + dataset = mlflow.data.from_pandas( + df=pd.concat([inputs, targets], axis="columns"), + name="evaluation", + source=f"{inputs_lineage.source.uri} & {targets_lineage.source.uri}", + targets=schemas.TargetsSchema.cnt, + ) + logger.debug("- Dataset: {}", dataset.to_dict()) + # model + logger.info("With model: {}", self.mlflow_service.registry_name) + model_uri = registries.uri_for_model_alias_or_version( + name=self.mlflow_service.registry_name, alias_or_version=self.alias_or_version + ) + logger.debug("- Model URI: {}", model_uri) + # metrics + logger.debug("Convert metrics: {}", self.metrics) + extra_metrics = [metric.to_mlflow() for metric in self.metrics] + logger.debug("- Extra metrics: {}", extra_metrics) + # thresholds + logger.info("Convert thresholds: {}", self.thresholds) + validation_thresholds = { + name: threshold.to_mlflow() for name, threshold in self.thresholds.items() + } + logger.debug("- Validation thresholds: {}", validation_thresholds) + # evaluations + logger.info("Compute evaluations: {}", self.model_type) + evaluations = mlflow.evaluate( + data=dataset, + model=model_uri, + model_type=self.model_type, + evaluators=self.evaluators, + extra_metrics=extra_metrics, + validation_thresholds=validation_thresholds, + ) + logger.debug("- Evaluations metrics: {}", evaluations.metrics) + # notify + self.alerts_service.notify( + title="Evaluations Job Finished", + message=f"Evaluation metrics: {evaluations.metrics}", + ) + return locals() diff --git a/tests/confs/valid/0. tuning.yaml b/tests/confs/valid/0. tuning.yaml new file mode 100644 index 0000000..b76fe0b --- /dev/null +++ b/tests/confs/valid/0. tuning.yaml @@ -0,0 +1,14 @@ +job: + KIND: TuningJob + inputs: + KIND: ParquetReader + path: "${tests_path:}/data/inputs_sample.parquet" + limit: 1500 + targets: + KIND: ParquetReader + path: "${tests_path:}/data/targets_sample.parquet" + limit: 1500 + splitter: + KIND: TimeSeriesSplitter + n_splits: 3 + test_size: 167 # 1 week diff --git a/tests/confs/valid/1. training.yaml b/tests/confs/valid/1. training.yaml new file mode 100644 index 0000000..86ea35a --- /dev/null +++ b/tests/confs/valid/1. training.yaml @@ -0,0 +1,10 @@ +job: + KIND: TrainingJob + inputs: + KIND: ParquetReader + path: "${tests_path:}/data/inputs_sample.parquet" + limit: 1500 + targets: + KIND: ParquetReader + path: "${tests_path:}/data/targets_sample.parquet" + limit: 1500 diff --git a/tests/confs/valid/2. promotion.yaml b/tests/confs/valid/2. promotion.yaml new file mode 100644 index 0000000..0f5feec --- /dev/null +++ b/tests/confs/valid/2. promotion.yaml @@ -0,0 +1,2 @@ +job: + KIND: PromotionJob diff --git a/tests/confs/valid/3. inference.yaml b/tests/confs/valid/3. inference.yaml new file mode 100644 index 0000000..061b7f1 --- /dev/null +++ b/tests/confs/valid/3. inference.yaml @@ -0,0 +1,9 @@ +job: + KIND: InferenceJob + inputs: + KIND: ParquetReader + path: "${tests_path:}/data/inputs_sample.parquet" + limit: 1500 + outputs: + KIND: ParquetWriter + path: "${tmp_path:}/outputs_sample.parquet" diff --git a/tests/confs/valid/5. evaluations.yaml b/tests/confs/valid/5. evaluations.yaml new file mode 100644 index 0000000..c9f1f95 --- /dev/null +++ b/tests/confs/valid/5. evaluations.yaml @@ -0,0 +1,10 @@ +job: + KIND: EvaluationsJob + inputs: + KIND: ParquetReader + path: "${tests_path:}/data/inputs_sample.parquet" + limit: 1500 + targets: + KIND: ParquetReader + path: "${tests_path:}/data/targets_sample.parquet" + limit: 1500 diff --git a/tests/confs/valid/6. explanations.yaml b/tests/confs/valid/6. explanations.yaml new file mode 100644 index 0000000..8f4721c --- /dev/null +++ b/tests/confs/valid/6. explanations.yaml @@ -0,0 +1,12 @@ +job: + KIND: ExplanationsJob + inputs_samples: + KIND: ParquetReader + path: "${tests_path:}/data/inputs_sample.parquet" + limit: 100 + models_explanations: + KIND: ParquetWriter + path: "${tmp_path:}/models_explanations.parquet" + samples_explanations: + KIND: ParquetWriter + path: "${tmp_path:}/samples_explanations.parquet" diff --git a/tests/jobs/test_evaluations.py b/tests/jobs/test_evaluations.py new file mode 100644 index 0000000..3f5f1bc --- /dev/null +++ b/tests/jobs/test_evaluations.py @@ -0,0 +1,158 @@ +# %% IMPORTS + +import _pytest.capture as pc +import pytest +from bikes import jobs +from bikes.core import metrics, schemas +from bikes.io import datasets, registries, services + +# %% JOBS + + +@pytest.mark.parametrize( + "alias_or_version, thresholds", + [ + ( + 1, + { + "mean_squared_error": metrics.Threshold( + threshold=float("inf"), greater_is_better=False + ) + }, + ), + ( + "Promotion", + {"r2_score": metrics.Threshold(threshold=-1, greater_is_better=True)}, + ), + pytest.param( + "Promotion", + {"r2_score": metrics.Threshold(threshold=100, greater_is_better=True)}, + marks=pytest.mark.xfail( + reason="Invalid threshold for metric.", + raises=metrics.MlflowModelValidationFailedException, + ), + ), + ], +) +def test_evaluations_job( + alias_or_version: str | int, + thresholds: dict[str, metrics.Threshold], + mlflow_service: services.MlflowService, + alerts_service: services.AlertsService, + logger_service: services.LoggerService, + inputs_reader: datasets.ParquetReader, + targets_reader: datasets.ParquetReader, + model_alias: registries.Version, + metric: metrics.Metric, + capsys: pc.CaptureFixture[str], +) -> None: + # given + if isinstance(alias_or_version, int): + assert alias_or_version == model_alias.version, "Model version should be the same!" + else: + assert alias_or_version == model_alias.aliases[0], "Model alias should be the same!" + run_config = mlflow_service.RunConfig( + name="EvaluationsTest", tags={"context": "evaluations"}, description="Evaluations job." + ) + # when + job = jobs.EvaluationsJob( + logger_service=logger_service, + alerts_service=alerts_service, + mlflow_service=mlflow_service, + run_config=run_config, + inputs=inputs_reader, + targets=targets_reader, + alias_or_version=alias_or_version, + metrics=[metric], + thresholds=thresholds, + ) + with job as runner: + out = runner.run() + # then + # - vars + assert set(out) == { + "self", + "logger", + "client", + "run", + "inputs", + "inputs_", + "inputs_lineage", + "targets", + "targets_", + "targets_lineage", + "dataset", + "model_uri", + "extra_metrics", + "validation_thresholds", + "evaluations", + } + # - run + assert run_config.tags is not None, "Run config tags should be set!" + assert out["run"].info.run_name == run_config.name, "Run name should be the same!" + assert run_config.description in out["run"].data.tags.values(), "Run desc. should be tags!" + assert ( + out["run"].data.tags.items() > run_config.tags.items() + ), "Run tags should be a subset of tags!" + # - data + assert out["inputs"].ndim == out["inputs_"].ndim == 2, "Inputs should be a dataframe!" + assert out["targets"].ndim == out["targets_"].ndim == 2, "Targets should be a dataframe!" + # - lineage + assert out["inputs_lineage"].name == "inputs", "Inputs lineage name should be inputs!" + assert ( + out["inputs_lineage"].source.uri == inputs_reader.path + ), "Inputs lineage source should be the inputs reader path!" + assert out["targets_lineage"].name == "targets", "Targets lineage name should be targets!" + assert ( + out["targets_lineage"].source.uri == targets_reader.path + ), "Targets lineage source should be the targets reader path!" + assert ( + out["targets_lineage"].targets == schemas.TargetsSchema.cnt + ), "Targets lineage target should be cnt!" + # - dataset + assert out["dataset"].name == "evaluation", "Dataset name should be evaluation!" + assert out["dataset"].predictions is None, "Dataset predictions should be None!" + assert ( + out["dataset"].targets == schemas.TargetsSchema.cnt + ), "Dataset targets should be the target column!" + assert ( + inputs_reader.path in out["dataset"].source.uri + ), "Dataset source should contain the inputs path!" + assert ( + targets_reader.path in out["dataset"].source.uri + ), "Dataset source should contain the targets path!" + # - model uri + assert str(alias_or_version) in out["model_uri"], "Model URI should contain the model alias!" + assert ( + mlflow_service.registry_name in out["model_uri"] + ), "Model URI should contain the registry name!" + # - extra metrics + assert len(out["extra_metrics"]) == len( + job.metrics + ), "Extra metrics should have the same length as metrics!" + assert ( + out["extra_metrics"][0].name == job.metrics[0].name + ), "Extra metrics name should be the same!" + assert ( + out["extra_metrics"][0].greater_is_better == job.metrics[0].greater_is_better + ), "Extra metrics greatter is better should be the same!" + # - validation thresholds + assert ( + out["validation_thresholds"].keys() == thresholds.keys() + ), "Validation thresholds should have the same keys as thresholds!" + # - evaluations + assert ( + out["evaluations"].metrics["example_count"] == inputs_reader.limit + ), "Evaluations should have the same number of examples as the inputs!" + assert job.metrics[0].name in out["evaluations"].metrics, "Metric should be logged in Mlflow!" + # - mlflow tracking + experiment = mlflow_service.client().get_experiment_by_name(name=mlflow_service.experiment_name) + assert ( + experiment.name == mlflow_service.experiment_name + ), "Mlflow Experiment name should be the same!" + runs = mlflow_service.client().search_runs(experiment_ids=experiment.experiment_id) + assert len(runs) == 2, "There should be a two Mlflow run for training and evaluations!" + assert metric.name in runs[0].data.metrics, "Metric should be logged in Mlflow!" + assert runs[0].info.status == "FINISHED", "Mlflow run status should be set as FINISHED!" + # - alerting service + assert "Evaluations" in capsys.readouterr().out, "Alerting service should be called!" From f4c5aa8228de5e9da39ca6125d662414f4732df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 20 Jul 2024 14:54:19 +0200 Subject: [PATCH 16/21] feat(mlproject): add mlflow project and tasks --- MLproject | 9 +++ poetry.lock | 159 +++++++++++++++++++++++++--------------------- pyproject.toml | 4 ++ python_env.yaml | 90 ++++++++++++++++++++++++++ requirements.txt | 89 ++++++++++++++++++++++++++ tasks/__init__.py | 15 ++++- tasks/cleans.py | 22 ++++++- tasks/dags.py | 29 --------- tasks/projects.py | 65 +++++++++++++++++++ 9 files changed, 376 insertions(+), 106 deletions(-) create mode 100644 MLproject create mode 100644 python_env.yaml create mode 100644 requirements.txt delete mode 100644 tasks/dags.py create mode 100644 tasks/projects.py diff --git a/MLproject b/MLproject new file mode 100644 index 0000000..1cba85a --- /dev/null +++ b/MLproject @@ -0,0 +1,9 @@ +# https://mlflow.org/docs/latest/projects.html + +name: bikes +python_env: python_env.yaml +entry_points: + main: + parameters: + conf_file: path + command: "PYTHONPATH=src python -m bikes {conf_file}" diff --git a/poetry.lock b/poetry.lock index 89767c1..83bd5ba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -67,13 +67,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.3.0" +version = "3.4.0" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.3.0-py3-none-any.whl", hash = "sha256:c168c3723482c031df3c207d4ba8fa702717ccb9fc0bfe4117166c1f537b4a54"}, - {file = "argcomplete-3.3.0.tar.gz", hash = "sha256:fd03ff4a5b9e6580569d34b273f741e85cd9e072f3feeeee3eba4891c70eda62"}, + {file = "argcomplete-3.4.0-py3-none-any.whl", hash = "sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5"}, + {file = "argcomplete-3.4.0.tar.gz", hash = "sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f"}, ] [package.extras] @@ -153,13 +153,13 @@ files = [ [[package]] name = "cachetools" -version = "5.3.3" +version = "5.4.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, + {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, + {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, ] [[package]] @@ -402,21 +402,20 @@ test = ["pytest"] [[package]] name = "commitizen" -version = "3.27.0" +version = "3.28.0" description = "Python commitizen client tool" optional = false python-versions = ">=3.8" files = [ - {file = "commitizen-3.27.0-py3-none-any.whl", hash = "sha256:11948fa563d5ad5464baf09eaacff3cf8cbade1ca029ed9c4978f2227f033130"}, - {file = "commitizen-3.27.0.tar.gz", hash = "sha256:5874d0c7e8e1be3b75b1b0a2269cffe3dd5c843b860d84b0bdbb9ea86e3474b8"}, + {file = "commitizen-3.28.0-py3-none-any.whl", hash = "sha256:372dba10bb082be0e571cfa9ac0946f4333c3f4b2e242fbe32ae2f2afea143e4"}, + {file = "commitizen-3.28.0.tar.gz", hash = "sha256:de3a90b3246233260649e423963cd702d56a3b499ea02886a6412ebfb76f9462"}, ] [package.dependencies] -argcomplete = ">=1.12.1,<3.4" +argcomplete = ">=1.12.1,<3.5" charset-normalizer = ">=2.1.0,<4" colorama = ">=0.4.1,<0.5.0" decli = ">=0.6.0,<0.7.0" -importlib_metadata = ">=4.13,<8" jinja2 = ">=2.10.3" packaging = ">=19" pyyaml = ">=3.08" @@ -1698,43 +1697,43 @@ files = [ [[package]] name = "mypy" -version = "1.10.1" +version = "1.11.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, - {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, - {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, - {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, - {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, - {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, - {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, - {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, - {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, - {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, - {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, - {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, - {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, - {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, - {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, - {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, - {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, - {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, - {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, + {file = "mypy-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3824187c99b893f90c845bab405a585d1ced4ff55421fdf5c84cb7710995229"}, + {file = "mypy-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96f8dbc2c85046c81bcddc246232d500ad729cb720da4e20fce3b542cab91287"}, + {file = "mypy-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a5d8d8dd8613a3e2be3eae829ee891b6b2de6302f24766ff06cb2875f5be9c6"}, + {file = "mypy-1.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72596a79bbfb195fd41405cffa18210af3811beb91ff946dbcb7368240eed6be"}, + {file = "mypy-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:35ce88b8ed3a759634cb4eb646d002c4cef0a38f20565ee82b5023558eb90c00"}, + {file = "mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb"}, + {file = "mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1"}, + {file = "mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3"}, + {file = "mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d"}, + {file = "mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a"}, + {file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"}, + {file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"}, + {file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"}, + {file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"}, + {file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"}, + {file = "mypy-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:940bfff7283c267ae6522ef926a7887305945f716a7704d3344d6d07f02df850"}, + {file = "mypy-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14f9294528b5f5cf96c721f231c9f5b2733164e02c1c018ed1a0eff8a18005ac"}, + {file = "mypy-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7b54c27783991399046837df5c7c9d325d921394757d09dbcbf96aee4649fe9"}, + {file = "mypy-1.11.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65f190a6349dec29c8d1a1cd4aa71284177aee5949e0502e6379b42873eddbe7"}, + {file = "mypy-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbe286303241fea8c2ea5466f6e0e6a046a135a7e7609167b07fd4e7baf151bf"}, + {file = "mypy-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:104e9c1620c2675420abd1f6c44bab7dd33cc85aea751c985006e83dcd001095"}, + {file = "mypy-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f006e955718ecd8d159cee9932b64fba8f86ee6f7728ca3ac66c3a54b0062abe"}, + {file = "mypy-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:becc9111ca572b04e7e77131bc708480cc88a911adf3d0239f974c034b78085c"}, + {file = "mypy-1.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6801319fe76c3f3a3833f2b5af7bd2c17bb93c00026a2a1b924e6762f5b19e13"}, + {file = "mypy-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1a184c64521dc549324ec6ef7cbaa6b351912be9cb5edb803c2808a0d7e85ac"}, + {file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"}, + {file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] @@ -2030,13 +2029,13 @@ types-pytz = ">=2022.1.1" [[package]] name = "pandera" -version = "0.20.1" +version = "0.20.3" description = "A light-weight and flexible data validation and testing tool for statistical data objects." optional = false python-versions = ">=3.7" files = [ - {file = "pandera-0.20.1-py3-none-any.whl", hash = "sha256:ebf5cd5e42bacc451ac332f531cca2d6788a0662a2e565cb8d095e5bc55ebb6c"}, - {file = "pandera-0.20.1.tar.gz", hash = "sha256:eda8d8330d16b2a1ae38eddcb34c4da287ce03c84696f654399a0068663c7e4d"}, + {file = "pandera-0.20.3-py3-none-any.whl", hash = "sha256:0c251a3947d8c6d7a0e26602e78fa425268bc9f448f3a0fded85249b158a65c2"}, + {file = "pandera-0.20.3.tar.gz", hash = "sha256:d8542a68493d2dfe3226c186cc145be8d27535d7edf396178e93811515fe3470"}, ] [package.dependencies] @@ -2607,13 +2606,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pynvml" -version = "11.5.0" -description = "Python Bindings for the NVIDIA Management Library" +version = "11.5.3" +description = "Python utilities for the NVIDIA Management Library" optional = false python-versions = ">=3.6" files = [ - {file = "pynvml-11.5.0-py3-none-any.whl", hash = "sha256:5cce014ac01b098d08f06178f86c37be409b80b2e903a5a03ce15eed60f55e25"}, - {file = "pynvml-11.5.0.tar.gz", hash = "sha256:d027b21b95b1088b9fc278117f9f61b7c67f8e33a787e9f83f735f0f71ac32d0"}, + {file = "pynvml-11.5.3-py3-none-any.whl", hash = "sha256:a5fba3ab14febda50d19dbda012ef62ae0aed45b7ccc07af0bc5be79223e450c"}, + {file = "pynvml-11.5.3.tar.gz", hash = "sha256:183d223ae487e5f00402d8da06c68c978ef8a9295793ee75559839c6ade7b229"}, ] [[package]] @@ -3119,29 +3118,29 @@ files = [ [[package]] name = "ruff" -version = "0.5.1" +version = "0.5.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, - {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, - {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, - {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, - {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, - {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, - {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, + {file = "ruff-0.5.3-py3-none-linux_armv6l.whl", hash = "sha256:b12424d9db7347fa63c5ed9af010003338c63c629fb9c9c6adb2aa4f5699729b"}, + {file = "ruff-0.5.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8d72c5684bbd4ed304a9a955ee2e67f57b35f6193222ade910cca8a805490e3"}, + {file = "ruff-0.5.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2fc2cdb85ccac1e816cc9d5d8cedefd93661bd957756d902543af32a6b04a71"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf4bc751240b2fab5d19254571bcacb315c7b0b00bf3c912d52226a82bbec073"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc697ec874fdd7c7ba0a85ec76ab38f8595224868d67f097c5ffc21136e72fcd"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e791d34d3557a3819b3704bc1f087293c821083fa206812842fa363f6018a192"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:76bb5a87fd397520b91a83eae8a2f7985236d42dd9459f09eef58e7f5c1d8316"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8cfc7a26422c78e94f1ec78ec02501bbad2df5834907e75afe474cc6b83a8c1"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96066c4328a49fce2dd40e80f7117987369feec30ab771516cf95f1cc2db923c"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfe9ab5bdc0b08470c3b261643ad54ea86edc32b64d1e080892d7953add3ad"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7704582a026fa02cca83efd76671a98ee6eb412c4230209efe5e2a006c06db62"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:08058d077e21b856d32ebf483443390e29dc44d927608dc8f092ff6776519da9"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:77d49484429ed7c7e6e2e75a753f153b7b58f875bdb4158ad85af166a1ec1822"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:642cbff6cbfa38d2566d8db086508d6f472edb136cbfcc4ea65997745368c29e"}, + {file = "ruff-0.5.3-py3-none-win32.whl", hash = "sha256:eafc45dd8bdc37a00b28e68cc038daf3ca8c233d73fea276dcd09defb1352841"}, + {file = "ruff-0.5.3-py3-none-win_amd64.whl", hash = "sha256:cbaec2ddf4f78e5e9ecf5456ea0f496991358a1d883862ed0b9e947e2b6aea93"}, + {file = "ruff-0.5.3-py3-none-win_arm64.whl", hash = "sha256:05fbd2cb404775d6cd7f2ff49504e2d20e13ef95fa203bd1ab22413af70d420b"}, + {file = "ruff-0.5.3.tar.gz", hash = "sha256:2a3eb4f1841771fa5b67a56be9c2d16fd3cc88e378bd86aaeaec2f7e6bcdd0a2"}, ] [[package]] @@ -3230,18 +3229,19 @@ test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "me [[package]] name = "setuptools" -version = "70.3.0" +version = "71.0.4" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, - {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, + {file = "setuptools-71.0.4-py3-none-any.whl", hash = "sha256:ed2feca703be3bdbd94e6bb17365d91c6935c6b2a8d0bb09b66a2c435ba0b1a5"}, + {file = "setuptools-71.0.4.tar.gz", hash = "sha256:48297e5d393a62b7cb2a10b8f76c63a73af933bd809c9e0d0d6352a1a0135dd8"}, ] [package.extras] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shap" @@ -3418,13 +3418,13 @@ sqlcipher = ["sqlcipher3_binary"] [[package]] name = "sqlparse" -version = "0.5.0" +version = "0.5.1" description = "A non-validating SQL parser." optional = false python-versions = ">=3.8" files = [ - {file = "sqlparse-0.5.0-py3-none-any.whl", hash = "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"}, - {file = "sqlparse-0.5.0.tar.gz", hash = "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93"}, + {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"}, + {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"}, ] [package.extras] @@ -3599,6 +3599,17 @@ files = [ {file = "types_pytz-2024.1.0.20240417-py3-none-any.whl", hash = "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659"}, ] +[[package]] +name = "types-pyyaml" +version = "6.0.12.20240311" +description = "Typing stubs for PyYAML" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-PyYAML-6.0.12.20240311.tar.gz", hash = "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342"}, + {file = "types_PyYAML-6.0.12.20240311-py3-none-any.whl", hash = "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"}, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -3827,4 +3838,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "af49d976e486109834116d313106521513707aba2831087db962144ffeefb1da" +content-hash = "bfd753415cb70a98d003b7096ad3c4b530f7a087ebf2ed425f712103c5646c32" diff --git a/pyproject.toml b/pyproject.toml index e664e50..66037a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,6 +57,7 @@ pre-commit = "^3.7.1" [tool.poetry.group.dev.dependencies] invoke = "^2.2.0" +pyyaml = "^6.0.1" [tool.poetry.group.docs.dependencies] pdoc = "^14.5.1" @@ -65,6 +66,9 @@ pdoc = "^14.5.1" ipykernel = "^6.29.4" nbformat = "^5.10.4" +[tool.poetry.group.types.dependencies] +types-pyyaml = "^6.0.12.20240311" + # CONFIGURATIONS [tool.bandit] diff --git a/python_env.yaml b/python_env.yaml new file mode 100644 index 0000000..f314f0d --- /dev/null +++ b/python_env.yaml @@ -0,0 +1,90 @@ +dependencies: +- alembic==1.13.2 +- aniso8601==9.0.1 +- annotated-types==0.7.0 +- antlr4-python3-runtime==4.9.3 +- blinker==1.8.2 +- cachetools==5.4.0 +- certifi==2024.7.4 +- charset-normalizer==3.3.2 +- click==8.1.7 +- cloudpickle==3.0.0 +- colorama==0.4.6 +- contourpy==1.2.1 +- cycler==0.12.1 +- deprecated==1.2.14 +- docker==7.1.0 +- entrypoints==0.4 +- flask==3.0.3 +- fonttools==4.53.1 +- gitdb==4.0.11 +- gitpython==3.1.43 +- graphene==3.3 +- graphql-core==3.2.3 +- graphql-relay==3.2.0 +- greenlet==3.0.3 +- gunicorn==22.0.0 +- idna==3.7 +- importlib-metadata==7.2.1 +- itsdangerous==2.2.0 +- jinja2==3.1.4 +- joblib==1.4.2 +- kiwisolver==1.4.5 +- llvmlite==0.43.0 +- loguru==0.7.2 +- mako==1.3.5 +- markdown==3.6 +- markupsafe==2.1.5 +- matplotlib==3.9.1 +- mlflow==2.14.3 +- multimethod==1.10 +- mypy-extensions==1.0.0 +- numba==0.60.0 +- numpy==1.26.4 +- omegaconf==2.3.0 +- opentelemetry-api==1.16.0 +- opentelemetry-sdk==1.16.0 +- opentelemetry-semantic-conventions==0.37b0 +- packaging==24.1 +- pandas==2.2.2 +- pandera==0.20.3 +- pillow==10.4.0 +- plotly==5.22.0 +- plyer==2.1.0 +- protobuf==4.25.3 +- psutil==6.0.0 +- pyarrow==15.0.2 +- pydantic-core==2.20.1 +- pydantic-settings==2.3.4 +- pydantic==2.8.2 +- pynvml==11.5.3 +- pyparsing==3.1.2 +- python-dateutil==2.9.0.post0 +- python-dotenv==1.0.1 +- pytz==2024.1 +- pyyaml==6.0.1 +- querystring-parser==1.2.4 +- requests==2.32.3 +- scikit-learn==1.4.2 +- scipy==1.14.0 +- setuptools==71.0.4 +- shap==0.46.0 +- six==1.16.0 +- slicer==0.0.8 +- smmap==5.0.1 +- sqlalchemy==2.0.31 +- sqlparse==0.5.1 +- tenacity==8.5.0 +- threadpoolctl==3.5.0 +- tqdm==4.66.4 +- typeguard==4.3.0 +- typing-extensions==4.12.2 +- typing-inspect==0.9.0 +- tzdata==2024.1 +- urllib3==2.2.2 +- waitress==3.0.0 +- werkzeug==3.0.3 +- win32-setctime==1.1.0 +- wrapt==1.16.0 +- zipp==3.19.2 +python: '3.12' diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..29ce839 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,89 @@ +alembic==1.13.2 ; python_version >= "3.12" and python_version < "4.0" +aniso8601==9.0.1 ; python_version >= "3.12" and python_version < "4.0" +annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0" +antlr4-python3-runtime==4.9.3 ; python_version >= "3.12" and python_version < "4.0" +blinker==1.8.2 ; python_version >= "3.12" and python_version < "4.0" +cachetools==5.4.0 ; python_version >= "3.12" and python_version < "4.0" +certifi==2024.7.4 ; python_version >= "3.12" and python_version < "4.0" +charset-normalizer==3.3.2 ; python_version >= "3.12" and python_version < "4.0" +click==8.1.7 ; python_version >= "3.12" and python_version < "4.0" +cloudpickle==3.0.0 ; python_version >= "3.12" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows") +contourpy==1.2.1 ; python_version >= "3.12" and python_version < "4.0" +cycler==0.12.1 ; python_version >= "3.12" and python_version < "4.0" +deprecated==1.2.14 ; python_version >= "3.12" and python_version < "4.0" +docker==7.1.0 ; python_version >= "3.12" and python_version < "4.0" +entrypoints==0.4 ; python_version >= "3.12" and python_version < "4.0" +flask==3.0.3 ; python_version >= "3.12" and python_version < "4.0" +fonttools==4.53.1 ; python_version >= "3.12" and python_version < "4.0" +gitdb==4.0.11 ; python_version >= "3.12" and python_version < "4.0" +gitpython==3.1.43 ; python_version >= "3.12" and python_version < "4.0" +graphene==3.3 ; python_version >= "3.12" and python_version < "4.0" +graphql-core==3.2.3 ; python_version >= "3.12" and python_version < "4" +graphql-relay==3.2.0 ; python_version >= "3.12" and python_version < "4" +greenlet==3.0.3 ; python_version < "3.13" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32") and python_version >= "3.12" +gunicorn==22.0.0 ; python_version >= "3.12" and python_version < "4.0" and platform_system != "Windows" +idna==3.7 ; python_version >= "3.12" and python_version < "4.0" +importlib-metadata==7.2.1 ; python_version >= "3.12" and python_version < "4.0" +itsdangerous==2.2.0 ; python_version >= "3.12" and python_version < "4.0" +jinja2==3.1.4 ; python_version >= "3.12" and python_version < "4.0" +joblib==1.4.2 ; python_version >= "3.12" and python_version < "4.0" +kiwisolver==1.4.5 ; python_version >= "3.12" and python_version < "4.0" +llvmlite==0.43.0 ; python_version >= "3.12" and python_version < "4.0" +loguru==0.7.2 ; python_version >= "3.12" and python_version < "4.0" +mako==1.3.5 ; python_version >= "3.12" and python_version < "4.0" +markdown==3.6 ; python_version >= "3.12" and python_version < "4.0" +markupsafe==2.1.5 ; python_version >= "3.12" and python_version < "4.0" +matplotlib==3.9.1 ; python_version >= "3.12" and python_version < "4.0" +mlflow==2.14.3 ; python_version >= "3.12" and python_version < "4.0" +multimethod==1.10 ; python_version >= "3.12" and python_version < "4.0" +mypy-extensions==1.0.0 ; python_version >= "3.12" and python_version < "4.0" +numba==0.60.0 ; python_version >= "3.12" and python_version < "4.0" +numpy==1.26.4 ; python_version >= "3.12" and python_version < "4.0" +omegaconf==2.3.0 ; python_version >= "3.12" and python_version < "4.0" +opentelemetry-api==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +opentelemetry-sdk==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +opentelemetry-semantic-conventions==0.37b0 ; python_version >= "3.12" and python_version < "4.0" +packaging==24.1 ; python_version >= "3.12" and python_version < "4.0" +pandas==2.2.2 ; python_version >= "3.12" and python_version < "4.0" +pandera==0.20.3 ; python_version >= "3.12" and python_version < "4.0" +pillow==10.4.0 ; python_version >= "3.12" and python_version < "4.0" +plotly==5.22.0 ; python_version >= "3.12" and python_version < "4.0" +plyer==2.1.0 ; python_version >= "3.12" and python_version < "4.0" +protobuf==4.25.3 ; python_version >= "3.12" and python_version < "4.0" +psutil==6.0.0 ; python_version >= "3.12" and python_version < "4.0" +pyarrow==15.0.2 ; python_version >= "3.12" and python_version < "4.0" +pydantic-core==2.20.1 ; python_version >= "3.12" and python_version < "4.0" +pydantic-settings==2.3.4 ; python_version >= "3.12" and python_version < "4.0" +pydantic==2.8.2 ; python_version >= "3.12" and python_version < "4.0" +pynvml==11.5.3 ; python_version >= "3.12" and python_version < "4.0" +pyparsing==3.1.2 ; python_version >= "3.12" and python_version < "4.0" +python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" +python-dotenv==1.0.1 ; python_version >= "3.12" and python_version < "4.0" +pytz==2024.1 ; python_version >= "3.12" and python_version < "4.0" +pywin32==306 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" +pyyaml==6.0.1 ; python_version >= "3.12" and python_version < "4.0" +querystring-parser==1.2.4 ; python_version >= "3.12" and python_version < "4.0" +requests==2.32.3 ; python_version >= "3.12" and python_version < "4.0" +scikit-learn==1.4.2 ; python_version >= "3.12" and python_version < "4.0" +scipy==1.14.0 ; python_version >= "3.12" and python_version < "4.0" +setuptools==71.0.4 ; python_version >= "3.12" and python_version < "4.0" +shap==0.46.0 ; python_version >= "3.12" and python_version < "4.0" +six==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +slicer==0.0.8 ; python_version >= "3.12" and python_version < "4.0" +smmap==5.0.1 ; python_version >= "3.12" and python_version < "4.0" +sqlalchemy==2.0.31 ; python_version >= "3.12" and python_version < "4.0" +sqlparse==0.5.1 ; python_version >= "3.12" and python_version < "4.0" +tenacity==8.5.0 ; python_version >= "3.12" and python_version < "4.0" +threadpoolctl==3.5.0 ; python_version >= "3.12" and python_version < "4.0" +tqdm==4.66.4 ; python_version >= "3.12" and python_version < "4.0" +typeguard==4.3.0 ; python_version >= "3.12" and python_version < "4.0" +typing-extensions==4.12.2 ; python_version >= "3.12" and python_version < "4.0" +typing-inspect==0.9.0 ; python_version >= "3.12" and python_version < "4.0" +tzdata==2024.1 ; python_version >= "3.12" and python_version < "4.0" +urllib3==2.2.2 ; python_version >= "3.12" and python_version < "4.0" +waitress==3.0.0 ; python_version >= "3.12" and python_version < "4.0" and platform_system == "Windows" +werkzeug==3.0.3 ; python_version >= "3.12" and python_version < "4.0" +win32-setctime==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" +wrapt==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +zipp==3.19.2 ; python_version >= "3.12" and python_version < "4.0" diff --git a/tasks/__init__.py b/tasks/__init__.py index e9359de..6a6751c 100644 --- a/tasks/__init__.py +++ b/tasks/__init__.py @@ -6,7 +6,18 @@ from invoke import Collection -from . import checks, cleans, commits, containers, dags, docs, formats, installs, mlflow, packages +from . import ( + checks, + cleans, + commits, + containers, + docs, + formats, + installs, + mlflow, + packages, + projects, +) # %% NAMESPACES @@ -18,9 +29,9 @@ ns.add_collection(cleans) ns.add_collection(commits) ns.add_collection(containers) -ns.add_collection(dags, default=True) ns.add_collection(docs) ns.add_collection(formats) ns.add_collection(installs) ns.add_collection(mlflow) ns.add_collection(packages) +ns.add_collection(projects, default=True) diff --git a/tasks/cleans.py b/tasks/cleans.py index 02a719a..f356b46 100644 --- a/tasks/cleans.py +++ b/tasks/cleans.py @@ -89,6 +89,21 @@ def python(ctx: Context) -> None: ctx.run(r"find . -type d -name __pycache__ -exec rm -r {} \+") +# %% PROJECTS + + +@task +def requirements(ctx: Context) -> None: + """Clean the project requirements file.""" + ctx.run("rm -f requirements.txt") + + +@task +def environment(ctx: Context) -> None: + """Clean the project environment file.""" + ctx.run("rm -f python_env.yaml") + + # %% - Combines @@ -107,11 +122,16 @@ def sources(_: Context) -> None: """Run all sources tasks.""" +@task(pre=[requirements, environment]) +def projects(_: Context) -> None: + """Run all projects tasks.""" + + @task(pre=[tools, folders], default=True) def all(_: Context) -> None: """Run all tools and folders tasks.""" -@task(pre=[all, sources]) +@task(pre=[all, sources, projects]) def reset(_: Context) -> None: """Run all tools, folders, and sources tasks.""" diff --git a/tasks/dags.py b/tasks/dags.py deleted file mode 100644 index 0f51cfa..0000000 --- a/tasks/dags.py +++ /dev/null @@ -1,29 +0,0 @@ -"""DAG tasks for pyinvoke.""" - -# %% IMPORTS - -from invoke.context import Context -from invoke.tasks import call, task - -# %% TASKS - - -@task -def job(ctx: Context, name: str) -> None: - """Run the project for the given job name.""" - ctx.run(f"poetry run {ctx.project.name} confs/{name}.yaml") - - -@task( - pre=[ - call(job, name="tuning"), # type: ignore[arg-type] - call(job, name="training"), # type: ignore[arg-type] - call(job, name="promotion"), # type: ignore[arg-type] - call(job, name="inference"), # type: ignore[arg-type] - call(job, name="evaluations"), # type: ignore[arg-type] - call(job, name="explanations"), # type: ignore[arg-type] - ], - default=True, -) -def all(_: Context) -> None: - """Run all DAG tasks.""" diff --git a/tasks/projects.py b/tasks/projects.py new file mode 100644 index 0000000..90d521e --- /dev/null +++ b/tasks/projects.py @@ -0,0 +1,65 @@ +"""Project tasks for pyinvoke.""" + +# mypy: disable-error-code="arg-type" + +# %% IMPORTS + +import yaml +from invoke.context import Context +from invoke.tasks import call, task + +# %% CONFIGS + +PYTHON_VERSION = ".python-version" +REQUIREMENTS = "requirements.txt" +ENVIRONMENT = "python_env.yaml" + +# %% TASKS + + +@task +def requirements(ctx: Context) -> None: + """Export the project requirements file.""" + ctx.run(f"poetry export --without-urls --without-hashes --output={REQUIREMENTS}") + + +@task(pre=[requirements]) +def environment(ctx: Context) -> None: + """Export the project environment file.""" + with open(PYTHON_VERSION, "r") as reader: + python = reader.read().strip() # version + configuration: dict[str, object] = {"python": python} + with open(REQUIREMENTS, "r") as reader: + dependencies: list[str] = [] + for line in reader: + dependency = line.split(" ")[0] + if "pywin32" not in dependency: + dependencies.append(dependency) + configuration["dependencies"] = dependencies + with open(ENVIRONMENT, "w") as writer: + yaml.dump(configuration, writer) + + +@task +def run(ctx: Context, job: str) -> None: + """Run an mlflow project from MLproject file.""" + ctx.run( + f"mlflow run --experiment-name={ctx.project.name}" + f" --run-name={job.upper()} -P conf_file=confs/{job}.yaml ." + ) + + +@task( + pre=[ + environment, + call(run, job="tuning"), + call(run, job="training"), + call(run, job="promotion"), + call(run, job="inference"), + call(run, job="evaluations"), + call(run, job="explanations"), + ], + default=True, +) +def all(_: Context) -> None: + """Run all project tasks.""" From f071dd1397f5c7592fd82a2fe169f5ecaf3af901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sat, 20 Jul 2024 15:00:19 +0200 Subject: [PATCH 17/21] fix(projects): change naming convention --- tasks/projects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/projects.py b/tasks/projects.py index 90d521e..bd80341 100644 --- a/tasks/projects.py +++ b/tasks/projects.py @@ -45,7 +45,7 @@ def run(ctx: Context, job: str) -> None: """Run an mlflow project from MLproject file.""" ctx.run( f"mlflow run --experiment-name={ctx.project.name}" - f" --run-name={job.upper()} -P conf_file=confs/{job}.yaml ." + f" --run-name={job.capitalize()} -P conf_file=confs/{job}.yaml ." ) From 2d182abfd899640b5566033f30cfc38caa017a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sun, 21 Jul 2024 16:49:44 +0200 Subject: [PATCH 18/21] feat(kpi): add key performance indicators --- notebooks/process.ipynb | 719 ---------------------------------------- 1 file changed, 719 deletions(-) delete mode 100644 notebooks/process.ipynb diff --git a/notebooks/process.ipynb b/notebooks/process.ipynb deleted file mode 100644 index 27c0461..0000000 --- a/notebooks/process.ipynb +++ /dev/null @@ -1,719 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. **Extract** all data from CSV files.\n", - "2. **Transform** data into inputs/targets.\n", - "3. **Split** inputs/targets into train/test sets.\n", - "4. **Sample** inputs/targets for the testing sets.\n", - "5. **Load** outputs inputs/targets to parquet files." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# IMPORTS" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from sklearn.model_selection import train_test_split" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# CONFIGS" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Extract" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "HOUR_FILE = \"../data/hour.csv\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Transform" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "INDEX_COL = \"instant\"\n", - "TARGET_COL = 'cnt'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Split" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "SHUFFLE = False # time-sensitive\n", - "TEST_SIZE = 0.2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Sample" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "SAMPLE_RATIO = 0.15\n", - "SAMPLE_RANDOM_STATE = 0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Load" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "INPUTS_TRAIN_FILE = \"../data/inputs_train.parquet\"\n", - "INPUTS_TEST_FILE = \"../data/inputs_test.parquet\"\n", - "TARGETS_TRAIN_FILE = \"../data/targets_train.parquet\"\n", - "TARGETS_TEST_FILE = \"../data/targets_test.parquet\"\n", - "INPUTS_SAMPLE_FILE = \"../tests/data/inputs_sample.parquet\"\n", - "TARGETS_SAMPLE_FILE = \"../tests/data/targets_sample.parquet\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# EXTRACT" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hour: (17379, 16)\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
    dtedayseasonyrmnthhrholidayweekdayworkingdayweathersittempatemphumwindspeedcasualregisteredcnt
    instant
    12011-01-01101006010.240.28790.810.031316
    22011-01-01101106010.220.27270.800.083240
    32011-01-01101206010.220.27270.800.052732
    42011-01-01101306010.240.28790.750.031013
    52011-01-01101406010.240.28790.750.0011
    \n", - "
    " - ], - "text/plain": [ - " dteday season yr mnth hr holiday weekday workingday \\\n", - "instant \n", - "1 2011-01-01 1 0 1 0 0 6 0 \n", - "2 2011-01-01 1 0 1 1 0 6 0 \n", - "3 2011-01-01 1 0 1 2 0 6 0 \n", - "4 2011-01-01 1 0 1 3 0 6 0 \n", - "5 2011-01-01 1 0 1 4 0 6 0 \n", - "\n", - " weathersit temp atemp hum windspeed casual registered cnt \n", - "instant \n", - "1 1 0.24 0.2879 0.81 0.0 3 13 16 \n", - "2 1 0.22 0.2727 0.80 0.0 8 32 40 \n", - "3 1 0.22 0.2727 0.80 0.0 5 27 32 \n", - "4 1 0.24 0.2879 0.75 0.0 3 10 13 \n", - "5 1 0.24 0.2879 0.75 0.0 0 1 1 " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hour = pd.read_csv(HOUR_FILE, index_col=INDEX_COL)\n", - "print(\"Hour:\", hour.shape)\n", - "hour.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# TRANFORM" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inputs: (17379, 15)\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
    dtedayseasonyrmnthhrholidayweekdayworkingdayweathersittempatemphumwindspeedcasualregistered
    instant
    12011-01-01101006010.240.28790.810.0313
    22011-01-01101106010.220.27270.800.0832
    32011-01-01101206010.220.27270.800.0527
    42011-01-01101306010.240.28790.750.0310
    52011-01-01101406010.240.28790.750.001
    \n", - "
    " - ], - "text/plain": [ - " dteday season yr mnth hr holiday weekday workingday \\\n", - "instant \n", - "1 2011-01-01 1 0 1 0 0 6 0 \n", - "2 2011-01-01 1 0 1 1 0 6 0 \n", - "3 2011-01-01 1 0 1 2 0 6 0 \n", - "4 2011-01-01 1 0 1 3 0 6 0 \n", - "5 2011-01-01 1 0 1 4 0 6 0 \n", - "\n", - " weathersit temp atemp hum windspeed casual registered \n", - "instant \n", - "1 1 0.24 0.2879 0.81 0.0 3 13 \n", - "2 1 0.22 0.2727 0.80 0.0 8 32 \n", - "3 1 0.22 0.2727 0.80 0.0 5 27 \n", - "4 1 0.24 0.2879 0.75 0.0 3 10 \n", - "5 1 0.24 0.2879 0.75 0.0 0 1 " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "inputs = hour.drop(TARGET_COL, axis=\"columns\")\n", - "print(\"Inputs:\", inputs.shape)\n", - "inputs.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Targets: (17379, 1)\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
    cnt
    instant
    116
    240
    332
    413
    51
    \n", - "
    " - ], - "text/plain": [ - " cnt\n", - "instant \n", - "1 16\n", - "2 40\n", - "3 32\n", - "4 13\n", - "5 1" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "targets = hour[TARGET_COL].to_frame()\n", - "print(\"Targets:\", targets.shape)\n", - "targets.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# SPLIT" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((13903, 15), (3476, 15), (13903, 1), (3476, 1))" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "inputs_train, inputs_test, targets_train, targets_test = train_test_split(\n", - " inputs, targets, test_size=TEST_SIZE, shuffle=SHUFFLE\n", - ")\n", - "inputs_train.shape, inputs_test.shape, targets_train.shape, targets_test.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# SAMPLE" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((2085, 15), (2085, 1))" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "inputs_train_sample = inputs_train.sample(frac=SAMPLE_RATIO, random_state=SAMPLE_RANDOM_STATE)\n", - "targets_train_sample = targets_train.sample(frac=SAMPLE_RATIO, random_state=SAMPLE_RANDOM_STATE)\n", - "inputs_train_sample.shape, targets_train_sample.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# LOAD" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "inputs_train.to_parquet(INPUTS_TRAIN_FILE)\n", - "inputs_test.to_parquet(INPUTS_TEST_FILE)\n", - "targets_train.to_parquet(TARGETS_TRAIN_FILE)\n", - "targets_test.to_parquet(TARGETS_TEST_FILE)\n", - "inputs_train_sample.to_parquet(INPUTS_SAMPLE_FILE)\n", - "targets_train_sample.to_parquet(TARGETS_SAMPLE_FILE)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From ee17d0a9de59efd2eb99d667786ac417ec8b3b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sun, 21 Jul 2024 16:50:28 +0200 Subject: [PATCH 19/21] fix(kpi): add key performance indicators --- notebooks/indicators.ipynb | 7951 ++++++++++++++++++++++++++++++++++++ notebooks/processing.ipynb | 719 ++++ 2 files changed, 8670 insertions(+) create mode 100644 notebooks/indicators.ipynb create mode 100644 notebooks/processing.ipynb diff --git a/notebooks/indicators.ipynb b/notebooks/indicators.ipynb new file mode 100644 index 0000000..8c7f8f7 --- /dev/null +++ b/notebooks/indicators.ipynb @@ -0,0 +1,7951 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Compute Key-Performance Indicators (KPIs) from the MLflow server.**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# IMPORTS" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import mlflow\n", + "import pandas as pd\n", + "import plotly.express as px" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# OPTIONS" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "pd.options.display.max_columns = None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CONFIGS" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "MAX_RESULTS = 100\n", + "TRACKING_URI = \"http://localhost:5000\"\n", + "REGISTRY_URI = \"http://localhost:5000\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CLIENTS" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "client = mlflow.tracking.MlflowClient(tracking_uri=TRACKING_URI, registry_uri=REGISTRY_URI)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# INDICATORS" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 7)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    artifact_locationcreation_timeexperiment_idlast_update_timelifecycle_stagenametags
    0file:///home/fmind/mlops-python-package/mlruns...2024-07-20 12:43:59.7215627575662605739322024-07-20 12:43:59.721activebikes{}
    \n", + "
    " + ], + "text/plain": [ + " artifact_location creation_time \\\n", + "0 file:///home/fmind/mlops-python-package/mlruns... 2024-07-20 12:43:59.721 \n", + "\n", + " experiment_id last_update_time lifecycle_stage name tags \n", + "0 562757566260573932 2024-07-20 12:43:59.721 active bikes {} " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "experiments = client.search_experiments(\n", + " view_type=mlflow.entities.ViewType.ALL, max_results=MAX_RESULTS, order_by=[\"creation_time DESC\"]\n", + ")\n", + "experiments = [dict(experiment) for experiment in experiments]\n", + "experiments = pd.DataFrame(experiments).assign(\n", + " creation_time=lambda data: pd.to_datetime(data[\"creation_time\"], unit=\"ms\"),\n", + " last_update_time=lambda data: pd.to_datetime(data[\"last_update_time\"], unit=\"ms\"),\n", + ")\n", + "print(experiments.shape)\n", + "experiments.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(28, 29)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    artifact_uriend_timeexperiment_idlifecycle_stagerun_idrun_namerun_uuidstart_timestatususer_idmetricsparamstagsmlflow.usermlflow.source.namemlflow.source.typemlflow.project.entryPointmlflow.source.git.commitmlflow.source.git.repoURLmlflow.gitRepoURLmlflow.runNamemlflow.project.envmlflow.project.backendmlflow.datasetsestimator_nameestimator_classmlflow.log-model.historymlflow.autologgingmlflow.parentRunId
    0file:///home/fmind/mlops-python-package/mlruns...2024-07-21 14:08:59.757562757566260573932active2f6920e2006841d7a72567e9f25df89fExplanations2f6920e2006841d7a72567e9f25df89f2024-07-21 14:08:29.817FINISHEDfmind{}{'conf_file': 'confs/explanations.yaml'}{'mlflow.user': 'fmind', 'mlflow.source.name':...fmindfile:///home/fmind/mlops-python-packagePROJECTmainf071dd1397f5c7592fd82a2fe169f5ecaf3af901git@github.com:fmind/mlops-python-packagegit@github.com:fmind/mlops-python-packageExplanationsvirtualenvlocalNaNNaNNaNNaNNaNNaN
    1file:///home/fmind/mlops-python-package/mlruns...2024-07-21 14:08:28.634562757566260573932active94fa6a85393745f9b8bb5cac75f865e4Evaluations94fa6a85393745f9b8bb5cac75f865e42024-07-21 14:08:24.395FINISHEDfmind{'example_count': 13903.0, 'mean_absolute_erro...{'conf_file': 'confs/evaluations.yaml'}{'mlflow.user': 'fmind', 'mlflow.source.name':...fmindfile:///home/fmind/mlops-python-packagePROJECTmainf071dd1397f5c7592fd82a2fe169f5ecaf3af901git@github.com:fmind/mlops-python-packagegit@github.com:fmind/mlops-python-packageEvaluationsvirtualenvlocal[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"h...NaNNaNNaNNaNNaN
    2file:///home/fmind/mlops-python-package/mlruns...2024-07-21 14:08:23.205562757566260573932activeda669581953a4a46ab84efaabc8f3e92Inferenceda669581953a4a46ab84efaabc8f3e922024-07-21 14:08:19.775FINISHEDfmind{}{'conf_file': 'confs/inference.yaml'}{'mlflow.user': 'fmind', 'mlflow.source.name':...fmindfile:///home/fmind/mlops-python-packagePROJECTmainf071dd1397f5c7592fd82a2fe169f5ecaf3af901git@github.com:fmind/mlops-python-packagegit@github.com:fmind/mlops-python-packageInferencevirtualenvlocalNaNNaNNaNNaNNaNNaN
    3file:///home/fmind/mlops-python-package/mlruns...2024-07-21 14:08:18.412562757566260573932active023a21263eaa43228b324fb432932cf4Promotion023a21263eaa43228b324fb432932cf42024-07-21 14:08:15.431FINISHEDfmind{}{'conf_file': 'confs/promotion.yaml'}{'mlflow.user': 'fmind', 'mlflow.source.name':...fmindfile:///home/fmind/mlops-python-packagePROJECTmainf071dd1397f5c7592fd82a2fe169f5ecaf3af901git@github.com:fmind/mlops-python-packagegit@github.com:fmind/mlops-python-packagePromotionvirtualenvlocalNaNNaNNaNNaNNaNNaN
    4file:///home/fmind/mlops-python-package/mlruns...2024-07-21 14:08:13.567562757566260573932actived37276201a5b4ff98addae88f5ed1a34Trainingd37276201a5b4ff98addae88f5ed1a342024-07-21 14:07:54.473FINISHEDfmind{'training_mean_squared_error': 124.5105461557...{'conf_file': 'confs/training.yaml', 'memory':...{'mlflow.user': 'fmind', 'mlflow.source.name':...fmindfile:///home/fmind/mlops-python-packagePROJECTmainf071dd1397f5c7592fd82a2fe169f5ecaf3af901git@github.com:fmind/mlops-python-packagegit@github.com:fmind/mlops-python-packageTrainingvirtualenvlocalNaNPipelinesklearn.pipeline.Pipeline[{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\"...NaNNaN
    \n", + "
    " + ], + "text/plain": [ + " artifact_uri end_time \\\n", + "0 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:59.757 \n", + "1 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:28.634 \n", + "2 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:23.205 \n", + "3 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:18.412 \n", + "4 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:13.567 \n", + "\n", + " experiment_id lifecycle_stage run_id \\\n", + "0 562757566260573932 active 2f6920e2006841d7a72567e9f25df89f \n", + "1 562757566260573932 active 94fa6a85393745f9b8bb5cac75f865e4 \n", + "2 562757566260573932 active da669581953a4a46ab84efaabc8f3e92 \n", + "3 562757566260573932 active 023a21263eaa43228b324fb432932cf4 \n", + "4 562757566260573932 active d37276201a5b4ff98addae88f5ed1a34 \n", + "\n", + " run_name run_uuid start_time \\\n", + "0 Explanations 2f6920e2006841d7a72567e9f25df89f 2024-07-21 14:08:29.817 \n", + "1 Evaluations 94fa6a85393745f9b8bb5cac75f865e4 2024-07-21 14:08:24.395 \n", + "2 Inference da669581953a4a46ab84efaabc8f3e92 2024-07-21 14:08:19.775 \n", + "3 Promotion 023a21263eaa43228b324fb432932cf4 2024-07-21 14:08:15.431 \n", + "4 Training d37276201a5b4ff98addae88f5ed1a34 2024-07-21 14:07:54.473 \n", + "\n", + " status user_id metrics \\\n", + "0 FINISHED fmind {} \n", + "1 FINISHED fmind {'example_count': 13903.0, 'mean_absolute_erro... \n", + "2 FINISHED fmind {} \n", + "3 FINISHED fmind {} \n", + "4 FINISHED fmind {'training_mean_squared_error': 124.5105461557... \n", + "\n", + " params \\\n", + "0 {'conf_file': 'confs/explanations.yaml'} \n", + "1 {'conf_file': 'confs/evaluations.yaml'} \n", + "2 {'conf_file': 'confs/inference.yaml'} \n", + "3 {'conf_file': 'confs/promotion.yaml'} \n", + "4 {'conf_file': 'confs/training.yaml', 'memory':... \n", + "\n", + " tags mlflow.user \\\n", + "0 {'mlflow.user': 'fmind', 'mlflow.source.name':... fmind \n", + "1 {'mlflow.user': 'fmind', 'mlflow.source.name':... fmind \n", + "2 {'mlflow.user': 'fmind', 'mlflow.source.name':... fmind \n", + "3 {'mlflow.user': 'fmind', 'mlflow.source.name':... fmind \n", + "4 {'mlflow.user': 'fmind', 'mlflow.source.name':... fmind \n", + "\n", + " mlflow.source.name mlflow.source.type \\\n", + "0 file:///home/fmind/mlops-python-package PROJECT \n", + "1 file:///home/fmind/mlops-python-package PROJECT \n", + "2 file:///home/fmind/mlops-python-package PROJECT \n", + "3 file:///home/fmind/mlops-python-package PROJECT \n", + "4 file:///home/fmind/mlops-python-package PROJECT \n", + "\n", + " mlflow.project.entryPoint mlflow.source.git.commit \\\n", + "0 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", + "1 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", + "2 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", + "3 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", + "4 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", + "\n", + " mlflow.source.git.repoURL \\\n", + "0 git@github.com:fmind/mlops-python-package \n", + "1 git@github.com:fmind/mlops-python-package \n", + "2 git@github.com:fmind/mlops-python-package \n", + "3 git@github.com:fmind/mlops-python-package \n", + "4 git@github.com:fmind/mlops-python-package \n", + "\n", + " mlflow.gitRepoURL mlflow.runName \\\n", + "0 git@github.com:fmind/mlops-python-package Explanations \n", + "1 git@github.com:fmind/mlops-python-package Evaluations \n", + "2 git@github.com:fmind/mlops-python-package Inference \n", + "3 git@github.com:fmind/mlops-python-package Promotion \n", + "4 git@github.com:fmind/mlops-python-package Training \n", + "\n", + " mlflow.project.env mlflow.project.backend \\\n", + "0 virtualenv local \n", + "1 virtualenv local \n", + "2 virtualenv local \n", + "3 virtualenv local \n", + "4 virtualenv local \n", + "\n", + " mlflow.datasets estimator_name \\\n", + "0 NaN NaN \n", + "1 [{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"h... NaN \n", + "2 NaN NaN \n", + "3 NaN NaN \n", + "4 NaN Pipeline \n", + "\n", + " estimator_class \\\n", + "0 NaN \n", + "1 NaN \n", + "2 NaN \n", + "3 NaN \n", + "4 sklearn.pipeline.Pipeline \n", + "\n", + " mlflow.log-model.history mlflow.autologging \\\n", + "0 NaN NaN \n", + "1 NaN NaN \n", + "2 NaN NaN \n", + "3 NaN NaN \n", + "4 [{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\"... NaN \n", + "\n", + " mlflow.parentRunId \n", + "0 NaN \n", + "1 NaN \n", + "2 NaN \n", + "3 NaN \n", + "4 NaN " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "runs = client.search_runs(\n", + " experiment_ids=experiments[\"experiment_id\"].unique(),\n", + " run_view_type=mlflow.entities.ViewType.ALL,\n", + " max_results=MAX_RESULTS,\n", + " order_by=[\"created DESC\"],\n", + ")\n", + "runs = [dict(run.info) | dict(run.data) for run in runs]\n", + "runs = pd.DataFrame(runs).assign(\n", + " end_time=lambda data: pd.to_datetime(data[\"end_time\"], unit=\"ms\"),\n", + " start_time=lambda data: pd.to_datetime(data[\"start_time\"], unit=\"ms\"),\n", + ")\n", + "runs = pd.concat([runs, pd.json_normalize(runs['tags'])], axis=\"columns\")\n", + "print(runs.shape)\n", + "runs.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 6)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    aliasescreation_timestampdescriptionlast_updated_timestampnametags
    0{'Champion': '3'}2024-07-20 12:46:27.0132024-07-21 14:08:17.804bikes{}
    \n", + "
    " + ], + "text/plain": [ + " aliases creation_timestamp description \\\n", + "0 {'Champion': '3'} 2024-07-20 12:46:27.013 \n", + "\n", + " last_updated_timestamp name tags \n", + "0 2024-07-21 14:08:17.804 bikes {} " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "models = client.search_registered_models(\n", + " max_results=MAX_RESULTS, order_by=[\"creation_timestamp DESC\"]\n", + ")\n", + "models = [dict(model) for model in models]\n", + "models = pd.DataFrame(models).assign(\n", + " creation_timestamp=lambda data: pd.to_datetime(data[\"creation_timestamp\"], unit=\"ms\"),\n", + " last_updated_timestamp=lambda data: pd.to_datetime(data[\"last_updated_timestamp\"], unit=\"ms\"),\n", + ").drop(columns=['latest_versions'])\n", + "print(models.shape)\n", + "models" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, 14)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    aliasescreation_timestampcurrent_stagedescriptionlast_updated_timestampnamerun_idrun_linksourcestatusstatus_messagetagsuser_idversion
    0Champion2024-07-21 14:08:12.799None2024-07-21 14:08:12.799bikesd37276201a5b4ff98addae88f5ed1a34file:///home/fmind/mlops-python-package/mlruns...READY{}3
    1None2024-07-20 12:52:29.627None2024-07-20 12:52:29.627bikesb428ae1513a54e16a5bf3959cf3eeb8efile:///home/fmind/mlops-python-package/mlruns...READY{}2
    2None2024-07-20 12:46:27.017None2024-07-20 12:46:27.017bikes795eace5f76a4fe4af3754460b5e25e4file:///home/fmind/mlops-python-package/mlruns...READY{}1
    \n", + "
    " + ], + "text/plain": [ + " aliases creation_timestamp current_stage description \\\n", + "0 Champion 2024-07-21 14:08:12.799 None \n", + "1 None 2024-07-20 12:52:29.627 None \n", + "2 None 2024-07-20 12:46:27.017 None \n", + "\n", + " last_updated_timestamp name run_id run_link \\\n", + "0 2024-07-21 14:08:12.799 bikes d37276201a5b4ff98addae88f5ed1a34 \n", + "1 2024-07-20 12:52:29.627 bikes b428ae1513a54e16a5bf3959cf3eeb8e \n", + "2 2024-07-20 12:46:27.017 bikes 795eace5f76a4fe4af3754460b5e25e4 \n", + "\n", + " source status status_message \\\n", + "0 file:///home/fmind/mlops-python-package/mlruns... READY \n", + "1 file:///home/fmind/mlops-python-package/mlruns... READY \n", + "2 file:///home/fmind/mlops-python-package/mlruns... READY \n", + "\n", + " tags user_id version \n", + "0 {} 3 \n", + "1 {} 2 \n", + "2 {} 1 " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "versions = client.search_model_versions(\n", + " max_results=MAX_RESULTS, order_by=[\"creation_timestamp DESC\"]\n", + ")\n", + "versions = [dict(version) for version in versions]\n", + "versions = pd.DataFrame(versions).assign(\n", + " aliases=lambda data: data['aliases'].map(lambda x: x[0] if len(x) else None),\n", + " creation_timestamp=lambda data: pd.to_datetime(data[\"creation_timestamp\"], unit=\"ms\"),\n", + " last_updated_timestamp=lambda data: pd.to_datetime(data[\"last_updated_timestamp\"], unit=\"ms\"),\n", + ")\n", + "print(versions.shape)\n", + "versions.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# DASHBOARDS" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "all", + "customdata": [ + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932", + "562757566260573932", + "2024-07-20T12:43:59.721000", + "active", + "bikes", + {} + ] + ], + "fillcolor": "rgba(255,255,255,0)", + "hoveron": "points", + "hovertemplate": "%{hovertext}

    lifecycle_stage=%{customdata[3]}
    creation_time=%{x}
    artifact_location=%{customdata[0]}
    experiment_id=%{customdata[1]}
    last_update_time=%{customdata[2]}
    name=%{customdata[4]}
    tags=%{customdata[5]}", + "hovertext": [ + "bikes" + ], + "legendgroup": "active", + "line": { + "color": "rgba(255,255,255,0)" + }, + "marker": { + "color": "#636efa" + }, + "name": "active", + "offsetgroup": "active", + "orientation": "h", + "pointpos": 0, + "showlegend": true, + "type": "box", + "x": [ + "2024-07-20T12:43:59.721000" + ], + "x0": " ", + "xaxis": "x", + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "boxmode": "group", + "legend": { + "title": { + "text": "lifecycle_stage" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Experiment Creation Time" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "creation_time" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.strip(\n", + " experiments,\n", + " x=\"creation_time\",\n", + " color=\"lifecycle_stage\",\n", + " hover_name=\"name\",\n", + " hover_data=experiments.columns,\n", + " title=\"Experiment Creation Time\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "all", + "customdata": [ + [ + { + "Champion": "3" + }, + "", + "2024-07-21T14:08:17.804000", + "bikes", + {} + ] + ], + "fillcolor": "rgba(255,255,255,0)", + "hoveron": "points", + "hovertemplate": "%{hovertext}

    creation_timestamp=%{x}
    aliases=%{customdata[0]}
    description=%{customdata[1]}
    last_updated_timestamp=%{customdata[2]}
    name=%{customdata[3]}
    tags=%{customdata[4]}", + "hovertext": [ + "bikes" + ], + "legendgroup": "", + "line": { + "color": "rgba(255,255,255,0)" + }, + "marker": { + "color": "#636efa" + }, + "name": "", + "offsetgroup": "", + "orientation": "h", + "pointpos": 0, + "showlegend": false, + "type": "box", + "x": [ + "2024-07-20T12:46:27.013000" + ], + "x0": " ", + "xaxis": "x", + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "boxmode": "group", + "legend": { + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Model Creation Timestamp" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "creation_timestamp" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.strip(\n", + " models,\n", + " x=\"creation_timestamp\",\n", + " hover_name=\"name\",\n", + " hover_data=models.columns,\n", + " title=\"Model Creation Timestamp\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "all", + "customdata": [ + [ + { + "Champion": "3" + }, + "", + "2024-07-21T14:08:17.804000", + "bikes", + {} + ] + ], + "fillcolor": "rgba(255,255,255,0)", + "hoveron": "points", + "hovertemplate": "%{hovertext}

    creation_timestamp=%{x}
    aliases=%{customdata[0]}
    description=%{customdata[1]}
    last_updated_timestamp=%{customdata[2]}
    name=%{customdata[3]}
    tags=%{customdata[4]}", + "hovertext": [ + "bikes" + ], + "legendgroup": "", + "line": { + "color": "rgba(255,255,255,0)" + }, + "marker": { + "color": "#636efa" + }, + "name": "", + "offsetgroup": "", + "orientation": "h", + "pointpos": 0, + "showlegend": false, + "type": "box", + "x": [ + "2024-07-20T12:46:27.013000" + ], + "x0": " ", + "xaxis": "x", + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "boxmode": "group", + "legend": { + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Model Creation Timestamp" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "creation_timestamp" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.strip(\n", + " models,\n", + " x=\"creation_timestamp\",\n", + " hover_name=\"name\",\n", + " hover_data=models.columns,\n", + " title=\"Model Creation Timestamp\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "all", + "customdata": [ + [ + "Champion", + "None", + "", + "2024-07-21T14:08:12.799000", + "bikes", + "d37276201a5b4ff98addae88f5ed1a34", + "", + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d37276201a5b4ff98addae88f5ed1a34/artifacts/model", + "READY", + "", + {}, + "", + "3" + ], + [ + null, + "None", + "", + "2024-07-20T12:52:29.627000", + "bikes", + "b428ae1513a54e16a5bf3959cf3eeb8e", + "", + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/b428ae1513a54e16a5bf3959cf3eeb8e/artifacts/model", + "READY", + "", + {}, + "", + "2" + ], + [ + null, + "None", + "", + "2024-07-20T12:46:27.017000", + "bikes", + "795eace5f76a4fe4af3754460b5e25e4", + "", + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/795eace5f76a4fe4af3754460b5e25e4/artifacts/model", + "READY", + "", + {}, + "", + "1" + ] + ], + "fillcolor": "rgba(255,255,255,0)", + "hoveron": "points", + "hovertemplate": "%{hovertext}

    name=%{customdata[4]}
    creation_timestamp=%{x}
    aliases=%{customdata[0]}
    current_stage=%{customdata[1]}
    description=%{customdata[2]}
    last_updated_timestamp=%{customdata[3]}
    run_id=%{customdata[5]}
    run_link=%{customdata[6]}
    source=%{customdata[7]}
    status=%{customdata[8]}
    status_message=%{customdata[9]}
    tags=%{customdata[10]}
    user_id=%{customdata[11]}
    version=%{customdata[12]}", + "hovertext": [ + "bikes", + "bikes", + "bikes" + ], + "legendgroup": "bikes", + "line": { + "color": "rgba(255,255,255,0)" + }, + "marker": { + "color": "#636efa" + }, + "name": "bikes", + "offsetgroup": "bikes", + "orientation": "h", + "pointpos": 0, + "showlegend": true, + "type": "box", + "x": [ + "2024-07-21T14:08:12.799000", + "2024-07-20T12:52:29.627000", + "2024-07-20T12:46:27.017000" + ], + "x0": " ", + "xaxis": "x", + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "boxmode": "group", + "legend": { + "title": { + "text": "name" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Version Creation Timestamp" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "creation_timestamp" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.strip(\n", + " versions,\n", + " x=\"creation_timestamp\",\n", + " color=\"name\",\n", + " hover_name=\"name\",\n", + " hover_data=versions.columns,\n", + " title=\"Version Creation Timestamp\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "all", + "customdata": [ + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/2f6920e2006841d7a72567e9f25df89f/artifacts", + "2024-07-21T14:08:59.757000", + "562757566260573932", + "active", + "2f6920e2006841d7a72567e9f25df89f", + "Explanations", + "2f6920e2006841d7a72567e9f25df89f", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/explanations.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Explanations", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Explanations", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/94fa6a85393745f9b8bb5cac75f865e4/artifacts", + "2024-07-21T14:08:28.634000", + "562757566260573932", + "active", + "94fa6a85393745f9b8bb5cac75f865e4", + "Evaluations", + "94fa6a85393745f9b8bb5cac75f865e4", + "FINISHED", + "fmind", + { + "example_count": 13903, + "max_error": 4294967295, + "mean_absolute_error": 2044457567.3205063, + "mean_absolute_percentage_error": 55189262.03890929, + "mean_on_target": 174.63914263108683, + "mean_squared_error": 296.66338200388407, + "r2_score": 0.9893562621162568, + "root_mean_squared_error": 17.223918892165166, + "sum_on_target": 2428008 + }, + { + "conf_file": "confs/evaluations.yaml" + }, + { + "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"8fce50ebd83a4de3af6a7245453472d3\"}]", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Evaluations", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Evaluations", + "virtualenv", + "local", + "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"8fce50ebd83a4de3af6a7245453472d3\"}]", + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/da669581953a4a46ab84efaabc8f3e92/artifacts", + "2024-07-21T14:08:23.205000", + "562757566260573932", + "active", + "da669581953a4a46ab84efaabc8f3e92", + "Inference", + "da669581953a4a46ab84efaabc8f3e92", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/inference.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Inference", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Inference", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/023a21263eaa43228b324fb432932cf4/artifacts", + "2024-07-21T14:08:18.412000", + "562757566260573932", + "active", + "023a21263eaa43228b324fb432932cf4", + "Promotion", + "023a21263eaa43228b324fb432932cf4", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/promotion.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Promotion", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Promotion", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d37276201a5b4ff98addae88f5ed1a34/artifacts", + "2024-07-21T14:08:13.567000", + "562757566260573932", + "active", + "d37276201a5b4ff98addae88f5ed1a34", + "Training", + "d37276201a5b4ff98addae88f5ed1a34", + "FINISHED", + "fmind", + { + "mean_squared_error": -1786.7527777777777, + "system/cpu_utilization_percentage": 0, + "system/disk_available_megabytes": 34541.6, + "system/disk_usage_megabytes": 71449.6, + "system/disk_usage_percentage": 67.4, + "system/network_receive_megabytes": 0, + "system/network_transmit_megabytes": 0, + "system/system_memory_usage_megabytes": 4388.8, + "system/system_memory_usage_percentage": 29.1, + "training_mean_absolute_error": 6.8051192198812736, + "training_mean_squared_error": 124.51054615575788, + "training_r2_score": 0.9948851411922456, + "training_root_mean_squared_error": 11.158429376742852, + "training_score": 0.9948851411922456 + }, + { + "conf_file": "confs/training.yaml", + "memory": "None", + "regressor": "RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42)", + "regressor__bootstrap": "True", + "regressor__ccp_alpha": "0.0", + "regressor__criterion": "squared_error", + "regressor__max_depth": "20", + "regressor__max_features": "1.0", + "regressor__max_leaf_nodes": "None", + "regressor__max_samples": "None", + "regressor__min_impurity_decrease": "0.0", + "regressor__min_samples_leaf": "1", + "regressor__min_samples_split": "2", + "regressor__min_weight_fraction_leaf": "0.0", + "regressor__monotonic_cst": "None", + "regressor__n_estimators": "200", + "regressor__n_jobs": "None", + "regressor__oob_score": "False", + "regressor__random_state": "42", + "regressor__verbose": "0", + "regressor__warm_start": "False", + "steps": "[('transformer', ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])), ('regressor', RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42))]", + "transformer": "ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])", + "transformer__categoricals": "OneHotEncoder(handle_unknown='ignore', sparse_output=False)", + "transformer__categoricals__categories": "auto", + "transformer__categoricals__drop": "None", + "transformer__categoricals__dtype": "", + "transformer__categoricals__feature_name_combiner": "concat", + "transformer__categoricals__handle_unknown": "ignore", + "transformer__categoricals__max_categories": "None", + "transformer__categoricals__min_frequency": "None", + "transformer__categoricals__sparse_output": "False", + "transformer__n_jobs": "None", + "transformer__numericals": "passthrough", + "transformer__remainder": "drop", + "transformer__sparse_threshold": "0.3", + "transformer__transformer_weights": "None", + "transformer__transformers": "[('categoricals', OneHotEncoder(handle_unknown='ignore', sparse_output=False), ['season', 'weathersit']), ('numericals', 'passthrough', ['yr', 'mnth', 'hr', 'holiday', 'weekday', 'workingday', 'temp', 'atemp', 'hum', 'windspeed', 'casual'])]", + "transformer__verbose": "False", + "transformer__verbose_feature_names_out": "True", + "verbose": "False" + }, + { + "estimator_class": "sklearn.pipeline.Pipeline", + "estimator_name": "Pipeline", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:05.047879\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e007980b27a14ec787fc3860c945fbe3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:08.647799\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"8fce50ebd83a4de3af6a7245453472d3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Training", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Training", + "virtualenv", + "local", + null, + "Pipeline", + "sklearn.pipeline.Pipeline", + "[{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:05.047879\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e007980b27a14ec787fc3860c945fbe3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:08.647799\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"8fce50ebd83a4de3af6a7245453472d3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/2319443aa2dc4b93b3b42acd925b7070/artifacts", + "2024-07-21T14:07:52.347000", + "562757566260573932", + "active", + "2319443aa2dc4b93b3b42acd925b7070", + "nimble-grouse-107", + "2319443aa2dc4b93b3b42acd925b7070", + "FINISHED", + "fmind", + { + "mean_fit_time": 2.335359275341034, + "mean_score_time": 0.04631972312927246, + "mean_test_score": -5517.252604166667, + "rank_test_score": 1, + "std_fit_time": 0.3590436626364938, + "std_score_time": 0.004401981271699938, + "std_test_score": 1613.520146542553 + }, + { + "max_depth": "7", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "e9c8cff5399044b0a2637c0c0ce6689a", + "mlflow.runName": "nimble-grouse-107", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + null, + null, + "nimble-grouse-107", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "e9c8cff5399044b0a2637c0c0ce6689a" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/37dc2776a7ea41d08c1350d9569813c6/artifacts", + "2024-07-21T14:07:52.347000", + "562757566260573932", + "active", + "37dc2776a7ea41d08c1350d9569813c6", + "youthful-dog-682", + "37dc2776a7ea41d08c1350d9569813c6", + "FINISHED", + "fmind", + { + "mean_fit_time": 1.6250869631767273, + "mean_score_time": 0.039045751094818115, + "mean_test_score": -8287.860416666666, + "rank_test_score": 2, + "std_fit_time": 0.30070612377456823, + "std_score_time": 0.0034828563269759423, + "std_test_score": 1045.7595024691313 + }, + { + "max_depth": "5", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "e9c8cff5399044b0a2637c0c0ce6689a", + "mlflow.runName": "youthful-dog-682", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + null, + null, + "youthful-dog-682", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "e9c8cff5399044b0a2637c0c0ce6689a" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/54f8d9d33515402b875a1e36f7aa0319/artifacts", + "2024-07-21T14:07:52.347000", + "562757566260573932", + "active", + "54f8d9d33515402b875a1e36f7aa0319", + "hilarious-frog-164", + "54f8d9d33515402b875a1e36f7aa0319", + "FINISHED", + "fmind", + { + "mean_fit_time": 1.0542340278625488, + "mean_score_time": 0.034685373306274414, + "mean_test_score": -16644.957118055558, + "rank_test_score": 3, + "std_fit_time": 0.1530062338353499, + "std_score_time": 0.0005786305205599668, + "std_test_score": 5315.459715152708 + }, + { + "max_depth": "3", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "e9c8cff5399044b0a2637c0c0ce6689a", + "mlflow.runName": "hilarious-frog-164", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + null, + null, + "hilarious-frog-164", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "e9c8cff5399044b0a2637c0c0ce6689a" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/e9c8cff5399044b0a2637c0c0ce6689a/artifacts", + "2024-07-21T14:07:53.274000", + "562757566260573932", + "active", + "e9c8cff5399044b0a2637c0c0ce6689a", + "Tuning", + "e9c8cff5399044b0a2637c0c0ce6689a", + "FINISHED", + "fmind", + { + "best_cv_score": -5517.252604166667, + "system/cpu_utilization_percentage": 7.4, + "system/disk_available_megabytes": 34541.7, + "system/disk_usage_megabytes": 71449.5, + "system/disk_usage_percentage": 67.4, + "system/network_receive_megabytes": 8.62606500000004, + "system/network_transmit_megabytes": 8.622220999999996, + "system/system_memory_usage_megabytes": 4269.4, + "system/system_memory_usage_percentage": 28.3, + "training_score": -1951.0630079838884 + }, + { + "best_max_depth": "7", + "conf_file": "confs/tuning.yaml", + "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", + "error_score": "raise", + "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", + "n_jobs": "None", + "param_grid": "{'max_depth': [3, 5, 7]}", + "pre_dispatch": "2*n_jobs", + "refit": "True", + "return_train_score": "False", + "scoring": "", + "verbose": "3" + }, + { + "estimator_class": "sklearn.model_selection._search.GridSearchCV", + "estimator_name": "GridSearchCV", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:07:47.385038\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"d1707c2f4b8346818f7747a0d7ab01ad\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-21 14:07:50.180719\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"982e3a8c13734ff58f0ff20b1f759967\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Tuning", + "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Tuning", + "virtualenv", + "local", + null, + "GridSearchCV", + "sklearn.model_selection._search.GridSearchCV", + "[{\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:07:47.385038\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"d1707c2f4b8346818f7747a0d7ab01ad\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-21 14:07:50.180719\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"982e3a8c13734ff58f0ff20b1f759967\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d0e46ae61af6441b856375a09e30594e/artifacts", + "2024-07-20T12:53:12.588000", + "562757566260573932", + "active", + "d0e46ae61af6441b856375a09e30594e", + "EXPLANATIONS", + "d0e46ae61af6441b856375a09e30594e", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/explanations.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "EXPLANATIONS", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "EXPLANATIONS", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d54dd7a19b10422191be93d1cc53213a/artifacts", + "2024-07-20T12:52:42.983000", + "562757566260573932", + "active", + "d54dd7a19b10422191be93d1cc53213a", + "EVALUATIONS", + "d54dd7a19b10422191be93d1cc53213a", + "FINISHED", + "fmind", + { + "example_count": 13903, + "max_error": 4294967295, + "mean_absolute_error": 2044457567.3205063, + "mean_absolute_percentage_error": 55189262.03890929, + "mean_on_target": 174.63914263108683, + "mean_squared_error": 296.66338200388407, + "r2_score": 0.9893562621162568, + "root_mean_squared_error": 17.223918892165166, + "sum_on_target": 2428008 + }, + { + "conf_file": "confs/evaluations.yaml" + }, + { + "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"d8305c29a5a54e0caed2ed9413d739d7\"}]", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "EVALUATIONS", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "EVALUATIONS", + "virtualenv", + "local", + "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"d8305c29a5a54e0caed2ed9413d739d7\"}]", + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/7bd2297aa53b47a6b8bca64e9b4c4071/artifacts", + "2024-07-20T12:52:38.115000", + "562757566260573932", + "active", + "7bd2297aa53b47a6b8bca64e9b4c4071", + "INFERENCE", + "7bd2297aa53b47a6b8bca64e9b4c4071", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/inference.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "INFERENCE", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "INFERENCE", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/87d4d36b5b034e538dff16e40e80a5d9/artifacts", + "2024-07-20T12:52:33.932000", + "562757566260573932", + "active", + "87d4d36b5b034e538dff16e40e80a5d9", + "PROMOTION", + "87d4d36b5b034e538dff16e40e80a5d9", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/promotion.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "PROMOTION", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "PROMOTION", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/b428ae1513a54e16a5bf3959cf3eeb8e/artifacts", + "2024-07-20T12:52:30.318000", + "562757566260573932", + "active", + "b428ae1513a54e16a5bf3959cf3eeb8e", + "TRAINING", + "b428ae1513a54e16a5bf3959cf3eeb8e", + "FINISHED", + "fmind", + { + "mean_squared_error": -1786.7527777777777, + "system/cpu_utilization_percentage": 0, + "system/disk_available_megabytes": 35065.7, + "system/disk_usage_megabytes": 70918.1, + "system/disk_usage_percentage": 66.9, + "system/network_receive_megabytes": 0, + "system/network_transmit_megabytes": 0, + "system/system_memory_usage_megabytes": 3441.1, + "system/system_memory_usage_percentage": 22.8, + "training_mean_absolute_error": 6.8051192198812736, + "training_mean_squared_error": 124.51054615575788, + "training_r2_score": 0.9948851411922456, + "training_root_mean_squared_error": 11.158429376742852, + "training_score": 0.9948851411922456 + }, + { + "conf_file": "confs/training.yaml", + "memory": "None", + "regressor": "RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42)", + "regressor__bootstrap": "True", + "regressor__ccp_alpha": "0.0", + "regressor__criterion": "squared_error", + "regressor__max_depth": "20", + "regressor__max_features": "1.0", + "regressor__max_leaf_nodes": "None", + "regressor__max_samples": "None", + "regressor__min_impurity_decrease": "0.0", + "regressor__min_samples_leaf": "1", + "regressor__min_samples_split": "2", + "regressor__min_weight_fraction_leaf": "0.0", + "regressor__monotonic_cst": "None", + "regressor__n_estimators": "200", + "regressor__n_jobs": "None", + "regressor__oob_score": "False", + "regressor__random_state": "42", + "regressor__verbose": "0", + "regressor__warm_start": "False", + "steps": "[('transformer', ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])), ('regressor', RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42))]", + "transformer": "ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])", + "transformer__categoricals": "OneHotEncoder(handle_unknown='ignore', sparse_output=False)", + "transformer__categoricals__categories": "auto", + "transformer__categoricals__drop": "None", + "transformer__categoricals__dtype": "", + "transformer__categoricals__feature_name_combiner": "concat", + "transformer__categoricals__handle_unknown": "ignore", + "transformer__categoricals__max_categories": "None", + "transformer__categoricals__min_frequency": "None", + "transformer__categoricals__sparse_output": "False", + "transformer__n_jobs": "None", + "transformer__numericals": "passthrough", + "transformer__remainder": "drop", + "transformer__sparse_threshold": "0.3", + "transformer__transformer_weights": "None", + "transformer__transformers": "[('categoricals', OneHotEncoder(handle_unknown='ignore', sparse_output=False), ['season', 'weathersit']), ('numericals', 'passthrough', ['yr', 'mnth', 'hr', 'holiday', 'weekday', 'workingday', 'temp', 'atemp', 'hum', 'windspeed', 'casual'])]", + "transformer__verbose": "False", + "transformer__verbose_feature_names_out": "True", + "verbose": "False" + }, + { + "estimator_class": "sklearn.pipeline.Pipeline", + "estimator_name": "Pipeline", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:24.146985\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"6bf30a1cf60945d5837e380b08b18783\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:26.416323\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"d8305c29a5a54e0caed2ed9413d739d7\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "TRAINING", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "TRAINING", + "virtualenv", + "local", + null, + "Pipeline", + "sklearn.pipeline.Pipeline", + "[{\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:24.146985\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"6bf30a1cf60945d5837e380b08b18783\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:26.416323\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"d8305c29a5a54e0caed2ed9413d739d7\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/515ecd02027a4f19a43b586a0e19b221/artifacts", + "2024-07-20T12:52:12.773000", + "562757566260573932", + "active", + "515ecd02027a4f19a43b586a0e19b221", + "TUNING", + "515ecd02027a4f19a43b586a0e19b221", + "FINISHED", + "fmind", + { + "best_cv_score": -5517.252604166667, + "system/cpu_utilization_percentage": 6.5, + "system/disk_available_megabytes": 35065.7, + "system/disk_usage_megabytes": 70918.1, + "system/disk_usage_percentage": 66.9, + "system/network_receive_megabytes": 0.007126000000027943, + "system/network_transmit_megabytes": 0.007125999999999522, + "system/system_memory_usage_megabytes": 3465.2, + "system/system_memory_usage_percentage": 23, + "training_score": -1951.0630079838884 + }, + { + "best_max_depth": "7", + "conf_file": "confs/tuning.yaml", + "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", + "error_score": "raise", + "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", + "n_jobs": "None", + "param_grid": "{'max_depth': [3, 5, 7]}", + "pre_dispatch": "2*n_jobs", + "refit": "True", + "return_train_score": "False", + "scoring": "", + "verbose": "3" + }, + { + "estimator_class": "sklearn.model_selection._search.GridSearchCV", + "estimator_name": "GridSearchCV", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:07.924106\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"de91989dcdc246068666a87d36e3287b\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:52:10.363319\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"8f4374171a1347dd88c01b46e4196a8a\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "TUNING", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "TUNING", + "virtualenv", + "local", + null, + "GridSearchCV", + "sklearn.model_selection._search.GridSearchCV", + "[{\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:07.924106\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"de91989dcdc246068666a87d36e3287b\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:52:10.363319\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"8f4374171a1347dd88c01b46e4196a8a\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/5f28aabdcccc494491f27e3700ee75dd/artifacts", + "2024-07-20T12:52:12.230000", + "562757566260573932", + "active", + "5f28aabdcccc494491f27e3700ee75dd", + "treasured-shrimp-728", + "5f28aabdcccc494491f27e3700ee75dd", + "FINISHED", + "fmind", + { + "mean_fit_time": 0.9817702770233154, + "mean_score_time": 0.03579825162887573, + "mean_test_score": -16644.957118055558, + "rank_test_score": 3, + "std_fit_time": 0.15158578334750608, + "std_score_time": 0.006110784505381323, + "std_test_score": 5315.459715152708 + }, + { + "max_depth": "3", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "515ecd02027a4f19a43b586a0e19b221", + "mlflow.runName": "treasured-shrimp-728", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + null, + null, + "treasured-shrimp-728", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "515ecd02027a4f19a43b586a0e19b221" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/81386b0b3ac842e4a995576f092bbac5/artifacts", + "2024-07-20T12:52:12.230000", + "562757566260573932", + "active", + "81386b0b3ac842e4a995576f092bbac5", + "angry-cub-96", + "81386b0b3ac842e4a995576f092bbac5", + "FINISHED", + "fmind", + { + "mean_fit_time": 1.510183572769165, + "mean_score_time": 0.03509628772735596, + "mean_test_score": -8287.860416666666, + "rank_test_score": 2, + "std_fit_time": 0.23992070497194215, + "std_score_time": 0.0011799521253510422, + "std_test_score": 1045.7595024691313 + }, + { + "max_depth": "5", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "515ecd02027a4f19a43b586a0e19b221", + "mlflow.runName": "angry-cub-96", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + null, + null, + "angry-cub-96", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "515ecd02027a4f19a43b586a0e19b221" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/a69515beaf3047b5816de516de1ecb83/artifacts", + "2024-07-20T12:52:12.230000", + "562757566260573932", + "active", + "a69515beaf3047b5816de516de1ecb83", + "adaptable-gull-964", + "a69515beaf3047b5816de516de1ecb83", + "FINISHED", + "fmind", + { + "mean_fit_time": 2.1361553072929382, + "mean_score_time": 0.039887070655822754, + "mean_test_score": -5517.252604166667, + "rank_test_score": 1, + "std_fit_time": 0.3223141495079878, + "std_score_time": 0.0009398759994274763, + "std_test_score": 1613.520146542553 + }, + { + "max_depth": "7", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "515ecd02027a4f19a43b586a0e19b221", + "mlflow.runName": "adaptable-gull-964", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + null, + null, + "adaptable-gull-964", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "515ecd02027a4f19a43b586a0e19b221" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/f07658777ac84b83a238ab67713e31b2/artifacts", + "2024-07-20T12:47:10.242000", + "562757566260573932", + "active", + "f07658777ac84b83a238ab67713e31b2", + "explanations", + "f07658777ac84b83a238ab67713e31b2", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/explanations.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "explanations", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "explanations", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/b8e7d22143cd4330a42af7d4896549ad/artifacts", + "2024-07-20T12:46:40.437000", + "562757566260573932", + "active", + "b8e7d22143cd4330a42af7d4896549ad", + "evaluations", + "b8e7d22143cd4330a42af7d4896549ad", + "FINISHED", + "fmind", + { + "example_count": 13903, + "max_error": 4294967295, + "mean_absolute_error": 2044457567.3205063, + "mean_absolute_percentage_error": 55189262.03890929, + "mean_on_target": 174.63914263108683, + "mean_squared_error": 296.66338200388407, + "r2_score": 0.9893562621162568, + "root_mean_squared_error": 17.223918892165166, + "sum_on_target": 2428008 + }, + { + "conf_file": "confs/evaluations.yaml" + }, + { + "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"b64cc85729ce4b2abf7546f49640eacf\"}]", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "evaluations", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "evaluations", + "virtualenv", + "local", + "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"b64cc85729ce4b2abf7546f49640eacf\"}]", + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/e130d952a9fa4865aac2928db108d233/artifacts", + "2024-07-20T12:46:35.412000", + "562757566260573932", + "active", + "e130d952a9fa4865aac2928db108d233", + "inference", + "e130d952a9fa4865aac2928db108d233", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/inference.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "inference", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "inference", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/0ab3086f66e84ac79ef14ec1a5680922/artifacts", + "2024-07-20T12:46:31.253000", + "562757566260573932", + "active", + "0ab3086f66e84ac79ef14ec1a5680922", + "promotion", + "0ab3086f66e84ac79ef14ec1a5680922", + "FINISHED", + "fmind", + {}, + { + "conf_file": "confs/promotion.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "promotion", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "promotion", + "virtualenv", + "local", + null, + null, + null, + null, + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/795eace5f76a4fe4af3754460b5e25e4/artifacts", + "2024-07-20T12:46:27.543000", + "562757566260573932", + "active", + "795eace5f76a4fe4af3754460b5e25e4", + "training", + "795eace5f76a4fe4af3754460b5e25e4", + "FINISHED", + "fmind", + { + "mean_squared_error": -1786.7527777777777, + "system/cpu_utilization_percentage": 0, + "system/disk_available_megabytes": 35587.9, + "system/disk_usage_megabytes": 70394.1, + "system/disk_usage_percentage": 66.4, + "system/network_receive_megabytes": 0, + "system/network_transmit_megabytes": 0, + "system/system_memory_usage_megabytes": 9466.8, + "system/system_memory_usage_percentage": 62.8, + "training_mean_absolute_error": 6.8051192198812736, + "training_mean_squared_error": 124.51054615575788, + "training_r2_score": 0.9948851411922456, + "training_root_mean_squared_error": 11.158429376742852, + "training_score": 0.9948851411922456 + }, + { + "conf_file": "confs/training.yaml", + "memory": "None", + "regressor": "RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42)", + "regressor__bootstrap": "True", + "regressor__ccp_alpha": "0.0", + "regressor__criterion": "squared_error", + "regressor__max_depth": "20", + "regressor__max_features": "1.0", + "regressor__max_leaf_nodes": "None", + "regressor__max_samples": "None", + "regressor__min_impurity_decrease": "0.0", + "regressor__min_samples_leaf": "1", + "regressor__min_samples_split": "2", + "regressor__min_weight_fraction_leaf": "0.0", + "regressor__monotonic_cst": "None", + "regressor__n_estimators": "200", + "regressor__n_jobs": "None", + "regressor__oob_score": "False", + "regressor__random_state": "42", + "regressor__verbose": "0", + "regressor__warm_start": "False", + "steps": "[('transformer', ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])), ('regressor', RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42))]", + "transformer": "ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])", + "transformer__categoricals": "OneHotEncoder(handle_unknown='ignore', sparse_output=False)", + "transformer__categoricals__categories": "auto", + "transformer__categoricals__drop": "None", + "transformer__categoricals__dtype": "", + "transformer__categoricals__feature_name_combiner": "concat", + "transformer__categoricals__handle_unknown": "ignore", + "transformer__categoricals__max_categories": "None", + "transformer__categoricals__min_frequency": "None", + "transformer__categoricals__sparse_output": "False", + "transformer__n_jobs": "None", + "transformer__numericals": "passthrough", + "transformer__remainder": "drop", + "transformer__sparse_threshold": "0.3", + "transformer__transformer_weights": "None", + "transformer__transformers": "[('categoricals', OneHotEncoder(handle_unknown='ignore', sparse_output=False), ['season', 'weathersit']), ('numericals', 'passthrough', ['yr', 'mnth', 'hr', 'holiday', 'weekday', 'workingday', 'temp', 'atemp', 'hum', 'windspeed', 'casual'])]", + "transformer__verbose": "False", + "transformer__verbose_feature_names_out": "True", + "verbose": "False" + }, + { + "estimator_class": "sklearn.pipeline.Pipeline", + "estimator_name": "Pipeline", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:21.035281\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"3cd314ac3cdb4c8eb2a7b60dd2d396df\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:23.203673\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"b64cc85729ce4b2abf7546f49640eacf\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "training", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "training", + "virtualenv", + "local", + null, + "Pipeline", + "sklearn.pipeline.Pipeline", + "[{\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:21.035281\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"3cd314ac3cdb4c8eb2a7b60dd2d396df\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:23.203673\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"b64cc85729ce4b2abf7546f49640eacf\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/1bfdbbf6df3d4b899ab48941e58fa4de/artifacts", + "2024-07-20T12:46:03.231000", + "562757566260573932", + "active", + "1bfdbbf6df3d4b899ab48941e58fa4de", + "learned-mole-85", + "1bfdbbf6df3d4b899ab48941e58fa4de", + "FINISHED", + "fmind", + { + "mean_fit_time": 4.399524390697479, + "mean_score_time": 0.14234960079193115, + "mean_test_score": -8287.860416666666, + "rank_test_score": 2, + "std_fit_time": 0.6041601907827593, + "std_score_time": 0.008689780141727426, + "std_test_score": 1045.7595024691313 + }, + { + "max_depth": "5", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "bab549993e48428fb3f5a0b4b83d5645", + "mlflow.runName": "learned-mole-85", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + null, + null, + "learned-mole-85", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "bab549993e48428fb3f5a0b4b83d5645" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/bab549993e48428fb3f5a0b4b83d5645/artifacts", + "2024-07-20T12:46:03.878000", + "562757566260573932", + "active", + "bab549993e48428fb3f5a0b4b83d5645", + "tuning", + "bab549993e48428fb3f5a0b4b83d5645", + "FINISHED", + "fmind", + { + "best_cv_score": -5517.252604166667, + "system/cpu_utilization_percentage": 56.6, + "system/disk_available_megabytes": 35635.6, + "system/disk_usage_megabytes": 70345.4, + "system/disk_usage_percentage": 66.4, + "system/network_receive_megabytes": 0.03039199999994935, + "system/network_transmit_megabytes": 0.48478400000000477, + "system/system_memory_usage_megabytes": 9749, + "system/system_memory_usage_percentage": 64.6, + "training_score": -1951.0630079838884 + }, + { + "best_max_depth": "7", + "conf_file": "confs/tuning.yaml", + "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", + "error_score": "raise", + "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", + "n_jobs": "None", + "param_grid": "{'max_depth': [3, 5, 7]}", + "pre_dispatch": "2*n_jobs", + "refit": "True", + "return_train_score": "False", + "scoring": "", + "verbose": "3" + }, + { + "estimator_class": "sklearn.model_selection._search.GridSearchCV", + "estimator_name": "GridSearchCV", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:45:56.543992\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e78ada09386b4e6b98b52cbaae8196e6\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:46:00.949836\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"b84db06a9be445a3a4c35cd20cdc5532\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "tuning", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "tuning", + "virtualenv", + "local", + null, + "GridSearchCV", + "sklearn.model_selection._search.GridSearchCV", + "[{\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:45:56.543992\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e78ada09386b4e6b98b52cbaae8196e6\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:46:00.949836\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"b84db06a9be445a3a4c35cd20cdc5532\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + null, + null + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/bc6a629fbacf4dfb93d73cf49d2fadb2/artifacts", + "2024-07-20T12:46:03.231000", + "562757566260573932", + "active", + "bc6a629fbacf4dfb93d73cf49d2fadb2", + "gentle-jay-790", + "bc6a629fbacf4dfb93d73cf49d2fadb2", + "FINISHED", + "fmind", + { + "mean_fit_time": 3.0013614892959595, + "mean_score_time": 0.18937814235687256, + "mean_test_score": -16644.957118055558, + "rank_test_score": 3, + "std_fit_time": 0.48890581262807953, + "std_score_time": 0.06921257470224487, + "std_test_score": 5315.459715152708 + }, + { + "max_depth": "3", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "bab549993e48428fb3f5a0b4b83d5645", + "mlflow.runName": "gentle-jay-790", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + null, + null, + "gentle-jay-790", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "bab549993e48428fb3f5a0b4b83d5645" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/e7a424df7a474652984ebab24398f78e/artifacts", + "2024-07-20T12:46:03.231000", + "562757566260573932", + "active", + "e7a424df7a474652984ebab24398f78e", + "clean-sloth-537", + "e7a424df7a474652984ebab24398f78e", + "FINISHED", + "fmind", + { + "mean_fit_time": 3.5007389187812805, + "mean_score_time": 0.05425143241882324, + "mean_test_score": -5517.252604166667, + "rank_test_score": 1, + "std_fit_time": 0.3245513505947697, + "std_score_time": 0.005157635720925865, + "std_test_score": 1613.520146542553 + }, + { + "max_depth": "7", + "n_estimators": "200", + "random_state": "42" + }, + { + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "bab549993e48428fb3f5a0b4b83d5645", + "mlflow.runName": "clean-sloth-537", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", + "mlflow.user": "fmind" + }, + "fmind", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", + null, + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + null, + null, + "clean-sloth-537", + null, + null, + null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + "sklearn", + "bab549993e48428fb3f5a0b4b83d5645" + ], + [ + "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/6f23412a2dd34ff4944cad9d545448f1/artifacts", + null, + "562757566260573932", + "active", + "6f23412a2dd34ff4944cad9d545448f1", + "polite-snail-973", + "6f23412a2dd34ff4944cad9d545448f1", + "RUNNING", + "fmind", + {}, + { + "conf_file": "confs/tuning.yaml" + }, + { + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "polite-snail-973", + "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", + "mlflow.user": "fmind" + }, + "fmind", + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "50ee7202afcbac4516be893b3c96c5434a5fd05b", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "polite-snail-973", + "virtualenv", + null, + null, + null, + null, + null, + null, + null + ] + ], + "fillcolor": "rgba(255,255,255,0)", + "hoveron": "points", + "hovertemplate": "%{hovertext}

    experiment_id=%{customdata[2]}
    start_time=%{x}
    artifact_uri=%{customdata[0]}
    end_time=%{customdata[1]}
    lifecycle_stage=%{customdata[3]}
    run_id=%{customdata[4]}
    run_name=%{customdata[5]}
    run_uuid=%{customdata[6]}
    status=%{customdata[7]}
    user_id=%{customdata[8]}
    metrics=%{customdata[9]}
    params=%{customdata[10]}
    tags=%{customdata[11]}
    mlflow.user=%{customdata[12]}
    mlflow.source.name=%{customdata[13]}
    mlflow.source.type=%{customdata[14]}
    mlflow.project.entryPoint=%{customdata[15]}
    mlflow.source.git.commit=%{customdata[16]}
    mlflow.source.git.repoURL=%{customdata[17]}
    mlflow.gitRepoURL=%{customdata[18]}
    mlflow.runName=%{customdata[19]}
    mlflow.project.env=%{customdata[20]}
    mlflow.project.backend=%{customdata[21]}
    mlflow.datasets=%{customdata[22]}
    estimator_name=%{customdata[23]}
    estimator_class=%{customdata[24]}
    mlflow.log-model.history=%{customdata[25]}
    mlflow.autologging=%{customdata[26]}
    mlflow.parentRunId=%{customdata[27]}", + "hovertext": [ + "Explanations", + "Evaluations", + "Inference", + "Promotion", + "Training", + "nimble-grouse-107", + "youthful-dog-682", + "hilarious-frog-164", + "Tuning", + "EXPLANATIONS", + "EVALUATIONS", + "INFERENCE", + "PROMOTION", + "TRAINING", + "TUNING", + "treasured-shrimp-728", + "angry-cub-96", + "adaptable-gull-964", + "explanations", + "evaluations", + "inference", + "promotion", + "training", + "learned-mole-85", + "tuning", + "gentle-jay-790", + "clean-sloth-537", + "polite-snail-973" + ], + "legendgroup": "562757566260573932", + "line": { + "color": "rgba(255,255,255,0)" + }, + "marker": { + "color": "#636efa" + }, + "name": "562757566260573932", + "offsetgroup": "562757566260573932", + "orientation": "h", + "pointpos": 0, + "showlegend": true, + "type": "box", + "x": [ + "2024-07-21T14:08:29.817000", + "2024-07-21T14:08:24.395000", + "2024-07-21T14:08:19.775000", + "2024-07-21T14:08:15.431000", + "2024-07-21T14:07:54.473000", + "2024-07-21T14:07:19.282000", + "2024-07-21T14:07:19.282000", + "2024-07-21T14:07:19.282000", + "2024-07-21T14:07:19.282000", + "2024-07-20T12:52:44.033000", + "2024-07-20T12:52:39.147000", + "2024-07-20T12:52:35.057000", + "2024-07-20T12:52:31.479000", + "2024-07-20T12:52:13.797000", + "2024-07-20T12:51:43.548000", + "2024-07-20T12:51:43.548000", + "2024-07-20T12:51:43.548000", + "2024-07-20T12:51:43.548000", + "2024-07-20T12:46:41.664000", + "2024-07-20T12:46:36.460000", + "2024-07-20T12:46:32.379000", + "2024-07-20T12:46:28.853000", + "2024-07-20T12:46:05.345000", + "2024-07-20T12:44:40.852000", + "2024-07-20T12:44:40.852000", + "2024-07-20T12:44:40.852000", + "2024-07-20T12:44:40.852000", + "2024-07-20T12:43:59.876000" + ], + "x0": " ", + "xaxis": "x", + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "boxmode": "group", + "legend": { + "title": { + "text": "experiment_id" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Run Start Time" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "start_time" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ] + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.strip(\n", + " runs,\n", + " x=\"start_time\",\n", + " color=\"experiment_id\",\n", + " hover_name=\"run_name\",\n", + " hover_data=runs.columns,\n", + " title=\"Run Start Time\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "hovertemplate": "estimator_class=%{x}
    count=%{y}", + "legendgroup": "", + "marker": { + "color": "#636efa", + "pattern": { + "shape": "" + } + }, + "name": "", + "offsetgroup": "", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": [ + null, + null, + null, + null, + "sklearn.pipeline.Pipeline", + "bikes.core.models.BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + "sklearn.model_selection._search.GridSearchCV", + null, + null, + null, + null, + "sklearn.pipeline.Pipeline", + "sklearn.model_selection._search.GridSearchCV", + "bikes.core.models.BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null, + null, + null, + null, + "sklearn.pipeline.Pipeline", + "bikes.core.models.BaselineSklearnModel", + "sklearn.model_selection._search.GridSearchCV", + "bikes.core.models.BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", + null + ], + "xaxis": "x", + "y": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "yaxis": "y" + } + ], + "layout": { + "barmode": "relative", + "legend": { + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Run Estimator Class Distribution" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "estimator_class" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "count" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "px.bar(runs, x=\"estimator_class\", title=\"Run Estimator Class Distribution\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/processing.ipynb b/notebooks/processing.ipynb new file mode 100644 index 0000000..27c0461 --- /dev/null +++ b/notebooks/processing.ipynb @@ -0,0 +1,719 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. **Extract** all data from CSV files.\n", + "2. **Transform** data into inputs/targets.\n", + "3. **Split** inputs/targets into train/test sets.\n", + "4. **Sample** inputs/targets for the testing sets.\n", + "5. **Load** outputs inputs/targets to parquet files." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# IMPORTS" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.model_selection import train_test_split" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CONFIGS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Extract" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "HOUR_FILE = \"../data/hour.csv\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Transform" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "INDEX_COL = \"instant\"\n", + "TARGET_COL = 'cnt'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Split" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "SHUFFLE = False # time-sensitive\n", + "TEST_SIZE = 0.2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Sample" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "SAMPLE_RATIO = 0.15\n", + "SAMPLE_RANDOM_STATE = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "INPUTS_TRAIN_FILE = \"../data/inputs_train.parquet\"\n", + "INPUTS_TEST_FILE = \"../data/inputs_test.parquet\"\n", + "TARGETS_TRAIN_FILE = \"../data/targets_train.parquet\"\n", + "TARGETS_TEST_FILE = \"../data/targets_test.parquet\"\n", + "INPUTS_SAMPLE_FILE = \"../tests/data/inputs_sample.parquet\"\n", + "TARGETS_SAMPLE_FILE = \"../tests/data/targets_sample.parquet\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# EXTRACT" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hour: (17379, 16)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    dtedayseasonyrmnthhrholidayweekdayworkingdayweathersittempatemphumwindspeedcasualregisteredcnt
    instant
    12011-01-01101006010.240.28790.810.031316
    22011-01-01101106010.220.27270.800.083240
    32011-01-01101206010.220.27270.800.052732
    42011-01-01101306010.240.28790.750.031013
    52011-01-01101406010.240.28790.750.0011
    \n", + "
    " + ], + "text/plain": [ + " dteday season yr mnth hr holiday weekday workingday \\\n", + "instant \n", + "1 2011-01-01 1 0 1 0 0 6 0 \n", + "2 2011-01-01 1 0 1 1 0 6 0 \n", + "3 2011-01-01 1 0 1 2 0 6 0 \n", + "4 2011-01-01 1 0 1 3 0 6 0 \n", + "5 2011-01-01 1 0 1 4 0 6 0 \n", + "\n", + " weathersit temp atemp hum windspeed casual registered cnt \n", + "instant \n", + "1 1 0.24 0.2879 0.81 0.0 3 13 16 \n", + "2 1 0.22 0.2727 0.80 0.0 8 32 40 \n", + "3 1 0.22 0.2727 0.80 0.0 5 27 32 \n", + "4 1 0.24 0.2879 0.75 0.0 3 10 13 \n", + "5 1 0.24 0.2879 0.75 0.0 0 1 1 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hour = pd.read_csv(HOUR_FILE, index_col=INDEX_COL)\n", + "print(\"Hour:\", hour.shape)\n", + "hour.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# TRANFORM" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Inputs: (17379, 15)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    dtedayseasonyrmnthhrholidayweekdayworkingdayweathersittempatemphumwindspeedcasualregistered
    instant
    12011-01-01101006010.240.28790.810.0313
    22011-01-01101106010.220.27270.800.0832
    32011-01-01101206010.220.27270.800.0527
    42011-01-01101306010.240.28790.750.0310
    52011-01-01101406010.240.28790.750.001
    \n", + "
    " + ], + "text/plain": [ + " dteday season yr mnth hr holiday weekday workingday \\\n", + "instant \n", + "1 2011-01-01 1 0 1 0 0 6 0 \n", + "2 2011-01-01 1 0 1 1 0 6 0 \n", + "3 2011-01-01 1 0 1 2 0 6 0 \n", + "4 2011-01-01 1 0 1 3 0 6 0 \n", + "5 2011-01-01 1 0 1 4 0 6 0 \n", + "\n", + " weathersit temp atemp hum windspeed casual registered \n", + "instant \n", + "1 1 0.24 0.2879 0.81 0.0 3 13 \n", + "2 1 0.22 0.2727 0.80 0.0 8 32 \n", + "3 1 0.22 0.2727 0.80 0.0 5 27 \n", + "4 1 0.24 0.2879 0.75 0.0 3 10 \n", + "5 1 0.24 0.2879 0.75 0.0 0 1 " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inputs = hour.drop(TARGET_COL, axis=\"columns\")\n", + "print(\"Inputs:\", inputs.shape)\n", + "inputs.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Targets: (17379, 1)\n" + ] + }, + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    cnt
    instant
    116
    240
    332
    413
    51
    \n", + "
    " + ], + "text/plain": [ + " cnt\n", + "instant \n", + "1 16\n", + "2 40\n", + "3 32\n", + "4 13\n", + "5 1" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "targets = hour[TARGET_COL].to_frame()\n", + "print(\"Targets:\", targets.shape)\n", + "targets.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SPLIT" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((13903, 15), (3476, 15), (13903, 1), (3476, 1))" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inputs_train, inputs_test, targets_train, targets_test = train_test_split(\n", + " inputs, targets, test_size=TEST_SIZE, shuffle=SHUFFLE\n", + ")\n", + "inputs_train.shape, inputs_test.shape, targets_train.shape, targets_test.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SAMPLE" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((2085, 15), (2085, 1))" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inputs_train_sample = inputs_train.sample(frac=SAMPLE_RATIO, random_state=SAMPLE_RANDOM_STATE)\n", + "targets_train_sample = targets_train.sample(frac=SAMPLE_RATIO, random_state=SAMPLE_RANDOM_STATE)\n", + "inputs_train_sample.shape, targets_train_sample.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LOAD" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "inputs_train.to_parquet(INPUTS_TRAIN_FILE)\n", + "inputs_test.to_parquet(INPUTS_TEST_FILE)\n", + "targets_train.to_parquet(TARGETS_TRAIN_FILE)\n", + "targets_test.to_parquet(TARGETS_TEST_FILE)\n", + "inputs_train_sample.to_parquet(INPUTS_SAMPLE_FILE)\n", + "targets_train_sample.to_parquet(TARGETS_SAMPLE_FILE)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From b300bb0368ddae6c277a9f9ee0b7d23c4e65f771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sun, 21 Jul 2024 17:57:06 +0200 Subject: [PATCH 20/21] style(style): improve docs, styles, and readme --- README.md | 96 +- notebooks/explain.ipynb | 2 +- notebooks/indicators.ipynb | 1838 ++++++--------------------------- notebooks/processing.ipynb | 2 +- notebooks/prototype.ipynb | 76 +- poetry.lock | 52 +- src/bikes/io/registries.py | 10 +- src/bikes/jobs/evaluations.py | 1 + src/bikes/settings.py | 2 +- tests/core/test_models.py | 6 +- tests/io/test_datasets.py | 2 + tests/io/test_services.py | 4 +- tests/jobs/test_base.py | 10 +- 13 files changed, 490 insertions(+), 1611 deletions(-) diff --git a/README.md b/README.md index 07b0dcd..0fc2137 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,13 @@ You can use this package as part of your MLOps toolkit or platform (e.g., Model - [Programming](#programming) - [Language: Python](#language-python) - [Version: Pyenv](#version-pyenv) + - [Observability](#observability) + - [Reproducibility: Mlflow Project](#reproducibility-mlflow-project) + - [Monitoring : Mlflow Evaluate](#monitoring--mlflow-evaluate) + - [Alerting: Plyer](#alerting-plyer) + - [Lineage: Mlflow Dataset](#lineage-mlflow-dataset) + - [Explainability: SHAP](#explainability-shap) + - [Infrastructure: Mlflow System Metrics](#infrastructure-mlflow-system-metrics) - [Tips](#tips) - [AI/ML Practices](#aiml-practices) - [Data Catalog](#data-catalog) @@ -173,6 +180,8 @@ $ poetry run [package] confs/tuning.yaml $ poetry run [package] confs/training.yaml $ poetry run [package] confs/promotion.yaml $ poetry run [package] confs/inference.yaml +$ poetry run [package] confs/evaluations.yaml +$ poetry run [package] confs/explanations.yaml ``` In production, you can build, ship, and run the project as a Python package: @@ -210,7 +219,7 @@ You can invoke the actions from the [command-line](https://www.pyinvoke.org/) or ```bash # execute the project DAG -$ inv dags +$ inv projects # create a code archive $ inv packages # list other actions @@ -231,13 +240,16 @@ $ inv --list - **cleans.coverage** - Clean the coverage tool. - **cleans.dist** - Clean the dist folder. - **cleans.docs** - Clean the docs folder. +- **cleans.environment** - Clean the project environment file. - **cleans.folders** - Run all folders tasks. - **cleans.mlruns** - Clean the mlruns folder. - **cleans.mypy** - Clean the mypy tool. - **cleans.outputs** - Clean the outputs folder. - **cleans.poetry** - Clean poetry lock file. - **cleans.pytest** - Clean the pytest tool. +- **cleans.projects** - Run all projects tasks. - **cleans.python** - Clean python caches and bytecodes. +- **cleans.requirements** - Clean the project requirements file. - **cleans.reset** - Run all tools, folders, and sources tasks. - **cleans.ruff** - Clean the ruff tool. - **cleans.sources** - Run all sources tasks. @@ -251,8 +263,6 @@ $ inv --list - **containers.build** - Build the container image with the given tag. - **containers.compose** - Start up docker compose. - **containers.run** - Run the container image with the given tag. -- **dags.all (dags)** - Run all DAG tasks. -- **dags.job** - Run the project for the given job name. - **docs.all (docs)** - Run all docs tasks. - **docs.api** - Document the API with pdoc using the given format and output directory. - **docs.serve** - Serve the API docs with pdoc using the given format and computer port. @@ -267,6 +277,10 @@ $ inv --list - **mlflow.serve** - Start mlflow server with the given host, port, and backend uri. - **packages.all (packages)** - Run all package tasks. - **packages.build** - Build a python package with the given format. +- **projects.all (projects)** - Run all project tasks. +- **projects.environment** - Export the project environment file. +- **projects.requirements** - Export the project requirements file. +- **projects.run** - Run an mlflow project from MLproject file. ## Workflows @@ -719,6 +733,82 @@ Select your programming environment. - **Alternatives**: - Manual installation: time consuming +## Observability + +### Reproducibility: [Mlflow Project](https://mlflow.org/docs/latest/projects.html) + +- **Motivations**: + - Share common project formats. + - Ensure the project can be reused. + - Avoid randomness in project execution. +- **Limitations**: + - Mlflow Project is best suited for small projects. +- **Alternatives**: + - [DVC](https://dvc.org/): both data and models. + - [Metaflow](https://metaflow.org/): focus on machine learning. + - **[Apache Airflow](https://airflow.apache.org/)**: for large scale projects. + +### Monitoring : [Mlflow Evaluate](https://mlflow.org/docs/latest/model-evaluation/index.html) + +- **Motivations**: + - Compute the model metrics. + - Validate model with thresholds. + - Perform post-training evaluations. +- **Limitations**: + - Mlflow Evaluate is less feature-rich as alternatives. +- **Alternatives**: + - **[Giskard](https://www.giskard.ai/)**: open-core and super complete. + - **[Evidently](https://www.evidentlyai.com/)**: open-source with more metrics. + - [Arize AI](https://arize.com/): more feature-rich but less flexible. + - [Graphana](https://grafana.com/): you must do everything yourself. + +### Alerting: [Plyer](https://github.com/kivy/plyer) + +- **Motivations**: + - Simple solution. + - Send notifications on system. + - Cross-system: Mac, Linux, Windows. +- **Limitations**: + - Should not be used for large scale projects. +- **Alternatives**: + - [Slack](https://slack.com/): for chat-oriented solutions. + - [Datadog](https://www.datadoghq.com/): for infrastructure oriented solutions. + +### Lineage: [Mlflow Dataset](https://mlflow.org/docs/latest/tracking/data-api.html) + +- **Motivations**: + - Store information in Mlflow. + - Track metadata about run datasets. + - Keep URI of the dataset source (e.g., website). +- **Limitations**: + - Not as feature-rich as alternative solutions. +- **Alternatives**: + - [Databricks Lineage](https://docs.databricks.com/en/admin/system-tables/lineage.html): limited to Databricks. + - [OpenLineage and Marquez](https://marquezproject.github.io/): open-source and flexible. + +### Explainability: [SHAP](https://shap.readthedocs.io/en/latest/) + +- **Motivations**: + - Most popular toolkit. + - Support various models (linear, model, ...). + - Integration with Mlflow through the [SHAP module](https://mlflow.org/docs/latest/python_api/mlflow.shap.html). +- **Limitations**: + - Super slow on large dataset. + - Mlflow SHAP module is not mature enough. +- **Alternatives**: + - [LIME](https://github.com/marcotcr/lime): not maintained anymore. + +### Infrastructure: [Mlflow System Metrics](https://mlflow.org/docs/latest/system-metrics/index.html) + +- **Motivations**: + - Track infrastructure information (RAM, CPU, ...). + - Integrated with Mlflow tracking. + - Provide hardware insights. +- **Limitations**: + - Not as mature as alternative solutions. +- **Alternatives**: + - [Datadog](https://www.datadoghq.com/): popular and mature solution. + # Tips This sections gives some tips and tricks to enrich the develop experience. diff --git a/notebooks/explain.ipynb b/notebooks/explain.ipynb index e7bfb55..69a6507 100644 --- a/notebooks/explain.ipynb +++ b/notebooks/explain.ipynb @@ -4568,7 +4568,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/indicators.ipynb b/notebooks/indicators.ipynb index 8c7f8f7..3425fb2 100644 --- a/notebooks/indicators.ipynb +++ b/notebooks/indicators.ipynb @@ -128,9 +128,9 @@ " \n", " 0\n", " file:///home/fmind/mlops-python-package/mlruns...\n", - " 2024-07-20 12:43:59.721\n", - " 562757566260573932\n", - " 2024-07-20 12:43:59.721\n", + " 2024-07-21 15:02:02.224\n", + " 598443335336095652\n", + " 2024-07-21 15:02:02.224\n", " active\n", " bikes\n", " {}\n", @@ -141,10 +141,10 @@ ], "text/plain": [ " artifact_location creation_time \\\n", - "0 file:///home/fmind/mlops-python-package/mlruns... 2024-07-20 12:43:59.721 \n", + "0 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 15:02:02.224 \n", "\n", " experiment_id last_update_time lifecycle_stage name tags \n", - "0 562757566260573932 2024-07-20 12:43:59.721 active bikes {} " + "0 598443335336095652 2024-07-21 15:02:02.224 active bikes {} " ] }, "execution_count": 5, @@ -174,7 +174,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "(28, 29)\n" + "(9, 29)\n" ] }, { @@ -233,13 +233,13 @@ " \n", " 0\n", " file:///home/fmind/mlops-python-package/mlruns...\n", - " 2024-07-21 14:08:59.757\n", - " 562757566260573932\n", + " 2024-07-21 15:04:07.438\n", + " 598443335336095652\n", " active\n", - " 2f6920e2006841d7a72567e9f25df89f\n", + " 5936b0cb0d9b47b2a1862344a79e55e7\n", " Explanations\n", - " 2f6920e2006841d7a72567e9f25df89f\n", - " 2024-07-21 14:08:29.817\n", + " 5936b0cb0d9b47b2a1862344a79e55e7\n", + " 2024-07-21 15:03:28.331\n", " FINISHED\n", " fmind\n", " {}\n", @@ -249,7 +249,7 @@ " file:///home/fmind/mlops-python-package\n", " PROJECT\n", " main\n", - " f071dd1397f5c7592fd82a2fe169f5ecaf3af901\n", + " ee17d0a9de59efd2eb99d667786ac417ec8b3b63\n", " git@github.com:fmind/mlops-python-package\n", " git@github.com:fmind/mlops-python-package\n", " Explanations\n", @@ -265,13 +265,13 @@ " \n", " 1\n", " file:///home/fmind/mlops-python-package/mlruns...\n", - " 2024-07-21 14:08:28.634\n", - " 562757566260573932\n", + " 2024-07-21 15:03:25.782\n", + " 598443335336095652\n", " active\n", - " 94fa6a85393745f9b8bb5cac75f865e4\n", + " ef5b224b3f4e4dbcb05169cfc4f358f7\n", " Evaluations\n", - " 94fa6a85393745f9b8bb5cac75f865e4\n", - " 2024-07-21 14:08:24.395\n", + " ef5b224b3f4e4dbcb05169cfc4f358f7\n", + " 2024-07-21 15:03:19.637\n", " FINISHED\n", " fmind\n", " {'example_count': 13903.0, 'mean_absolute_erro...\n", @@ -281,7 +281,7 @@ " file:///home/fmind/mlops-python-package\n", " PROJECT\n", " main\n", - " f071dd1397f5c7592fd82a2fe169f5ecaf3af901\n", + " ee17d0a9de59efd2eb99d667786ac417ec8b3b63\n", " git@github.com:fmind/mlops-python-package\n", " git@github.com:fmind/mlops-python-package\n", " Evaluations\n", @@ -297,13 +297,13 @@ " \n", " 2\n", " file:///home/fmind/mlops-python-package/mlruns...\n", - " 2024-07-21 14:08:23.205\n", - " 562757566260573932\n", + " 2024-07-21 15:03:18.035\n", + " 598443335336095652\n", " active\n", - " da669581953a4a46ab84efaabc8f3e92\n", + " 65f34c799e814cfe82d844b0eff6a16f\n", " Inference\n", - " da669581953a4a46ab84efaabc8f3e92\n", - " 2024-07-21 14:08:19.775\n", + " 65f34c799e814cfe82d844b0eff6a16f\n", + " 2024-07-21 15:03:13.853\n", " FINISHED\n", " fmind\n", " {}\n", @@ -313,7 +313,7 @@ " file:///home/fmind/mlops-python-package\n", " PROJECT\n", " main\n", - " f071dd1397f5c7592fd82a2fe169f5ecaf3af901\n", + " ee17d0a9de59efd2eb99d667786ac417ec8b3b63\n", " git@github.com:fmind/mlops-python-package\n", " git@github.com:fmind/mlops-python-package\n", " Inference\n", @@ -329,13 +329,13 @@ " \n", " 3\n", " file:///home/fmind/mlops-python-package/mlruns...\n", - " 2024-07-21 14:08:18.412\n", - " 562757566260573932\n", + " 2024-07-21 15:03:12.321\n", + " 598443335336095652\n", " active\n", - " 023a21263eaa43228b324fb432932cf4\n", + " a5dbcb3fc6a24fdc863fb31eb0fc4d7a\n", " Promotion\n", - " 023a21263eaa43228b324fb432932cf4\n", - " 2024-07-21 14:08:15.431\n", + " a5dbcb3fc6a24fdc863fb31eb0fc4d7a\n", + " 2024-07-21 15:03:09.011\n", " FINISHED\n", " fmind\n", " {}\n", @@ -345,7 +345,7 @@ " file:///home/fmind/mlops-python-package\n", " PROJECT\n", " main\n", - " f071dd1397f5c7592fd82a2fe169f5ecaf3af901\n", + " ee17d0a9de59efd2eb99d667786ac417ec8b3b63\n", " git@github.com:fmind/mlops-python-package\n", " git@github.com:fmind/mlops-python-package\n", " Promotion\n", @@ -361,13 +361,13 @@ " \n", " 4\n", " file:///home/fmind/mlops-python-package/mlruns...\n", - " 2024-07-21 14:08:13.567\n", - " 562757566260573932\n", + " 2024-07-21 15:03:07.098\n", + " 598443335336095652\n", " active\n", - " d37276201a5b4ff98addae88f5ed1a34\n", + " 47302e957d8542198a281aad07b2413b\n", " Training\n", - " d37276201a5b4ff98addae88f5ed1a34\n", - " 2024-07-21 14:07:54.473\n", + " 47302e957d8542198a281aad07b2413b\n", + " 2024-07-21 15:02:42.090\n", " FINISHED\n", " fmind\n", " {'training_mean_squared_error': 124.5105461557...\n", @@ -377,7 +377,7 @@ " file:///home/fmind/mlops-python-package\n", " PROJECT\n", " main\n", - " f071dd1397f5c7592fd82a2fe169f5ecaf3af901\n", + " ee17d0a9de59efd2eb99d667786ac417ec8b3b63\n", " git@github.com:fmind/mlops-python-package\n", " git@github.com:fmind/mlops-python-package\n", " Training\n", @@ -386,7 +386,7 @@ " NaN\n", " Pipeline\n", " sklearn.pipeline.Pipeline\n", - " [{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\"...\n", + " [{\"run_id\": \"47302e957d8542198a281aad07b2413b\"...\n", " NaN\n", " NaN\n", " \n", @@ -396,25 +396,25 @@ ], "text/plain": [ " artifact_uri end_time \\\n", - "0 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:59.757 \n", - "1 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:28.634 \n", - "2 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:23.205 \n", - "3 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:18.412 \n", - "4 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 14:08:13.567 \n", + "0 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 15:04:07.438 \n", + "1 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 15:03:25.782 \n", + "2 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 15:03:18.035 \n", + "3 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 15:03:12.321 \n", + "4 file:///home/fmind/mlops-python-package/mlruns... 2024-07-21 15:03:07.098 \n", "\n", " experiment_id lifecycle_stage run_id \\\n", - "0 562757566260573932 active 2f6920e2006841d7a72567e9f25df89f \n", - "1 562757566260573932 active 94fa6a85393745f9b8bb5cac75f865e4 \n", - "2 562757566260573932 active da669581953a4a46ab84efaabc8f3e92 \n", - "3 562757566260573932 active 023a21263eaa43228b324fb432932cf4 \n", - "4 562757566260573932 active d37276201a5b4ff98addae88f5ed1a34 \n", + "0 598443335336095652 active 5936b0cb0d9b47b2a1862344a79e55e7 \n", + "1 598443335336095652 active ef5b224b3f4e4dbcb05169cfc4f358f7 \n", + "2 598443335336095652 active 65f34c799e814cfe82d844b0eff6a16f \n", + "3 598443335336095652 active a5dbcb3fc6a24fdc863fb31eb0fc4d7a \n", + "4 598443335336095652 active 47302e957d8542198a281aad07b2413b \n", "\n", " run_name run_uuid start_time \\\n", - "0 Explanations 2f6920e2006841d7a72567e9f25df89f 2024-07-21 14:08:29.817 \n", - "1 Evaluations 94fa6a85393745f9b8bb5cac75f865e4 2024-07-21 14:08:24.395 \n", - "2 Inference da669581953a4a46ab84efaabc8f3e92 2024-07-21 14:08:19.775 \n", - "3 Promotion 023a21263eaa43228b324fb432932cf4 2024-07-21 14:08:15.431 \n", - "4 Training d37276201a5b4ff98addae88f5ed1a34 2024-07-21 14:07:54.473 \n", + "0 Explanations 5936b0cb0d9b47b2a1862344a79e55e7 2024-07-21 15:03:28.331 \n", + "1 Evaluations ef5b224b3f4e4dbcb05169cfc4f358f7 2024-07-21 15:03:19.637 \n", + "2 Inference 65f34c799e814cfe82d844b0eff6a16f 2024-07-21 15:03:13.853 \n", + "3 Promotion a5dbcb3fc6a24fdc863fb31eb0fc4d7a 2024-07-21 15:03:09.011 \n", + "4 Training 47302e957d8542198a281aad07b2413b 2024-07-21 15:02:42.090 \n", "\n", " status user_id metrics \\\n", "0 FINISHED fmind {} \n", @@ -445,11 +445,11 @@ "4 file:///home/fmind/mlops-python-package PROJECT \n", "\n", " mlflow.project.entryPoint mlflow.source.git.commit \\\n", - "0 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", - "1 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", - "2 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", - "3 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", - "4 main f071dd1397f5c7592fd82a2fe169f5ecaf3af901 \n", + "0 main ee17d0a9de59efd2eb99d667786ac417ec8b3b63 \n", + "1 main ee17d0a9de59efd2eb99d667786ac417ec8b3b63 \n", + "2 main ee17d0a9de59efd2eb99d667786ac417ec8b3b63 \n", + "3 main ee17d0a9de59efd2eb99d667786ac417ec8b3b63 \n", + "4 main ee17d0a9de59efd2eb99d667786ac417ec8b3b63 \n", "\n", " mlflow.source.git.repoURL \\\n", "0 git@github.com:fmind/mlops-python-package \n", @@ -491,7 +491,7 @@ "1 NaN NaN \n", "2 NaN NaN \n", "3 NaN NaN \n", - "4 [{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\"... NaN \n", + "4 [{\"run_id\": \"47302e957d8542198a281aad07b2413b\"... NaN \n", "\n", " mlflow.parentRunId \n", "0 NaN \n", @@ -567,10 +567,10 @@ " \n", " \n", " 0\n", - " {'Champion': '3'}\n", - " 2024-07-20 12:46:27.013\n", + " {'Champion': '1'}\n", + " 2024-07-21 15:03:06.208\n", " \n", - " 2024-07-21 14:08:17.804\n", + " 2024-07-21 15:03:11.695\n", " bikes\n", " {}\n", " \n", @@ -580,10 +580,10 @@ ], "text/plain": [ " aliases creation_timestamp description \\\n", - "0 {'Champion': '3'} 2024-07-20 12:46:27.013 \n", + "0 {'Champion': '1'} 2024-07-21 15:03:06.208 \n", "\n", " last_updated_timestamp name tags \n", - "0 2024-07-21 14:08:17.804 bikes {} " + "0 2024-07-21 15:03:11.695 bikes {} " ] }, "execution_count": 7, @@ -613,7 +613,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "(3, 14)\n" + "(1, 14)\n" ] }, { @@ -657,46 +657,12 @@ " \n", " 0\n", " Champion\n", - " 2024-07-21 14:08:12.799\n", + " 2024-07-21 15:03:06.212\n", " None\n", " \n", - " 2024-07-21 14:08:12.799\n", + " 2024-07-21 15:03:06.212\n", " bikes\n", - " d37276201a5b4ff98addae88f5ed1a34\n", - " \n", - " file:///home/fmind/mlops-python-package/mlruns...\n", - " READY\n", - " \n", - " {}\n", - " \n", - " 3\n", - " \n", - " \n", - " 1\n", - " None\n", - " 2024-07-20 12:52:29.627\n", - " None\n", - " \n", - " 2024-07-20 12:52:29.627\n", - " bikes\n", - " b428ae1513a54e16a5bf3959cf3eeb8e\n", - " \n", - " file:///home/fmind/mlops-python-package/mlruns...\n", - " READY\n", - " \n", - " {}\n", - " \n", - " 2\n", - " \n", - " \n", - " 2\n", - " None\n", - " 2024-07-20 12:46:27.017\n", - " None\n", - " \n", - " 2024-07-20 12:46:27.017\n", - " bikes\n", - " 795eace5f76a4fe4af3754460b5e25e4\n", + " 47302e957d8542198a281aad07b2413b\n", " \n", " file:///home/fmind/mlops-python-package/mlruns...\n", " READY\n", @@ -711,24 +677,16 @@ ], "text/plain": [ " aliases creation_timestamp current_stage description \\\n", - "0 Champion 2024-07-21 14:08:12.799 None \n", - "1 None 2024-07-20 12:52:29.627 None \n", - "2 None 2024-07-20 12:46:27.017 None \n", + "0 Champion 2024-07-21 15:03:06.212 None \n", "\n", " last_updated_timestamp name run_id run_link \\\n", - "0 2024-07-21 14:08:12.799 bikes d37276201a5b4ff98addae88f5ed1a34 \n", - "1 2024-07-20 12:52:29.627 bikes b428ae1513a54e16a5bf3959cf3eeb8e \n", - "2 2024-07-20 12:46:27.017 bikes 795eace5f76a4fe4af3754460b5e25e4 \n", + "0 2024-07-21 15:03:06.212 bikes 47302e957d8542198a281aad07b2413b \n", "\n", " source status status_message \\\n", "0 file:///home/fmind/mlops-python-package/mlruns... READY \n", - "1 file:///home/fmind/mlops-python-package/mlruns... READY \n", - "2 file:///home/fmind/mlops-python-package/mlruns... READY \n", "\n", " tags user_id version \n", - "0 {} 3 \n", - "1 {} 2 \n", - "2 {} 1 " + "0 {} 1 " ] }, "execution_count": 8, @@ -774,9 +732,9 @@ "boxpoints": "all", "customdata": [ [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932", - "562757566260573932", - "2024-07-20T12:43:59.721000", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652", + "598443335336095652", + "2024-07-21T15:02:02.224000", "active", "bikes", {} @@ -802,7 +760,7 @@ "showlegend": true, "type": "box", "x": [ - "2024-07-20T12:43:59.721000" + "2024-07-21T15:02:02.224000" ], "x0": " ", "xaxis": "x", @@ -1690,10 +1648,10 @@ "customdata": [ [ { - "Champion": "3" + "Champion": "1" }, "", - "2024-07-21T14:08:17.804000", + "2024-07-21T15:03:11.695000", "bikes", {} ] @@ -1718,7 +1676,7 @@ "showlegend": false, "type": "box", "x": [ - "2024-07-20T12:46:27.013000" + "2024-07-21T15:03:06.208000" ], "x0": " ", "xaxis": "x", @@ -2602,10 +2560,10 @@ "customdata": [ [ { - "Champion": "3" + "Champion": "1" }, "", - "2024-07-21T14:08:17.804000", + "2024-07-21T15:03:11.695000", "bikes", {} ] @@ -2630,7 +2588,7 @@ "showlegend": false, "type": "box", "x": [ - "2024-07-20T12:46:27.013000" + "2024-07-21T15:03:06.208000" ], "x0": " ", "xaxis": "x", @@ -3516,41 +3474,11 @@ "Champion", "None", "", - "2024-07-21T14:08:12.799000", - "bikes", - "d37276201a5b4ff98addae88f5ed1a34", - "", - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d37276201a5b4ff98addae88f5ed1a34/artifacts/model", - "READY", - "", - {}, - "", - "3" - ], - [ - null, - "None", - "", - "2024-07-20T12:52:29.627000", - "bikes", - "b428ae1513a54e16a5bf3959cf3eeb8e", - "", - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/b428ae1513a54e16a5bf3959cf3eeb8e/artifacts/model", - "READY", - "", - {}, - "", - "2" - ], - [ - null, - "None", - "", - "2024-07-20T12:46:27.017000", + "2024-07-21T15:03:06.212000", "bikes", - "795eace5f76a4fe4af3754460b5e25e4", + "47302e957d8542198a281aad07b2413b", "", - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/795eace5f76a4fe4af3754460b5e25e4/artifacts/model", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/47302e957d8542198a281aad07b2413b/artifacts/model", "READY", "", {}, @@ -3562,8 +3490,6 @@ "hoveron": "points", "hovertemplate": "%{hovertext}

    name=%{customdata[4]}
    creation_timestamp=%{x}
    aliases=%{customdata[0]}
    current_stage=%{customdata[1]}
    description=%{customdata[2]}
    last_updated_timestamp=%{customdata[3]}
    run_id=%{customdata[5]}
    run_link=%{customdata[6]}
    source=%{customdata[7]}
    status=%{customdata[8]}
    status_message=%{customdata[9]}
    tags=%{customdata[10]}
    user_id=%{customdata[11]}
    version=%{customdata[12]}", "hovertext": [ - "bikes", - "bikes", "bikes" ], "legendgroup": "bikes", @@ -3580,9 +3506,7 @@ "showlegend": true, "type": "box", "x": [ - "2024-07-21T14:08:12.799000", - "2024-07-20T12:52:29.627000", - "2024-07-20T12:46:27.017000" + "2024-07-21T15:03:06.212000" ], "x0": " ", "xaxis": "x", @@ -4469,13 +4393,13 @@ "boxpoints": "all", "customdata": [ [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/2f6920e2006841d7a72567e9f25df89f/artifacts", - "2024-07-21T14:08:59.757000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/5936b0cb0d9b47b2a1862344a79e55e7/artifacts", + "2024-07-21T15:04:07.438000", + "598443335336095652", "active", - "2f6920e2006841d7a72567e9f25df89f", + "5936b0cb0d9b47b2a1862344a79e55e7", "Explanations", - "2f6920e2006841d7a72567e9f25df89f", + "5936b0cb0d9b47b2a1862344a79e55e7", "FINISHED", "fmind", {}, @@ -4488,7 +4412,7 @@ "mlflow.project.entryPoint": "main", "mlflow.project.env": "virtualenv", "mlflow.runName": "Explanations", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", "mlflow.source.name": "file:///home/fmind/mlops-python-package", "mlflow.source.type": "PROJECT", @@ -4498,7 +4422,7 @@ "file:///home/fmind/mlops-python-package", "PROJECT", "main", - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "git@github.com:fmind/mlops-python-package", "git@github.com:fmind/mlops-python-package", "Explanations", @@ -4512,13 +4436,13 @@ null ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/94fa6a85393745f9b8bb5cac75f865e4/artifacts", - "2024-07-21T14:08:28.634000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/ef5b224b3f4e4dbcb05169cfc4f358f7/artifacts", + "2024-07-21T15:03:25.782000", + "598443335336095652", "active", - "94fa6a85393745f9b8bb5cac75f865e4", + "ef5b224b3f4e4dbcb05169cfc4f358f7", "Evaluations", - "94fa6a85393745f9b8bb5cac75f865e4", + "ef5b224b3f4e4dbcb05169cfc4f358f7", "FINISHED", "fmind", { @@ -4536,13 +4460,13 @@ "conf_file": "confs/evaluations.yaml" }, { - "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"8fce50ebd83a4de3af6a7245453472d3\"}]", + "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"c18c304506ec438c9937a5804b4e19bc\"}]", "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", "mlflow.project.backend": "local", "mlflow.project.entryPoint": "main", "mlflow.project.env": "virtualenv", "mlflow.runName": "Evaluations", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", "mlflow.source.name": "file:///home/fmind/mlops-python-package", "mlflow.source.type": "PROJECT", @@ -4552,13 +4476,13 @@ "file:///home/fmind/mlops-python-package", "PROJECT", "main", - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "git@github.com:fmind/mlops-python-package", "git@github.com:fmind/mlops-python-package", "Evaluations", "virtualenv", "local", - "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"8fce50ebd83a4de3af6a7245453472d3\"}]", + "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"c18c304506ec438c9937a5804b4e19bc\"}]", null, null, null, @@ -4566,13 +4490,13 @@ null ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/da669581953a4a46ab84efaabc8f3e92/artifacts", - "2024-07-21T14:08:23.205000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/65f34c799e814cfe82d844b0eff6a16f/artifacts", + "2024-07-21T15:03:18.035000", + "598443335336095652", "active", - "da669581953a4a46ab84efaabc8f3e92", + "65f34c799e814cfe82d844b0eff6a16f", "Inference", - "da669581953a4a46ab84efaabc8f3e92", + "65f34c799e814cfe82d844b0eff6a16f", "FINISHED", "fmind", {}, @@ -4585,7 +4509,7 @@ "mlflow.project.entryPoint": "main", "mlflow.project.env": "virtualenv", "mlflow.runName": "Inference", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", "mlflow.source.name": "file:///home/fmind/mlops-python-package", "mlflow.source.type": "PROJECT", @@ -4595,7 +4519,7 @@ "file:///home/fmind/mlops-python-package", "PROJECT", "main", - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "git@github.com:fmind/mlops-python-package", "git@github.com:fmind/mlops-python-package", "Inference", @@ -4609,13 +4533,13 @@ null ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/023a21263eaa43228b324fb432932cf4/artifacts", - "2024-07-21T14:08:18.412000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/a5dbcb3fc6a24fdc863fb31eb0fc4d7a/artifacts", + "2024-07-21T15:03:12.321000", + "598443335336095652", "active", - "023a21263eaa43228b324fb432932cf4", + "a5dbcb3fc6a24fdc863fb31eb0fc4d7a", "Promotion", - "023a21263eaa43228b324fb432932cf4", + "a5dbcb3fc6a24fdc863fb31eb0fc4d7a", "FINISHED", "fmind", {}, @@ -4628,7 +4552,7 @@ "mlflow.project.entryPoint": "main", "mlflow.project.env": "virtualenv", "mlflow.runName": "Promotion", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", "mlflow.source.name": "file:///home/fmind/mlops-python-package", "mlflow.source.type": "PROJECT", @@ -4638,7 +4562,7 @@ "file:///home/fmind/mlops-python-package", "PROJECT", "main", - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "git@github.com:fmind/mlops-python-package", "git@github.com:fmind/mlops-python-package", "Promotion", @@ -4652,25 +4576,25 @@ null ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d37276201a5b4ff98addae88f5ed1a34/artifacts", - "2024-07-21T14:08:13.567000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/47302e957d8542198a281aad07b2413b/artifacts", + "2024-07-21T15:03:07.098000", + "598443335336095652", "active", - "d37276201a5b4ff98addae88f5ed1a34", + "47302e957d8542198a281aad07b2413b", "Training", - "d37276201a5b4ff98addae88f5ed1a34", + "47302e957d8542198a281aad07b2413b", "FINISHED", "fmind", { "mean_squared_error": -1786.7527777777777, - "system/cpu_utilization_percentage": 0, - "system/disk_available_megabytes": 34541.6, - "system/disk_usage_megabytes": 71449.6, - "system/disk_usage_percentage": 67.4, - "system/network_receive_megabytes": 0, - "system/network_transmit_megabytes": 0, - "system/system_memory_usage_megabytes": 4388.8, - "system/system_memory_usage_percentage": 29.1, + "system/cpu_utilization_percentage": 15.6, + "system/disk_available_megabytes": 35139.3, + "system/disk_usage_megabytes": 70848.1, + "system/disk_usage_percentage": 66.8, + "system/network_receive_megabytes": 0.001855000000034579, + "system/network_transmit_megabytes": 0.003730000000018663, + "system/system_memory_usage_megabytes": 4143.6, + "system/system_memory_usage_percentage": 27.5, "training_mean_absolute_error": 6.8051192198812736, "training_mean_squared_error": 124.51054615575788, "training_r2_score": 0.9948851411922456, @@ -4724,12 +4648,12 @@ "estimator_class": "sklearn.pipeline.Pipeline", "estimator_name": "Pipeline", "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.log-model.history": "[{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:05.047879\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e007980b27a14ec787fc3860c945fbe3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:08.647799\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"8fce50ebd83a4de3af6a7245453472d3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + "mlflow.log-model.history": "[{\"run_id\": \"47302e957d8542198a281aad07b2413b\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 15:02:54.863113\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"4fd09447dee548f586e05d2edbfbe2d8\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"47302e957d8542198a281aad07b2413b\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 15:02:59.278448\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"c18c304506ec438c9937a5804b4e19bc\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", "mlflow.project.backend": "local", "mlflow.project.entryPoint": "main", "mlflow.project.env": "virtualenv", "mlflow.runName": "Training", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", "mlflow.source.name": "file:///home/fmind/mlops-python-package", "mlflow.source.type": "PROJECT", @@ -4739,7 +4663,7 @@ "file:///home/fmind/mlops-python-package", "PROJECT", "main", - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "git@github.com:fmind/mlops-python-package", "git@github.com:fmind/mlops-python-package", "Training", @@ -4748,83 +4672,99 @@ null, "Pipeline", "sklearn.pipeline.Pipeline", - "[{\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:05.047879\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e007980b27a14ec787fc3860c945fbe3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"d37276201a5b4ff98addae88f5ed1a34\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:08:08.647799\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"8fce50ebd83a4de3af6a7245453472d3\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", + "[{\"run_id\": \"47302e957d8542198a281aad07b2413b\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 15:02:54.863113\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"4fd09447dee548f586e05d2edbfbe2d8\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"47302e957d8542198a281aad07b2413b\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 15:02:59.278448\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"c18c304506ec438c9937a5804b4e19bc\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", null, null ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/2319443aa2dc4b93b3b42acd925b7070/artifacts", - "2024-07-21T14:07:52.347000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/38a4df3abf194e06b5eeaaa0bb383ee8/artifacts", + "2024-07-21T15:02:40.466000", + "598443335336095652", "active", - "2319443aa2dc4b93b3b42acd925b7070", - "nimble-grouse-107", - "2319443aa2dc4b93b3b42acd925b7070", + "38a4df3abf194e06b5eeaaa0bb383ee8", + "Tuning", + "38a4df3abf194e06b5eeaaa0bb383ee8", "FINISHED", "fmind", { - "mean_fit_time": 2.335359275341034, - "mean_score_time": 0.04631972312927246, - "mean_test_score": -5517.252604166667, - "rank_test_score": 1, - "std_fit_time": 0.3590436626364938, - "std_score_time": 0.004401981271699938, - "std_test_score": 1613.520146542553 + "best_cv_score": -5517.252604166667, + "system/cpu_utilization_percentage": 17.1, + "system/disk_available_megabytes": 35143.4, + "system/disk_usage_megabytes": 70843.7, + "system/disk_usage_percentage": 66.8, + "system/network_receive_megabytes": 0.012593999999978678, + "system/network_transmit_megabytes": 0.006136999999995396, + "system/system_memory_usage_megabytes": 4245, + "system/system_memory_usage_percentage": 28.1, + "training_score": -1951.0630079838884 }, { - "max_depth": "7", - "n_estimators": "200", - "random_state": "42" + "best_max_depth": "7", + "conf_file": "confs/tuning.yaml", + "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", + "error_score": "raise", + "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", + "n_jobs": "None", + "param_grid": "{'max_depth': [3, 5, 7]}", + "pre_dispatch": "2*n_jobs", + "refit": "True", + "return_train_score": "False", + "scoring": "", + "verbose": "3" }, { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "e9c8cff5399044b0a2637c0c0ce6689a", - "mlflow.runName": "nimble-grouse-107", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", + "estimator_class": "sklearn.model_selection._search.GridSearchCV", + "estimator_name": "GridSearchCV", + "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.log-model.history": "[{\"run_id\": \"38a4df3abf194e06b5eeaaa0bb383ee8\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 15:02:33.521812\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"67c6c33385b04cb5ad03402d17d4e377\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"38a4df3abf194e06b5eeaaa0bb383ee8\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-21 15:02:37.041779\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"301cd67b8f704f2280ce6b59d6846c7c\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + "mlflow.project.backend": "local", + "mlflow.project.entryPoint": "main", + "mlflow.project.env": "virtualenv", + "mlflow.runName": "Tuning", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", + "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", + "mlflow.source.name": "file:///home/fmind/mlops-python-package", + "mlflow.source.type": "PROJECT", "mlflow.user": "fmind" }, "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", - null, - null, - "nimble-grouse-107", - null, - null, + "file:///home/fmind/mlops-python-package", + "PROJECT", + "main", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", + "git@github.com:fmind/mlops-python-package", + "git@github.com:fmind/mlops-python-package", + "Tuning", + "virtualenv", + "local", null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", + "GridSearchCV", + "sklearn.model_selection._search.GridSearchCV", + "[{\"run_id\": \"38a4df3abf194e06b5eeaaa0bb383ee8\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 15:02:33.521812\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"67c6c33385b04cb5ad03402d17d4e377\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"38a4df3abf194e06b5eeaaa0bb383ee8\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-21 15:02:37.041779\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"301cd67b8f704f2280ce6b59d6846c7c\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", null, - "sklearn", - "e9c8cff5399044b0a2637c0c0ce6689a" + null ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/37dc2776a7ea41d08c1350d9569813c6/artifacts", - "2024-07-21T14:07:52.347000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/38c04e59e8344096bf574faf63b10cd1/artifacts", + "2024-07-21T15:02:39.624000", + "598443335336095652", "active", - "37dc2776a7ea41d08c1350d9569813c6", - "youthful-dog-682", - "37dc2776a7ea41d08c1350d9569813c6", + "38c04e59e8344096bf574faf63b10cd1", + "charming-boar-572", + "38c04e59e8344096bf574faf63b10cd1", "FINISHED", "fmind", { - "mean_fit_time": 1.6250869631767273, - "mean_score_time": 0.039045751094818115, - "mean_test_score": -8287.860416666666, - "rank_test_score": 2, - "std_fit_time": 0.30070612377456823, - "std_score_time": 0.0034828563269759423, - "std_test_score": 1045.7595024691313 + "mean_fit_time": 1.0880586504936218, + "mean_score_time": 0.03774416446685791, + "mean_test_score": -16644.957118055558, + "rank_test_score": 3, + "std_fit_time": 0.15489854371698458, + "std_score_time": 0.001806776770578061, + "std_test_score": 5315.459715152708 }, { - "max_depth": "5", + "max_depth": "3", "n_estimators": "200", "random_state": "42" }, @@ -4832,9 +4772,9 @@ "estimator_class": "bikes.core.models.BaselineSklearnModel", "estimator_name": "BaselineSklearnModel", "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "e9c8cff5399044b0a2637c0c0ce6689a", - "mlflow.runName": "youthful-dog-682", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.parentRunId": "38a4df3abf194e06b5eeaaa0bb383ee8", + "mlflow.runName": "charming-boar-572", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", "mlflow.source.type": "LOCAL", "mlflow.user": "fmind" @@ -4843,10 +4783,10 @@ "/home/fmind/mlops-python-package/src/bikes/__main__.py", "LOCAL", null, - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", null, null, - "youthful-dog-682", + "charming-boar-572", null, null, null, @@ -4854,29 +4794,29 @@ "bikes.core.models.BaselineSklearnModel", null, "sklearn", - "e9c8cff5399044b0a2637c0c0ce6689a" + "38a4df3abf194e06b5eeaaa0bb383ee8" ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/54f8d9d33515402b875a1e36f7aa0319/artifacts", - "2024-07-21T14:07:52.347000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/82f77216b8ee4a2d8dc0869d4a6bfc48/artifacts", + "2024-07-21T15:02:39.624000", + "598443335336095652", "active", - "54f8d9d33515402b875a1e36f7aa0319", - "hilarious-frog-164", - "54f8d9d33515402b875a1e36f7aa0319", + "82f77216b8ee4a2d8dc0869d4a6bfc48", + "luxuriant-bird-233", + "82f77216b8ee4a2d8dc0869d4a6bfc48", "FINISHED", "fmind", { - "mean_fit_time": 1.0542340278625488, - "mean_score_time": 0.034685373306274414, - "mean_test_score": -16644.957118055558, - "rank_test_score": 3, - "std_fit_time": 0.1530062338353499, - "std_score_time": 0.0005786305205599668, - "std_test_score": 5315.459715152708 + "mean_fit_time": 2.5814242362976074, + "mean_score_time": 0.04819995164871216, + "mean_test_score": -5517.252604166667, + "rank_test_score": 1, + "std_fit_time": 0.41318261395357886, + "std_score_time": 0.00042696711729265627, + "std_test_score": 1613.520146542553 }, { - "max_depth": "3", + "max_depth": "7", "n_estimators": "200", "random_state": "42" }, @@ -4884,9 +4824,9 @@ "estimator_class": "bikes.core.models.BaselineSklearnModel", "estimator_name": "BaselineSklearnModel", "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "e9c8cff5399044b0a2637c0c0ce6689a", - "mlflow.runName": "hilarious-frog-164", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "mlflow.parentRunId": "38a4df3abf194e06b5eeaaa0bb383ee8", + "mlflow.runName": "luxuriant-bird-233", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", "mlflow.source.type": "LOCAL", "mlflow.user": "fmind" @@ -4895,10 +4835,10 @@ "/home/fmind/mlops-python-package/src/bikes/__main__.py", "LOCAL", null, - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", null, null, - "hilarious-frog-164", + "luxuriant-bird-233", null, null, null, @@ -4906,1228 +4846,116 @@ "bikes.core.models.BaselineSklearnModel", null, "sklearn", - "e9c8cff5399044b0a2637c0c0ce6689a" + "38a4df3abf194e06b5eeaaa0bb383ee8" ], [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/e9c8cff5399044b0a2637c0c0ce6689a/artifacts", - "2024-07-21T14:07:53.274000", - "562757566260573932", + "file:///home/fmind/mlops-python-package/mlruns/598443335336095652/e110400581f846d08f802c970ae25458/artifacts", + "2024-07-21T15:02:39.624000", + "598443335336095652", "active", - "e9c8cff5399044b0a2637c0c0ce6689a", - "Tuning", - "e9c8cff5399044b0a2637c0c0ce6689a", + "e110400581f846d08f802c970ae25458", + "capricious-bear-977", + "e110400581f846d08f802c970ae25458", "FINISHED", "fmind", { - "best_cv_score": -5517.252604166667, - "system/cpu_utilization_percentage": 7.4, - "system/disk_available_megabytes": 34541.7, - "system/disk_usage_megabytes": 71449.5, - "system/disk_usage_percentage": 67.4, - "system/network_receive_megabytes": 8.62606500000004, - "system/network_transmit_megabytes": 8.622220999999996, - "system/system_memory_usage_megabytes": 4269.4, - "system/system_memory_usage_percentage": 28.3, - "training_score": -1951.0630079838884 + "mean_fit_time": 1.7571877837181091, + "mean_score_time": 0.0408632755279541, + "mean_test_score": -8287.860416666666, + "rank_test_score": 2, + "std_fit_time": 0.2750353199252692, + "std_score_time": 0.0028638736758093077, + "std_test_score": 1045.7595024691313 }, { - "best_max_depth": "7", - "conf_file": "confs/tuning.yaml", - "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", - "error_score": "raise", - "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", - "n_jobs": "None", - "param_grid": "{'max_depth': [3, 5, 7]}", - "pre_dispatch": "2*n_jobs", - "refit": "True", - "return_train_score": "False", - "scoring": "", - "verbose": "3" + "max_depth": "5", + "n_estimators": "200", + "random_state": "42" }, { - "estimator_class": "sklearn.model_selection._search.GridSearchCV", - "estimator_name": "GridSearchCV", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.log-model.history": "[{\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:07:47.385038\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"d1707c2f4b8346818f7747a0d7ab01ad\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-21 14:07:50.180719\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"982e3a8c13734ff58f0ff20b1f759967\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "Tuning", - "mlflow.source.git.commit": "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", + "estimator_class": "bikes.core.models.BaselineSklearnModel", + "estimator_name": "BaselineSklearnModel", + "mlflow.autologging": "sklearn", + "mlflow.parentRunId": "38a4df3abf194e06b5eeaaa0bb383ee8", + "mlflow.runName": "capricious-bear-977", + "mlflow.source.git.commit": "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", + "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "mlflow.source.type": "LOCAL", "mlflow.user": "fmind" }, "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "f071dd1397f5c7592fd82a2fe169f5ecaf3af901", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "Tuning", - "virtualenv", - "local", + "/home/fmind/mlops-python-package/src/bikes/__main__.py", + "LOCAL", null, - "GridSearchCV", - "sklearn.model_selection._search.GridSearchCV", - "[{\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-21 14:07:47.385038\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"d1707c2f4b8346818f7747a0d7ab01ad\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"e9c8cff5399044b0a2637c0c0ce6689a\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-21 14:07:50.180719\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"982e3a8c13734ff58f0ff20b1f759967\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", + "ee17d0a9de59efd2eb99d667786ac417ec8b3b63", null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d0e46ae61af6441b856375a09e30594e/artifacts", - "2024-07-20T12:53:12.588000", - "562757566260573932", - "active", - "d0e46ae61af6441b856375a09e30594e", - "EXPLANATIONS", - "d0e46ae61af6441b856375a09e30594e", - "FINISHED", - "fmind", - {}, - { - "conf_file": "confs/explanations.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "EXPLANATIONS", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "EXPLANATIONS", - "virtualenv", - "local", null, + "capricious-bear-977", null, null, null, + "BaselineSklearnModel", + "bikes.core.models.BaselineSklearnModel", null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/d54dd7a19b10422191be93d1cc53213a/artifacts", - "2024-07-20T12:52:42.983000", - "562757566260573932", - "active", - "d54dd7a19b10422191be93d1cc53213a", - "EVALUATIONS", - "d54dd7a19b10422191be93d1cc53213a", - "FINISHED", - "fmind", - { - "example_count": 13903, - "max_error": 4294967295, - "mean_absolute_error": 2044457567.3205063, - "mean_absolute_percentage_error": 55189262.03890929, - "mean_on_target": 174.63914263108683, - "mean_squared_error": 296.66338200388407, - "r2_score": 0.9893562621162568, - "root_mean_squared_error": 17.223918892165166, - "sum_on_target": 2428008 - }, - { - "conf_file": "confs/evaluations.yaml" - }, - { - "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"d8305c29a5a54e0caed2ed9413d739d7\"}]", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "EVALUATIONS", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "EVALUATIONS", - "virtualenv", - "local", - "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"d8305c29a5a54e0caed2ed9413d739d7\"}]", - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/7bd2297aa53b47a6b8bca64e9b4c4071/artifacts", - "2024-07-20T12:52:38.115000", - "562757566260573932", - "active", - "7bd2297aa53b47a6b8bca64e9b4c4071", - "INFERENCE", - "7bd2297aa53b47a6b8bca64e9b4c4071", - "FINISHED", - "fmind", - {}, - { - "conf_file": "confs/inference.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "INFERENCE", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "INFERENCE", - "virtualenv", - "local", - null, - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/87d4d36b5b034e538dff16e40e80a5d9/artifacts", - "2024-07-20T12:52:33.932000", - "562757566260573932", - "active", - "87d4d36b5b034e538dff16e40e80a5d9", - "PROMOTION", - "87d4d36b5b034e538dff16e40e80a5d9", - "FINISHED", - "fmind", - {}, - { - "conf_file": "confs/promotion.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "PROMOTION", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "PROMOTION", - "virtualenv", - "local", - null, - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/b428ae1513a54e16a5bf3959cf3eeb8e/artifacts", - "2024-07-20T12:52:30.318000", - "562757566260573932", - "active", - "b428ae1513a54e16a5bf3959cf3eeb8e", - "TRAINING", - "b428ae1513a54e16a5bf3959cf3eeb8e", - "FINISHED", - "fmind", - { - "mean_squared_error": -1786.7527777777777, - "system/cpu_utilization_percentage": 0, - "system/disk_available_megabytes": 35065.7, - "system/disk_usage_megabytes": 70918.1, - "system/disk_usage_percentage": 66.9, - "system/network_receive_megabytes": 0, - "system/network_transmit_megabytes": 0, - "system/system_memory_usage_megabytes": 3441.1, - "system/system_memory_usage_percentage": 22.8, - "training_mean_absolute_error": 6.8051192198812736, - "training_mean_squared_error": 124.51054615575788, - "training_r2_score": 0.9948851411922456, - "training_root_mean_squared_error": 11.158429376742852, - "training_score": 0.9948851411922456 - }, - { - "conf_file": "confs/training.yaml", - "memory": "None", - "regressor": "RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42)", - "regressor__bootstrap": "True", - "regressor__ccp_alpha": "0.0", - "regressor__criterion": "squared_error", - "regressor__max_depth": "20", - "regressor__max_features": "1.0", - "regressor__max_leaf_nodes": "None", - "regressor__max_samples": "None", - "regressor__min_impurity_decrease": "0.0", - "regressor__min_samples_leaf": "1", - "regressor__min_samples_split": "2", - "regressor__min_weight_fraction_leaf": "0.0", - "regressor__monotonic_cst": "None", - "regressor__n_estimators": "200", - "regressor__n_jobs": "None", - "regressor__oob_score": "False", - "regressor__random_state": "42", - "regressor__verbose": "0", - "regressor__warm_start": "False", - "steps": "[('transformer', ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])), ('regressor', RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42))]", - "transformer": "ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])", - "transformer__categoricals": "OneHotEncoder(handle_unknown='ignore', sparse_output=False)", - "transformer__categoricals__categories": "auto", - "transformer__categoricals__drop": "None", - "transformer__categoricals__dtype": "", - "transformer__categoricals__feature_name_combiner": "concat", - "transformer__categoricals__handle_unknown": "ignore", - "transformer__categoricals__max_categories": "None", - "transformer__categoricals__min_frequency": "None", - "transformer__categoricals__sparse_output": "False", - "transformer__n_jobs": "None", - "transformer__numericals": "passthrough", - "transformer__remainder": "drop", - "transformer__sparse_threshold": "0.3", - "transformer__transformer_weights": "None", - "transformer__transformers": "[('categoricals', OneHotEncoder(handle_unknown='ignore', sparse_output=False), ['season', 'weathersit']), ('numericals', 'passthrough', ['yr', 'mnth', 'hr', 'holiday', 'weekday', 'workingday', 'temp', 'atemp', 'hum', 'windspeed', 'casual'])]", - "transformer__verbose": "False", - "transformer__verbose_feature_names_out": "True", - "verbose": "False" - }, - { - "estimator_class": "sklearn.pipeline.Pipeline", - "estimator_name": "Pipeline", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.log-model.history": "[{\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:24.146985\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"6bf30a1cf60945d5837e380b08b18783\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:26.416323\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"d8305c29a5a54e0caed2ed9413d739d7\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "TRAINING", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "TRAINING", - "virtualenv", - "local", - null, - "Pipeline", - "sklearn.pipeline.Pipeline", - "[{\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:24.146985\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"6bf30a1cf60945d5837e380b08b18783\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"b428ae1513a54e16a5bf3959cf3eeb8e\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:26.416323\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"d8305c29a5a54e0caed2ed9413d739d7\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/515ecd02027a4f19a43b586a0e19b221/artifacts", - "2024-07-20T12:52:12.773000", - "562757566260573932", - "active", - "515ecd02027a4f19a43b586a0e19b221", - "TUNING", - "515ecd02027a4f19a43b586a0e19b221", - "FINISHED", - "fmind", - { - "best_cv_score": -5517.252604166667, - "system/cpu_utilization_percentage": 6.5, - "system/disk_available_megabytes": 35065.7, - "system/disk_usage_megabytes": 70918.1, - "system/disk_usage_percentage": 66.9, - "system/network_receive_megabytes": 0.007126000000027943, - "system/network_transmit_megabytes": 0.007125999999999522, - "system/system_memory_usage_megabytes": 3465.2, - "system/system_memory_usage_percentage": 23, - "training_score": -1951.0630079838884 - }, - { - "best_max_depth": "7", - "conf_file": "confs/tuning.yaml", - "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", - "error_score": "raise", - "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", - "n_jobs": "None", - "param_grid": "{'max_depth': [3, 5, 7]}", - "pre_dispatch": "2*n_jobs", - "refit": "True", - "return_train_score": "False", - "scoring": "", - "verbose": "3" - }, - { - "estimator_class": "sklearn.model_selection._search.GridSearchCV", - "estimator_name": "GridSearchCV", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.log-model.history": "[{\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:07.924106\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"de91989dcdc246068666a87d36e3287b\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:52:10.363319\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"8f4374171a1347dd88c01b46e4196a8a\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "TUNING", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "TUNING", - "virtualenv", - "local", - null, - "GridSearchCV", - "sklearn.model_selection._search.GridSearchCV", - "[{\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:52:07.924106\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"de91989dcdc246068666a87d36e3287b\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"515ecd02027a4f19a43b586a0e19b221\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:52:10.363319\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"8f4374171a1347dd88c01b46e4196a8a\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/5f28aabdcccc494491f27e3700ee75dd/artifacts", - "2024-07-20T12:52:12.230000", - "562757566260573932", - "active", - "5f28aabdcccc494491f27e3700ee75dd", - "treasured-shrimp-728", - "5f28aabdcccc494491f27e3700ee75dd", - "FINISHED", - "fmind", - { - "mean_fit_time": 0.9817702770233154, - "mean_score_time": 0.03579825162887573, - "mean_test_score": -16644.957118055558, - "rank_test_score": 3, - "std_fit_time": 0.15158578334750608, - "std_score_time": 0.006110784505381323, - "std_test_score": 5315.459715152708 - }, - { - "max_depth": "3", - "n_estimators": "200", - "random_state": "42" - }, - { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "515ecd02027a4f19a43b586a0e19b221", - "mlflow.runName": "treasured-shrimp-728", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", - "mlflow.user": "fmind" - }, - "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - null, - null, - "treasured-shrimp-728", - null, - null, - null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - "sklearn", - "515ecd02027a4f19a43b586a0e19b221" - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/81386b0b3ac842e4a995576f092bbac5/artifacts", - "2024-07-20T12:52:12.230000", - "562757566260573932", - "active", - "81386b0b3ac842e4a995576f092bbac5", - "angry-cub-96", - "81386b0b3ac842e4a995576f092bbac5", - "FINISHED", - "fmind", - { - "mean_fit_time": 1.510183572769165, - "mean_score_time": 0.03509628772735596, - "mean_test_score": -8287.860416666666, - "rank_test_score": 2, - "std_fit_time": 0.23992070497194215, - "std_score_time": 0.0011799521253510422, - "std_test_score": 1045.7595024691313 - }, - { - "max_depth": "5", - "n_estimators": "200", - "random_state": "42" - }, - { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "515ecd02027a4f19a43b586a0e19b221", - "mlflow.runName": "angry-cub-96", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", - "mlflow.user": "fmind" - }, - "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - null, - null, - "angry-cub-96", - null, - null, - null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - "sklearn", - "515ecd02027a4f19a43b586a0e19b221" - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/a69515beaf3047b5816de516de1ecb83/artifacts", - "2024-07-20T12:52:12.230000", - "562757566260573932", - "active", - "a69515beaf3047b5816de516de1ecb83", - "adaptable-gull-964", - "a69515beaf3047b5816de516de1ecb83", - "FINISHED", - "fmind", - { - "mean_fit_time": 2.1361553072929382, - "mean_score_time": 0.039887070655822754, - "mean_test_score": -5517.252604166667, - "rank_test_score": 1, - "std_fit_time": 0.3223141495079878, - "std_score_time": 0.0009398759994274763, - "std_test_score": 1613.520146542553 - }, - { - "max_depth": "7", - "n_estimators": "200", - "random_state": "42" - }, - { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "515ecd02027a4f19a43b586a0e19b221", - "mlflow.runName": "adaptable-gull-964", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", - "mlflow.user": "fmind" - }, - "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - null, - null, - "adaptable-gull-964", - null, - null, - null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - "sklearn", - "515ecd02027a4f19a43b586a0e19b221" - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/f07658777ac84b83a238ab67713e31b2/artifacts", - "2024-07-20T12:47:10.242000", - "562757566260573932", - "active", - "f07658777ac84b83a238ab67713e31b2", - "explanations", - "f07658777ac84b83a238ab67713e31b2", - "FINISHED", - "fmind", - {}, - { - "conf_file": "confs/explanations.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "explanations", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "explanations", - "virtualenv", - "local", - null, - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/b8e7d22143cd4330a42af7d4896549ad/artifacts", - "2024-07-20T12:46:40.437000", - "562757566260573932", - "active", - "b8e7d22143cd4330a42af7d4896549ad", - "evaluations", - "b8e7d22143cd4330a42af7d4896549ad", - "FINISHED", - "fmind", - { - "example_count": 13903, - "max_error": 4294967295, - "mean_absolute_error": 2044457567.3205063, - "mean_absolute_percentage_error": 55189262.03890929, - "mean_on_target": 174.63914263108683, - "mean_squared_error": 296.66338200388407, - "r2_score": 0.9893562621162568, - "root_mean_squared_error": 17.223918892165166, - "sum_on_target": 2428008 - }, - { - "conf_file": "confs/evaluations.yaml" - }, - { - "mlflow.datasets": "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"b64cc85729ce4b2abf7546f49640eacf\"}]", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "evaluations", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "evaluations", - "virtualenv", - "local", - "[{\"name\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"hash\":\"ce0fe6e33c74e2fa3659d51482be5f27\",\"model\":\"b64cc85729ce4b2abf7546f49640eacf\"}]", - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/e130d952a9fa4865aac2928db108d233/artifacts", - "2024-07-20T12:46:35.412000", - "562757566260573932", - "active", - "e130d952a9fa4865aac2928db108d233", - "inference", - "e130d952a9fa4865aac2928db108d233", - "FINISHED", - "fmind", - {}, - { - "conf_file": "confs/inference.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "inference", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "inference", - "virtualenv", - "local", - null, - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/0ab3086f66e84ac79ef14ec1a5680922/artifacts", - "2024-07-20T12:46:31.253000", - "562757566260573932", - "active", - "0ab3086f66e84ac79ef14ec1a5680922", - "promotion", - "0ab3086f66e84ac79ef14ec1a5680922", - "FINISHED", - "fmind", - {}, - { - "conf_file": "confs/promotion.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "promotion", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "promotion", - "virtualenv", - "local", - null, - null, - null, - null, - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/795eace5f76a4fe4af3754460b5e25e4/artifacts", - "2024-07-20T12:46:27.543000", - "562757566260573932", - "active", - "795eace5f76a4fe4af3754460b5e25e4", - "training", - "795eace5f76a4fe4af3754460b5e25e4", - "FINISHED", - "fmind", - { - "mean_squared_error": -1786.7527777777777, - "system/cpu_utilization_percentage": 0, - "system/disk_available_megabytes": 35587.9, - "system/disk_usage_megabytes": 70394.1, - "system/disk_usage_percentage": 66.4, - "system/network_receive_megabytes": 0, - "system/network_transmit_megabytes": 0, - "system/system_memory_usage_megabytes": 9466.8, - "system/system_memory_usage_percentage": 62.8, - "training_mean_absolute_error": 6.8051192198812736, - "training_mean_squared_error": 124.51054615575788, - "training_r2_score": 0.9948851411922456, - "training_root_mean_squared_error": 11.158429376742852, - "training_score": 0.9948851411922456 - }, - { - "conf_file": "confs/training.yaml", - "memory": "None", - "regressor": "RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42)", - "regressor__bootstrap": "True", - "regressor__ccp_alpha": "0.0", - "regressor__criterion": "squared_error", - "regressor__max_depth": "20", - "regressor__max_features": "1.0", - "regressor__max_leaf_nodes": "None", - "regressor__max_samples": "None", - "regressor__min_impurity_decrease": "0.0", - "regressor__min_samples_leaf": "1", - "regressor__min_samples_split": "2", - "regressor__min_weight_fraction_leaf": "0.0", - "regressor__monotonic_cst": "None", - "regressor__n_estimators": "200", - "regressor__n_jobs": "None", - "regressor__oob_score": "False", - "regressor__random_state": "42", - "regressor__verbose": "0", - "regressor__warm_start": "False", - "steps": "[('transformer', ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])), ('regressor', RandomForestRegressor(max_depth=20, n_estimators=200, random_state=42))]", - "transformer": "ColumnTransformer(transformers=[('categoricals',\n OneHotEncoder(handle_unknown='ignore',\n sparse_output=False),\n ['season', 'weathersit']),\n ('numericals', 'passthrough',\n ['yr', 'mnth', 'hr', 'holiday', 'weekday',\n 'workingday', 'temp', 'atemp', 'hum',\n 'windspeed', 'casual'])])", - "transformer__categoricals": "OneHotEncoder(handle_unknown='ignore', sparse_output=False)", - "transformer__categoricals__categories": "auto", - "transformer__categoricals__drop": "None", - "transformer__categoricals__dtype": "", - "transformer__categoricals__feature_name_combiner": "concat", - "transformer__categoricals__handle_unknown": "ignore", - "transformer__categoricals__max_categories": "None", - "transformer__categoricals__min_frequency": "None", - "transformer__categoricals__sparse_output": "False", - "transformer__n_jobs": "None", - "transformer__numericals": "passthrough", - "transformer__remainder": "drop", - "transformer__sparse_threshold": "0.3", - "transformer__transformer_weights": "None", - "transformer__transformers": "[('categoricals', OneHotEncoder(handle_unknown='ignore', sparse_output=False), ['season', 'weathersit']), ('numericals', 'passthrough', ['yr', 'mnth', 'hr', 'holiday', 'weekday', 'workingday', 'temp', 'atemp', 'hum', 'windspeed', 'casual'])]", - "transformer__verbose": "False", - "transformer__verbose_feature_names_out": "True", - "verbose": "False" - }, - { - "estimator_class": "sklearn.pipeline.Pipeline", - "estimator_name": "Pipeline", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.log-model.history": "[{\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:21.035281\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"3cd314ac3cdb4c8eb2a7b60dd2d396df\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:23.203673\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"b64cc85729ce4b2abf7546f49640eacf\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "training", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "training", - "virtualenv", - "local", - null, - "Pipeline", - "sklearn.pipeline.Pipeline", - "[{\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:21.035281\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"3cd314ac3cdb4c8eb2a7b60dd2d396df\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"tensor\\\", \\\"tensor-spec\\\": {\\\"dtype\\\": \\\"float64\\\", \\\"shape\\\": [-1]}}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 203898413}, {\"run_id\": \"795eace5f76a4fe4af3754460b5e25e4\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:46:23.203673\", \"flavors\": {\"python_function\": {\"streamable\": false, \"cloudpickle_version\": \"3.0.0\", \"python_model\": \"python_model.pkl\", \"loader_module\": \"mlflow.pyfunc.model\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}, \"code\": null}}, \"model_uuid\": \"b64cc85729ce4b2abf7546f49640eacf\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 205599260}]", - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/1bfdbbf6df3d4b899ab48941e58fa4de/artifacts", - "2024-07-20T12:46:03.231000", - "562757566260573932", - "active", - "1bfdbbf6df3d4b899ab48941e58fa4de", - "learned-mole-85", - "1bfdbbf6df3d4b899ab48941e58fa4de", - "FINISHED", - "fmind", - { - "mean_fit_time": 4.399524390697479, - "mean_score_time": 0.14234960079193115, - "mean_test_score": -8287.860416666666, - "rank_test_score": 2, - "std_fit_time": 0.6041601907827593, - "std_score_time": 0.008689780141727426, - "std_test_score": 1045.7595024691313 - }, - { - "max_depth": "5", - "n_estimators": "200", - "random_state": "42" - }, - { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "bab549993e48428fb3f5a0b4b83d5645", - "mlflow.runName": "learned-mole-85", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", - "mlflow.user": "fmind" - }, - "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - null, - null, - "learned-mole-85", - null, - null, - null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - "sklearn", - "bab549993e48428fb3f5a0b4b83d5645" - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/bab549993e48428fb3f5a0b4b83d5645/artifacts", - "2024-07-20T12:46:03.878000", - "562757566260573932", - "active", - "bab549993e48428fb3f5a0b4b83d5645", - "tuning", - "bab549993e48428fb3f5a0b4b83d5645", - "FINISHED", - "fmind", - { - "best_cv_score": -5517.252604166667, - "system/cpu_utilization_percentage": 56.6, - "system/disk_available_megabytes": 35635.6, - "system/disk_usage_megabytes": 70345.4, - "system/disk_usage_percentage": 66.4, - "system/network_receive_megabytes": 0.03039199999994935, - "system/network_transmit_megabytes": 0.48478400000000477, - "system/system_memory_usage_megabytes": 9749, - "system/system_memory_usage_percentage": 64.6, - "training_score": -1951.0630079838884 - }, - { - "best_max_depth": "7", - "conf_file": "confs/tuning.yaml", - "cv": "KIND='TimeSeriesSplitter' gap=0 n_splits=4 test_size=1440", - "error_score": "raise", - "estimator": "KIND='BaselineSklearnModel' max_depth=20 n_estimators=200 random_state=42", - "n_jobs": "None", - "param_grid": "{'max_depth': [3, 5, 7]}", - "pre_dispatch": "2*n_jobs", - "refit": "True", - "return_train_score": "False", - "scoring": "", - "verbose": "3" - }, - { - "estimator_class": "sklearn.model_selection._search.GridSearchCV", - "estimator_name": "GridSearchCV", - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.log-model.history": "[{\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:45:56.543992\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e78ada09386b4e6b98b52cbaae8196e6\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:46:00.949836\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"b84db06a9be445a3a4c35cd20cdc5532\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", - "mlflow.project.backend": "local", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "tuning", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "tuning", - "virtualenv", - "local", - null, - "GridSearchCV", - "sklearn.model_selection._search.GridSearchCV", - "[{\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"model\", \"utc_time_created\": \"2024-07-20 12:45:56.543992\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"e78ada09386b4e6b98b52cbaae8196e6\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3726525}, {\"run_id\": \"bab549993e48428fb3f5a0b4b83d5645\", \"artifact_path\": \"best_estimator\", \"utc_time_created\": \"2024-07-20 12:46:00.949836\", \"flavors\": {\"python_function\": {\"model_path\": \"model.pkl\", \"predict_fn\": \"predict\", \"loader_module\": \"mlflow.sklearn\", \"python_version\": \"3.12.4\", \"env\": {\"conda\": \"conda.yaml\", \"virtualenv\": \"python_env.yaml\"}}, \"sklearn\": {\"pickled_model\": \"model.pkl\", \"sklearn_version\": \"1.4.2\", \"serialization_format\": \"cloudpickle\", \"code\": null}}, \"model_uuid\": \"b84db06a9be445a3a4c35cd20cdc5532\", \"mlflow_version\": \"2.14.3\", \"signature\": {\"inputs\": \"[{\\\"type\\\": \\\"datetime\\\", \\\"name\\\": \\\"dteday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"season\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"yr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"mnth\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"hr\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"holiday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weekday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"boolean\\\", \\\"name\\\": \\\"workingday\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"integer\\\", \\\"name\\\": \\\"weathersit\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"temp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"atemp\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"hum\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"float\\\", \\\"name\\\": \\\"windspeed\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"casual\\\", \\\"required\\\": true}, {\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"registered\\\", \\\"required\\\": true}]\", \"outputs\": \"[{\\\"type\\\": \\\"long\\\", \\\"name\\\": \\\"prediction\\\", \\\"required\\\": true}]\", \"params\": null}, \"saved_input_example_info\": {\"artifact_path\": \"input_example.json\", \"type\": \"dataframe\", \"pandas_orient\": \"split\"}, \"model_size_bytes\": 3713919}]", - null, - null - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/bc6a629fbacf4dfb93d73cf49d2fadb2/artifacts", - "2024-07-20T12:46:03.231000", - "562757566260573932", - "active", - "bc6a629fbacf4dfb93d73cf49d2fadb2", - "gentle-jay-790", - "bc6a629fbacf4dfb93d73cf49d2fadb2", - "FINISHED", - "fmind", - { - "mean_fit_time": 3.0013614892959595, - "mean_score_time": 0.18937814235687256, - "mean_test_score": -16644.957118055558, - "rank_test_score": 3, - "std_fit_time": 0.48890581262807953, - "std_score_time": 0.06921257470224487, - "std_test_score": 5315.459715152708 - }, - { - "max_depth": "3", - "n_estimators": "200", - "random_state": "42" - }, - { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "bab549993e48428fb3f5a0b4b83d5645", - "mlflow.runName": "gentle-jay-790", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", - "mlflow.user": "fmind" - }, - "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - null, - null, - "gentle-jay-790", - null, - null, - null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - "sklearn", - "bab549993e48428fb3f5a0b4b83d5645" - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/e7a424df7a474652984ebab24398f78e/artifacts", - "2024-07-20T12:46:03.231000", - "562757566260573932", - "active", - "e7a424df7a474652984ebab24398f78e", - "clean-sloth-537", - "e7a424df7a474652984ebab24398f78e", - "FINISHED", - "fmind", - { - "mean_fit_time": 3.5007389187812805, - "mean_score_time": 0.05425143241882324, - "mean_test_score": -5517.252604166667, - "rank_test_score": 1, - "std_fit_time": 0.3245513505947697, - "std_score_time": 0.005157635720925865, - "std_test_score": 1613.520146542553 - }, - { - "max_depth": "7", - "n_estimators": "200", - "random_state": "42" - }, - { - "estimator_class": "bikes.core.models.BaselineSklearnModel", - "estimator_name": "BaselineSklearnModel", - "mlflow.autologging": "sklearn", - "mlflow.parentRunId": "bab549993e48428fb3f5a0b4b83d5645", - "mlflow.runName": "clean-sloth-537", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.name": "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "mlflow.source.type": "LOCAL", - "mlflow.user": "fmind" - }, - "fmind", - "/home/fmind/mlops-python-package/src/bikes/__main__.py", - "LOCAL", - null, - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - null, - null, - "clean-sloth-537", - null, - null, - null, - "BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - "sklearn", - "bab549993e48428fb3f5a0b4b83d5645" - ], - [ - "file:///home/fmind/mlops-python-package/mlruns/562757566260573932/6f23412a2dd34ff4944cad9d545448f1/artifacts", - null, - "562757566260573932", - "active", - "6f23412a2dd34ff4944cad9d545448f1", - "polite-snail-973", - "6f23412a2dd34ff4944cad9d545448f1", - "RUNNING", - "fmind", - {}, - { - "conf_file": "confs/tuning.yaml" - }, - { - "mlflow.gitRepoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.project.entryPoint": "main", - "mlflow.project.env": "virtualenv", - "mlflow.runName": "polite-snail-973", - "mlflow.source.git.commit": "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "mlflow.source.git.repoURL": "git@github.com:fmind/mlops-python-package", - "mlflow.source.name": "file:///home/fmind/mlops-python-package", - "mlflow.source.type": "PROJECT", - "mlflow.user": "fmind" - }, - "fmind", - "file:///home/fmind/mlops-python-package", - "PROJECT", - "main", - "50ee7202afcbac4516be893b3c96c5434a5fd05b", - "git@github.com:fmind/mlops-python-package", - "git@github.com:fmind/mlops-python-package", - "polite-snail-973", - "virtualenv", - null, - null, - null, - null, - null, - null, - null - ] - ], - "fillcolor": "rgba(255,255,255,0)", - "hoveron": "points", - "hovertemplate": "%{hovertext}

    experiment_id=%{customdata[2]}
    start_time=%{x}
    artifact_uri=%{customdata[0]}
    end_time=%{customdata[1]}
    lifecycle_stage=%{customdata[3]}
    run_id=%{customdata[4]}
    run_name=%{customdata[5]}
    run_uuid=%{customdata[6]}
    status=%{customdata[7]}
    user_id=%{customdata[8]}
    metrics=%{customdata[9]}
    params=%{customdata[10]}
    tags=%{customdata[11]}
    mlflow.user=%{customdata[12]}
    mlflow.source.name=%{customdata[13]}
    mlflow.source.type=%{customdata[14]}
    mlflow.project.entryPoint=%{customdata[15]}
    mlflow.source.git.commit=%{customdata[16]}
    mlflow.source.git.repoURL=%{customdata[17]}
    mlflow.gitRepoURL=%{customdata[18]}
    mlflow.runName=%{customdata[19]}
    mlflow.project.env=%{customdata[20]}
    mlflow.project.backend=%{customdata[21]}
    mlflow.datasets=%{customdata[22]}
    estimator_name=%{customdata[23]}
    estimator_class=%{customdata[24]}
    mlflow.log-model.history=%{customdata[25]}
    mlflow.autologging=%{customdata[26]}
    mlflow.parentRunId=%{customdata[27]}", - "hovertext": [ - "Explanations", - "Evaluations", - "Inference", - "Promotion", - "Training", - "nimble-grouse-107", - "youthful-dog-682", - "hilarious-frog-164", - "Tuning", - "EXPLANATIONS", - "EVALUATIONS", - "INFERENCE", - "PROMOTION", - "TRAINING", - "TUNING", - "treasured-shrimp-728", - "angry-cub-96", - "adaptable-gull-964", - "explanations", - "evaluations", - "inference", - "promotion", - "training", - "learned-mole-85", - "tuning", - "gentle-jay-790", - "clean-sloth-537", - "polite-snail-973" - ], - "legendgroup": "562757566260573932", - "line": { - "color": "rgba(255,255,255,0)" - }, - "marker": { - "color": "#636efa" - }, - "name": "562757566260573932", - "offsetgroup": "562757566260573932", - "orientation": "h", - "pointpos": 0, - "showlegend": true, - "type": "box", - "x": [ - "2024-07-21T14:08:29.817000", - "2024-07-21T14:08:24.395000", - "2024-07-21T14:08:19.775000", - "2024-07-21T14:08:15.431000", - "2024-07-21T14:07:54.473000", - "2024-07-21T14:07:19.282000", - "2024-07-21T14:07:19.282000", - "2024-07-21T14:07:19.282000", - "2024-07-21T14:07:19.282000", - "2024-07-20T12:52:44.033000", - "2024-07-20T12:52:39.147000", - "2024-07-20T12:52:35.057000", - "2024-07-20T12:52:31.479000", - "2024-07-20T12:52:13.797000", - "2024-07-20T12:51:43.548000", - "2024-07-20T12:51:43.548000", - "2024-07-20T12:51:43.548000", - "2024-07-20T12:51:43.548000", - "2024-07-20T12:46:41.664000", - "2024-07-20T12:46:36.460000", - "2024-07-20T12:46:32.379000", - "2024-07-20T12:46:28.853000", - "2024-07-20T12:46:05.345000", - "2024-07-20T12:44:40.852000", - "2024-07-20T12:44:40.852000", - "2024-07-20T12:44:40.852000", - "2024-07-20T12:44:40.852000", - "2024-07-20T12:43:59.876000" - ], - "x0": " ", - "xaxis": "x", - "y0": " ", - "yaxis": "y" - } - ], - "layout": { - "boxmode": "group", - "legend": { - "title": { - "text": "experiment_id" - }, - "tracegroupgap": 0 - }, - "template": { - "data": { - "bar": [ + "sklearn", + "38a4df3abf194e06b5eeaaa0bb383ee8" + ] + ], + "fillcolor": "rgba(255,255,255,0)", + "hoveron": "points", + "hovertemplate": "%{hovertext}

    experiment_id=%{customdata[2]}
    start_time=%{x}
    artifact_uri=%{customdata[0]}
    end_time=%{customdata[1]}
    lifecycle_stage=%{customdata[3]}
    run_id=%{customdata[4]}
    run_name=%{customdata[5]}
    run_uuid=%{customdata[6]}
    status=%{customdata[7]}
    user_id=%{customdata[8]}
    metrics=%{customdata[9]}
    params=%{customdata[10]}
    tags=%{customdata[11]}
    mlflow.user=%{customdata[12]}
    mlflow.source.name=%{customdata[13]}
    mlflow.source.type=%{customdata[14]}
    mlflow.project.entryPoint=%{customdata[15]}
    mlflow.source.git.commit=%{customdata[16]}
    mlflow.source.git.repoURL=%{customdata[17]}
    mlflow.gitRepoURL=%{customdata[18]}
    mlflow.runName=%{customdata[19]}
    mlflow.project.env=%{customdata[20]}
    mlflow.project.backend=%{customdata[21]}
    mlflow.datasets=%{customdata[22]}
    estimator_name=%{customdata[23]}
    estimator_class=%{customdata[24]}
    mlflow.log-model.history=%{customdata[25]}
    mlflow.autologging=%{customdata[26]}
    mlflow.parentRunId=%{customdata[27]}", + "hovertext": [ + "Explanations", + "Evaluations", + "Inference", + "Promotion", + "Training", + "Tuning", + "charming-boar-572", + "luxuriant-bird-233", + "capricious-bear-977" + ], + "legendgroup": "598443335336095652", + "line": { + "color": "rgba(255,255,255,0)" + }, + "marker": { + "color": "#636efa" + }, + "name": "598443335336095652", + "offsetgroup": "598443335336095652", + "orientation": "h", + "pointpos": 0, + "showlegend": true, + "type": "box", + "x": [ + "2024-07-21T15:03:28.331000", + "2024-07-21T15:03:19.637000", + "2024-07-21T15:03:13.853000", + "2024-07-21T15:03:09.011000", + "2024-07-21T15:02:42.090000", + "2024-07-21T15:02:02.378000", + "2024-07-21T15:02:02.378000", + "2024-07-21T15:02:02.378000", + "2024-07-21T15:02:02.378000" + ], + "x0": " ", + "xaxis": "x", + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "boxmode": "group", + "legend": { + "title": { + "text": "experiment_id" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ { "error_x": { "color": "#2a3f5f" @@ -7013,51 +5841,13 @@ null, null, "sklearn.pipeline.Pipeline", - "bikes.core.models.BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - "sklearn.model_selection._search.GridSearchCV", - null, - null, - null, - null, - "sklearn.pipeline.Pipeline", - "sklearn.model_selection._search.GridSearchCV", - "bikes.core.models.BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - "bikes.core.models.BaselineSklearnModel", - null, - null, - null, - null, - "sklearn.pipeline.Pipeline", - "bikes.core.models.BaselineSklearnModel", "sklearn.model_selection._search.GridSearchCV", "bikes.core.models.BaselineSklearnModel", "bikes.core.models.BaselineSklearnModel", - null + "bikes.core.models.BaselineSklearnModel" ], "xaxis": "x", "y": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 1, 1, 1, diff --git a/notebooks/processing.ipynb b/notebooks/processing.ipynb index 27c0461..78f28c4 100644 --- a/notebooks/processing.ipynb +++ b/notebooks/processing.ipynb @@ -711,7 +711,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/notebooks/prototype.ipynb b/notebooks/prototype.ipynb index b457eaf..7d222f6 100644 --- a/notebooks/prototype.ipynb +++ b/notebooks/prototype.ipynb @@ -106737,25 +106737,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/sklearn/pipeline.py:408: UserWarning:\n", + "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/joblib/memory.py:577: UserWarning:\n", "\n", - "Persisting input arguments took 0.80s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", - "\n", - "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/sklearn/pipeline.py:408: UserWarning:\n", - "\n", - "Persisting input arguments took 0.78s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", - "\n", - "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/sklearn/pipeline.py:408: UserWarning:\n", - "\n", - "Persisting input arguments took 0.90s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", - "\n", - "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/sklearn/pipeline.py:408: UserWarning:\n", - "\n", - "Persisting input arguments took 0.96s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", - "\n", - "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/sklearn/pipeline.py:408: UserWarning:\n", - "\n", - "Persisting input arguments took 1.04s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", + "Persisting input arguments took 1.02s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", "\n" ] }, @@ -107330,10 +107314,10 @@ " \n", " \n", " 4\n", - " 8.870042\n", - " 1.365375\n", - " 0.056343\n", - " 0.005585\n", + " 9.851526\n", + " 2.065956\n", + " 0.071210\n", + " 0.029418\n", " 20\n", " 200\n", " {'regressor__max_depth': 20, 'regressor__n_est...\n", @@ -107347,10 +107331,10 @@ " \n", " \n", " 1\n", - " 7.606831\n", - " 0.860855\n", - " 0.050878\n", - " 0.003308\n", + " 6.918022\n", + " 0.886340\n", + " 0.043904\n", + " 0.005060\n", " 15\n", " 200\n", " {'regressor__max_depth': 15, 'regressor__n_est...\n", @@ -107364,10 +107348,10 @@ " \n", " \n", " 5\n", - " 10.341928\n", - " 1.903503\n", - " 0.066688\n", - " 0.008134\n", + " 11.964708\n", + " 1.272631\n", + " 0.074480\n", + " 0.013998\n", " 20\n", " 250\n", " {'regressor__max_depth': 20, 'regressor__n_est...\n", @@ -107381,10 +107365,10 @@ " \n", " \n", " 7\n", - " 8.646172\n", - " 1.280304\n", - " 0.057035\n", - " 0.006029\n", + " 8.290697\n", + " 1.105596\n", + " 0.049447\n", + " 0.004403\n", " 25\n", " 200\n", " {'regressor__max_depth': 25, 'regressor__n_est...\n", @@ -107398,10 +107382,10 @@ " \n", " \n", " 2\n", - " 9.656019\n", - " 1.224665\n", - " 0.064132\n", - " 0.006463\n", + " 8.716824\n", + " 1.402426\n", + " 0.055110\n", + " 0.008181\n", " 15\n", " 250\n", " {'regressor__max_depth': 15, 'regressor__n_est...\n", @@ -107419,11 +107403,11 @@ ], "text/plain": [ " mean_fit_time std_fit_time mean_score_time std_score_time \\\n", - "4 8.870042 1.365375 0.056343 0.005585 \n", - "1 7.606831 0.860855 0.050878 0.003308 \n", - "5 10.341928 1.903503 0.066688 0.008134 \n", - "7 8.646172 1.280304 0.057035 0.006029 \n", - "2 9.656019 1.224665 0.064132 0.006463 \n", + "4 9.851526 2.065956 0.071210 0.029418 \n", + "1 6.918022 0.886340 0.043904 0.005060 \n", + "5 11.964708 1.272631 0.074480 0.013998 \n", + "7 8.290697 1.105596 0.049447 0.004403 \n", + "2 8.716824 1.402426 0.055110 0.008181 \n", "\n", " param_regressor__max_depth param_regressor__n_estimators \\\n", "4 20 200 \n", @@ -113455,9 +113439,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/sklearn/pipeline.py:408: UserWarning:\n", + "/home/fmind/mlops-python-package/.venv/lib/python3.12/site-packages/joblib/memory.py:577: UserWarning:\n", "\n", - "Persisting input arguments took 0.62s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", + "Persisting input arguments took 0.54s to run.If this happens often in your code, it can cause performance problems (results will be correct in all cases). The reason for this is probably some large input arguments for a wrapped function.\n", "\n" ] }, @@ -116323,7 +116307,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.12.4" }, "orig_nbformat": 4 }, diff --git a/poetry.lock b/poetry.lock index 83bd5ba..9a13b56 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2377,13 +2377,13 @@ files = [ [[package]] name = "pure-eval" -version = "0.2.2" +version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, ] [package.extras] @@ -2631,20 +2631,20 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "8.2.2" +version = "8.3.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, - {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, + {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, + {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2.0" +pluggy = ">=1.5,<2" [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] @@ -3118,29 +3118,29 @@ files = [ [[package]] name = "ruff" -version = "0.5.3" +version = "0.5.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.3-py3-none-linux_armv6l.whl", hash = "sha256:b12424d9db7347fa63c5ed9af010003338c63c629fb9c9c6adb2aa4f5699729b"}, - {file = "ruff-0.5.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8d72c5684bbd4ed304a9a955ee2e67f57b35f6193222ade910cca8a805490e3"}, - {file = "ruff-0.5.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2fc2cdb85ccac1e816cc9d5d8cedefd93661bd957756d902543af32a6b04a71"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf4bc751240b2fab5d19254571bcacb315c7b0b00bf3c912d52226a82bbec073"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc697ec874fdd7c7ba0a85ec76ab38f8595224868d67f097c5ffc21136e72fcd"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e791d34d3557a3819b3704bc1f087293c821083fa206812842fa363f6018a192"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:76bb5a87fd397520b91a83eae8a2f7985236d42dd9459f09eef58e7f5c1d8316"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8cfc7a26422c78e94f1ec78ec02501bbad2df5834907e75afe474cc6b83a8c1"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96066c4328a49fce2dd40e80f7117987369feec30ab771516cf95f1cc2db923c"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfe9ab5bdc0b08470c3b261643ad54ea86edc32b64d1e080892d7953add3ad"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7704582a026fa02cca83efd76671a98ee6eb412c4230209efe5e2a006c06db62"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:08058d077e21b856d32ebf483443390e29dc44d927608dc8f092ff6776519da9"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:77d49484429ed7c7e6e2e75a753f153b7b58f875bdb4158ad85af166a1ec1822"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:642cbff6cbfa38d2566d8db086508d6f472edb136cbfcc4ea65997745368c29e"}, - {file = "ruff-0.5.3-py3-none-win32.whl", hash = "sha256:eafc45dd8bdc37a00b28e68cc038daf3ca8c233d73fea276dcd09defb1352841"}, - {file = "ruff-0.5.3-py3-none-win_amd64.whl", hash = "sha256:cbaec2ddf4f78e5e9ecf5456ea0f496991358a1d883862ed0b9e947e2b6aea93"}, - {file = "ruff-0.5.3-py3-none-win_arm64.whl", hash = "sha256:05fbd2cb404775d6cd7f2ff49504e2d20e13ef95fa203bd1ab22413af70d420b"}, - {file = "ruff-0.5.3.tar.gz", hash = "sha256:2a3eb4f1841771fa5b67a56be9c2d16fd3cc88e378bd86aaeaec2f7e6bcdd0a2"}, + {file = "ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf"}, + {file = "ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be"}, + {file = "ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff"}, + {file = "ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e"}, + {file = "ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4"}, + {file = "ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7"}, + {file = "ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed"}, ] [[package]] diff --git a/src/bikes/io/registries.py b/src/bikes/io/registries.py index f4bd672..82a824d 100644 --- a/src/bikes/io/registries.py +++ b/src/bikes/io/registries.py @@ -48,7 +48,15 @@ def uri_for_model_version(name: str, version: int) -> str: def uri_for_model_alias_or_version(name: str, alias_or_version: str | int) -> str: - """Create a model URi from a model name and an alias or version.""" + """Create a model URi from a model name and an alias or version. + + Args: + name (str): name of the mlflow registered model. + alias_or_version (str | int): alias or version of the registered model. + + Returns: + str: model URI as "models:/name@alias" or "models:/name/version" based on input. + """ if isinstance(alias_or_version, int): return uri_for_model_version(name=name, version=alias_or_version) else: diff --git a/src/bikes/jobs/evaluations.py b/src/bikes/jobs/evaluations.py index 93cbf0c..b6ecfd9 100644 --- a/src/bikes/jobs/evaluations.py +++ b/src/bikes/jobs/evaluations.py @@ -54,6 +54,7 @@ class EvaluationsJob(base.Job): @T.override def run(self) -> base.Locals: # services + # - logger logger = self.logger_service.logger() logger.info("With logger: {}", logger) # - mlflow diff --git a/src/bikes/settings.py b/src/bikes/settings.py index aeeb2d2..2a33796 100644 --- a/src/bikes/settings.py +++ b/src/bikes/settings.py @@ -1,4 +1,4 @@ -"""Define settings of the application.""" +"""Define settings for the application.""" # %% IMPORTS diff --git a/tests/core/test_models.py b/tests/core/test_models.py index f8f3e0e..47ce7f0 100644 --- a/tests/core/test_models.py +++ b/tests/core/test_models.py @@ -83,7 +83,9 @@ def test_baseline_sklearn_model( inputs_test.columns ), "SHAP values should have more features than inputs!" # - feature importances - assert feature_importances["importance"].sum() == 1.0, "Importance values should sum to 1.0!" + assert ( + feature_importances["importance"].sum() == 1.0 + ), "Feature importances should add up to 1.0!" assert len(feature_importances["feature"]) >= len( inputs_train.columns - ), "Importance features should have more features than inputs!" + ), "Feature importances should have more features than inputs!" diff --git a/tests/io/test_datasets.py b/tests/io/test_datasets.py index e6ecc04..2201f65 100644 --- a/tests/io/test_datasets.py +++ b/tests/io/test_datasets.py @@ -17,9 +17,11 @@ def test_parquet_reader(limit: int | None, inputs_path: str) -> None: data = reader.read() lineage = reader.lineage(name="inputs", data=data) # then + # - data assert data.ndim == 2, "Data should be a dataframe!" if limit is not None: assert len(data) == limit, "Data should have the limit size!" + # - lineage assert lineage.name == "inputs", "Lineage name should be inputs!" assert lineage.source.uri == inputs_path, "Lineage source uri should be the inputs path!" assert set(lineage.schema.input_names()) == set( diff --git a/tests/io/test_services.py b/tests/io/test_services.py index abb0a1b..a11e28b 100644 --- a/tests/io/test_services.py +++ b/tests/io/test_services.py @@ -1,9 +1,9 @@ # %% IMPORTS - import _pytest.capture as pc import _pytest.logging as pl import mlflow +import plyer import pytest import pytest_mock as pm from bikes.io import services @@ -29,8 +29,6 @@ def test_logger_service( def test_alerts_service( enable: bool, mocker: pm.MockerFixture, capsys: pc.CaptureFixture[str] ) -> None: - import plyer - # given service = services.AlertsService(enable=enable) mocker.patch("plyer.notification.notify") diff --git a/tests/jobs/test_base.py b/tests/jobs/test_base.py index 1b37fde..c86982a 100644 --- a/tests/jobs/test_base.py +++ b/tests/jobs/test_base.py @@ -7,7 +7,9 @@ def test_job( - logger_service: services.LoggerService, mlflow_service: services.MlflowService + logger_service: services.LoggerService, + alerts_service: services.AlertsService, + mlflow_service: services.MlflowService, ) -> None: # given class MyJob(base.Job): @@ -17,14 +19,16 @@ def run(self) -> base.Locals: a, b = 1, "test" return locals() - job = MyJob(logger_service=logger_service, mlflow_service=mlflow_service) + job = MyJob( + logger_service=logger_service, alerts_service=alerts_service, mlflow_service=mlflow_service + ) # when with job as runner: out = runner.run() # then # - inputs assert hasattr(job, "logger_service"), "Job should have an Logger service!" - assert hasattr(job, "mlflow_service"), "Job should have an Mlflow service!" assert hasattr(job, "alerts_service"), "Job should have a alerter service!" + assert hasattr(job, "mlflow_service"), "Job should have an Mlflow service!" # - outputs assert set(out) == {"self", "a", "b"}, "Run should return local variables!" From 5c6b5ee7aaee7e44d71ac2100dda6fc535176797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9d=C3=A9ric=20Hurier=20=28Fmind=29?= Date: Sun, 21 Jul 2024 17:57:10 +0200 Subject: [PATCH 21/21] =?UTF-8?q?bump:=20version=201.0.1=20=E2=86=92=201.1?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d360fc3..a14121f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +## v1.1.0 (2024-07-21) + +### Feat + +- **kpi**: add key performance indicators +- **mlproject**: add mlflow project and tasks +- **monitoring**: add mlflow.evaluate API +- **lineage**: add lineage features through mlflow data api +- **explanations**: add explainability features and tooling +- **data**: add train, test, and sample data +- **notification**: add service and alerts with plyer +- **observability**: add alerting with plyer notifications +- **observability**: add infrastructure through mlflow system metrics + +### Fix + +- **kpi**: add key performance indicators +- **projects**: change naming convention +- **evaluation**: add evaluation files +- **loading**: use version or alias for loading models +- **warnings**: improve styles and remove warnings +- **mlflow**: remove input examples following the addition of lineage +- **paths**: fix path for explanation job +- **data**: fix models explanations name +- **data**: add parquet data + ## v1.0.1 (2024-06-28) ### Fix diff --git a/pyproject.toml b/pyproject.toml index 66037a1..a0ce1b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ [tool.poetry] name = "bikes" -version = "1.0.1" +version = "1.1.0" description = "Predict the number of bikes available." repository = "https://github.com/fmind/mlops-python-package" documentation = "https://fmind.github.io/mlops-python-package/"