diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 76e46290..42710a25 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -19,6 +19,10 @@ jobs: publish: runs-on: ubuntu-latest environment: pypi-publish + # The "v*.*.*" trigger also matches RC tags (e.g. v2.0.0rc2), so guard + # against publishing pre-releases to real PyPI. RC tags are handled by + # publish-testpypi.yml instead. + if: ${{ !contains(github.ref_name, 'rc') }} steps: - name: Checkout code diff --git a/CHANGELOG.md b/CHANGELOG.md index ccbc64bd..40ab1d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,133 @@ Going forward, this file is updated automatically by `cz bump` on each release. --- +## v2.0.0 (2026-06-24) + +### BREAKING CHANGE + +- internal package layout, configuration objects, and import + paths have changed. See the migration guide for details. + +### Feat + +- DeepTab v2 API with split-config design (#400) +- **config**: warn on misplaced config slots +- **training**: add unregister_optimizer, unregister_scheduler with built-in protection +- **inspection**: expose public read-only task_model property +- **models**: thread observability_config through all estimators +- **core**: add ObservabilityConfig +- **models**: expose ObservabilityConfig on base estimator constructor +- **models**: add observability mixin wiring ObservabilityConfig to base estimators +- **models**: integrate ObservabilityConfig into fit mixin +- **training**: rewrite configure_optimizers, add contrastive pretraining fixes, and cleanup +- introduce IDataModule/ITaskModel protocols and default factories, wire into SklearnBase +- **configs**: add optimizer/scheduler fields to TrainerConfig and InferenceModel support +- **training**: wire optimizer/scheduler registry into LightningModule and extend losses +- **training**: add optimizer/scheduler registry with all torch.optim classes +- **api**: export exception and warning types from deeptab and deeptab.core +- **configs,models**: add **post_init** validation using typed exceptions +- **core**: add exception hierarchy and message factories +- **models**: wire evaluate() in lss_base, regressor_base, and classifier_base to new deeptab.metrics registry +- **metrics**: add deeptab metrics ABC, regression, classification, lss +- add tweedie, inflated poissons, log normal etc. distribution +- light weight inference wrapper +- **serialization**: warn when save/load path lacks .deeptab extension +- **inspection**: add profile() method for pre-training dry-run diagnostics +- **training**: add class-imbalance loss registry and weighted sampling +- **core**: add set_seed/seed_context reproducibility helpers +- **core**: add sklearn_compat module and update serialization/core exports +- add rich model artifact serialization metadata +- model inspection api added +- **data**: add optional TabularBatch return mode +- **data**: add stratified splitting for classification and schema property +- **data**: add FeatureSchema and TabularBatch typed containers +- **configs**: add SplitConfig for train/validation splitting parameters +- **root**: expose configs, data, distributions, metrics, models in top-level **init** +- **models**: add \_docstring helper to centralize generate_docstring for all models +- **models**: expose stable classes in **all** and add **getattr** shim for experimental +- **models**: add split base classes for classifier, regressor, and LSS task variants +- **configs**: add configs/core.py with shared base configuration definitions +- **configs**: add configs/experimental sub module for ModernNCA, Tangos, Trompt +- **configs**: add configs sub module with per-model config modules +- **hpo**: add hpo module with get_search_space mapper +- **metrics**: add metrics module stubs for classification, regression, distributional +- **distributions**: add distributions module with 12 distribution classes +- **data**: add data module with MambularDataModule, MambularDataset, batch, schema, split +- **training**: add training module with lightning module, losses, optimizers, schedulers +- **core**: add core module with BaseModel, registry, embeddings, pooling, serialization +- **architectures**: add experimental sub-package with ModernNCA, Tangos, Trompt +- **architectures**: add architectures module with all stable model definitions +- **nn**: add nn module with blocks, normalization, and initialization +- **config**: split config into trainer, model and preprocessing config +- **sklearn_parent**: implement split-config path in SklearnBase.**init**, get_params, set_params +- **models**: add split config **init** to all Classifier and Regressor wrappers +- **base_models**: replace DefaultXXConfig with XXConfig in all base model constructors +- **configs**: add \*Config for all architectures +- **configs**: add ENODEConfig architecture only config +- **hardware**: add print_hardware_info for CPU/CUDA/MPS detection + +### Fix + +- **sklearn_compat**: satisfy pandas typing in ensure_dataframe +- **training**: register custom torchmetrics via nn.ModuleDict so state moves to device +- **sklearn_compat**: cast pandas category columns to object in ensure_dataframe +- **modernnca**: support LSS prediction and add experimental model tests +- **models**: adapt child class to use class var, update docstring example +- **transformer**: use batch_first attention to prevent cross-sample leakage +- **hpo**: rebuild model per trial and map activation names to modules +- save default artificats to /artifacts/model.deeptab +- **base**: add **sklearn_is_fitted**, use check_is_fitted +- **sklearn_compat**: raise ValueError for 1D array input in ensure_dataframe +- **exceptions**: inherit EmptyDataError and ColumnCountError from ValueError for sklearn compat +- add seed to DataLoader/sampler generators +- data validation for parameters +- **models**: read optimizer_type and preprocessor live from config in \_build_model +- **test**: add typed error, fix preprocessing config +- **architectures,distributions**: replace ValueError with typed exceptions +- **docs**: remove dead cross-reference links and fix tables +- **training**: apply distribution parameter transform before passing predictions to metrics +- use r2 metric for regresion as default +- use getattr for task_model access in InspectionMixin +- enable side bar navigation for api reference +- **tests**: update flat-kwarg error assertions to match native TypeError message +- **tests**: update config lookup to search configs.models and configs.experimental +- training parameter added +- modernca config and model update +- **lss**: use getattr fallback for lr/weight_decay in SklearnBaseLSS.fit() + +### Refactor + +- **models**: drop legacy flat-kwargs constructor +- **core**: centralize optional-dependency +- replace SplitConfig with TrainerConfig.stratify and refresh docs +- **models**: adopt declarative class variable estimator pattern +- **hpo**: rename mapper.py to search_space.py and fix lss_base error +- **core**: update inspection and serialization for \_ attribute rename +- **models**: prefix non-constructor attributes with \_ for sklearn compliance +- extract \_FitMixin, \_PredictMixin, \_SerializationMixin, \_HyperparameterMixin, \_ObservabilityMixin from SklearnBase +- **configs**: remove legacy BaseConfig class +- **distributions**: separate dist classes, add registry +- consolidate save/load into core.serialization helpers +- **models**: update base classifier/regressor/lss model internals +- **data**: update datamodule and dataset internals +- **models**: update imports to use TabularDataModule +- **data**: rename to TabularDataset/TabularDataModule and move task-specific label logic to DataModule +- **models**: replace \*\*kwargs with explicit signatures in stable model constructors +- **hpo**: add missing exports to hpo/**init**.py +- **models**: update training and hpo imports to go through package boundaries +- **architectures**: update core imports to go through package boundary +- **architectures**: add lazy **getattr** boundary with TYPE_CHECKING guards +- **nn**: expose public API via nn/**init**.py boundary +- **training**: expose public API via training/**init**.py boundary +- **core**: expose public API via core/**init**.py boundary +- **architectures**: update config imports to use configs/models/ and configs/experimental/ +- **models**: update config imports to use configs/models/, configs/experimental/, and configs/core +- **configs**: update **init** to import from core, models/, and experimental/ +- **configs**: remove deprecated flat config files superseded by models/ and experimental/ +- **models**: update import paths in experimental ModernNCA, Tangos, Trompt modules +- **models**: update import paths in ndtf, node, resnet, saint, tabm, tabr, tabtransformer, tabularnn +- **modules**: remove legacy arch_utils, base_models, data_utils, utils + ## v1.8.0 (2026-05-24) ### Feat diff --git a/LICENSE b/LICENSE index d938d149..6c7fca17 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 BASF +Copyright (c) 2024 OpenTabular Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 59363091..370e89ab 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ ## Why DeepTab? - **Familiar interface.** A scikit-learn `fit`/`predict`/`evaluate` API that drops into existing pipelines, including `GridSearchCV`. -- **Automatic preprocessing.** Feature-type detection, encoding, scaling, and missing-value handling are built in. +- **Automatic preprocessing.** Feature-type detection, encoding, scaling, and missing-value handling are powered by [PreTab](https://github.com/OpenTabular/PreTab) and applied for you. - **One model, three tasks.** Every architecture ships as a classifier, a regressor, and a distributional (`LSS`) variant for uncertainty quantification. - **A broad model zoo.** 15 stable architectures plus experimental models, all behind the same interface, with [selection guidance](https://deeptab.readthedocs.io/en/latest/model_zoo/index.html). - **Built for real data.** Mixed feature types, class imbalance, GPU acceleration, and early stopping work out of the box. diff --git a/deeptab/__init__.py b/deeptab/__init__.py index 91a34020..5b431f3f 100644 --- a/deeptab/__init__.py +++ b/deeptab/__init__.py @@ -8,6 +8,7 @@ NotFittedError, PerformanceWarning, ) +from .core.hardware import print_hardware_info from .core.inference import InferenceModel from .core.reproducibility import seed_context, set_seed @@ -25,6 +26,7 @@ "distributions", "metrics", "models", + "print_hardware_info", "seed_context", "set_seed", ] diff --git a/deeptab/configs/experimental/tangos_config.py b/deeptab/configs/experimental/tangos_config.py index 45f9c2eb..cb153ed4 100644 --- a/deeptab/configs/experimental/tangos_config.py +++ b/deeptab/configs/experimental/tangos_config.py @@ -25,9 +25,9 @@ class TangosConfig(BaseModelConfig): skip_connections : bool, default=False Whether to use skip connections in the TANGOS. lamda1 : float, default=0.5 - Weight on the task-specific orthogonality regularisation term. + Weight on the specialization regularisation term (multiplies ``spec_loss``). lamda2 : float, default=0.1 - Weight on the cross-task specialisation regularisation term. + Weight on the orthogonalization regularisation term (multiplies ``orth_loss``). subsample : float, default=0.5 Fraction of features subsampled for regularisation estimation. """ diff --git a/deeptab/core/__init__.py b/deeptab/core/__init__.py index 84eab92f..a0b1c2e7 100644 --- a/deeptab/core/__init__.py +++ b/deeptab/core/__init__.py @@ -18,6 +18,7 @@ NotFittedError, PerformanceWarning, ) +from .hardware import print_hardware_info from .inference import InferenceModel from .inspection import ImportanceGetter, InspectionMixin, get_feature_dimensions from .registry import MODEL_REGISTRY, ModelInfo @@ -67,6 +68,7 @@ "get_feature_dimensions", "load_state_dict", "make_random_batches", + "print_hardware_info", "restore_loaded_metadata", "save_state_dict", "seed_context", diff --git a/deeptab/core/hardware.py b/deeptab/core/hardware.py new file mode 100644 index 00000000..ac20ec2a --- /dev/null +++ b/deeptab/core/hardware.py @@ -0,0 +1,215 @@ +from __future__ import annotations + +import os +import platform +import sys +from typing import Any + +import torch + +__all__ = ["get_hardware_info", "print_hardware_info"] + + +def _mps_available() -> bool: + """Return ``True`` when the Apple Silicon MPS backend is usable.""" + backends = getattr(torch, "backends", None) + mps = getattr(backends, "mps", None) + if mps is None: + return False + try: + return bool(mps.is_available()) + except Exception: # pragma: no cover - defensive, backend should not raise + return False + + +def _mps_built() -> bool: + """Return ``True`` when this PyTorch build includes the MPS backend.""" + backends = getattr(torch, "backends", None) + mps = getattr(backends, "mps", None) + if mps is None or not hasattr(mps, "is_built"): + return False + try: + return bool(mps.is_built()) + except Exception: # pragma: no cover - defensive + return False + + +def _recommended_accelerator(cuda_available: bool, mps_available: bool) -> str: + """Pick the accelerator DeepTab would use by default.""" + if cuda_available: + return "cuda" + if mps_available: + return "mps" + return "cpu" + + +def _cuda_devices(detailed: bool) -> list[dict[str, Any]]: + """Return one entry per visible CUDA device.""" + devices: list[dict[str, Any]] = [] + for index in range(torch.cuda.device_count()): + entry: dict[str, Any] = { + "index": index, + "name": torch.cuda.get_device_name(index), + } + if detailed: + major, minor = torch.cuda.get_device_capability(index) + props = torch.cuda.get_device_properties(index) + free, _total = torch.cuda.mem_get_info(index) + entry.update( + { + "compute_capability": f"{major}.{minor}", + "multi_processor_count": props.multi_processor_count, + "total_memory_gb": round(props.total_memory / 1024**3, 2), + "free_memory_gb": round(free / 1024**3, 2), + } + ) + devices.append(entry) + return devices + + +def _mps_detail() -> dict[str, Any]: + """Return MPS memory counters when the build exposes them.""" + detail: dict[str, Any] = {} + mps = getattr(torch, "mps", None) + if mps is None: + return detail + if hasattr(mps, "current_allocated_memory"): + detail["allocated_memory_gb"] = round(mps.current_allocated_memory() / 1024**3, 3) + if hasattr(mps, "driver_allocated_memory"): + detail["driver_allocated_memory_gb"] = round(mps.driver_allocated_memory() / 1024**3, 3) + return detail + + +def get_hardware_info(detailed: bool = False) -> dict[str, Any]: + """Return the compute hardware DeepTab can see on this machine. + + The report covers the CPU, NVIDIA CUDA GPUs, and the Apple Silicon MPS + backend, plus the ``accelerator`` value DeepTab would pick by default. It is + safe to call at import time and never raises on machines without a GPU. + + Parameters + ---------- + detailed : bool, default=False + When ``False``, return a compact summary: core count, device counts, + availability flags, and the recommended accelerator. When ``True``, + also include per-GPU memory, compute capability, multiprocessor count, + the CUDA / cuDNN versions PyTorch was built against, and MPS memory + counters where the build exposes them. + + Returns + ------- + dict + A nested dictionary with the keys ``platform``, ``cpu``, ``cuda``, + ``mps``, and ``recommended_accelerator``. + + Examples + -------- + >>> from deeptab import get_hardware_info + >>> info = get_hardware_info() + >>> sorted(info) + ['cpu', 'cuda', 'mps', 'platform', 'recommended_accelerator'] + >>> info["cpu"]["logical_cores"] >= 1 + True + """ + cuda_available = torch.cuda.is_available() + mps_available = _mps_available() + + info: dict[str, Any] = { + "platform": { + "system": platform.system(), + "machine": platform.machine(), + "python": platform.python_version(), + "torch": torch.__version__, + }, + "cpu": { + "logical_cores": os.cpu_count(), + }, + "cuda": { + "available": cuda_available, + "device_count": torch.cuda.device_count() if cuda_available else 0, + "devices": _cuda_devices(detailed) if cuda_available else [], + }, + "mps": { + "available": mps_available, + "built": _mps_built(), + }, + "recommended_accelerator": _recommended_accelerator(cuda_available, mps_available), + } + + if detailed: + info["platform"]["processor"] = platform.processor() + info["platform"]["python_implementation"] = platform.python_implementation() + info["platform"]["executable"] = sys.executable + info["cuda"]["built_version"] = torch.version.cuda + cudnn = getattr(torch.backends, "cudnn", None) + info["cuda"]["cudnn_version"] = cudnn.version() if cuda_available and cudnn is not None else None + if mps_available: + info["mps"].update(_mps_detail()) + + return info + + +def print_hardware_info(detailed: bool = False) -> None: + """Print :func:`get_hardware_info` as a readable report. + + Parameters + ---------- + detailed : bool, default=False + Forwarded to :func:`get_hardware_info`. When ``True``, the report adds + per-GPU memory and capability, build versions, and MPS memory counters. + + Examples + -------- + >>> from deeptab import print_hardware_info + >>> print_hardware_info() # doctest: +SKIP + DeepTab hardware report + ----------------------- + Platform: Darwin (arm64), Python 3.11.8, PyTorch 2.2.0 + ... + """ + info = get_hardware_info(detailed=detailed) + plat = info["platform"] + cpu = info["cpu"] + cuda = info["cuda"] + mps = info["mps"] + + lines = [ + "DeepTab hardware report", + "-----------------------", + f"Platform: {plat['system']} ({plat['machine']}), Python {plat['python']}, PyTorch {plat['torch']}", + f"CPU: {cpu['logical_cores']} logical cores", + ] + + if cuda["available"]: + lines.append(f"CUDA: available, {cuda['device_count']} device(s)") + for device in cuda["devices"]: + if detailed: + lines.append( + f" [{device['index']}] {device['name']}: " + f"{device['total_memory_gb']} GB total, " + f"{device['free_memory_gb']} GB free, " + f"compute capability {device['compute_capability']}, " + f"{device['multi_processor_count']} SMs" + ) + else: + lines.append(f" [{device['index']}] {device['name']}") + if detailed: + lines.append(f" Built against CUDA {cuda['built_version']}, cuDNN {cuda['cudnn_version']}") + else: + lines.append("CUDA: not available") + + if mps["available"]: + mps_line = "MPS (Apple Silicon): available" + if detailed and "driver_allocated_memory_gb" in mps: + allocated = mps["driver_allocated_memory_gb"] + if allocated > 0: + mps_line += f", {allocated} GB driver-allocated" + else: + mps_line += ", none allocated yet" + lines.append(mps_line) + else: + lines.append(f"MPS (Apple Silicon): not available (built: {mps['built']})") + + lines.append(f"Recommended accelerator: {info['recommended_accelerator']}") + + print("\n".join(lines)) diff --git a/deeptab/core/observability.py b/deeptab/core/observability.py index 66bca14a..f9b5f17d 100644 --- a/deeptab/core/observability.py +++ b/deeptab/core/observability.py @@ -300,12 +300,9 @@ def build_structlog_logger(config: ObservabilityConfig, run_dir: str | None = No ImportError If ``structlog`` is not installed, with an actionable install hint. """ - try: - import structlog # type: ignore[import-untyped] - except ImportError as exc: - raise ImportError( - "structlog is required when structured_logging=True. Install it with: pip install 'deeptab[logs]'" - ) from exc + from deeptab.core.optional_deps import require_structlog + + structlog = require_structlog() import json import os @@ -458,16 +455,15 @@ def build_lightning_loggers( """ import os + from deeptab.core.optional_deps import require_mlflow, require_tensorboard + loggers: list[Any] = [] for tracker in config.experiment_trackers: if tracker == "mlflow": - try: - from lightning.pytorch.loggers import MLFlowLogger - except ImportError as exc: - raise ImportError( - "MLflow logging requires the mlflow package. Install it with: pip install 'deeptab[mlflow]'" - ) from exc + require_mlflow() + from lightning.pytorch.loggers import MLFlowLogger + # Ensure the artifact location directory exists if config.mlflow_artifact_location: os.makedirs(config.mlflow_artifact_location, exist_ok=True) @@ -482,13 +478,9 @@ def build_lightning_loggers( ) elif tracker == "tensorboard": - try: - from lightning.pytorch.loggers import TensorBoardLogger - except ImportError as exc: - raise ImportError( - "TensorBoard logging requires the tensorboard package. " - "Install it with: pip install 'deeptab[tensorboard]'" - ) from exc + require_tensorboard() + from lightning.pytorch.loggers import TensorBoardLogger + loggers.append( TensorBoardLogger( save_dir=config.tensorboard_save_dir, diff --git a/deeptab/core/optional_deps.py b/deeptab/core/optional_deps.py new file mode 100644 index 00000000..87e3e854 --- /dev/null +++ b/deeptab/core/optional_deps.py @@ -0,0 +1,86 @@ +"""Guards for optional third-party dependencies. + +DeepTab keeps its default install lightweight: structured logging and the +experiment-tracking backends are shipped as optional extras. Each helper here +imports one optional dependency on demand and raises a clear, actionable +:class:`ImportError` — pointing at the matching ``pip install 'deeptab[...]'`` +command — when the package is not installed. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from types import ModuleType + + +def require_structlog() -> ModuleType: + """Return the :mod:`structlog` module. + + Returns + ------- + module + The imported ``structlog`` module. + + Raises + ------ + ImportError + If ``structlog`` is not installed, with an actionable install hint. + """ + try: + import structlog # type: ignore[import-untyped] + except ImportError as exc: + raise ImportError( + "Structured logging requires the optional 'structlog' dependency. " + "Install it with: pip install 'deeptab[logs]'" + ) from exc + + return structlog + + +def require_mlflow() -> ModuleType: + """Return the :mod:`mlflow` module. + + Returns + ------- + module + The imported ``mlflow`` module. + + Raises + ------ + ImportError + If ``mlflow`` is not installed, with an actionable install hint. + """ + try: + import mlflow # type: ignore[import-untyped] + except ImportError as exc: + raise ImportError( + "MLflow tracking requires the optional 'mlflow' dependency. Install it with: pip install 'deeptab[mlflow]'" + ) from exc + + return mlflow + + +def require_tensorboard() -> Any: + """Return ``torch.utils.tensorboard.SummaryWriter``. + + Returns + ------- + type + The ``SummaryWriter`` class from ``torch.utils.tensorboard``. + + Raises + ------ + ImportError + If ``tensorboard`` is not installed, with an actionable install hint. + """ + try: + from torch.utils.tensorboard import SummaryWriter + except ImportError as exc: + raise ImportError( + "TensorBoard logging requires the optional 'tensorboard' dependency. " + "Install it with: pip install 'deeptab[tensorboard]'" + ) from exc + + return SummaryWriter diff --git a/deeptab/core/sklearn_compat.py b/deeptab/core/sklearn_compat.py index 6326c822..60f70bc6 100644 --- a/deeptab/core/sklearn_compat.py +++ b/deeptab/core/sklearn_compat.py @@ -24,6 +24,8 @@ def ensure_dataframe(X: Any, context: str = "fit") -> pd.DataFrame: - Empty DataFrames raise :exc:`~deeptab.core.exceptions.EmptyDataError`. - ``bool`` columns are silently cast to ``int8``; they represent valid binary features but sklearn's ``SimpleImputer`` rejects the ``bool`` dtype. + - ``category`` columns are silently cast to ``object`` so they are detected and + preprocessed as categorical features (the underlying categories are kept). - Any remaining non-numeric, non-object column dtype raises :exc:`~deeptab.core.exceptions.ColumnDtypeError` naming each offending column. - Columns where every value is NaN issue a @@ -56,9 +58,18 @@ def ensure_dataframe(X: Any, context: str = "fit") -> pd.DataFrame: df = df.copy() df[bool_cols] = df[bool_cols].astype("int8") + # category → object: treat pandas categoricals as categorical features. + # The dtype detector downstream keys off object/string dtype, so cast here + # while preserving the underlying category values. + cat_cols = [c for c, dt in df.dtypes.items() if isinstance(dt, pd.CategoricalDtype)] + if cat_cols: + if not bool_cols: + df = df.copy() + df = df.astype(dict.fromkeys(cat_cols, "object")) + # Catch any other dtype that is neither numeric nor object/string bad_cols = [ - (c, dt) + (str(c), dt) for c, dt in df.dtypes.items() if not ( pd.api.types.is_numeric_dtype(dt) or pd.api.types.is_object_dtype(dt) or pd.api.types.is_string_dtype(dt) diff --git a/deeptab/models/base.py b/deeptab/models/base.py index bf3889bc..0301bbfb 100644 --- a/deeptab/models/base.py +++ b/deeptab/models/base.py @@ -148,7 +148,6 @@ def __init__( trainer_config=None, observability_config: ObservabilityConfig | None = None, random_state=None, - **kwargs, ): model_cls = type(self)._model_cls config_cls = type(self)._config_cls @@ -202,28 +201,19 @@ def __init__( self._optimizer_type = getattr(self.trainer_config, "optimizer_type", "Adam") self._optimizer_kwargs = {} else: - # ---- Legacy flat-kwargs path (backward compat) ---- + # ---- No configs provided: fall back to defaults ---- self.model_config = None self.preprocessing_config = None self.trainer_config = None - self._config_kwargs = { - k: v - for k, v in kwargs.items() - if k not in self._preprocessor_arg_names and not k.startswith("optimizer") - } - self.config = config_cls(**self._config_kwargs) + self._config_kwargs = {} + self.config = config_cls() - self._preprocessor_kwargs = {k: v for k, v in kwargs.items() if k in self._preprocessor_arg_names} - self._preprocessor = Preprocessor(**self._preprocessor_kwargs) + self._preprocessor_kwargs = {} + self._preprocessor = Preprocessor() - self._optimizer_type = kwargs.get("optimizer_type", "Adam") - self._optimizer_kwargs = { - k: v - for k, v in kwargs.items() - if k not in ["lr", "weight_decay", "patience", "lr_patience", "optimizer_type"] - and k.startswith("optimizer_") - } + self._optimizer_type = "Adam" + self._optimizer_kwargs = {} self._estimator = model_cls self._task_model = None diff --git a/deeptab/training/lightning_module.py b/deeptab/training/lightning_module.py index 5ea3fdd5..9619add7 100644 --- a/deeptab/training/lightning_module.py +++ b/deeptab/training/lightning_module.py @@ -205,6 +205,17 @@ def __init__( # Store custom metrics self.train_metrics = train_metrics or {} self.val_metrics = val_metrics or {} + # torchmetrics ``Metric`` objects are ``nn.Module`` subclasses that hold + # internal state tensors. Register them as submodules so Lightning moves + # that state to the training device; otherwise the state stays on CPU and + # raises a device-mismatch error on GPU/MPS. Plain-callable metrics carry + # no device state and are left untouched. + self._train_metric_modules = nn.ModuleDict( + {name: metric for name, metric in self.train_metrics.items() if isinstance(metric, nn.Module)} + ) + self._val_metric_modules = nn.ModuleDict( + {name: metric for name, metric in self.val_metrics.items() if isinstance(metric, nn.Module)} + ) # Scheduler / monitoring config self.scheduler_type = scheduler_type diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 00000000..de41f7ff --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,16 @@ +--- +orphan: true +--- + +# API Reference + +Complete API documentation for DeepTab, organised by module: the public estimators, +configuration dataclasses, data utilities, distribution families, metrics, and the +underlying Lightning training modules. + +- **[Models](models/index)**: Classifier, Regressor, and LSS classes +- **[Configs](configs/index)**: Configuration dataclasses +- **[Data](data/index)**: Datasets, data modules, and schemas +- **[Distributions](distributions/index)**: LSS distribution families +- **[Metrics](metrics/index)**: Task-aware metric classes +- **[Training](training/index)**: Lightning modules for advanced use diff --git a/docs/core_concepts/config_system.md b/docs/core_concepts/config_system.md index 41f74d93..00311391 100644 --- a/docs/core_concepts/config_system.md +++ b/docs/core_concepts/config_system.md @@ -3,7 +3,7 @@ DeepTab uses a split-config API. Architecture, preprocessing, and training settings are kept in separate dataclasses so experiments can change one layer without mixing concerns. ```{important} -The model constructor accepts `model_config`, `preprocessing_config`, and `trainer_config`. Flat constructor arguments are legacy compatibility only; new documentation and experiments should use split configs. +The model constructor accepts `model_config`, `preprocessing_config`, and `trainer_config`. All settings must go through these config objects; the flat constructor arguments from v1 are no longer accepted and raise a `TypeError`. ``` ## The Three Config Layers @@ -16,6 +16,38 @@ The model constructor accepts `model_config`, `preprocessing_config`, and `train All three are optional. If omitted, DeepTab creates default config objects internally. +### Moving from v1 + +In v1, architecture, preprocessing, and training options were all passed as flat keyword arguments on the estimator. In v2 those same options live in three dedicated config objects. The estimator call is the only thing that changes; `fit`, `predict`, and `evaluate` behave exactly as before. + +```python +# v1: every option flat on the estimator +from deeptab.models import MambularClassifier + +model = MambularClassifier( + d_model=128, + n_layers=4, + numerical_preprocessing="ple", + lr=1e-3, +) +``` + +```python +# v2: options grouped by concern +from deeptab.models import MambularClassifier +from deeptab.configs import MambularConfig, PreprocessingConfig, TrainerConfig + +model = MambularClassifier( + model_config=MambularConfig(d_model=128, n_layers=4), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="ple"), + trainer_config=TrainerConfig(lr=1e-3), +) +``` + +```{tip} +Each option moves to the config that owns its concern: architecture fields go to the model config, anything passed to `pretab.Preprocessor` goes to `PreprocessingConfig`, and training or optimizer fields go to `TrainerConfig`. The tables further down list which fields belong where. +``` + ### Where to find every field Each config has a complete, authoritative field reference. Use the table below as the index. diff --git a/docs/core_concepts/custom_models.md b/docs/core_concepts/custom_models.md index 4d760788..de78adcd 100644 --- a/docs/core_concepts/custom_models.md +++ b/docs/core_concepts/custom_models.md @@ -213,13 +213,15 @@ class MyEmbeddedModel(BaseModel): ## Checklist -- [ ] Config is a `@dataclass` subclassing `BaseModelConfig`. -- [ ] Mutable config defaults use `field(default_factory=...)`. -- [ ] Architecture subclasses `BaseModel` and calls `super().__init__(config=config, **kwargs)`. -- [ ] Constructor calls `self.save_hyperparameters(ignore=["feature_information"])`. -- [ ] Input width comes from `get_feature_dimensions(...)` or an `EmbeddingLayer`, never a hard-coded value. -- [ ] `forward` returns raw outputs (no final softmax/sigmoid). -- [ ] Each estimator sets `_model_cls` and `_config_cls`. +| Piece | Requirement | +| ------------ | ---------------------------------------------------------------------------------------------- | +| Config | A `@dataclass` subclassing `BaseModelConfig`. | +| Config | Mutable defaults use `field(default_factory=...)`. | +| Architecture | Subclasses `BaseModel` and calls `super().__init__(config=config, **kwargs)`. | +| Architecture | Constructor calls `self.save_hyperparameters(ignore=["feature_information"])`. | +| Architecture | Input width comes from `get_feature_dimensions(...)` or an `EmbeddingLayer`, never hard-coded. | +| Architecture | `forward` returns raw outputs (no final softmax/sigmoid). | +| Estimator | Each estimator sets `_model_cls` and `_config_cls`. | ## Next Steps diff --git a/docs/core_concepts/index.md b/docs/core_concepts/index.md new file mode 100644 index 00000000..42575c4b --- /dev/null +++ b/docs/core_concepts/index.md @@ -0,0 +1,18 @@ +--- +orphan: true +--- + +# Core Concepts + +These pages explain how DeepTab works under the hood: the scikit-learn interface, +the split-config system, the training and evaluation pipeline, observability, and +deployment-safe inference. + +- **[sklearn API](sklearn_api)**: The fit/predict/evaluate interface +- **[Model Tiers](model_tiers)**: Stable versus experimental models +- **[Custom Models](custom_models)**: Building your own architectures +- **[Config System](config_system)**: Split configuration for model, preprocessing, and training +- **[Observability](observability)**: Lifecycle events, structured logging, and experiment tracking +- **[Training and Evaluation](training_and_evaluation)**: The fit pipeline, metrics, and reproducibility +- **[Model Operations](model_operations)**: Serialisation and inspection +- **[Inference](inference)**: Deployment-safe prediction with `InferenceModel` diff --git a/docs/core_concepts/model_operations.md b/docs/core_concepts/model_operations.md index 01dad4c1..7a684541 100644 --- a/docs/core_concepts/model_operations.md +++ b/docs/core_concepts/model_operations.md @@ -24,23 +24,23 @@ predictions = loaded.predict(X_test) ``` ```{tip} -Use the class that matches the saved model type. Using the wrong class will raise an error with a clear message pointing to the mismatch. +`load()` reconstructs whatever model type was saved, regardless of which estimator class you call it on. Calling `MLPRegressor.load("classifier.deeptab")` still returns an `MLPClassifier`. Calling `load()` from the matching class keeps the intent clear, but the returned object always has the saved type. ``` ### What is inside the artifact The bundle saved to disk is a PyTorch-serialised dictionary containing: -| Key | Contents | -| ----------------------- | ------------------------------------------------------------------------- | -| `task_model_state_dict` | Neural network weights (Lightning module state dict) | -| `preprocessor` | Fitted `pretab.Preprocessor` object | -| `feature_info` | Numerical, categorical, and embedding feature metadata | -| `config` | Model config dataclass used during training | -| `artifact_metadata` | Architecture, schema, preprocessing, task, and version sub-blocks | -| `input_columns` | Ordered list of column names, for feature-name validation at predict time | -| `classes_` | Class labels for classifiers | -| `versions` | Python, PyTorch, Lightning, NumPy, pandas, scikit-learn versions | +| Key | Contents | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `task_model_state_dict` | Neural network weights (Lightning module state dict) | +| `preprocessor` | Fitted `pretab.Preprocessor` object | +| `feature_info` | Numerical, categorical, and embedding feature metadata | +| `config` | Model config dataclass used during training | +| `artifact_metadata` | Architecture, schema, preprocessing, task, and version sub-blocks | +| `input_columns` | Ordered list of column names, for feature-name validation at predict time | +| `classes_` | Class labels for classifiers | +| `versions` | Python, platform, and key package versions (`deeptab`, `torch`, `lightning`, `numpy`, `pandas`, `scikit-learn`, `pretab`, ...) | ### Why everything lives in one bundle @@ -142,7 +142,7 @@ The schema grows with the number of features, not the number of rows. It is the ## Model Inspection -All DeepTab estimators inherit `InspectionMixin`, which provides four read-only methods and one dry-run profiler. They are safe to call before or after fitting. +All DeepTab estimators inherit `InspectionMixin`, which provides four read-only methods and one dry-run profiler. `describe()`, `summary()`, and `runtime_info()` are safe to call before or after fitting; `parameter_table()` requires a built model and raises otherwise. ### `describe()`: structured dict @@ -151,15 +151,19 @@ Returns a structured snapshot of the estimator and its fitted state: ```python info = model.describe() # { -# "estimator": "MLPClassifier", -# "architecture": "MLP", -# "task": "classification", -# "built": True, -# "fitted": True, -# "model_config": "MLPConfig", -# "feature_counts": {"numerical": 8, "categorical": 2, "embedding": 0, "total": 10}, -# "num_classes": 2, -# "parameters": {"total": 45312, "trainable": 45312, "non_trainable": 0}, +# "estimator": "MLPClassifier", +# "architecture": "MLP", +# "task": "classification", +# "built": True, +# "fitted": True, +# "model_config": "MLPConfig", +# "preprocessing_config": "PreprocessingConfig", +# "trainer_config": "TrainerConfig", +# "feature_counts": {"numerical": 8, "categorical": 2, "embedding": 0, "total": 10}, +# "num_classes": 3, +# "family": None, +# "returns_ensemble": False, +# "parameters": {"total": 45312, "trainable": 45312, "non_trainable": 0}, # } ``` @@ -180,10 +184,12 @@ print(model.summary()) # Features: 10 total (8 numerical, 2 categorical, 0 embedding) # Parameters: 45,312 total, 45,312 trainable, 0 non-trainable # Device: cpu -# Precision: None -# Accelerator: None +# Precision: 32-true +# Accelerator: CPUAccelerator ``` +The `Device`, `Precision`, and `Accelerator` lines appear only once a trainer is attached (after building or fitting); they are omitted when the value is unknown. + ### `parameter_table()`: per-parameter DataFrame Returns one row per parameter: @@ -208,8 +214,8 @@ info = model.runtime_info() # "fitted": True, # "device": "cpu", # "dtype": "float32", -# "precision": None, -# "accelerator": None, +# "precision": "32-true", +# "accelerator": "CPUAccelerator", # "max_epochs": 100, # "current_epoch": 87, # "batch_size": 64, diff --git a/docs/core_concepts/model_tiers.md b/docs/core_concepts/model_tiers.md index 2edb3743..73a30149 100644 --- a/docs/core_concepts/model_tiers.md +++ b/docs/core_concepts/model_tiers.md @@ -49,38 +49,20 @@ guide. ## Choosing a Tier -Use stable models when: - -- the code will run in production; -- experiments need long-term reproducibility; -- collaborators need a lower-maintenance baseline; -- APIs must remain stable across minor releases. - -Use experimental models when: - -- you are evaluating recent architectures; -- you can pin DeepTab to an exact version; -- breaking changes are acceptable; -- the goal is research feedback rather than deployment. - -## Version Pinning - -For stable-only projects, pin a compatible range: - -```text -deeptab>=2.0,<3.0 +| Consideration | Stable | Experimental | +| ------------------ | -------------------------------------- | ---------------------------------------- | +| Primary use | Production and long-running projects | Prototyping and research comparisons | +| Reproducibility | Stable across minor releases | Requires pinning an exact version | +| API stability | Compatible within a major version | May introduce breaking changes | +| Maintenance burden | Lower; safe baseline for collaborators | Higher; tracks recent, evolving research | +| Goal | Reliable deployment | Early evaluation and research feedback | + +```{note} +**Version pinning.** For stable-only projects, pin a compatible range such as +`deeptab>=2.0,<3.0`. For projects that use experimental models, pin the exact +version (`deeptab==2.0.0`), since their APIs may change between releases. ``` -For experimental-model projects, pin the exact version: - -```text -deeptab==2.0.0 -``` - -## Documentation Policy - -Stable model docs should document both the paper idea and the actual DeepTab implementation. Experimental docs should be even more explicit about implementation differences, config limitations, and expected API volatility. - ## Next Steps - [Stable Models](../model_zoo/stable/index) diff --git a/docs/core_concepts/observability.md b/docs/core_concepts/observability.md index 4d05de7d..ac06935c 100644 --- a/docs/core_concepts/observability.md +++ b/docs/core_concepts/observability.md @@ -6,6 +6,20 @@ DeepTab can record what happens during training without you writing a single cal Observability is entirely opt-in. Estimators created without an `ObservabilityConfig` train exactly as before and emit nothing, so notebooks stay quiet by default. ``` +The default `pip install deeptab` does not include the observability backends. Install the extra you need: + +```bash +pip install 'deeptab[logs]' # structlog (structured logging) +pip install 'deeptab[tensorboard]' # TensorBoard tracker +pip install 'deeptab[mlflow]' # MLflow tracker +pip install 'deeptab[tracking]' # TensorBoard + MLflow +pip install 'deeptab[all]' # structlog + TensorBoard + MLflow +``` + +```{note} +Each backend is loaded lazily, so a missing package raises only when you enable the matching feature. +``` + --- ## Attaching observability @@ -18,7 +32,7 @@ from deeptab.models import MambularClassifier obs = ObservabilityConfig( experiment_name="churn_baseline", - structured_logging=True, # human-readable console + JSON event log + structured_logging=True, # console event log (add log_to_file=True for JSONL) experiment_trackers=["mlflow"], # also supports "tensorboard" ) @@ -46,12 +60,12 @@ Every output path is derived from `root_dir`, producing a single organised tree ```text deeptab_runs/ - runs/churn_baseline/20260611_174830_8f3a2c/ + runs/churn_baseline/20260611_174830_8f3a2c1d/ config.yaml # estimator hyperparameters lifecycle.jsonl # structured event log (when log_to_file=True) summary.json # final metrics - checkpoints/best.ckpt - tensorboard/churn_baseline/20260611_174830_8f3a2c/ + checkpoints/best_model.ckpt + tensorboard/churn_baseline/20260611_174830_8f3a2c1d/ events.out.tfevents... mlflow/ backend/mlflow.db @@ -66,23 +80,23 @@ The run identifier combines a timestamp and a short hash, so concurrent or repea `ObservabilityConfig` is a dataclass. All fields are optional and resolve sensible defaults relative to `root_dir`. -| Field | Default | Purpose | -| -------------------------- | ---------------- | ------------------------------------------------------------------------------ | -| `root_dir` | `"deeptab_runs"` | Base directory for all observability outputs. | -| `experiment_name` | `"default"` | Logical label used to group related runs. | -| `structured_logging` | `False` | Enable structured runtime logging via `structlog`. | -| `log_to_console` | `True` | Stream compact human-readable output to stdout. | -| `log_to_file` | `False` | Write a per-run `lifecycle.jsonl` inside the run directory. | -| `verbosity` | `1` | Which lifecycle events are emitted when `structured_logging=True` (see below). | -| `experiment_trackers` | `[]` | Lightning loggers to activate: `"tensorboard"`, `"mlflow"`, or both. | -| `tensorboard_save_dir` | `""` | Resolved to `/tensorboard` when empty. | -| `tensorboard_name` | `"deeptab"` | Sub-directory label inside the TensorBoard save dir. | -| `mlflow_experiment_name` | `"deeptab"` | Name of the MLflow experiment. | -| `mlflow_tracking_uri` | `""` | Resolved to a local SQLite store under `/mlflow` when empty. | -| `mlflow_artifact_location` | `""` | Resolved to `/mlflow/artifacts` when empty. | -| `mlflow_run_name` | `None` | Human-readable label for the MLflow run. | -| `mlflow_log_model` | `True` | Upload model checkpoints as MLflow artifacts. | -| `logger` | `None` | A user-provided Lightning logger appended alongside any built-in trackers. | +| Field | Default | Purpose | +| -------------------------- | ---------------- | ------------------------------------------------------------------------------------- | +| `root_dir` | `"deeptab_runs"` | Base directory for all observability outputs. | +| `experiment_name` | `"default"` | Logical label used to group related runs. | +| `structured_logging` | `False` | Enable structured runtime logging via `structlog`. | +| `log_to_console` | `True` | Stream compact human-readable output to stdout. | +| `log_to_file` | `False` | Write a per-run `lifecycle.jsonl` inside the run directory. | +| `verbosity` | `1` | Which lifecycle events are emitted when `structured_logging=True` (see below). | +| `experiment_trackers` | `[]` | Lightning loggers to activate: `"tensorboard"`, `"mlflow"`, or both. | +| `tensorboard_save_dir` | `""` | Resolved to `/tensorboard` when empty. | +| `tensorboard_name` | `"deeptab"` | Reserved label field; the TensorBoard sub-directory currently uses `experiment_name`. | +| `mlflow_experiment_name` | `"deeptab"` | Name of the MLflow experiment. | +| `mlflow_tracking_uri` | `""` | Resolved to a local SQLite store under `/mlflow` when empty. | +| `mlflow_artifact_location` | `""` | Resolved to `/mlflow/artifacts` when empty. | +| `mlflow_run_name` | `None` | Human-readable label for the MLflow run. | +| `mlflow_log_model` | `True` | Upload model checkpoints as MLflow artifacts. | +| `logger` | `None` | A user-provided Lightning logger appended alongside any built-in trackers. | ```{note} `experiment_trackers` is a list, not a single string. Pass `["tensorboard"]`, `["mlflow"]`, or `["mlflow", "tensorboard"]` to activate one or both. @@ -135,13 +149,17 @@ from deeptab.core.observability import ObservabilityConfig obs = ObservabilityConfig( logger=WandbLogger(project="churn"), # your existing tracker - experiment_trackers=["tensorboard"], # optional: keep DeepTab trackers too + experiment_trackers=["tensorboard"], # needed for the custom logger to attach ) model = MambularClassifier(observability_config=obs) model.fit(X_train, y_train, max_epochs=50) ``` +```{warning} +A custom `logger` is only attached when `experiment_trackers` has at least one entry. With an empty `experiment_trackers`, DeepTab suppresses all Lightning loggers (so no stray `lightning_logs/` directory is created) and the `logger` is dropped. Keep at least one tracker active, such as `["tensorboard"]` above, for your logger to be picked up. +``` + ```{note} The `logger` field accepts a single Lightning logger instance. To attach several at once, wire them through the trackers you control or compose them in your own framework, then hand DeepTab the one entry point. ``` diff --git a/docs/core_concepts/training_and_evaluation.md b/docs/core_concepts/training_and_evaluation.md index b8f8bf61..1e88e5ba 100644 --- a/docs/core_concepts/training_and_evaluation.md +++ b/docs/core_concepts/training_and_evaluation.md @@ -58,14 +58,14 @@ cfg = PreprocessingConfig( ) ``` -| Field | Purpose | -| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `numerical_preprocessing` | Transform strategy: `"standardization"`, `"quantile"`, `"ple"`, `"minmax"`, `"robust"`, `"box-cox"`, `"yeo-johnson"`, or `None`. | -| `categorical_preprocessing` | Encoding strategy: `"int"`, `"one-hot"`, etc. | -| `n_bins` | Bins for binned / PLE-style transforms. | -| `scaling_strategy` | Optional post-transform scaling: `"standardization"`, `"minmax"`, `"robust"`, or `None`. | -| `binning_strategy`, `use_decision_tree_bins` | How bin edges are built. | -| `n_knots`, `degree`, `spline_implementation` | Spline preprocessing controls. | +| Field | Purpose | +| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `numerical_preprocessing` | Transform strategy: `"standardization"`, `"quantile"`, `"ple"`, `"splines"`, `"minmax"`, `"robust"`, `"box-cox"`, `"yeo-johnson"`, or `None`. | +| `categorical_preprocessing` | Encoding strategy: `"int"`, `"one-hot"`, etc. | +| `n_bins` | Bins for binned / PLE-style transforms. | +| `scaling_strategy` | Optional post-transform scaling: `"standardization"`, `"minmax"`, `"robust"`, or `None`. | +| `binning_strategy`, `use_decision_tree_bins` | How bin edges are built. | +| `n_knots`, `degree`, `spline_implementation` | Spline preprocessing controls. | Practical starting points: diff --git a/docs/developer_guide/ci_cd.md b/docs/developer_guide/ci_cd.md index 205ce248..bccf1f2a 100644 --- a/docs/developer_guide/ci_cd.md +++ b/docs/developer_guide/ci_cd.md @@ -16,55 +16,23 @@ DeepTab uses GitHub Actions for continuous integration and delivery. All workflo ## ci.yml (continuous integration) -Runs on every push to `main` and every pull request targeting `main`. Cancels in-progress runs for the same branch via `concurrency`. +Runs on every push to `main` and every pull request targeting `main`. In-progress runs for the same branch are cancelled via `concurrency`. -### Jobs +| Job | Runner / Python | What it does | Depends on | +| ----------- | --------------- | ------------------------------------------ | ---------- | +| `lint` | ubuntu / 3.10 | `ruff check .` and `ruff format --check .` | - | +| `typecheck` | ubuntu / 3.10 | `pyright` | - | +| `build` | ubuntu / 3.10 | `poetry build` and `twine check dist/*` | - | +| `tests` | full matrix | `pytest tests/ -v` | - | +| `smoke` | ubuntu / 3.12 | `pytest tests/ -m smoke --tb=short` | `lint` | +| `coverage` | ubuntu / 3.12 | branch coverage uploaded to Codecov | `tests` | -**`lint`** runs on `ubuntu-latest` / Python 3.10: +The `lint`, `typecheck`, `build`, and `tests` jobs run in parallel with `fail-fast: false`, so one failing matrix cell does not cancel the rest. The `tests` matrix covers every supported Python and OS combination listed in the [Support Matrix](support_matrix.md). -```bash -ruff check . # style and correctness -ruff format --check . # formatting (no changes applied) -``` - -**`typecheck`** runs on `ubuntu-latest` / Python 3.10: - -```bash -pyright -``` - -**`build`** runs on `ubuntu-latest` / Python 3.10: - -```bash -poetry build -twine check dist/* -``` - -**`tests`** runs across a full matrix: - -| Dimension | Values | -| --------- | ------------------------------------------------- | -| OS | `ubuntu-latest`, `macos-latest`, `windows-latest` | -| Python | `3.10`, `3.11`, `3.12`, `3.13` | - -```bash -pytest tests/ -v -``` - -**`smoke`** runs on `ubuntu-latest` / Python 3.12 after `lint` passes. It runs only the fast sanity-check tests marked with `@pytest.mark.smoke`: - -```bash -pytest tests/ -v -m smoke --tb=short +```{note} +The two Python versions are intentional. Compatibility-sensitive jobs (`lint`, `typecheck`, `build`) pin to the **lowest** supported version (3.10) so they catch code that relies on newer syntax or stdlib than we promise to support. The fast single-version gates (`smoke`, `coverage`) use a recent version (3.12), since they check behavior rather than compatibility. Full compatibility is verified by the `tests` matrix. ``` -**`coverage`** runs on `ubuntu-latest` / Python 3.12 after `tests` pass. It measures branch coverage and uploads the report to [Codecov](https://codecov.io/gh/OpenTabular/DeepTab): - -```bash -pytest tests/ --cov=deeptab --cov-branch --cov-report=xml:coverage.xml -q -``` - -The `lint`, `typecheck`, `build`, and `tests` jobs are independent and run in parallel, with `fail-fast: false` so a failure in one matrix cell does not cancel the others. The `smoke` job depends on `lint`, and `coverage` depends on `tests`. - --- ## docs.yml (documentation build) @@ -95,42 +63,21 @@ A `workflow_dispatch`-only workflow. Builds the package with Poetry and validate --- -## publish-testpypi.yml (release candidate publishing) +## Publishing (publish-testpypi.yml / publish-pypi.yml) -Triggered by any tag matching `v*.*.*rc*`. Uses [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/), so no `PYPI_TOKEN` secret is required. +Both publish jobs use [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/), so no `PYPI_TOKEN` secret is required. Each builds with `poetry build`, publishes, then creates a GitHub release. -Steps: +| Workflow | Tag pattern | Target | Release type | +| ---------------------- | ------------------ | -------------------------------------------------- | ------------ | +| `publish-testpypi.yml` | `v*.*.*rc*` | [TestPyPI](https://test.pypi.org/project/deeptab/) | Pre-release | +| `publish-pypi.yml` | `v*.*.*` (no `rc`) | [PyPI](https://pypi.org/project/deeptab/) | Release | -1. Build the package with `poetry build`. -2. Publish to [TestPyPI](https://test.pypi.org/project/deeptab/). -3. Create a GitHub pre-release via `gh release create`. - -The `pypi-publish` GitHub Environment is required; it must have the `v*rc*` tag pattern in its protection rules. - ---- - -## publish-pypi.yml (stable release publishing) - -Triggered by any tag matching `v*.*.*` that does **not** contain `rc` (stable only). Also uses OIDC trusted publishing. - -Steps: - -1. Build the package with `poetry build`. -2. Publish to [PyPI](https://pypi.org/project/deeptab/). -3. Create a GitHub release with auto-generated release notes. - -See the [Release process](release.md) page for the full end-to-end procedure including when and how to push these tags. +The `pypi-publish` GitHub Environment must allow the matching tag pattern in its protection rules. See the [Release process](release.md) page for when and how to push these tags. --- ## Adding or modifying a workflow 1. Edit the relevant YAML file in `.github/workflows/`. -2. Use [act](https://github.com/nektos/act) to test locally before pushing: - -```bash -act push --job tests -``` - -3. Keep job names consistent, since they are displayed in PR status checks and on the Actions tab. -4. Pin third-party actions to a full commit SHA or a tagged version (e.g. `actions/checkout@v4`) and keep them up to date via `just update` (which runs `pre-commit autoupdate`). +2. Keep job names consistent, since they appear in PR status checks and on the Actions tab. +3. Pin third-party actions to a tagged version or full commit SHA (e.g. `actions/checkout@v4`) and keep them current via `just update` (which runs `pre-commit autoupdate`). diff --git a/docs/developer_guide/contributing.md b/docs/developer_guide/contributing.md index 1fc50cfe..c7b83529 100644 --- a/docs/developer_guide/contributing.md +++ b/docs/developer_guide/contributing.md @@ -1,153 +1,78 @@ # Contribution Guidelines -Thank you for considering contributing to our Python package! We appreciate your time and effort in helping us improve our project. Please take a moment to review the following guidelines to ensure a smooth and efficient contribution process. +Thanks for contributing to DeepTab. This page covers environment setup, the local workflow, and what a pull request needs to pass review. ## Code of Conduct -We kindly request all contributors to adhere to our Code of Conduct when participating in this project. It outlines our expectations for respectful and inclusive behavior within the community. +All contributors are expected to follow the project [Code of Conduct](https://github.com/OpenTabular/DeepTab/blob/main/CODE_OF_CONDUCT.md), which sets the standard for respectful and inclusive participation. -## Setting Up Development Environment +## Setting up the development environment -Before you start contributing to the project, you need to set up your development environment. This will allow you to make changes to the codebase, run tests, and build the documentation locally. The project uses `poetry` for dependency management and packaging. Along with that, `ruff` is used for source code formatting and linting. +The project uses [Poetry](https://python-poetry.org/docs/) for dependency management and the [just](https://just.systems/man/en/) command runner for common tasks (`justfile` defines testing, building, and formatting). -To set up the development environment for this Python package, follow these steps: +1. Clone the repository: -1. Clone the repository to your local machine using the command: - -``` +```bash git clone https://github.com/OpenTabular/DeepTab - cd DeepTab ``` -2. Install tools required for setting up development environment: - -- Install `poetry` for dependency management and packaging. You can install it using the following command or refer to the [official documentation](https://python-poetry.org/docs/) for more information. - -``` -pip install poetry -``` - -- Install `just` command runner. You can install it using the following command or refer to the [official documentation](https://just.systems/man/en/) for more information. +2. Install the prerequisites: `pip install poetry` and `just` (see the [just install guide](https://just.systems/man/en/packages.html), e.g. `brew install just`). -`justfile` in the source directory is used to define and run common tasks like testing, building, and formatting the codebase. - -3. In case you are able to successfully install `poetry` and `just`, you can run the following command to install the dependencies and set up the development environment: - -``` -# it will install the dependencies as defined in the pyproject.toml file -# it will also install the pre-commit hooks +3. Install dependencies and register the pre-commit hooks: +```bash just install ``` -In case you are not able to install `just`, you can follow the below steps to set up the development environment: - -``` -cd DeepTab +Without `just`, run the same steps directly: +```bash poetry install - poetry run pre-commit install --hook-type commit-msg --hook-type pre-commit --hook-type pre-push ``` -If you need to update the documentation, please install the documentation dependencies: +To work on the docs, also install the docs group with `poetry install --with docs`. -```bash -# Recommended: install via the docs dependency group -poetry install --with docs - -# Alternative: install directly -pip install -r docs/requirements_docs.txt -``` - -**Note:** You can also set up a virtual environment to isolate your development environment. - -## How to Contribute - -1. Create a new branch from `main` for your contributions. Please use descriptive and concise branch names. -2. Make your desired changes or additions to the codebase. -3. Ensure that your code adheres to [PEP8](https://peps.python.org/pep-0008/) coding style guidelines. -4. Write appropriate tests for your changes and verify they pass: - -```bash -just test -``` +## How to contribute -5. Update the documentation and examples, if necessary. -6. Build the HTML documentation and verify it works as expected: +1. Branch off `main` with a short, descriptive name. +2. Make your changes, keeping each pull request to a single logical focus. +3. Add or update tests, and run the full check suite locally before pushing: ```bash -just docs +just test # full suite with coverage +just check # lint, format, type-check, all pre-commit hooks (what CI runs) +just docs # build HTML docs (warnings treated as errors) ``` -Verify the output under `docs/_build/html/`, where `index.html` is the entry point. - -7. Run the full local check suite before pushing (lint, format, type-check, and all pre-commit hooks): - -```bash -just check -``` - -If `ruff-format` modifies any files, commit those changes before pushing: - -```bash -git add -u -git commit -m "style: apply ruff formatting" -``` - -8. Commit your changes following the Conventional Commits specification (see below): - -```bash -just commit -``` - -9. Submit a pull request from your branch to `main` in the original repository. -10. Wait for the maintainers to review your pull request. Address any feedback or comments if required. -11. Once approved, your changes will be merged into the main codebase. +4. Commit using Conventional Commits via `just commit`. If `just check` reformats files, commit those separately with `style: apply ruff formatting`. +5. Open a pull request to `main`, reference any related issues, and address review feedback until approved and merged. ## Pre-commit Hooks -This project uses [pre-commit](https://pre-commit.com/) to enforce code quality automatically. The hooks run at two stages: +This project uses [pre-commit](https://pre-commit.com/) to enforce code quality automatically. `just install` registers all three hook types so each fires at the right time: -- **commit**: `ruff` format and lint checks, plus general file hygiene hooks (trailing whitespace, end-of-file, merge conflicts). -- **push**: `pyright` type checking, which is slower and so is deferred until push. - -A separate `commit-msg` hook validates that every commit message follows the Conventional Commits format. - -`just install` registers all three hook types (`commit-msg`, `pre-commit`, `pre-push`) so everything fires at the right time automatically. +| Stage | Hook | +| ------------ | ----------------------------------------------------------------------- | +| `commit-msg` | Validates the message against Conventional Commits. | +| `pre-commit` | `ruff` format and lint, plus file hygiene (whitespace, EOF, conflicts). | +| `pre-push` | `pyright` type checking (slower, so deferred to push). Also runs in CI. | ```{important} -Run `just check` before opening a PR. It executes the commit and push stage hooks against every file in the repo, giving you the same signal CI will see. +Run `just check` before opening a PR. It executes the commit and push stage hooks against every file, giving you the same signal CI will see. ``` -```bash -# Lint and auto-fix with ruff -just lint - -# Run the ruff formatter -just format - -# Run the pyright type checker -just types - -# Run ALL hooks across ALL files (commit + push stages), equivalent to what CI checks -just check -``` +Individual recipes are available when you want to run one step: -If pre-commit reports files that _would be reformatted_, run `just format`, stage the changes, and commit before pushing. Formatting-only changes should be committed separately with `style: apply ruff formatting`. - -### Type checking (pyright) - -Type checking with `pyright` runs automatically on `git push` via the pre-push hook (registered by `just install`). It also runs in CI as the `typecheck` job in `.github/workflows/ci.yml`. - -To run it manually at any time: - -```bash -just types -``` +| Command | Action | +| ------------- | ----------------------------------------------- | +| `just lint` | Lint and auto-fix with ruff. | +| `just format` | Run the ruff formatter. | +| `just types` | Run the pyright type checker. | +| `just check` | Run all hooks across all files (commit + push). | -Fix any reported errors before opening a PR. +If pre-commit reports files that _would be reformatted_, run `just format` and commit the result separately with `style: apply ruff formatting`. ## Documentation @@ -170,20 +95,16 @@ For the end-to-end release procedure (version bump, tags, PyPI publishing) see: ## Submitting Contributions -When submitting your contributions, please ensure the following: +Before requesting review, make sure your pull request: -- Include a clear and concise description of the changes made in your pull request. -- Reference any relevant issues or feature requests in the pull request description. -- Make sure your code follows the project's coding style and conventions. -- Include appropriate tests that cover your changes, ensuring they pass successfully. -- Update the documentation if necessary to reflect the changes made. -- Ensure that your pull request has a single, logical focus. +- Has a clear description and references any related issues. +- Keeps a single, logical focus. +- Includes passing tests and updated docs for the changes made. ## Issue Tracker -If you encounter any bugs, have feature requests, or need assistance, please visit our [Issue Tracker](https://github.com/OpenTabular/DeepTab/issues). Make sure to search for existing issues before creating a new one. +Report bugs, request features, or ask for help on the [Issue Tracker](https://github.com/OpenTabular/DeepTab/issues). Search existing issues before opening a new one. ## License -By contributing to this project, you agree that your contributions will be licensed under the LICENSE of the project. -Please note that the above guidelines are subject to change, and the project maintainers hold the right to reject or request modifications to any contributions. Thank you for your understanding and support in making this project better! +By contributing, you agree that your contributions are licensed under the project LICENSE. diff --git a/docs/developer_guide/documentation.md b/docs/developer_guide/documentation.md index 615ee067..356131d0 100644 --- a/docs/developer_guide/documentation.md +++ b/docs/developer_guide/documentation.md @@ -87,24 +87,16 @@ Sphinx raises a warning when `autodoc` documents the same symbol more than once. :noindex: ``` -## Code blocks in pages +## Code blocks and diagrams -Use fenced code blocks with a language tag for syntax highlighting: +Use fenced code blocks with a language tag for syntax highlighting (` ```python `, ` ```bash `). The `sphinxcontrib-mermaid` extension is enabled, so diagrams use a `{mermaid}` fence: ````markdown ```python model = MLPClassifier() model.fit(X_train, y_train) ``` -```` - -For shell commands use ` ```bash ` or ` ```sh `. - -## Mermaid diagrams -The `sphinxcontrib-mermaid` extension is enabled. Use a `mermaid` code fence: - -````markdown ```{mermaid} flowchart LR A[Start] --> B[End] diff --git a/docs/developer_guide/model_promotion_policy.md b/docs/developer_guide/model_promotion_policy.md index 6a377cd2..72bc5d6b 100644 --- a/docs/developer_guide/model_promotion_policy.md +++ b/docs/developer_guide/model_promotion_policy.md @@ -15,46 +15,17 @@ A model enters the codebase as experimental. A maintainer promotes it to stable ## Promotion Requirements -### 1. Public API - -The model's public constructor signature must be consistent with other stable estimators in `deeptab/models/`. Parameter names must follow existing conventions (e.g. `n_layers`, `d_model`, `dropout`). `__init__` must accept a config object from `deeptab/configs/` with all config fields reflected as constructor kwargs. - -### 2. Documentation - -A model page must exist under `docs/api/models/` and include: - -- A one-paragraph description of the architecture. -- A **When to use** section: what problem or data type this model is suited for. -- A **Limitations** section: known failure modes, dataset-size requirements, or computational constraints. -- A full parameter table generated from the config docstring. - -All public methods must have docstrings that render without warnings under `just docs`. - -### 3. End-to-end Example - -At least one runnable example must exist in `examples/` or `docs/examples/` that demonstrates loading data, constructing the model, fitting, and predicting. The example must run to completion without error against the current main branch. - -### 4. Save / Load Support - -If save/load is part of the stable core contract for the task type, the model must be saveable and reloadable via the standard DeepTab mechanism, with a round-trip test confirming identical predictions before and after reload. - -### 5. Tests - -A behavioral test must exist (in a dedicated file or in `tests/test_base.py`) covering: - -- Fit on a small synthetic dataset. -- Predict returning an array of the expected shape and dtype. -- Config serialization round-trip. - -All tests must pass in CI (`just test`). - -### 6. No Open Critical Bugs - -No open GitHub issues labelled `bug` for the model may describe a failure in a core workflow (fit, predict, save/load). Known limitations that are not bugs must be documented in the model's Limitations section. - -### 7. Registry - -A config class must exist in `deeptab/configs/` and be exported from `deeptab/configs/__init__.py`. The model must be exported from `deeptab/models/experimental/__init__.py` while experimental, or from `deeptab/models/__init__.py` once stable. The `MODEL_REGISTRY` in `deeptab/core/registry.py` must contain a `ModelInfo` entry with the correct `status` and `import_path`. +Every criterion below must be met before promotion. Each is objective and reviewable. + +| # | Requirement | What it means | +| --- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | Public API | Constructor matches stable-estimator conventions (`n_layers`, `d_model`, `dropout`, ...) and takes a `deeptab/configs/` config with every field mirrored as a kwarg. | +| 2 | Documentation | A page under `docs/api/models/` with architecture summary, **When to use**, **Limitations**, and a generated parameter table. All public methods render docstrings without `just docs` warnings. | +| 3 | End-to-end example | A runnable example in `examples/` or `docs/examples/` covering load → construct → fit → predict, passing against current `main`. | +| 4 | Save / Load | If save/load is part of the task's stable contract, the model round-trips via the standard mechanism with a test asserting identical predictions. | +| 5 | Tests | A behavioral test covering fit on synthetic data, predict shape/dtype, and config serialization round-trip. All pass in CI (`just test`). | +| 6 | No critical bugs | No open `bug` issues describing a failure in fit, predict, or save/load. Non-bug limitations are documented in the Limitations section. | +| 7 | Registry | Config class exported from `deeptab/configs/__init__.py`; model exported from the experimental package; `MODEL_REGISTRY` entry present with correct `status` and `import_path`. | ## Promotion PR diff --git a/docs/developer_guide/release.md b/docs/developer_guide/release.md index 935c653b..30886524 100644 --- a/docs/developer_guide/release.md +++ b/docs/developer_guide/release.md @@ -1,6 +1,6 @@ # Build and Release -The document outlines the steps to build and release the `deeptab` package. It is assumed that all feature branches and PRs for the release have been reviewed, approved, and merged into `main` before starting this process. +The document outlines the steps to build and release `deeptab` package. It is assumed that all feature branches and PRs for the release have been reviewed, approved, and merged into `main` before starting this process. ## Release workflow @@ -22,9 +22,9 @@ flowchart TD QAP -->|Yes| D["Build docs: just docs"]:::setup D --> E[Commit changes & push branch]:::git E --> F{Release type?}:::decision - F -->|RC| RC1["cz bump --dry-run
then cz bump rcN"]:::setup - F -->|Stable| ST1["cz bump --dry-run
then cz bump"]:::setup - RC1 --> RC2["git tag vX.Y.ZrcN
git push origin vX.Y.ZrcN"]:::git + F -->|RC| RC1["just bump-rc-preview
then just bump-rc
(append --increment MAJOR
if not auto-detected)
"]:::setup + F -->|Stable| ST1["just bump-preview
then just bump
(append --increment MAJOR
if not auto-detected)
"]:::setup + RC1 --> RC2["git push --follow-tags
(pushes vX.Y.ZrcN)"]:::git RC2 --> RC3[CI: publish-testpypi.yml]:::ci RC3 --> RC4[TestPyPI + GitHub pre-release]:::rc RC4 -->|Issues found| B @@ -32,7 +32,7 @@ flowchart TD ST1 --> ST2["Open PR: release/vX.Y.Z → main"]:::pr ST2 --> ST3{Review & approve}:::decision ST3 --> ST4[Merge PR into main]:::pr - ST4 --> ST5["git checkout main && git pull
git tag vX.Y.Z
git push origin vX.Y.Z"]:::git + ST4 --> ST5["git checkout main && git pull
git tag -d vX.Y.Z (local)
git tag vX.Y.Z && git push origin vX.Y.Z"]:::git ST5 --> ST6[CI: publish-pypi.yml]:::ci ST6 --> ST7[PyPI + GitHub Release]:::stable @@ -68,17 +68,17 @@ Only **bug fixes and documentation changes** belong on the release branch. New f ``` ```{warning} -If you update any dependencies (e.g. to resolve security findings), regenerate the lock file immediately: +If you update any dependencies (e.g. to resolve security findings), upgrade the specific package (this also rewrites `poetry.lock`): - poetry update + poetry update # no just recipe: targets a single package Then verify the change does not break any tests. ``` -**Security audit:** run `pip-audit` and resolve any vulnerability with an available fix before bumping the version: +**Security audit:** run `just audit` and resolve any vulnerability with an available fix before bumping the version: ```bash -poetry run pip-audit +just audit ``` Vulnerabilities with no upstream fix available should be noted and tracked as known accepted risks. @@ -87,29 +87,16 @@ Vulnerabilities with no upstream fix available should be noted and tracked as kn Run all checks in the order shown below. **Each step must pass cleanly before proceeding to the next.** -### 3.1 Linting - -```bash -just lint -``` - -Runs `ruff check --fix` and auto-corrects fixable issues. Review and manually resolve any remaining errors. - -### 3.2 Formatting - -```bash -just format -``` - -Runs `ruff format` to ensure consistent code style across the codebase. +## 3. Quality checks -### 3.3 Pre-commit hooks +Run these in order. **Each must pass cleanly before proceeding to the next.** -```bash -just check -``` - -Runs all pre-commit hooks across all files: ruff lint/format, prettier (YAML/Markdown/JSON), and Pyright type checking. +| Step | Command | What it does | +| ------ | ------------- | --------------------------------------------------------------------- | +| Lint | `just lint` | `ruff check --fix`; review and resolve any errors it cannot auto-fix. | +| Format | `just format` | `ruff format` for consistent code style. | +| Hooks | `just check` | All pre-commit hooks across all files: ruff, prettier, and Pyright. | +| Tests | `just test` | Full test suite with coverage. | ```{important} If `just check` modifies any files, stage and commit them before continuing: @@ -117,14 +104,6 @@ If `just check` modifies any files, stage and commit them before continuing: git add -u && git commit -m "style: apply pre-commit formatting" ``` -### 3.4 Unit tests - -```bash -just test -``` - -Runs the full test suite with coverage reporting. - ```{warning} A test failure at this stage must be fixed on the release branch before proceeding. Do not skip, suppress, or comment out failing tests. ``` @@ -159,69 +138,105 @@ Prefer `just commit` over a manual `git commit` to stay consistent with the conv ## 6. Version bump +The version bump is driven entirely by [Commitizen](https://commitizen-tools.github.io/commitizen/). The increment (MAJOR / MINOR / PATCH) is inferred from the conventional-commit messages since the last tag, the version in `pyproject.toml` is updated, and the matching `CHANGELOG.md` section is generated and committed with an annotated tag. + ```{important} -Always run `--dry-run` first and review the proposed CHANGELOG entries carefully before applying the bump. +Always run `--dry-run` first and review the proposed version and CHANGELOG entries carefully before applying the bump. +``` + +The following Commitizen settings in `pyproject.toml` shape this behaviour: + +| Setting | Value | Effect | +| ---------------------------- | ------ | --------------------------------------------------------------------------------------------- | +| `prerelease_offset` | `1` | Prereleases start at `rc1` (not the default `rc0`) | +| `changelog_merge_prerelease` | `true` | On the stable bump, all `rcN` CHANGELOG sections are rolled up into a single `vX.Y.Z` section | +| `update_changelog_on_bump` | `true` | `CHANGELOG.md` is regenerated automatically on every bump | + +The bump commands are wrapped in `just` recipes so the correct Commitizen flags are applied consistently: + +| Recipe | Wraps | Use for | +| ---------------------- | ----------------------------------- | --------------------- | +| `just bump-rc-preview` | `cz bump --prerelease rc --dry-run` | Preview an RC bump | +| `just bump-rc` | `cz bump --prerelease rc` | Apply an RC bump | +| `just bump-preview` | `cz bump --dry-run` | Preview a stable bump | +| `just bump` | `cz bump` | Apply a stable bump | + +Each recipe forwards extra arguments to Commitizen, so flags such as `--increment MAJOR` can be appended directly (e.g. `just bump-rc-preview --increment MAJOR`). + +### 6a. Release candidate bump + +Use the `bump-rc` recipes to cut an RC. The first prerelease of a cycle is `rc1` (thanks to `prerelease_offset = 1`); subsequent ones increment to `rc2`, `rc3`, and so on. + +```{note} +Commitizen can only infer the target version from commits. For a **major** release where the commit history does not contain a `feat!:` / `BREAKING CHANGE:` marker, force the increment explicitly with `--increment MAJOR` (likewise `MINOR` / `PATCH`). ``` **Step 1, preview:** ```bash -poetry run cz bump --dry-run +# Append --increment MAJOR/MINOR/PATCH if the bump is not inferred correctly +just bump-rc-preview ``` -Inspect the output: - -- The proposed increment (MAJOR / MINOR / PATCH) matches expectations -- The CHANGELOG entries are complete and correctly classified -- There are no duplicate entries (can happen when multiple commits share identical messages) +Confirm the proposed tag (e.g. `v2.0.0rc1`) and that the CHANGELOG entries are complete and correctly classified. **Step 2, apply:** ```bash -poetry run cz bump +just bump-rc ``` -This will: - -- Update `version` in `pyproject.toml` -- Append the new section to `CHANGELOG.md` -- Create a local commit: `bump: version X.Y.Z-1 → X.Y.Z` +This updates `version` in `pyproject.toml`, appends the `vX.Y.ZrcN` section to `CHANGELOG.md`, creates the `bump:` commit, and creates the `vX.Y.ZrcN` tag locally. -**Step 3, review the bump commit:** +**Step 3, review and push** (commit and tag together): ```bash git show HEAD +git push --follow-tags origin release/vX.Y.Z +``` + +```{note} +`--follow-tags` pushes the annotated `vX.Y.ZrcN` tag along with the branch in one step, which triggers `publish-testpypi.yml`. See step 7, **Tag and publish a release candidate**, below if you prefer to push the tag separately. ``` -Check that `pyproject.toml` shows the correct version and that `CHANGELOG.md` reads cleanly. Manually amend duplicate entries if present, then push: +### 6b. Stable bump + +When all RCs are approved, cut the final stable version with the plain `bump` recipes. Because `changelog_merge_prerelease = true`, the intermediate `rcN` sections are merged into a single complete `vX.Y.Z` CHANGELOG section, so end users see the full release notes in one place. ```bash -git push origin release/vX.Y.Z +just bump-preview # append --increment MAJOR if needed +just bump ``` -**For a release candidate**, set the version explicitly instead of using `cz bump`: +This updates `pyproject.toml`, regenerates `CHANGELOG.md` (with prereleases merged), and creates the `bump:` commit plus the `vX.Y.Z` tag. + +**Review the bump commit:** ```bash -poetry version X.Y.ZrcN -poetry lock -git add pyproject.toml poetry.lock CHANGELOG.md -git commit -m "bump: version X.Y.Z-1 → X.Y.ZrcN" +git show HEAD +``` + +Check that `pyproject.toml` shows the correct version and that `CHANGELOG.md` reads cleanly. Manually amend duplicate entries if present, then push the branch (the stable tag is pushed later, after the release PR is merged — see step 9): + +```bash +git push origin release/vX.Y.Z ``` See **[Versioning](versioning.md)** for the full SemVer rules and commit-type reference. ## 7. Tag and publish a release candidate -RC tags are pushed **directly from the release branch**, with no PR to `main` required. +`cz bump --prerelease rc` (step 6a) already created the annotated `vX.Y.ZrcN` tag locally. RC tags are pushed **directly from the release branch**, with no PR to `main` required. + +If you pushed with `git push --follow-tags` in step 6a, the tag is already live and you can skip to verifying CI. Otherwise, push the tag explicitly: ```bash -git tag -a vX.Y.ZrcN -m "Release candidate vX.Y.ZrcN" git push origin vX.Y.ZrcN ``` This triggers `publish-testpypi.yml`, which publishes to **TestPyPI** and creates a GitHub pre-release. -If issues are found, fix them on the release branch (return to step 2), bump to the next RC (`rcN+1`), and repeat. +If issues are found, fix them on the release branch (return to step 2), bump to the next RC with `cz bump --prerelease rc` (which yields `rcN+1`), and repeat. ## 8. Release PR (stable only) @@ -236,10 +251,11 @@ Once all RCs are approved (or skipping RC for a straightforward release), open a ## 9. Create and push the stable tag -After the release PR is merged into `main`: +The stable `cz bump` in step 6b created a local `vX.Y.Z` tag on the release branch, but the authoritative tag must point at the merge commit on `main`. After the release PR is merged into `main`, drop the local tag and re-create it on `main`: ```bash git checkout main && git pull +git tag -d vX.Y.Z # remove the local tag created by cz bump git tag -a vX.Y.Z -m "Release vX.Y.Z" git push origin vX.Y.Z ``` @@ -250,12 +266,12 @@ Pushing the tag triggers PyPI publication immediately and cannot be undone. Conf ## 10. Publish package -The tag push automatically triggers the appropriate GitHub Actions workflow. See **[CI/CD](ci_cd.md)** for full details. In summary: - -- Stable tag (`vX.Y.Z`) → `publish-pypi.yml` → PyPI + GitHub Release -- RC tag (`vX.Y.ZrcN`) → `publish-testpypi.yml` → TestPyPI + GitHub pre-release +The tag push automatically triggers the appropriate GitHub Actions workflow. Both use **OIDC Trusted Publishing**, so no API tokens are required. See **[CI/CD](ci_cd.md)** for full details. -Both workflows use **OIDC Trusted Publishing**, so no API tokens are required. +| Tag pushed | Workflow | Result | +| ----------- | ---------------------- | ----------------------------- | +| `vX.Y.Z` | `publish-pypi.yml` | PyPI + GitHub Release | +| `vX.Y.ZrcN` | `publish-testpypi.yml` | TestPyPI + GitHub pre-release | ## 11. GitHub Release diff --git a/docs/developer_guide/support_matrix.md b/docs/developer_guide/support_matrix.md index 8fbb337a..13a2bba4 100644 --- a/docs/developer_guide/support_matrix.md +++ b/docs/developer_guide/support_matrix.md @@ -4,45 +4,20 @@ This page lists the officially supported versions of Python and core dependencie --- -## Python +## Python and Operating Systems -| Version | Status | -| ------- | ------------------------------------------------------------------------------------------------ | -| 3.10 | Supported | -| 3.11 | Supported | -| 3.12 | Supported | -| 3.13 | Supported | -| 3.14+ | Not yet supported. `scipy` wheels unavailable; will be added once dependency support catches up. | +| Category | Supported | Notes | +| -------- | ---------------------------------------------- | --------------------------------------------------------------- | +| Python | 3.10, 3.11, 3.12, 3.13 | 3.14+ pending `scipy` wheels; added once dependencies catch up. | +| OS | Linux, macOS, Windows (all `*-latest` runners) | | --- -## Operating Systems +## Core Dependencies and Policy -| OS | Status | -| ------------------------ | --------- | -| Linux (ubuntu-latest) | Supported | -| macOS (macos-latest) | Supported | -| Windows (windows-latest) | Supported | +The authoritative version constraints live in [`pyproject.toml`](https://github.com/OpenTabular/deeptab/blob/main/pyproject.toml) under `[tool.poetry.dependencies]`, which is updated on every release. Treat that file as the source of truth; the list below names the core packages and the policy that governs their bounds. ---- - -## Core Dependencies - -The table below shows the range of versions supported by the package metadata (`pyproject.toml`). The lower bound is the minimum version that has been tested; the upper bound is what Poetry's caret/range constraint allows. - -| Package | Minimum | Upper bound | Notes | -| ---------------------------------------------------- | ------- | ----------- | ---------------------------------------------------------- | -| [PyTorch](https://pytorch.org/) | 2.2.2 | < 2.10.0 | Pinned range; update when a new PyTorch stable is released | -| [Lightning](https://lightning.ai/) | 2.3.3 | < 3.0 | | -| [NumPy](https://numpy.org/) | 2.0.0 | < 3.0 | NumPy 1.x is **not** supported | -| [pandas](https://pandas.pydata.org/) | 2.0.3 | < 3.0 | | -| [scikit-learn](https://scikit-learn.org/) | 1.3.2 | < 2.0 | | -| [torchmetrics](https://torchmetrics.readthedocs.io/) | 1.5.2 | < 2.0 | | -| [scipy](https://scipy.org/) | 1.15.0 | < 2.0 | | - ---- - -## Policy +- **PyTorch, Lightning, NumPy, pandas, scikit-learn, torchmetrics, scipy** are the pinned core dependencies. NumPy 1.x is **not** supported. DeepTab follows a rolling support window, similar to [SPEC 0](https://scientific-python.org/specs/spec-0000/) used by the broader scientific Python ecosystem: @@ -51,15 +26,3 @@ DeepTab follows a rolling support window, similar to [SPEC 0](https://scientific - **PyTorch**: support the current stable release and the one prior. The upper bound in `pyproject.toml` is updated when a new PyTorch stable is released and CI passes. When a version is dropped, it is announced in the release notes and the `pyproject.toml` lower bound is bumped in the same minor release. - ---- - -## Updating the Matrix - -When CI is extended to cover a new Python or dependency version: - -1. Update `pyproject.toml` (the `[tool.poetry.dependencies]` version constraint). -2. Update `.github/workflows/ci.yml` (`matrix.python-version` or equivalent). -3. Update the table on this page to reflect the new status. - -All three changes should land in the same PR so the docs and the CI are always in sync. diff --git a/docs/developer_guide/testing.md b/docs/developer_guide/testing.md index 55a4a6ff..e60763ed 100644 --- a/docs/developer_guide/testing.md +++ b/docs/developer_guide/testing.md @@ -6,33 +6,23 @@ DeepTab uses [pytest](https://docs.pytest.org/) with [pytest-cov](https://pytest ## Running the test suite -```bash -just test -``` - -This expands to: - -```bash -poetry run pytest --cov=deeptab tests/ -``` - -To run a single file or a specific test: - -```bash -poetry run pytest tests/test_models.py -v -poetry run pytest tests/test_models.py::test_classifier_fit_predict_shape -v -``` +| Goal | Command | +| ----------------------------- | ------------------------------------------------------ | +| Full suite with coverage | `just test` | +| A single file | `poetry run pytest tests/test_models.py -v` | +| A single test | `poetry run pytest tests/test_models.py::test_name -v` | +| Live logs, stop on first fail | `poetry run pytest tests/ -x -s` | -To print live log output and stop on the first failure: - -```bash -poetry run pytest tests/ -x -s -``` +`just test` expands to `poetry run pytest --cov=deeptab tests/`. ## Writing new tests -- Place tests in `tests/` using the `test_*.py` naming convention. -- Prefer parametrize over copy-paste for variations of the same test: +| Convention | Guideline | +| ------------- | ----------------------------------------------------------------------------------------------- | +| Location | Place tests in `tests/` using the `test_*.py` naming convention. | +| Variations | Use `@pytest.mark.parametrize` instead of copy-pasting near-identical tests. | +| Data | Use small synthetic datasets (`n=64`, `d=8`); never download external data. | +| Trainer noise | Silence Lightning output with `logging.getLogger("lightning.pytorch").setLevel(logging.ERROR)`. | ```python import pytest @@ -42,33 +32,16 @@ def test_depth(n_layers): ... ``` -- Use small synthetic datasets (`n=64`, `d=8`) to keep tests fast. Avoid downloading external data in tests. -- Models rely on PyTorch Lightning internally. To suppress verbose trainer output in tests, set: - -```python -import logging -logging.getLogger("lightning.pytorch").setLevel(logging.ERROR) -``` - ## Coverage -A coverage report is printed to the terminal after every `just test` run. To generate an interactive HTML report: +A coverage report is printed after every `just test` run. For an interactive HTML report: ```bash poetry run pytest --cov=deeptab --cov-report=html tests/ open htmlcov/index.html ``` -## CI test matrix - -The `ci.yml` workflow runs the full suite on every push to `main` and on every pull request, across: - -| Dimension | Values | -| ---------- | ------------------------------------------------- | -| **Python** | 3.10, 3.11, 3.12, 3.13 | -| **OS** | `ubuntu-latest`, `macos-latest`, `windows-latest` | - -All 12 combinations run in parallel with `fail-fast: false`, so a failure in one combination does not cancel the others. +The full suite also runs in CI across every supported Python and OS combination. See [CI/CD](ci_cd.md) for the matrix. ## Pre-push checks diff --git a/docs/developer_guide/versioning.md b/docs/developer_guide/versioning.md index 0f80a808..cd38fd3e 100644 --- a/docs/developer_guide/versioning.md +++ b/docs/developer_guide/versioning.md @@ -16,16 +16,7 @@ MAJOR.MINOR.PATCH Release candidates use the suffix `rcN`, e.g. `1.8.0rc1`. -The version is defined **in one place only**, `pyproject.toml`, and read at runtime via `importlib.metadata` in `deeptab/_version.py`: - -```python -from importlib.metadata import PackageNotFoundError, version - -try: - __version__ = version("deeptab") -except PackageNotFoundError: - __version__ = "0+unknown" -``` +The version is defined **in one place only**, `pyproject.toml`, and read at runtime via `importlib.metadata` in `deeptab/_version.py`, so it never needs to be hard-coded in the package. ## Commit types and their effect @@ -63,35 +54,19 @@ The `commit-msg` pre-commit hook validates every commit message against the conv ## Bumping the version -On a `release/vX.Y.Z` branch, let commitizen determine the next version automatically: - -```bash -cz bump -``` +Version bumps are driven by [commitizen](https://commitizen-tools.github.io/commitizen/), wrapped in `just` recipes. Preview first with the `-preview` (dry-run) variant, then apply. Each apply recipe updates `version` in `pyproject.toml`, appends to `CHANGELOG.md`, and creates the bump commit and tag. -This command: +| Goal | Preview | Apply | +| ----------------- | ---------------------- | -------------- | +| Stable release | `just bump-preview` | `just bump` | +| Release candidate | `just bump-rc-preview` | `just bump-rc` | -1. Reads all conventional commits since the last tag. -2. Determines the next version (`MAJOR`, `MINOR`, or `PATCH`). -3. Updates `version` in `pyproject.toml`. -4. Appends the new section to `CHANGELOG.md`. -5. Creates a local commit `bump: version X.Y.Z-1 → X.Y.Z`. - -For a release candidate, set the version explicitly instead: - -```bash -poetry version 1.8.0rc1 -poetry lock -git add pyproject.toml poetry.lock CHANGELOG.md -git commit -m "bump: version 1.7.0 → 1.8.0rc1" -``` +The next version is inferred from the conventional commits since the last tag. To force a level when it is not auto-detected, append the increment, e.g. `just bump --increment MAJOR`. ## Changelog -`CHANGELOG.md` at the repository root is the authoritative changelog. It is updated automatically by `cz bump` on stable releases. For release candidates, update it manually before tagging. - -The changelog format groups changes under the commit types (`feat`, `fix`, `perf`, etc.) and lists the subject line of every matching commit since the previous release. +`CHANGELOG.md` at the repository root is the authoritative changelog, updated automatically by the bump recipes. Changes are grouped under their commit types (`feat`, `fix`, `perf`, ...) with the subject line of every matching commit since the previous release. ## Tags -All release tags follow the format `vMAJOR.MINOR.PATCH` (or `vMAJOR.MINOR.PATCHrcN` for RCs). Tags are what trigger the PyPI publish workflows. See the [Release process](release.md) page for the full end-to-end procedure. +Release tags follow `vMAJOR.MINOR.PATCH` (or `vMAJOR.MINOR.PATCHrcN` for RCs) and trigger the PyPI publish workflows. See the [Release process](release.md) page for the full end-to-end procedure. diff --git a/docs/getting_started/faq.md b/docs/getting_started/faq.md index 36aab29a..fb0a2878 100644 --- a/docs/getting_started/faq.md +++ b/docs/getting_started/faq.md @@ -6,21 +6,38 @@ Frequently asked questions about DeepTab and troubleshooting common issues. ### What's the difference between DeepTab v1 and v2? -Version 2.0 introduces a fully typed data layer (`TabularDataset`, `TabularDataModule`, `FeatureSchema`, `TabularBatch`) that makes it easier to work with tabular data at a lower level. The high-level estimator API remains unchanged and is still the recommended interface for most users. +v2.0 is a ground-up restructuring of DeepTab. The high-level estimator workflow stays familiar, but the package layout, configuration objects, and import paths have changed. Three things affect existing code: -Key changes in v2.0: +1. **Import paths** were reorganised under the `deeptab` namespace. +2. **Config classes** dropped their `Default` prefix (`DefaultMambularConfig` is now `MambularConfig`) and settings are split across `MambularConfig` (architecture), `PreprocessingConfig` (feature handling), and `TrainerConfig` (training). +3. **Data modules** were renamed to `TabularDataModule` and `TabularDataset`; the old `Mambular*` aliases are deprecated. -- **Automatic stratification** for classification tasks -- **Typed batch containers** with device management -- **Feature schema tracking** with metadata -- **Consistent label shapes** across tasks -- Deprecated `MambularDataset`/`MambularDataModule` aliases (use `TabularDataset`/`TabularDataModule`) +The split-config API is the main thing you reach for day to day. In v1 every option was a flat keyword argument on the estimator; in v2 the same options live in dedicated config objects, while `fit`, `predict`, and `evaluate` behave exactly as before. + +```python +# v1: settings passed as flat keyword arguments +model = MambularClassifier(d_model=128, n_layers=4, numerical_preprocessing="ple") +``` + +```python +# v2: settings grouped into focused config objects +from deeptab.configs import MambularConfig, PreprocessingConfig + +model = MambularClassifier( + model_config=MambularConfig(d_model=128, n_layers=4), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="ple"), +) +``` + +You only pass the configs you want to change; `MambularClassifier()` uses sensible defaults for all three. ```{important} -**Note on v1 support**: DeepTab v1 is no longer supported following the v2.0 release. The changes in package structure and API design were substantial enough that maintaining backward compatibility would have compromised the improvements in v2. If you're using v1 in production, we recommend planning a migration to v2. Pin your dependency to `deeptab<2.0` if you need to continue using v1, but be aware that no bug fixes or security updates will be provided for the v1 branch. +v2.0 is not backward compatible with v1, and v1 is no longer maintained. If you need to stay on v1, pin `deeptab<2.0`, but note that the v1 branch receives no bug fixes or security updates. ``` -See the [Overview](overview) for details on the new data API. +For a step-by-step upgrade walkthrough, see [Migrating from v1 to v2](migration). + +See the [Overview](overview) for the full v2 data API, and the [homepage](../index) for the complete list of new features. ### Which model should I use? @@ -28,58 +45,106 @@ See the [Overview](overview) for details on the new data API. When in doubt, start with `MambularClassifier` or `MambularRegressor`. ``` -Mambular tends to work well across a variety of tabular problems. For a full selection guide by dataset size, feature type, and compute constraints, see the [Model Comparison](../model_zoo/comparison_tables) page. +Mambular tends to work well across a variety of tabular problems. -Quick pointers: +| Goal | Try | +| ------------------------------- | -------------------- | +| Strong general-purpose baseline | `TabM` or `Mambular` | +| Many categorical features | `TabTransformer` | +| Fastest baseline | `MLP` or `ResNet` | +| Uncertainty estimates | any `LSS` variant | +| Interpretability | `NODE` or `NDTF` | -- **Strong general-purpose baseline** → `TabM` or `Mambular` -- **Many categorical features** → `TabTransformer` -- **Fastest baseline** → `MLP` or `ResNet` -- **Uncertainty estimates** → any `LSS` variant -- **Interpretability** → `NODE` or `NDTF` +These are starting points, not rules. For the detailed comparison by dataset size, feature mix, and compute budget, see the [Model Comparison](../model_zoo/comparison_tables) page. ### Do I need a GPU? -No, but it helps significantly for larger datasets and more complex architectures. The short answer: +No, DeepTab runs on CPU. Whether a GPU helps depends on your dataset more than on any single rule: the number of rows, the number of features (and how dense or high-cardinality they are), the model's per-batch cost, the batch size, and how many epochs you train all interact. The [Model Zoo Comparison Tables](../model_zoo/comparison_tables) give the per-model cost driver and rough crossover points; treat the guidance below as a starting heuristic, not a hard threshold. + +As a practical rule, reach for a GPU when several of these hold at once: -- **MLP, ResNet, TabM, MambaTab**: train comfortably on CPU up to ~100K to 500K rows. -- **Mambular, TabulaRNN, TabTransformer, NODE**: CPU is fine up to ~10K to 20K rows; GPU recommended beyond that. -- **FTTransformer, AutoInt, MambAttention, ENODE, NDTF, TabR**: GPU recommended above ~5K to 10K rows. -- **SAINT**: GPU strongly recommended above ~2K rows (row attention makes every batch expensive). +- **Dense, wide data**: many numerical features per row, so each forward and backward pass does substantially more matrix work that parallelises well on a GPU. +- **Long training runs**: more than ~100 epochs, where even a modest per-epoch speedup compounds into a large wall-clock difference. +- **Larger batch sizes**: bigger batches expose more parallelism, which a GPU can absorb while a CPU saturates. Conversely, very small batches may not fill the device and can erase the benefit. +- **Attention- or sequence-heavy architectures**: models whose cost grows faster than linearly with features or rows (for example `SAINT`'s row attention, or the transformer and recurrent families) hit the GPU-recommended regime at much smaller dataset sizes than `MLP`, `ResNet`, `TabM`, or `MambaTab`. -For a full per-model breakdown including the cost driver for each architecture, see the [Model Zoo Comparison Tables](../model_zoo/comparison_tables) in the Model Zoo. +For small datasets, short runs, or the lightweight models above, CPU is usually fine and avoids data-transfer overhead. When in doubt, profile one configuration both ways and compare wall-clock time per epoch. ### How do I know if my GPU is being used? -Check CUDA availability: +Use two checks. First, see what hardware DeepTab can detect: ```python -import torch -print(f"CUDA available: {torch.cuda.is_available()}") +from deeptab import print_hardware_info + +print_hardware_info() ``` -DeepTab will automatically use the first available GPU. If CUDA is available but you're not seeing speedups, ensure you're training on a reasonably large dataset, since small batches may not benefit from GPU parallelism. +The report lists the CPU, any CUDA GPUs, the Apple Silicon MPS backend, and the `accelerator` DeepTab would pick by default. This only tells you what is _available_, not what a given run actually used. + +To confirm what a fitted estimator is _really_ running on, inspect its runtime info after `fit`: + +```python +model.fit(X, y) + +info = model.runtime_info() +print(info["accelerator"]) # e.g. "CUDAAccelerator", "MPSAccelerator", "CPUAccelerator" +print(info["root_device"]) # e.g. "cuda:0", "mps:0", "cpu" +print(info["device"]) # device the model parameters live on +print(info["num_devices"]) # number of devices in use +``` + +`model.summary()` prints the same device, precision, and accelerator fields in a readable block. + +```{warning} +By default DeepTab lets Lightning auto-select the best available accelerator, but an explicit `accelerator=` you pass to `fit()` always wins. If you accidentally pass `accelerator="cpu"`, training stays on the CPU even when a GPU is present, and `runtime_info()["accelerator"]` will report `"CPUAccelerator"`. Drop the argument (or set `accelerator="auto"`) to let DeepTab use the GPU. +``` ### Can I use DeepTab with PyTorch dataloaders? ```{note} -The high-level API uses `TabularDataModule` internally, but you can access `TabularDataset` directly for custom data loading. +For normal training you never build a `DataLoader` yourself: `model.fit(...)` constructs the `TabularDataModule` and its loaders internally. Reach for this lower-level path only when you need behaviour the estimator does not expose, such as a custom or weighted sampler, or running DeepTab data through your own training/evaluation loop. ``` -Yes. The internal `TabularDataModule` creates PyTorch `DataLoader` instances. If you need custom data loading logic, you can use `TabularDataset` directly: +Yes. The estimator does not accept a custom `DataLoader` directly, but after `fit` the fitted data module exposes a ready-to-use, preprocessed `TabularDataset`. You can wrap that dataset in any `DataLoader` (with your own sampler) and run the fitted network on the batches yourself. ```python -from deeptab.data import TabularDataset -from torch.utils.data import DataLoader +import torch +from torch.utils.data import DataLoader, WeightedRandomSampler +from deeptab.models import MambularClassifier -dataset = TabularDataset( - cat_feature_list=[...], - num_feature_list=[...], - embedding_feature_list=None, - y=labels, -) +model = MambularClassifier() +model.fit(X_train, y_train, max_epochs=1) # fits the preprocessor and builds the network + +# The fitted data module holds the preprocessed training dataset +dm = model._data_module +dm.setup("fit") +dataset = dm.train_dataset # a TabularDataset of preprocessed tensors + +# Wrap it in your own DataLoader, e.g. to oversample minority classes +sampler = WeightedRandomSampler(sample_weights, num_samples=len(dataset)) +dataloader = DataLoader(dataset, batch_size=128, sampler=sampler) +``` + +Each item is a `((num_features, cat_features, embeddings), label)` tuple, the same format DeepTab uses internally, so the default `DataLoader` collation batches it without a custom `collate_fn`. Feed those batches into the fitted network for a custom training or scoring loop: + +```python +net = model._task_model # the LightningModule (internal API) +device = next(net.parameters()).device +net.eval() + +with torch.no_grad(): + for (num_features, cat_features, embeddings), labels in dataloader: + num_features = [t.to(device) for t in num_features] + cat_features = [t.to(device) for t in cat_features] + embeddings = [t.to(device) for t in embeddings] if embeddings else None -dataloader = DataLoader(dataset, batch_size=128, shuffle=True) + logits = net(num_features, cat_features, embeddings) + # compute your own loss / metrics, or collect predictions ... +``` + +```{warning} +`model._data_module` and `model._task_model` are internal attributes and may change between releases. For standard training and inference, prefer the estimator API (`fit`, `predict`, `evaluate`), which manages preprocessing, batching, and device placement for you. ``` ## Data and preprocessing @@ -112,7 +177,7 @@ model = MambularClassifier() model.fit(df, y, max_epochs=50) ``` -The pretab preprocessor (used internally) applies median imputation for numerical features and mode imputation for categoricals by default. +The internal [PreTab](https://github.com/OpenTabular/PreTab) preprocessor imputes missing values as part of fitting, so you do not need a separate imputation step. The exact strategy follows the configured `PreprocessingConfig`; with the defaults it uses PreTab's built-in imputation for numerical and categorical features. ### Can I use NumPy arrays instead of DataFrames? @@ -182,24 +247,36 @@ model.fit(df, y, max_epochs=50) ### How do I speed up training? -```{tip} -Combine GPU acceleration with larger batch sizes and early stopping for fastest training. +Start by checking what hardware DeepTab is actually using, then adjust the parts that matter most. + +**1. Confirm you are on an accelerator.** Print the detected hardware: + +```python +from deeptab import print_hardware_info + +print_hardware_info() +``` + +If the recommended accelerator is `cpu` but you expect a GPU, install a CUDA-enabled PyTorch build (see the [installation guide](installation)). DeepTab uses the first available GPU automatically, but you can also force it explicitly: + +```python +model.fit(X_train, y_train, accelerator="gpu", max_epochs=100) ``` -Several options: +**2. Use a batch size that keeps the accelerator busy.** GPUs and MPS only pay off with larger batches. Try 256 or more; on very small datasets (under ~1K rows) the CPU can be faster because of transfer overhead. -1. **Use a GPU**: install CUDA-enabled PyTorch -2. **Increase batch size**: larger batches are more efficient when memory allows (`TrainerConfig(batch_size=...)`) -3. **Reduce epochs**: rely on early stopping instead of a fixed epoch count -4. **Use multi-worker data loading**: pass `num_workers` through `dataloader_kwargs` in `fit()` +**3. Check the learning rate.** Training that crawls for many epochs is often a learning-rate problem, not a hardware one. The default is conservative; a slightly higher rate can converge in far fewer epochs. Raise it carefully and watch the loss. + +**4. Lean on early stopping instead of a fixed epoch count**, and speed up data loading with extra workers. ```python from deeptab.configs import TrainerConfig model = MambularClassifier( trainer_config=TrainerConfig( - batch_size=512, # Larger batch size - patience=10, # Early stopping + batch_size=512, # keep the accelerator busy + lr=1e-3, # raise from the default if convergence is slow + patience=10, # stop once the validation metric plateaus ) ) @@ -207,24 +284,30 @@ model = MambularClassifier( model.fit(X_train, y_train, dataloader_kwargs={"num_workers": 4}, max_epochs=100) ``` -### Training is slow on GPU - ```{note} -GPUs need larger batch sizes to show a speedup over CPU. Small batches or datasets may run faster on CPU. +A GPU is not always faster. For small datasets or tiny batches the transfer overhead can outweigh the speedup, and the CPU may win. Benchmark both on your data. +``` + +```{warning} +Raising the learning rate too far makes training unstable and the loss can diverge. If that happens, lower it again and see [Training is unstable (loss explodes)](#training-is-unstable-loss-explodes). ``` -Ensure you're using GPU: +### How do I use multiple GPUs? + +Pass Lightning's multi-device arguments straight through `fit()`. Set `devices` to the number of GPUs (or a list of indices) and choose a `strategy` such as `"ddp"`: ```python -import torch -print(torch.cuda.is_available()) # Should be True +model = MambularClassifier() +model.fit( + X_train, y_train, + accelerator="gpu", + devices=2, # or [0, 1] to pick specific GPUs + strategy="ddp", # distributed data parallel + max_epochs=100, +) ``` -If True but still slow: - -- **Small batches**: GPU efficiency requires larger batches (try 256+) -- **Small dataset**: for < 1K samples, CPU may be faster due to transfer overhead -- **CPU bottleneck**: increase `num_workers` via `dataloader_kwargs` in `fit()` for faster data loading +For finer control over the distributed setup, drive `TabularDataModule` with your own Lightning module (advanced usage). ### How do I use early stopping? @@ -384,16 +467,16 @@ batch = batch.to("cuda") # Move entire batch The estimator API handles this automatically. -## Model-specific +## Choosing a model ### What's the difference between Mambular and MambaTab? -Both use Mamba (State Space Model) blocks, but differ in how they process features: +Both use Mamba (State Space Model) blocks, but differ in how they present features to the block: -- **Mambular**: Sequential model. Processes features one at a time in sequence, learning dependencies between features. -- **MambaTab**: Joint model. Applies Mamba to a concatenated representation of all features at once. +- **Mambular**: embeds each feature into its own token, then runs Mamba over that sequence of feature tokens and pools the result. Modelling features as a sequence lets it capture richer interactions between them, at a higher compute cost. +- **MambaTab**: concatenates all features and projects them through a single linear layer into one representation before the Mamba block. This is lighter and faster, but models feature interactions less explicitly. -Mambular tends to work better for datasets where feature order matters or where you want to learn sequential dependencies. +Mambular is the stronger general-purpose choice, reach for MambaTab when you want a more compact, faster Mamba-based model. ### When should I use distributional regression (LSS)? @@ -522,84 +605,38 @@ between releases. ### Can I use custom loss functions? -Not directly through the estimator API. If you need custom losses, use `TabularDataModule` with a custom Lightning module. - -### How do I extract learned features? - -Access intermediate representations: +Yes, for classifiers. Pass `loss_fct` to `fit()`: either an `nn.Module` instance, which is used as-is, or a registered loss name such as `"focal"`, `"bce"`, or `"cross_entropy"`, which is built and combined with any `class_weight` you set. ```python -model = MambularClassifier() -model.fit(X_train, y_train, max_epochs=50) - -# The raw architecture lives on the fitted Lightning module (internal API) -architecture = model._task_model.estimator -``` - -This is an advanced use case. See the source code for details. - -### Can I use multiple GPUs? - -DeepTab uses the first available GPU by default. For multi-GPU training, use Lightning's distributed strategies directly with `TabularDataModule` (advanced usage). - -## Contributing and support - -### How do I report a bug? - -Open an issue on [GitHub](https://github.com/OpenTabular/DeepTab/issues) with: - -- DeepTab version (`import deeptab; print(deeptab.__version__)`) -- Python version -- PyTorch version -- Minimal reproducible example -- Full error traceback - -### How do I request a feature? - -Open a feature request on [GitHub](https://github.com/OpenTabular/DeepTab/issues) describing: - -- The use case -- Why existing features don't solve it -- Proposed API (if applicable) - -### How do I contribute? - -See the [Contributing guide](../developer_guide/contributing) for: - -- Setting up the development environment -- Running tests -- Code style guidelines -- Submitting pull requests - -### Where can I get help? - -- Check this FAQ first -- Search [GitHub issues](https://github.com/OpenTabular/DeepTab/issues) -- Open a new issue for bugs or questions -- Join discussions on the GitHub repo +import torch.nn as nn +from deeptab.models import MambularClassifier -## Performance comparisons +model = MambularClassifier() -### How does DeepTab compare to XGBoost? +# A custom nn.Module loss +model.fit(X_train, y_train, loss_fct=nn.CrossEntropyLoss(label_smoothing=0.1)) -It depends on the dataset: +# Or a registered loss by name (here combined with class weighting) +model.fit(X_train, y_train, loss_fct="focal", class_weight="balanced") +``` -- **Small datasets (< 1K samples)**: XGBoost often wins -- **Large datasets (> 10K samples)**: DeepTab competitive or better, especially with complex feature interactions -- **Categorical-heavy data**: XGBoost may be more efficient -- **Need for uncertainty**: DeepTab LSS models provide distributional predictions +```{note} +When `loss_fct` is an `nn.Module`, it is used as given and `class_weight` is ignored. Regressors use the task default loss; to swap the loss for a regression model, drive `TabularDataModule` with a custom Lightning module. +``` -Use both and compare on your specific data. DeepTab makes experimentation easy. +### How do I extract learned features? -### Is DeepTab faster than training PyTorch manually? +Use the public `encode()` method on a fitted model. It runs the backbone and returns dense representations as a tensor of shape `(n_samples, embedding_dim)`, which you can feed into clustering, similarity search, or another downstream model. -No, DeepTab uses PyTorch under the hood. It provides convenience, not speed improvements. However, it does: +```python +model = MambularClassifier() +model.fit(X_train, y_train, max_epochs=50) -- Apply sensible defaults (early stopping, LR scheduling) -- Handle device management automatically -- Provide efficient data loading +embeddings = model.encode(X_test) # torch.Tensor, shape (n_samples, embedding_dim) +print(embeddings.shape) +``` -So while not "faster", it helps you get to a working model more quickly. +If you also passed external `embeddings` at fit time, supply them again with `model.encode(X_test, embeddings=...)` so the rows stay aligned. ## Still have questions? diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md new file mode 100644 index 00000000..9a4dba19 --- /dev/null +++ b/docs/getting_started/index.md @@ -0,0 +1,14 @@ +--- +orphan: true +--- + +# Getting Started + +New to DeepTab? Start here. These pages take you from installation to your first +trained model, and answer the most common questions along the way. + +- **[Overview](overview)**: What DeepTab is and when to use it +- **[Installation](installation)**: Setup, GPU support, and optional kernels +- **[Quickstart](quickstart)**: Train your first models in a few minutes +- **[FAQ](faq)**: Common questions, v1 support, and troubleshooting +- **[Migrating from v1 to v2](migration)**: Upgrade an existing v1 codebase diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index c9a281fd..b77529a6 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -2,7 +2,6 @@ ```{important} **Requirements:** Python 3.10+ | PyTorch 2.2+ (auto-installed) -**Installation time:** ~2 minutes ``` ## Quick Install @@ -20,15 +19,70 @@ import deeptab print(deeptab.__version__) # e.g., "2.0.0" ``` -## GPU Support +## Optional Dependencies -DeepTab automatically detects and uses your GPU, with no configuration needed. +The default install keeps the core small. Observability backends (structured logging and experiment trackers) ship as extras, so install only what you need: -**Verify GPU:** +```bash +pip install 'deeptab[logs]' # structlog (structured logging) +pip install 'deeptab[tensorboard]' # TensorBoard tracker +pip install 'deeptab[mlflow]' # MLflow tracker +pip install 'deeptab[tracking]' # TensorBoard + MLflow +pip install 'deeptab[all]' # structlog + TensorBoard + MLflow +``` + +```{note} +These backends are loaded lazily. Without the matching extra, DeepTab trains normally and raises only when you enable that specific feature. See the [Observability](../core_concepts/observability) guide for usage. +``` + +## Hardware Support + +DeepTab automatically detects and uses your accelerator, with no configuration +needed. It supports NVIDIA GPUs through CUDA and Apple Silicon through the MPS +backend, and falls back to the CPU when neither is present. + +**Inspect what DeepTab can see:** + +```python +from deeptab import print_hardware_info + +print_hardware_info() +``` + +```text +DeepTab hardware report +----------------------- +Platform: Darwin (arm64), Python 3.11.8, PyTorch 2.2.0 +CPU: 14 logical cores +CUDA: not available +MPS (Apple Silicon): available +Recommended accelerator: mps +``` + +The report covers the CPU core count, CUDA GPUs, the Apple Silicon MPS backend, +and the `accelerator` value DeepTab would pick by default. + +DeepTab already selects the best available accelerator, so you usually set +nothing. For portable scripts you can make this explicit with `accelerator="auto"`, +which uses a GPU when present and falls back to the CPU otherwise: + +```python +# Uses CUDA or MPS when available, otherwise CPU +model.fit(X_train, y_train, accelerator="auto", max_epochs=100) +``` + +```{tip} +Pin a specific backend (`"gpu"`, `"cuda"`, `"mps"`, or `"cpu"`) only to force +one. Unlike `"auto"`, those raise an error if the device is not present. +``` + +### NVIDIA GPUs (CUDA) ```python import torch -print(f"GPU available: {torch.cuda.is_available()}") + +print(f"CUDA available: {torch.cuda.is_available()}") +print(f"GPU count: {torch.cuda.device_count()}") ``` ```{warning} @@ -48,6 +102,25 @@ See [PyTorch installation guide](https://pytorch.org/get-started/locally/) for y export CUDA_VISIBLE_DEVICES=0,1 # Use specific GPUs ``` +### Apple Silicon (MPS) + +On M-series Macs, DeepTab uses the Metal Performance Shaders (MPS) backend. +MPS ships with the standard PyTorch build, so no extra install step is needed. + +```python +import torch + +print(f"MPS available: {torch.backends.mps.is_available()}") +print(f"MPS built: {torch.backends.mps.is_built()}") +``` + +```{note} +`is_available()` reports `True` only on macOS 12.3+ with Apple Silicon and a +PyTorch build that includes MPS. When it returns `False` but `is_built()` is +`True`, the backend is present but the OS or hardware does not support it, and +DeepTab runs on the CPU. +``` + ## Development Installation For contributing or using unreleased features: @@ -87,11 +160,12 @@ model = FTTransformerClassifier( ) ``` -**Training slow?** Check GPU is being used: +**Training slow?** Check which accelerator DeepTab detected: ```python -import torch -assert torch.cuda.is_available(), "GPU not detected" +from deeptab import print_hardware_info + +print_hardware_info() # "Recommended accelerator" should not be cpu ``` **Module not found?** Verify correct environment: diff --git a/docs/getting_started/migration.md b/docs/getting_started/migration.md new file mode 100644 index 00000000..998c93c7 --- /dev/null +++ b/docs/getting_started/migration.md @@ -0,0 +1,201 @@ +# Migrating from v1 to v2 + +DeepTab v2 keeps the `fit` / `predict` / `evaluate` workflow you already know and +rebuilds the rest around it. The package layout, the configuration objects, and a +few import paths changed, so v1 code needs a handful of edits before it runs. This +page walks through each change with before and after examples. + +```{warning} +**v2 is not backward compatible with v1, and v1 is no longer maintained.** The v1 +branch receives no bug fixes or security updates. If you are not ready to upgrade, +pin `deeptab<2.0` and plan the move when you can. +``` + +## Before you upgrade + +Pin the major version you test against so a future release never surprises a running +pipeline: + +```bash +pip install "deeptab>=2.0,<3.0" +``` + +Most projects only touch two things: how the estimator is built, and a few import +lines. If you only ever called `Model().fit(...)` and `predict(...)` with defaults, +the change is small. If you imported from internal modules, read [Import +paths](import-paths) closely. + +## Split configs + +This is the one change almost every project needs. In v1, architecture, +preprocessing, and training options were flat keyword arguments on the estimator. In +v2 they live in three focused config objects, so you can tune one concern without +touching the others. + +```python +# v1: every option flat on the estimator +from deeptab.models import MambularClassifier + +model = MambularClassifier( + d_model=128, + n_layers=4, + numerical_preprocessing="ple", + lr=1e-3, +) +``` + +```python +# v2: options grouped by concern +from deeptab.models import MambularClassifier +from deeptab.configs import MambularConfig, PreprocessingConfig, TrainerConfig + +model = MambularClassifier( + model_config=MambularConfig(d_model=128, n_layers=4), # architecture + preprocessing_config=PreprocessingConfig(numerical_preprocessing="ple"), # features + trainer_config=TrainerConfig(lr=1e-3), # training +) +``` + +Each option moves to the config that owns its concern: + +| v1 argument was about | Now lives on | Typical fields | +| ---------------------- | --------------------- | ---------------------------------------------------------------- | +| Neural architecture | `Config` | `d_model`, `n_layers`, `n_heads`, `dropout`, `layer_sizes` | +| Feature handling | `PreprocessingConfig` | `numerical_preprocessing`, `categorical_preprocessing`, `n_bins` | +| Training and optimizer | `TrainerConfig` | `max_epochs`, `batch_size`, `lr`, `patience`, `optimizer_type` | + +```{important} +Flat v1 keyword arguments are no longer accepted. A call like +`MambularClassifier(d_model=128)` now raises a `TypeError`. Move every setting into +its config object. +``` + +```{tip} +All three configs are optional. `MambularClassifier()` runs on sensible defaults, so +you only build the configs whose defaults you want to change. +``` + +The [Config System](../core_concepts/config_system) guide is the full field reference. + +## Config class renames + +Configuration classes dropped their `Default` prefix and moved to `deeptab.configs`. +A find and replace covers it. + +| v1 | v2 | +| ---------------------------- | --------------------- | +| `DefaultMambularConfig` | `MambularConfig` | +| `DefaultFTTransformerConfig` | `FTTransformerConfig` | +| `DefaultConfig` | `Config` | + +```python +# v1 +from deeptab.models import DefaultMambularConfig + +# v2 +from deeptab.configs import MambularConfig +``` + +(import-paths)= + +## Import paths + +The package was reorganised under the `deeptab` namespace. Estimators still come from +`deeptab.models`; supporting pieces moved to dedicated subpackages: + +| What you import | v2 location | +| ---------------------------------------------------------------- | ----------------------- | +| Estimators (`MambularClassifier`, ...) | `deeptab.models` | +| Config objects | `deeptab.configs` | +| Data layer | `deeptab.data` | +| Distributions for `LSS` | `deeptab.distributions` | +| Metrics | `deeptab.metrics` | +| Top-level helpers (`InferenceModel`, `set_seed`, `seed_context`) | `deeptab` | + +```{tip} +If an import breaks after upgrading, it was probably reaching into an internal v1 +module. Code that used only the public estimator and config imports needs the least +work. +``` + +## Data layer renames + +The data classes were renamed to give the pipeline a clear, typed contract. The old +`Mambular*` aliases are deprecated. + +| v1 | v2 | +| ------------------------------- | ------------------- | +| `Mambular*` data module aliases | `TabularDataModule` | +| `Mambular*` dataset aliases | `TabularDataset` | + +v2 also adds `FeatureSchema`, an inspectable description of the columns a model +expects, their order, and their types. You rarely build one by hand: DeepTab derives +it from your data during `fit` and stores it inside saved artifacts. + +## Saving, loading, and serving + +Persistence goes through a single self-describing `.deeptab` artifact that bundles +the architecture, feature schema, preprocessing, task type, and package versions +alongside the weights. A saved model carries everything it needs to reload itself. + +```python +# Save a fitted estimator +clf.save("churn_model.deeptab") + +# Load it back as a full estimator +from deeptab.models import MambularClassifier +clf = MambularClassifier.load("churn_model.deeptab") + +# Or load a read-only serving surface +from deeptab import InferenceModel +served = InferenceModel.from_path("churn_model.deeptab") +predictions = served.predict(X_new) +``` + +```{note} +`InferenceModel` exposes prediction and input validation only. Training is absent by +design, so a served model cannot be re-fitted by accident. See +[Inference](../core_concepts/inference) for the full serving surface. +``` + +## Experimental models + +ModernNCA, Tangos, and Trompt import from a separate namespace that makes their less +stable status explicit: + +```python +from deeptab.models.experimental import ModernNCAClassifier, TangosRegressor, TromptClassifier +``` + +```{warning} +Experimental models may change in minor releases. Pin an exact version such as +`deeptab==2.0.0` if you depend on one in production. +``` + +## What did not change + +The day to day modeling surface is intentionally stable: + +- `fit`, `predict`, `predict_proba`, and `evaluate` behave exactly as in v1. +- DeepTab is still scikit-learn compatible, including use inside `GridSearchCV`. +- Every architecture still ships as a classifier, a regressor, and a distributional + (`LSS`) variant sharing one interface. +- Automatic preprocessing and feature-type detection still run for you. + +## Upgrade checklist + +1. Pin `deeptab>=2.0,<3.0` and install into a clean environment. +2. Move flat estimator arguments into `MambularConfig`, `PreprocessingConfig`, and + `TrainerConfig` (or the configs for your model). +3. Rename `DefaultConfig` to `Config` and import it from `deeptab.configs`. +4. Update imports: estimators from `deeptab.models`, configs from `deeptab.configs`, + data classes from `deeptab.data`. +5. Replace `Mambular*` data module and dataset references with `TabularDataModule` + and `TabularDataset`. +6. Run your training script. A `TypeError` from the constructor almost always means a + setting still needs to move into a config. + +```{seealso} +The [FAQ](faq) covers common upgrade questions and the v1 support policy. The [Config +System](../core_concepts/config_system) guide is the authoritative field reference. +``` diff --git a/docs/getting_started/overview.md b/docs/getting_started/overview.md index 2e2d5cb2..944d66d8 100644 --- a/docs/getting_started/overview.md +++ b/docs/getting_started/overview.md @@ -1,6 +1,6 @@ # Overview -DeepTab brings modern deep learning to tabular data with a clean scikit-learn interface. No boilerplate PyTorch code, no manual data loaders, just `fit`, `predict`, and `evaluate`. +DeepTab is a library for deep learning on tabular data with a scikit-learn compatible interface. It handles feature preprocessing, batching, and the training loop, so the workflow stays `fit`, `predict`, and `evaluate` instead of hand-written PyTorch code and data loaders. Every architecture supports three tasks: classification, regression, and distributional regression for uncertainty quantification. ## What is DeepTab? @@ -14,15 +14,7 @@ DeepTab provides 15 stable neural architectures for tabular data: | **Tree-inspired** | NODE, ENODE, NDTF | Differentiable soft-tree structures | | **General baselines** | MLP, TabM, TabulaRNN | Dense, parameter-efficient ensemble, and recurrent | -**Plus 3 experimental models:** ModernNCA, Trompt, Tangos - -```{important} -**All models support three tasks:** - -- Classification (binary/multiclass) -- Regression (continuous) -- Distributional regression (uncertainty quantification) -``` +**Plus 3 experimental models:** ModernNCA, Tangos, Trompt **Example:** @@ -69,55 +61,51 @@ search = GridSearchCV(FTTransformerClassifier(), param_grid, cv=5) search.fit(X, y) ``` -### Smart Defaults, Full Control +### Defaults and Configuration -```{note} -**Automatic preprocessing:** +With no configuration, DeepTab detects feature types, encodes and scales them, and imputes missing values during preprocessing. Training runs on a GPU when one is available, with early stopping and checkpointing enabled. -- Feature type detection (numerical/categorical) -- Missing value handling -- Scaling and encoding -- GPU utilization -- Early stopping with checkpointing -``` - -**Configure when needed:** +Each layer is configurable when you need it. Architecture, preprocessing, and training settings live in separate config objects, so you can change one without touching the others: ```python from deeptab.configs import ResNetConfig, PreprocessingConfig, TrainerConfig +from deeptab.models import ResNetClassifier model = ResNetClassifier( model_config=ResNetConfig(d_model=128), preprocessing_config=PreprocessingConfig(numerical_preprocessing="quantile"), - trainer_config=TrainerConfig(lr=1e-3, batch_size=256) + trainer_config=TrainerConfig(lr=1e-3, batch_size=256), ) ``` -### Production-Ready +### Built for real datasets -DeepTab targets the data encountered in practice, not only clean benchmarks: +Beyond the defaults above, DeepTab handles details that come up with real data: -- Mixed numerical, categorical, and precomputed embedding features +- Mixed numerical, categorical, and precomputed embedding features in a single model - Automatic stratified splits for classification, preserving class proportions -- Built-in imputation of missing values during preprocessing -- Mini-batch training that scales to large datasets -- Single-device GPU acceleration by default, with other Lightning strategies (including multi-device training) available by forwarding trainer arguments to `fit()` +- Mini-batch training that scales to datasets larger than a single batch +- Multi-device and other Lightning training strategies, enabled by forwarding trainer arguments to `fit()` ## When to Use DeepTab -DeepTab is well suited to: - -- Tabular data with a mix of numerical and categorical features -- Datasets large enough for neural networks to be competitive, typically from a few thousand samples upward -- Problems with complex feature interactions -- Applications that require calibrated uncertainty through distributional regression -- Workflows that integrate with the scikit-learn ecosystem +DeepTab and gradient-boosted trees (XGBoost, LightGBM, CatBoost) are complementary tools. The table below shows where each tends to be the stronger starting point. -Gradient-boosted trees (XGBoost, LightGBM, CatBoost) remain a strong baseline and are often preferable for: +| Situation | Stronger starting point | +| -------------------------------------------------------------------------- | --------------------------------- | +| Mixed numerical and categorical features | DeepTab or gradient-boosted trees | +| A few thousand samples or more | DeepTab | +| Complex feature interactions | DeepTab | +| Calibrated uncertainty through distributional regression | DeepTab (`*LSS` variants) | +| Classification, regression, and distributional models behind one interface | DeepTab | +| Integration with scikit-learn pipelines and `GridSearchCV` | DeepTab or gradient-boosted trees | +| Small datasets where overfitting is a risk | Gradient-boosted trees | +| Data that does not fit in memory | Gradient-boosted trees | +| Latency-critical inference | Gradient-boosted trees | -- Small datasets, where neural networks are prone to overfitting -- Data that does not fit in memory -- Latency-critical inference, where tree ensembles are typically faster +```{note} +These are general guidelines, not strict rules. Results depend on the dataset, so when performance matters it is worth benchmarking DeepTab against a gradient-boosted baseline. +``` ## Next Steps diff --git a/docs/getting_started/quickstart.md b/docs/getting_started/quickstart.md index 9b183e6a..fe9f525f 100644 --- a/docs/getting_started/quickstart.md +++ b/docs/getting_started/quickstart.md @@ -39,7 +39,6 @@ model.fit(X_train, y_train, max_epochs=50) # Evaluate on test set metrics = model.evaluate(X_test, y_test) -# Returns e.g. {"accuracy": 0.91, "auroc": 0.96, "log_loss": 0.28} print(f"Test accuracy: {metrics['accuracy']:.3f}") # Make predictions @@ -87,7 +86,6 @@ X_train, X_test, y_train, y_test = train_test_split( model = FTTransformerRegressor() model.fit(X_train, y_train, max_epochs=50) -# Evaluate (returns RMSE, MAE, R² for regression) metrics = model.evaluate(X_test, y_test) print(f"Test RMSE: {metrics['rmse']:.3f}") @@ -250,9 +248,39 @@ Use the `.deeptab` extension for saved models. DeepTab accepts any extension but Note: `save()` writes a fitted estimator artifact, not just neural-network weights. The artifact includes the architecture/config, trained weights, fitted preprocessing state, feature schema and column order, task metadata such as classifier `classes_`, and package versions for debugging reloads across environments. -## Going further +## Inference guide -These examples cover the core workflow. For hyperparameter optimisation, custom optimizers and schedulers, cross-validation, working with embeddings, comparing architectures, and debugging, see the [Tutorials](../tutorials/imbalance_classification), [Core Concepts](../core_concepts/training_and_evaluation), and the [FAQ](faq). +For serving a fitted model, DeepTab provides `InferenceModel`, a read-only wrapper built for production. It loads an artifact, validates incoming data against the training schema, and predicts, while deliberately hiding `fit` and other training methods so deployment code cannot retrain a model by accident. + +```python +from deeptab import InferenceModel + +# Load a saved artifact (one type, regardless of the architecture inside) +model = InferenceModel.from_path("my_model.deeptab") + +# Validate new data against the training schema, then predict +X_valid = model.validate_input(X_new) +predictions = model.predict(X_valid) + +# Task-specific outputs +probabilities = model.predict_proba(X_valid) # classifiers only +params = model.predict_params(X_valid) # LSS models only +``` + +`validate_input` checks that the expected columns are present, reorders them to the training order, and reports missing or unexpected columns with clear messages. You can also wrap an already-fitted estimator without going through disk using `InferenceModel.from_estimator(estimator)`. + +```{note} +`InferenceModel` exposes only the prediction method that matches the task: `predict_proba` for classifiers and `predict_params` for `LSS` models. Calling the wrong one raises a clear error, so serving code never branches on the concrete model class. +``` + +If you only need a quick prediction during experimentation, calling `predict` on the fitted estimator directly works too: + +```python +predictions = model.predict(X_new) # estimator or InferenceModel +metrics = trained_estimator.evaluate(X_new, y_new) +``` + +See [Inference and deployment](../core_concepts/inference) for the full production contract, schema-validation options, and introspection helpers. ## Next steps @@ -263,4 +291,4 @@ Now that you've run your first models, explore: - **[API Reference](../api/models/index)**: Full documentation of all models and configs - **[FAQ](faq)**: Answers to common questions -For questions or issues, check the [FAQ](faq) or open an issue on [GitHub](https://github.com/OpenTabular/DeepTab/issues). +For questions or issues, open an issue on [GitHub](https://github.com/OpenTabular/DeepTab/issues). diff --git a/docs/homepage.md b/docs/homepage.md index c325a74c..0a11ba56 100644 --- a/docs/homepage.md +++ b/docs/homepage.md @@ -15,7 +15,7 @@ probabilities = model.predict_proba(X_test) ## Why DeepTab - **Familiar interface.** A scikit-learn `fit`/`predict`/`evaluate` API that drops into existing pipelines, including `GridSearchCV`. -- **Automatic preprocessing.** Feature-type detection, encoding, scaling, and missing-value handling are built in. +- **Automatic preprocessing.** Feature-type detection, encoding, scaling, and missing-value handling are powered by [PreTab](https://github.com/OpenTabular/PreTab) and applied for you. - **One model, three tasks.** Every architecture ships as a classifier, a regressor, and a distributional (`LSS`) variant for uncertainty quantification. - **A broad model zoo.** 15 stable architectures plus experimental models, all behind the same interface, with [selection guidance](model_zoo/comparison_tables). - **Built for real data.** Mixed feature types, class imbalance, GPU acceleration, and early stopping work out of the box. @@ -30,7 +30,7 @@ DeepTab requires Python 3.10+ and installs PyTorch automatically. See [Installat ## What's New in v2.0 -v2.0 is a ground-up restructuring of DeepTab. The high-level estimator API stays familiar, while the package layout, configuration objects, and import paths have moved. +v2.0 is a ground-up restructuring of DeepTab. The high-level estimator API stays familiar, while the package layout, configuration objects, and import paths have been updated. - **Split-config API**: separate model, preprocessing, and training configuration objects, so each concern can be tuned on its own. This is the first thing you reach for in v2. - **New models**: AutoInt, ENODE, and TabR (stable); Tangos, Trompt, and ModernNCA (experimental). @@ -44,7 +44,50 @@ v2.0 is a ground-up restructuring of DeepTab. The high-level estimator API stays - **Rebuilt docs and tutorials**: refreshed guides plus end-to-end, Colab-ready tutorials for [classification](tutorials/imbalance_classification), [regression](tutorials/skewed_regression), and [uncertainty quantification](tutorials/uncertainty_quantification). ```{warning} -Upgrading from v1 requires changes. Packages were reorganised, the `DefaultConfig` classes were renamed to `Config`, and the data modules became `TabularDataModule` / `TabularDataset`. See the [FAQ](getting_started/faq) for v1 support and upgrade notes. +**v2.0 is not backward compatible with v1, and v1 is no longer maintained.** Three +things changed that affect existing code: + +1. **Import paths** were reorganised under the `deeptab` namespace. +2. **Config classes** lost their `Default` prefix, so `DefaultMambularConfig` is now + `MambularConfig`. Settings are also split across `MambularConfig` (architecture), + `PreprocessingConfig` (feature handling), and `TrainerConfig` (optimisation). +3. **Data modules** were renamed to `TabularDataModule` and `TabularDataset`; the old + `Mambular*` aliases are deprecated. + +If you need to stay on v1 for now, pin `deeptab<2.0`. Note that the v1 branch receives +no bug fixes or security updates. See the [migration guide](getting_started/migration) +for a step-by-step upgrade walkthrough, and the [FAQ](getting_started/faq) for the +full support policy. +``` + +The high-level `fit`/`predict`/`evaluate` workflow is unchanged. In most cases only +the imports and config construction need updating: + +```python +# v1: settings passed as flat keyword arguments on the estimator +from deeptab.models import MambularClassifier + +model = MambularClassifier(d_model=128, n_layers=4, numerical_preprocessing="ple") +model.fit(X_train, y_train, max_epochs=50) +``` + +```python +# v2: settings grouped into focused config objects +from deeptab.models import MambularClassifier +from deeptab.configs import MambularConfig, PreprocessingConfig + +model = MambularClassifier( + model_config=MambularConfig(d_model=128, n_layers=4), # architecture + preprocessing_config=PreprocessingConfig(numerical_preprocessing="ple"), # features +) +model.fit(X_train, y_train, max_epochs=50) +``` + +```{note} +You only pass the configs you want to customise. `MambularClassifier()` with no +arguments uses sensible defaults for the architecture, preprocessing, and training. +The flat keyword-argument style from v1 is no longer accepted, so settings must go +through the relevant config object. ``` See the [Overview](getting_started/overview) for the full picture. @@ -59,61 +102,18 @@ Each architecture comes in three variants, `*Classifier`, `*Regressor`, and `*LS ## Documentation -### Getting Started - -- [Overview](getting_started/overview): What DeepTab is and when to use it -- [Installation](getting_started/installation): Setup, GPU support, and optional kernels -- [Quickstart](getting_started/quickstart): Train your first models in a few minutes -- [FAQ](getting_started/faq): Common questions and troubleshooting - -### Core Concepts - -- [sklearn API](core_concepts/sklearn_api): The fit/predict/evaluate interface -- [Model Tiers](core_concepts/model_tiers): Stable versus experimental models -- [Config System](core_concepts/config_system): Split configuration for model, preprocessing, and training -- [Training and Evaluation](core_concepts/training_and_evaluation): The fit pipeline, metrics, and reproducibility -- [Observability](core_concepts/observability): Lifecycle events, structured logging, and experiment tracking -- [Model Operations](core_concepts/model_operations): Serialisation and inspection -- [Inference](core_concepts/inference): Deployment-safe prediction with `InferenceModel` - -### Tutorials - -- [Imbalanced Classification](tutorials/imbalance_classification): An end-to-end classification workflow -- [Skewed-Target Regression](tutorials/skewed_regression): Regression on a right-skewed target -- [Uncertainty Quantification](tutorials/uncertainty_quantification): Prediction intervals with LSS models -- [Hyperparameter Optimisation](tutorials/hpo): Tuning models efficiently -- [Advanced Training and Inference](tutorials/advanced_training): Optimizers, schedulers, and production inference -- [Observability and Logging](tutorials/observability): Run directories and experiment trackers -- [Model Efficiency](tutorials/model_efficiency): Runtime and memory benchmarking -- [Experimental Models](tutorials/experimental): Working with cutting-edge architectures - -### Model Zoo - -- [Comparison Tables](model_zoo/comparison_tables): Selection guidance and performance across dimensions -- [Stable Models](model_zoo/stable/index): Production-ready architectures -- [Experimental Models](model_zoo/experimental/index): Models under evaluation -- [Efficiency and Benchmarking](model_zoo/efficiency): Runtime and memory guidance -- [Recommended Configs](model_zoo/recommended_configs): Hyperparameter recipes - -### API Reference - -- [Models](api/models/index): Classifier, Regressor, and LSS classes -- [Configs](api/configs/index): Configuration dataclasses -- [Data](api/data/index): Datasets, data modules, and schemas -- [Distributions](api/distributions/index): LSS distribution families -- [Metrics](api/metrics/index): Task-aware metric classes -- [Training](api/training/index): Lightning modules for advanced use - -### Developer Guide - -- [Contributing](developer_guide/contributing): How to contribute -- [Testing](developer_guide/testing): Test suite and coverage -- [Documentation](developer_guide/documentation): Building the docs locally -- [Versioning](developer_guide/versioning): Semantic versioning policy -- [CI/CD](developer_guide/ci_cd): Continuous integration -- [Release Process](developer_guide/release): Release workflow -- [Model Promotion Policy](developer_guide/model_promotion_policy): From experimental to stable -- [Support Matrix](developer_guide/support_matrix): Supported Python and PyTorch versions +```{note} +These are starting points for each area. The sidebar navigation is the source of +truth, so please review the individual documentation sections for the latest +updates and further documentation. +``` + +- **Getting Started**: Begin with the [Overview](getting_started/overview) and [Quickstart](getting_started/quickstart), then see [Installation](getting_started/installation) for GPU setup. +- **Core Concepts**: How DeepTab works, including the [sklearn API](core_concepts/sklearn_api), the [Config System](core_concepts/config_system), and [Training and Evaluation](core_concepts/training_and_evaluation). +- **Tutorials**: End-to-end, Colab-ready walkthroughs for [regression](tutorials/skewed_regression), [classification](tutorials/imbalance_classification), and [uncertainty quantification](tutorials/uncertainty_quantification). +- **Model Zoo**: Browse the [Stable Models](model_zoo/stable/index) and [Experimental Models](model_zoo/experimental/index), or use the [Comparison Tables](model_zoo/comparison_tables) for selection guidance. +- **API Reference**: Full reference for [Models](api/models/index), [Configs](api/configs/index), and the rest of the public API. +- **Developer Guide**: [Contributing](developer_guide/contributing), [Testing](developer_guide/testing), and the [Release Process](developer_guide/release) for maintainers. --- diff --git a/docs/index.rst b/docs/index.rst index edaff04c..5d8bb244 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,6 +11,7 @@ getting_started/installation getting_started/quickstart getting_started/faq + getting_started/migration .. toctree:: :caption: Core Concepts diff --git a/docs/model_zoo/comparison_tables.md b/docs/model_zoo/comparison_tables.md index 8eb2242e..ffa5d280 100644 --- a/docs/model_zoo/comparison_tables.md +++ b/docs/model_zoo/comparison_tables.md @@ -64,56 +64,6 @@ The "DeepTab Default Shape" column is taken from the current model config defaul - **Other:** Standard architectures (MLP, parameter-efficient ensembles, RNNs). ``` -## Architecture Categories - -### State Space Models (SSMs) - -**Feature-sequence models with linear sequence-length scaling in the Mamba blocks** - -| Model | Default Layers | Default Hidden Dim | Key Feature | Best Use Case | -| ------------- | -------------- | ------------------ | ---------------------------------------- | ----------------------------------------- | -| Mambular | 4 Mamba layers | 64 | Stacked Mamba blocks over feature tokens | General-purpose tabular sequence modeling | -| MambaTab | 1 Mamba layer | 64 | Lightweight Mamba block | Small datasets, speed | -| MambAttention | Hybrid | 64 | Mamba blocks plus feature attention | Complex feature interactions | - -### Transformer-Based - -**Attention mechanisms for feature and row interactions** - -| Model | Attention Scope | Default Hidden Dim | Key Feature | Best Use Case | -| -------------- | ------------------ | ------------------ | ------------------------------------------- | --------------------------------------- | -| FTTransformer | All feature tokens | 128 | Feature tokenization | Feature interactions | -| TabTransformer | Categorical tokens | 128 | Contextual categorical embeddings | Categorical-heavy data | -| SAINT | Row + column | 128 | Intersample (row) plus column attention | Semi-supervised or row-context settings | -| AutoInt | All feature tokens | 128 | Self-attentive feature interaction learning | Automatic interaction modeling | - -### Tree-Inspired - -**Differentiable tree and forest structures** - -| Model | Tree Type | Default Shape | Key Feature | Best Use Case | -| ----- | ------------------------------ | ---------------------------------- | ------------------------------------------- | -------------------------------------- | -| NODE | Oblivious differentiable trees | 4 layers, 128 trees/layer, depth 6 | Soft routing over oblivious trees | Interpretable tree-inspired modeling | -| ENODE | Embedded NODE variant | 4 layers, 64 trees/layer, depth 6 | Feature embeddings before NODE-style blocks | Tree-inspired modeling with embeddings | -| NDTF | Neural decision tree forest | 12 trees, random depths 4 to 15 | Multiple neural decision trees | Tree ensemble-style experiments | - -### Residual Networks - -**Deep feedforward networks with skip connections** - -| Model | Default Shape | Key Feature | Best Use Case | -| ------ | ----------------------------------------------- | ------------------------------ | ---------------------------------------------- | -| ResNet | 3 residual blocks, `[256, 128, 32]` layer sizes | Residual blocks | Fast baseline | -| TabR | `d_main=256`, `context_size=96` | Retrieval-augmented prediction | Larger datasets with useful neighbor structure | - -### Other Architectures - -| Model | Type | Default Shape | Key Feature | Best Use Case | -| --------- | ---------------------------- | -------------------------------------------------- | ----------------------------- | --------------------------- | -| MLP | Feedforward | `[256, 128, 32]` layer sizes | Simple dense baseline | Fastest baseline | -| TabM | Parameter-efficient ensemble | `[256, 256, 128]` layer sizes, 32 ensemble members | Batch ensembling | Strong efficient baseline | -| TabulaRNN | RNN | `d_model=128`, 4 recurrent layers | Sequential feature processing | Sequential feature modeling | - ## Model Selection by Use Case ```{note} @@ -158,27 +108,6 @@ The "DeepTab Default Shape" column is taken from the current model config defaul **Special cases:** For quantile regression, use any model in LSS mode with an appropriate distribution family. -## Recommended Decision Tree - -``` -Start Here -| -|- Dataset size <5K? -> Use MambaTab, ResNet, MLP, or TabM with regularization -| -|- Need tree-inspired interpretability? -> Use NODE, ENODE, or NDTF -| -|- Memory constrained (<8GB)? -> Prefer Mambular, MambaTab, MLP, ResNet, or TabM -| -|- Inference latency critical? -> Avoid retrieval/large attention; use MLP, ResNet, TabM, or Mamba variants -| -|- >60% categorical features? -> Consider TabTransformer -| -|- Need retrieval from similar training examples? -> Consider TabR -| -`- General purpose -> Mambular or TabM - `- Alternative -> FTTransformer when GPU memory and feature count permit -``` - ## Hardware Requirements by Model The table below gives practical guidance on whether each model trains comfortably on a **CPU-only machine** or requires a **GPU (CUDA, MPS, or other accelerator)**. Thresholds are rough estimates based on architecture cost, and the actual boundary depends on the number of features, hidden width, and depth used. diff --git a/docs/model_zoo/experimental/modernnca.md b/docs/model_zoo/experimental/modernnca.md index 58dac421..8c5f3f37 100644 --- a/docs/model_zoo/experimental/modernnca.md +++ b/docs/model_zoo/experimental/modernnca.md @@ -1,5 +1,7 @@ # ModernNCA +**Available as:** `ModernNCAClassifier`, `ModernNCARegressor`, and `ModernNCALSS` in `deeptab.models.experimental`. + **ModernNCA** is a differentiable nearest-neighbor model for tabular data. It learns a neural representation of each row, compares query rows to candidate rows in that representation space, and predicts by a softmax-weighted average of candidate labels. ```{warning} @@ -17,17 +19,17 @@ ModernNCA revisits Neighborhood Component Analysis (NCA) with modern tabular dee This makes ModernNCA useful when the target function is locally smooth in a representation space: rows with similar learned embeddings should have similar labels. -| Property | DeepTab ModernNCA | -| -------- | ----------------- | -| Inductive bias | Local similarity / soft nearest-neighbor prediction | -| Prediction form | Weighted candidate labels | -| Training mode | Candidate-aware via `train_with_candidates` | -| Inference cost | Pairwise distance to candidate rows | -| Best baseline comparisons | TabR, TabM, ResNet, MLP | +| Property | DeepTab ModernNCA | +| ------------------------- | --------------------------------------------------- | +| Inductive bias | Local similarity / soft nearest-neighbor prediction | +| Prediction form | Weighted candidate labels | +| Training mode | Candidate-aware via `train_with_candidates` | +| Inference cost | Pairwise distance to candidate rows | +| Best baseline comparisons | TabR, TabM, ResNet, MLP | ## Architectural Details -For a query row \(x_i\) and candidate rows \(\{x_j, y_j\}\), ModernNCA learns an encoder \(\phi_\theta\): +For a query row \(x*i\) and candidate rows \(\{x_j, y_j\}\), ModernNCA learns an encoder \(\phi*\theta\): ```text raw features @@ -44,11 +46,11 @@ embedding z = phi(x) Distances are converted to candidate weights: \[ -d_{ij} = \frac{\|\phi_\theta(x_i) - \phi_\theta(x_j)\|_2}{T} +d*{ij} = \frac{\|\phi*\theta(x*i) - \phi*\theta(x_j)\|\_2}{T} \] \[ -w_{ij} = \mathrm{softmax}_j(-d_{ij}) +w*{ij} = \mathrm{softmax}\_j(-d*{ij}) \] For regression, the output is the weighted average of candidate targets. For classification, candidate labels are one-hot encoded and the weighted class probabilities are log-transformed before loss computation. @@ -59,28 +61,28 @@ During training, DeepTab concatenates the current batch with a sampled subset of The implementation lives in `deeptab/architectures/experimental/modern_nca.py`. -| Component | Implementation | Role | -| --------- | -------------- | ---- | -| Optional feature embedding | `EmbeddingLayer` when `use_embeddings=True` | Converts raw columns into per-feature representations | -| Encoder | `nn.Linear(input_dim, config.dim)` | Projects the flattened row into metric space | -| Post-encoder | Repeated BatchNorm -> Linear -> ReLU -> Dropout -> Linear blocks | Adds nonlinear representation capacity | -| Candidate weighting | `torch.cdist` + `softmax(-distance / temperature)` | Differentiable neighbor weighting | -| Candidate prediction | Matrix multiply between weights and candidate labels | Produces regression values or class probabilities | -| Fallback head | `MLPhead` in `forward` | Allows non-candidate forward compatibility | +| Component | Implementation | Role | +| -------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------- | +| Optional feature embedding | `EmbeddingLayer` when `use_embeddings=True` | Converts raw columns into per-feature representations | +| Encoder | `nn.Linear(input_dim, config.dim)` | Projects the flattened row into metric space | +| Post-encoder | Repeated BatchNorm -> Linear -> ReLU -> Dropout -> Linear blocks | Adds nonlinear representation capacity | +| Candidate weighting | `torch.cdist` + `softmax(-distance / temperature)` | Differentiable neighbor weighting | +| Candidate prediction | Matrix multiply between weights and candidate labels | Produces regression values or class probabilities | +| Fallback head | `MLPhead` in `forward` | Allows non-candidate forward compatibility | ## Configuration -| Parameter | Default | Practical Effect | -| --------- | ------- | ---------------- | -| `dim` | `128` | Metric-space dimension after the encoder | -| `d_block` | `512` | Hidden width inside residual post-encoder blocks | -| `n_blocks` | `4` | Number of post-encoder blocks | -| `dropout` | `0.1` | Regularization inside post-encoder blocks | -| `temperature` | `0.75` | Softmax sharpness for candidate weighting | -| `sample_rate` | `0.5` | Fraction of candidate rows sampled during training | -| `embedding_type` | `"plr"` | Default embedding type when embeddings are enabled | -| `n_frequencies` | `75` | PLR frequency count | -| `frequencies_init_scale` | `0.045` | PLR initialization scale | +| Parameter | Default | Practical Effect | +| ------------------------ | ------- | -------------------------------------------------- | +| `dim` | `128` | Metric-space dimension after the encoder | +| `d_block` | `512` | Hidden width inside residual post-encoder blocks | +| `n_blocks` | `4` | Number of post-encoder blocks | +| `dropout` | `0.1` | Regularization inside post-encoder blocks | +| `temperature` | `0.75` | Softmax sharpness for candidate weighting | +| `sample_rate` | `0.5` | Fraction of candidate rows sampled during training | +| `embedding_type` | `"plr"` | Default embedding type when embeddings are enabled | +| `n_frequencies` | `75` | PLR frequency count | +| `frequencies_init_scale` | `0.045` | PLR initialization scale | ```python from deeptab.configs import ModernNCAConfig, PreprocessingConfig, TrainerConfig @@ -103,19 +105,19 @@ model = ModernNCAClassifier( ## Practical Guide -| Dataset Condition | Recommendation | -| ----------------- | -------------- | -| Small to medium data | ModernNCA is worth testing; candidate distance cost is manageable | -| Very large candidate pool | Reduce `sample_rate`, use smaller batches, or prefer TabR/parametric models | -| Noisy labels | Increase `temperature` or regularization; very sharp neighbor weights can overfit | -| Strong local clusters | ModernNCA may be competitive with retrieval models | -| Latency-sensitive inference | Prefer MLP/ResNet/TabM unless candidate search is acceptable | +| Dataset Condition | Recommendation | +| --------------------------- | --------------------------------------------------------------------------------- | +| Small to medium data | ModernNCA is worth testing; candidate distance cost is manageable | +| Very large candidate pool | Reduce `sample_rate`, use smaller batches, or prefer TabR/parametric models | +| Noisy labels | Increase `temperature` or regularization; very sharp neighbor weights can overfit | +| Strong local clusters | ModernNCA may be competitive with retrieval models | +| Latency-sensitive inference | Prefer MLP/ResNet/TabM unless candidate search is acceptable | Suggested search space: ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile", "ple"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile", "ple"], "model_config__dim": [64, 128, 256], "model_config__n_blocks": [2, 4, 6], "model_config__d_block": [256, 512], diff --git a/docs/model_zoo/experimental/tangos.md b/docs/model_zoo/experimental/tangos.md index 869e9fb0..e96bcd19 100644 --- a/docs/model_zoo/experimental/tangos.md +++ b/docs/model_zoo/experimental/tangos.md @@ -1,5 +1,7 @@ # Tangos +**Available as:** `TangosClassifier`, `TangosRegressor`, and `TangosLSS` in `deeptab.models.experimental`. + **Tangos** is an MLP-style tabular model with a gradient-attribution regularizer. It encourages hidden units to become specialized and diverse by penalizing latent-unit attributions with respect to input features. ```{warning} @@ -15,13 +17,13 @@ The research hypothesis is that tabular MLPs generalize better when hidden units - specialize on a sparse subset of input features, and - avoid learning highly overlapping feature attributions. -| Property | DeepTab Tangos | -| -------- | -------------- | -| Base architecture | MLP | -| Additional mechanism | Jacobian-based specialization and orthogonalization penalty | -| Training hook | `penalty_forward` | -| Main cost driver | `torch.func.jacrev` / Jacobian computation | -| Best baseline comparisons | MLP, ResNet, TabM | +| Property | DeepTab Tangos | +| ------------------------- | ----------------------------------------------------------- | +| Base architecture | MLP | +| Additional mechanism | Jacobian-based specialization and orthogonalization penalty | +| Training hook | `penalty_forward` | +| Main cost driver | `torch.func.jacrev` / Jacobian computation | +| Best baseline comparisons | MLP, ResNet, TabM | ## Architectural Details @@ -42,7 +44,7 @@ Linear output head During training, Tangos computes a representation Jacobian: \[ -J_{h,x} = \frac{\partial h(x)}{\partial x} +J\_{h,x} = \frac{\partial h(x)}{\partial x} \] where \(h(x)\) is the representation before the final output head. The model builds latent-unit attribution vectors from this Jacobian and adds: @@ -53,38 +55,38 @@ where \(h(x)\) is the representation before the final output head. The model bui The training loss is: \[ -\mathcal{L}_{total} = \mathcal{L}_{task} + \lambda_1 \mathcal{L}_{spec} + \lambda_2 \mathcal{L}_{orth} +\mathcal{L}_{total} = \mathcal{L}_{task} + \lambda*1 \mathcal{L}*{spec} + \lambda*2 \mathcal{L}*{orth} \] ## Main Building Blocks The implementation lives in `deeptab/architectures/experimental/tangos.py`. -| Component | Implementation | Role | -| --------- | -------------- | ---- | -| Dense body | `nn.ModuleList` of linear, normalization, activation, dropout layers | Learns tabular representation | -| Optional GLU | `nn.GLU()` when `use_glu=True` | Gated dense transformations | -| Optional skip connections | Shape-matched residual additions | Stabilizes deeper MLPs | -| Representation function | `repr_forward` | Hidden representation used for Jacobian attribution | -| Jacobian computation | `torch.func.vmap(torch.func.jacrev(...))` | Computes per-sample hidden-unit attributions | -| Specialization loss | L1 norm of attribution tensor | Encourages sparse feature usage | -| Orthogonality loss | Cosine similarity between neuron attributions | Encourages diverse hidden units | -| Output head | `nn.Linear(last_hidden, num_classes)` | Task prediction | +| Component | Implementation | Role | +| ------------------------- | -------------------------------------------------------------------- | --------------------------------------------------- | +| Dense body | `nn.ModuleList` of linear, normalization, activation, dropout layers | Learns tabular representation | +| Optional GLU | `nn.GLU()` when `use_glu=True` | Gated dense transformations | +| Optional skip connections | Shape-matched residual additions | Stabilizes deeper MLPs | +| Representation function | `repr_forward` | Hidden representation used for Jacobian attribution | +| Jacobian computation | `torch.func.vmap(torch.func.jacrev(...))` | Computes per-sample hidden-unit attributions | +| Specialization loss | L1 norm of attribution tensor | Encourages sparse feature usage | +| Orthogonality loss | Cosine similarity between neuron attributions | Encourages diverse hidden units | +| Output head | `nn.Linear(last_hidden, num_classes)` | Task prediction | ## Configuration -| Parameter | Default | Practical Effect | -| --------- | ------- | ---------------- | -| `layer_sizes` | `[256, 128, 32]` | Width/depth of the MLP body | -| `dropout` | `0.2` | Standard dropout regularization | -| `activation` | `nn.ReLU()` | Hidden activation | -| `use_glu` | `False` | Enables gated linear units | -| `skip_connections` | `False` | Adds residual connections when shapes match | -| `batch_norm` | inherited default `False` | Optional batch normalization | -| `layer_norm` | inherited default `False` | Optional layer normalization | -| `lamda1` | `0.5` | Weight for specialization penalty | -| `lamda2` | `0.1` | Weight for orthogonality penalty | -| `subsample` | `0.5` | Fraction used for regularization pair sampling | +| Parameter | Default | Practical Effect | +| ------------------ | ------------------------- | ---------------------------------------------- | +| `layer_sizes` | `[256, 128, 32]` | Width/depth of the MLP body | +| `dropout` | `0.2` | Standard dropout regularization | +| `activation` | `nn.ReLU()` | Hidden activation | +| `use_glu` | `False` | Enables gated linear units | +| `skip_connections` | `False` | Adds residual connections when shapes match | +| `batch_norm` | inherited default `False` | Optional batch normalization | +| `layer_norm` | inherited default `False` | Optional layer normalization | +| `lamda1` | `0.5` | Weight for specialization penalty | +| `lamda2` | `0.1` | Weight for orthogonality penalty | +| `subsample` | `0.5` | Fraction used for regularization pair sampling | ```python from deeptab.configs import PreprocessingConfig, TangosConfig, TrainerConfig @@ -98,7 +100,7 @@ model = TangosRegressor( lamda2=0.1, subsample=0.5, ), - preprocessing_config=PreprocessingConfig(numerical_preprocessing="standard"), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="standardization"), trainer_config=TrainerConfig(lr=1e-3, batch_size=128, max_epochs=100), random_state=101, ) @@ -106,19 +108,19 @@ model = TangosRegressor( ## Practical Guide -| Dataset Condition | Recommendation | -| ----------------- | -------------- | -| Small or noisy data | Try Tangos against MLP/ResNet; the regularizer may help | -| Very high feature count | Watch Jacobian memory and runtime | -| Large batch sizes | Reduce batch size if Jacobian computation is slow or memory-heavy | -| Need fast training | Prefer MLP, ResNet, or TabM | -| Want attribution diversity analysis | Tangos is a useful research model | +| Dataset Condition | Recommendation | +| ----------------------------------- | ----------------------------------------------------------------- | +| Small or noisy data | Try Tangos against MLP/ResNet; the regularizer may help | +| Very high feature count | Watch Jacobian memory and runtime | +| Large batch sizes | Reduce batch size if Jacobian computation is slow or memory-heavy | +| Need fast training | Prefer MLP, ResNet, or TabM | +| Want attribution diversity analysis | Tangos is a useful research model | Suggested search space: ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile"], "model_config__layer_sizes": [[128, 64], [256, 128, 32], [512, 256, 128]], "model_config__dropout": [0.0, 0.1, 0.2, 0.3], "model_config__lamda1": [0.1, 0.5, 1.0], diff --git a/docs/model_zoo/experimental/trompt.md b/docs/model_zoo/experimental/trompt.md index 62622fe1..b30d30ae 100644 --- a/docs/model_zoo/experimental/trompt.md +++ b/docs/model_zoo/experimental/trompt.md @@ -1,5 +1,7 @@ # Trompt +**Available as:** `TromptClassifier`, `TromptRegressor`, and `TromptLSS` in `deeptab.models.experimental`. + **Trompt** is a prompt-inspired tabular architecture. It uses learnable prompt/prototype records and feature-importance maps to repeatedly aggregate column representations, producing one prediction per cycle. ```{warning} @@ -19,13 +21,13 @@ In DeepTab, Trompt is implemented as a sequence of `TromptCell` modules. Each ce The model returns predictions from every cycle, so DeepTab treats Trompt as an ensemble-like model (`returns_ensemble=True`). -| Property | DeepTab Trompt | -| -------- | -------------- | -| Inductive bias | Prompt/prototype-mediated feature aggregation | -| Core representation | `P` latent prompt records of width `d_model` | -| Repeated computation | `n_cycles` Trompt cells | -| Output | One decoded prediction per cycle | -| Best baseline comparisons | FTTransformer, Mambular, TabM | +| Property | DeepTab Trompt | +| ------------------------- | --------------------------------------------- | +| Inductive bias | Prompt/prototype-mediated feature aggregation | +| Core representation | `P` latent prompt records of width `d_model` | +| Repeated computation | `n_cycles` Trompt cells | +| Output | One decoded prediction per cycle | +| Best baseline comparisons | FTTransformer, Mambular, TabM | ## Architectural Details @@ -63,15 +65,15 @@ Unlike FTTransformer, the current DeepTab Trompt implementation does not use a s The implementation lives in `deeptab/architectures/experimental/trompt.py` and `deeptab/nn/blocks/trompt.py`. -| Component | Implementation | Role | -| --------- | -------------- | ---- | -| Feature encoder | `EmbeddingLayer` | Produces per-column embeddings | -| Initial prompt records | `init_rec` parameter with shape `(P, d_model)` | Starting latent prompt state | -| Cell stack | `nn.ModuleList(TromptCell(...))` repeated `n_cycles` times | Iterative prompt-feature aggregation | -| Expander | `Expander(P)` | Expands feature embeddings into prompt slots | -| Feature importance | `ImportanceGetter(P, C, d_model)` | Computes prompt-to-column weights | -| Decoder | `TromptDecoder(d_model, num_classes)` | Converts prompt records to predictions | -| Ensemble behavior | `returns_ensemble=True` | Training loss is accumulated across cycle outputs | +| Component | Implementation | Role | +| ---------------------- | ---------------------------------------------------------- | ------------------------------------------------- | +| Feature encoder | `EmbeddingLayer` | Produces per-column embeddings | +| Initial prompt records | `init_rec` parameter with shape `(P, d_model)` | Starting latent prompt state | +| Cell stack | `nn.ModuleList(TromptCell(...))` repeated `n_cycles` times | Iterative prompt-feature aggregation | +| Expander | `Expander(P)` | Expands feature embeddings into prompt slots | +| Feature importance | `ImportanceGetter(P, C, d_model)` | Computes prompt-to-column weights | +| Decoder | `TromptDecoder(d_model, num_classes)` | Converts prompt records to predictions | +| Ensemble behavior | `returns_ensemble=True` | Training loss is accumulated across cycle outputs | ```{note} `n_cells` is present in `TromptConfig`, but the current DeepTab implementation constructs one `TromptCell` per cycle. Treat `n_cycles` and `P` as the primary practical controls. @@ -79,12 +81,12 @@ The implementation lives in `deeptab/architectures/experimental/trompt.py` and ` ## Configuration -| Parameter | Default | Practical Effect | -| --------- | ------- | ---------------- | -| `d_model` | `128` | Width of feature and prompt representations | -| `n_cycles` | `6` | Number of iterative prompt aggregation cycles | -| `n_cells` | `4` | Config field retained from the Trompt design; limited direct effect in current implementation | -| `P` | `128` | Number of prompt/prototype records | +| Parameter | Default | Practical Effect | +| ---------- | ------- | --------------------------------------------------------------------------------------------- | +| `d_model` | `128` | Width of feature and prompt representations | +| `n_cycles` | `6` | Number of iterative prompt aggregation cycles | +| `n_cells` | `4` | Config field retained from the Trompt design; limited direct effect in current implementation | +| `P` | `128` | Number of prompt/prototype records | ```python from deeptab.configs import PreprocessingConfig, TrainerConfig, TromptConfig @@ -105,19 +107,19 @@ model = TromptClassifier( ## Practical Guide -| Dataset Condition | Recommendation | -| ----------------- | -------------- | -| Mixed feature types | Trompt can be worth testing because all features pass through `EmbeddingLayer` | +| Dataset Condition | Recommendation | +| ------------------------------------ | -------------------------------------------------------------------------------------------- | +| Mixed feature types | Trompt can be worth testing because all features pass through `EmbeddingLayer` | | Need interpretable feature weighting | Inspect prompt-to-column weights conceptually, but internal tooling may require custom hooks | -| Large feature count | Reduce `P` or `d_model`; importance maps scale with prompt slots and columns | -| Need stable transformer baseline | Use FTTransformer | -| Need strong efficient baseline | Use TabM | +| Large feature count | Reduce `P` or `d_model`; importance maps scale with prompt slots and columns | +| Need stable transformer baseline | Use FTTransformer | +| Need strong efficient baseline | Use TabM | Suggested search space: ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile", "ple"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile", "ple"], "model_config__d_model": [64, 128, 256], "model_config__n_cycles": [2, 4, 6], "model_config__P": [32, 64, 128], diff --git a/docs/model_zoo/index.md b/docs/model_zoo/index.md new file mode 100644 index 00000000..20f145b3 --- /dev/null +++ b/docs/model_zoo/index.md @@ -0,0 +1,15 @@ +--- +orphan: true +--- + +# Model Zoo + +DeepTab ships 15 stable architectures plus experimental models, all behind the same +`fit`/`predict`/`evaluate` interface. Use these pages to compare models, understand +their efficiency trade-offs, and find recommended configurations. + +- **[Stable Models](stable/index)**: Production-ready architectures +- **[Experimental Models](experimental/index)**: Architectures under evaluation for promotion +- **[Comparison Tables](comparison_tables)**: Side-by-side model comparison and selection guidance +- **[Efficiency](efficiency)**: Runtime and memory characteristics +- **[Recommended Configs](recommended_configs)**: Sensible starting configurations per model diff --git a/docs/model_zoo/recommended_configs.md b/docs/model_zoo/recommended_configs.md index 8e4afdf3..bf0400ab 100644 --- a/docs/model_zoo/recommended_configs.md +++ b/docs/model_zoo/recommended_configs.md @@ -329,7 +329,7 @@ Preprocessing is part of the model in tabular deep learning. Tune it explicitly. | Data Condition | Candidate Setting | Notes | | ------------------------------------ | ----------------------------------------------------------- | ---------------------------------------------------------- | -| Roughly symmetric numerical features | `numerical_preprocessing="standard"` | Fast, simple, and easy to audit | +| Roughly symmetric numerical features | `numerical_preprocessing="standardization"` | Fast, simple, and easy to audit | | Heavy tails/outliers/skew | `numerical_preprocessing="quantile"` | Often robust for real-world tables | | Bounded features | `numerical_preprocessing="minmax"` | Use when scale bounds are meaningful | | Nonlinear numeric effects | `numerical_preprocessing="ple"`, tune `n_bins` | Connects to numerical feature embedding work | @@ -341,7 +341,7 @@ from deeptab.configs import PreprocessingConfig # Conservative baseline standard_prep = PreprocessingConfig( - numerical_preprocessing="standard", + numerical_preprocessing="standardization", categorical_preprocessing="int", ) @@ -371,7 +371,7 @@ Use small spaces first. Expand only after the baseline protocol is stable. ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile", "ple"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile", "ple"], "preprocessing_config__n_bins": [32, 64], "model_config__d_model": [64, 128, 256], "model_config__n_layers": [2, 4, 6], @@ -386,7 +386,7 @@ param_grid = { ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile", "ple"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile", "ple"], "model_config__d_model": [64, 128, 256], "model_config__n_layers": [2, 4, 6], "model_config__n_heads": [4, 8], @@ -401,7 +401,7 @@ param_grid = { ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile", "ple"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile", "ple"], "model_config__layer_sizes": [[256, 128], [256, 256, 128], [512, 256, 128]], "model_config__ensemble_size": [8, 16, 32], "model_config__dropout": [0.0, 0.1, 0.2], @@ -415,7 +415,7 @@ param_grid = { ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile", "ple"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile", "ple"], "model_config__d_main": [128, 256], "model_config__context_size": [32, 64, 96], "model_config__dropout0": [0.0, 0.2, 0.4], @@ -429,7 +429,7 @@ param_grid = { ```python param_grid = { - "preprocessing_config__numerical_preprocessing": ["standard", "quantile"], + "preprocessing_config__numerical_preprocessing": ["standardization", "quantile"], "model_config__num_layers": [2, 4, 6], "model_config__layer_dim": [64, 128, 256], "model_config__depth": [4, 6, 8], diff --git a/docs/model_zoo/stable/autoint.md b/docs/model_zoo/stable/autoint.md index c6d5d34b..4f272f0c 100644 --- a/docs/model_zoo/stable/autoint.md +++ b/docs/model_zoo/stable/autoint.md @@ -1,5 +1,7 @@ # AutoInt +**Available as:** `AutoIntClassifier`, `AutoIntRegressor`, and `AutoIntLSS` in `deeptab.models`. + ## Overview AutoInt learns feature interactions with stacked multi-head self-attention layers. It treats tabular columns as feature tokens, repeatedly attends across tokens, flattens the final token sequence, and predicts with a linear head. @@ -21,12 +23,12 @@ feature tokens -> [LayerNorm -> MultiheadAttention -> residual -> Linear -> resi ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Builds feature tokens. | -| Interaction layer | `nn.MultiheadAttention` | Learns pairwise and higher-order token interactions. | -| Residual projection | `nn.Linear(d_model, d_model)` | Updates each attended token. | -| Output head | `nn.Linear(d_model * n_inputs, num_classes)` | Uses all token states for prediction. | +| Component | DeepTab implementation | Role | +| ------------------- | -------------------------------------------- | ---------------------------------------------------- | +| Tokenizer | `EmbeddingLayer` | Builds feature tokens. | +| Interaction layer | `nn.MultiheadAttention` | Learns pairwise and higher-order token interactions. | +| Residual projection | `nn.Linear(d_model, d_model)` | Updates each attended token. | +| Output head | `nn.Linear(d_model * n_inputs, num_classes)` | Uses all token states for prediction. | ## Implementation Notes @@ -55,12 +57,12 @@ model = AutoIntClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `64` to `256` | Token width. | -| `n_layers` | `2` to `6` | Number of interaction layers. | -| `n_heads` | `4` to `8` | Attention heads; must divide `d_model`. | -| `attn_dropout` | `0.0` to `0.3` | Attention regularization. | +| Setting | Typical range | Effect | +| ----------------------------- | ----------------- | ----------------------------------------------- | +| `d_model` | `64` to `256` | Token width. | +| `n_layers` | `2` to `6` | Number of interaction layers. | +| `n_heads` | `4` to `8` | Attention heads; must divide `d_model`. | +| `attn_dropout` | `0.0` to `0.3` | Attention regularization. | | `transformer_dim_feedforward` | Present in config | Not used by the current `AutoInt` architecture. | ## When To Use diff --git a/docs/model_zoo/stable/enode.md b/docs/model_zoo/stable/enode.md index 5cd45e50..797fcb9d 100644 --- a/docs/model_zoo/stable/enode.md +++ b/docs/model_zoo/stable/enode.md @@ -1,5 +1,7 @@ # ENODE +**Available as:** `ENODEClassifier`, `ENODERegressor`, and `ENODELSS` in `deeptab.models`. + ## Overview ENODE is DeepTab's enhanced NODE variant. It keeps differentiable oblivious tree layers but operates on embedded feature tokens and aggregates the learned tree representation before a compact prediction head. @@ -21,12 +23,12 @@ feature tokens -> ENODEDenseBlock -> mean over feature axis -> Linear/ReLU/Dropo ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Builds embedded feature tokens. | -| Tree block | `ENODEDenseBlock` | Applies enhanced differentiable tree transformations. | -| Aggregation | `x.mean(axis=1)` | Produces one row representation. | -| Head | `nn.Linear -> ReLU -> Dropout -> nn.Linear` | Task output. | +| Component | DeepTab implementation | Role | +| ----------- | ------------------------------------------- | ----------------------------------------------------- | +| Tokenizer | `EmbeddingLayer` | Builds embedded feature tokens. | +| Tree block | `ENODEDenseBlock` | Applies enhanced differentiable tree transformations. | +| Aggregation | `x.mean(axis=1)` | Produces one row representation. | +| Head | `nn.Linear -> ReLU -> Dropout -> nn.Linear` | Task output. | ## Implementation Notes @@ -55,12 +57,12 @@ model = ENODERegressor( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `4` to `32` | Embedded feature width. | -| `num_layers` | `2` to `6` | Number of tree layers. | -| `layer_dim` | `32` to `128` | Tree-layer width. | -| `depth` | `4` to `8` | Soft decision depth. | +| Setting | Typical range | Effect | +| -------------- | -------------- | ------------------------------- | +| `d_model` | `4` to `32` | Embedded feature width. | +| `num_layers` | `2` to `6` | Number of tree layers. | +| `layer_dim` | `32` to `128` | Tree-layer width. | +| `depth` | `4` to `8` | Soft decision depth. | | `head_dropout` | `0.0` to `0.5` | Prediction-head regularization. | ## When To Use diff --git a/docs/model_zoo/stable/fttransformer.md b/docs/model_zoo/stable/fttransformer.md index f1fb2181..2b5380f6 100644 --- a/docs/model_zoo/stable/fttransformer.md +++ b/docs/model_zoo/stable/fttransformer.md @@ -1,5 +1,7 @@ # FTTransformer +**Available as:** `FTTransformerClassifier`, `FTTransformerRegressor`, and `FTTransformerLSS` in `deeptab.models`. + ## Overview FTTransformer is a feature-token Transformer for tabular data. It represents each column as a token, applies Transformer encoder layers over the feature sequence, pools the sequence, and predicts with an MLP head. @@ -22,13 +24,13 @@ feature tokens -> TransformerEncoder x n_layers -> pooling -> optional norm -> M ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Creates one vector per input feature. | +| Component | DeepTab implementation | Role | +| ------------- | ------------------------------- | ------------------------------------------------------ | +| Tokenizer | `EmbeddingLayer` | Creates one vector per input feature. | | Encoder block | `CustomTransformerEncoderLayer` | Multi-head attention plus feed-forward transformation. | -| Encoder stack | `nn.TransformerEncoder` | Repeats the block `n_layers` times. | -| Pooling | `pooling_method`, `use_cls` | Reduces feature tokens to one representation. | -| Head | `MLPhead` | Task-specific prediction head. | +| Encoder stack | `nn.TransformerEncoder` | Repeats the block `n_layers` times. | +| Pooling | `pooling_method`, `use_cls` | Reduces feature tokens to one representation. | +| Head | `MLPhead` | Task-specific prediction head. | ## Implementation Notes @@ -59,13 +61,13 @@ model = FTTransformerClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `64` to `256` | Token width and main capacity driver. | -| `n_layers` | `2` to `6` | Transformer depth. | -| `n_heads` | `4` to `8` | Attention heads; must divide `d_model`. | -| `transformer_dim_feedforward` | `2x` to `4x d_model` | Feed-forward capacity. | -| `pooling_method` | `"avg"` or `"cls"` | Sequence aggregation strategy. | +| Setting | Typical range | Effect | +| ----------------------------- | -------------------- | --------------------------------------- | +| `d_model` | `64` to `256` | Token width and main capacity driver. | +| `n_layers` | `2` to `6` | Transformer depth. | +| `n_heads` | `4` to `8` | Attention heads; must divide `d_model`. | +| `transformer_dim_feedforward` | `2x` to `4x d_model` | Feed-forward capacity. | +| `pooling_method` | `"avg"` or `"cls"` | Sequence aggregation strategy. | ## When To Use diff --git a/docs/model_zoo/stable/index.md b/docs/model_zoo/stable/index.md index 9c7d4738..401e5935 100644 --- a/docs/model_zoo/stable/index.md +++ b/docs/model_zoo/stable/index.md @@ -27,12 +27,12 @@ ndtf tabr ``` -| Family | Models | Use when | -| --- | --- | --- | -| MLP and residual baselines | [MLP](mlp), [ResNet](resnet), [TabM](tabm) | You need strong, fast baselines or parameter-efficient ensembles. | -| Transformer and attention models | [FTTransformer](fttransformer), [TabTransformer](tabtransformer), [SAINT](saint), [AutoInt](autoint) | Feature interactions are important and the dataset is large enough to support attention layers. | -| State-space and recurrent sequence models | [Mambular](mambular), [MambaTab](mambatab), [MambAttention](mambattention), [TabulaRNN](tabularnn) | You want to treat columns as a sequence and compare Mamba/RNN-style inductive biases. | -| Neural tree and retrieval models | [NODE](node), [ENODE](enode), [NDTF](ndtf), [TabR](tabr) | You want differentiable tree structure, ensemble behavior, or train-set retrieval at prediction time. | +| Family | Models | Use when | +| ----------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| MLP and residual baselines | [MLP](mlp), [ResNet](resnet), [TabM](tabm) | You need strong, fast baselines or parameter-efficient ensembles. | +| Transformer and attention models | [FTTransformer](fttransformer), [TabTransformer](tabtransformer), [SAINT](saint), [AutoInt](autoint) | Feature interactions are important and the dataset is large enough to support attention layers. | +| State-space and recurrent sequence models | [Mambular](mambular), [MambaTab](mambatab), [MambAttention](mambattention), [TabulaRNN](tabularnn) | You want to treat columns as a sequence and compare Mamba/RNN-style inductive biases. | +| Neural tree and retrieval models | [NODE](node), [ENODE](enode), [NDTF](ndtf), [TabR](tabr) | You want differentiable tree structure, ensemble behavior, or train-set retrieval at prediction time. | ## Selection Guide @@ -52,7 +52,7 @@ from deeptab.models import MLPClassifier model = MLPClassifier( model_config=MLPConfig(layer_sizes=[256, 128, 32], dropout=0.2), - preprocessing_config=PreprocessingConfig(numerical_preprocessing="standard"), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="standardization"), trainer_config=TrainerConfig(lr=1e-3, batch_size=256, max_epochs=100), random_state=101, ) @@ -65,11 +65,11 @@ predictions = model.predict(X_test) DeepTab 2.x separates model, preprocessing, and training settings: -| Config object | Contains | -| --- | --- | -| `*Config` model configs | Architecture fields such as width, depth, dropout, embeddings, heads, pooling, and ensemble size. | -| `PreprocessingConfig` | Numerical/categorical preprocessing choices such as standard scaling, quantile transforms, bins, and categorical encoding. | -| `TrainerConfig` | Optimizer and training-loop settings such as learning rate, batch size, epochs, patience, and weight decay. | +| Config object | Contains | +| ----------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `*Config` model configs | Architecture fields such as width, depth, dropout, embeddings, heads, pooling, and ensemble size. | +| `PreprocessingConfig` | Numerical/categorical preprocessing choices such as standard scaling, quantile transforms, bins, and categorical encoding. | +| `TrainerConfig` | Optimizer and training-loop settings such as learning rate, batch size, epochs, patience, and weight decay. | ## Research Context diff --git a/docs/model_zoo/stable/mambatab.md b/docs/model_zoo/stable/mambatab.md index 5e5f6541..75942a9d 100644 --- a/docs/model_zoo/stable/mambatab.md +++ b/docs/model_zoo/stable/mambatab.md @@ -1,5 +1,7 @@ # MambaTab +**Available as:** `MambaTabClassifier`, `MambaTabRegressor`, and `MambaTabLSS` in `deeptab.models`. + ## Overview MambaTab is exposed as a stable Mamba-family model, but the current DeepTab forward path behaves as a lightweight projected-feature network: it concatenates input features, projects them to `d_model`, normalizes and activates the representation, then predicts with `MLPhead`. @@ -22,18 +24,20 @@ features -> concat -> Linear(input_dim, d_model) -> LayerNorm -> activation -> M ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Input path | `torch.cat(...)` | Uses raw/preprocessed feature tensors directly. | -| Projection | `initial_layer` | Maps input vector to `d_model`. | -| Normalization | `LayerNorm` | Stabilizes projected representation. | -| Head | `MLPhead` | Produces predictions. | -| Mamba block | `self.mamba = Mamba(...)` or `MambaOriginal(...)` | Instantiated in `__init__`, but not called in the current `forward`. | +| Component | DeepTab implementation | Role | +| ------------- | ------------------------------------------------- | -------------------------------------------------------------------- | +| Input path | `torch.cat(...)` | Uses raw/preprocessed feature tensors directly. | +| Projection | `initial_layer` | Maps input vector to `d_model`. | +| Normalization | `LayerNorm` | Stabilizes projected representation. | +| Head | `MLPhead` | Produces predictions. | +| Mamba block | `self.mamba = Mamba(...)` or `MambaOriginal(...)` | Instantiated in `__init__`, but not called in the current `forward`. | ## Implementation Notes The presence of Mamba-related config fields (`d_state`, `d_conv`, `expand_factor`, `mamba_version`, `bidirectional`) does not mean they affect the current forward pass. They configure the instantiated `self.mamba` module, but that module is not applied before the head. +`mamba_version="mamba-torch"` (the default) selects DeepTab's local `Mamba` block; any other value selects `MambaOriginal`. Either way, the chosen block is built in `__init__` but skipped by `forward`, so this setting has no effect in the current release. + This distinction matters for research comparisons: document the DeepTab version and verify the forward path if you report MambaTab as a state-space model. ## Practical Config @@ -49,7 +53,7 @@ model = MambaTabRegressor( head_layer_sizes=[128], head_dropout=0.1, ), - preprocessing_config=PreprocessingConfig(numerical_preprocessing="standard"), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="standardization"), trainer_config=TrainerConfig(lr=1e-3, batch_size=256, max_epochs=100), random_state=101, ) @@ -57,13 +61,13 @@ model = MambaTabRegressor( Key settings in the current forward path: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `32` to `128` | Width of the projected representation. | -| `embedding_activation` | `Identity`, `ReLU`, `SiLU` | Activation after projection/norm. | -| `head_layer_sizes` | `[]` to `[256, 128]` | Extra MLPhead capacity. | -| `head_dropout` | `0.0` to `0.3` | Head regularization. | -| `axis` | `1` or `0` | Temporary unsqueeze axis before normalization. | +| Setting | Typical range | Effect | +| ---------------------- | -------------------------- | ---------------------------------------------- | +| `d_model` | `32` to `128` | Width of the projected representation. | +| `embedding_activation` | `Identity`, `ReLU`, `SiLU` | Activation after projection/norm. | +| `head_layer_sizes` | `[]` to `[256, 128]` | Extra MLPhead capacity. | +| `head_dropout` | `0.0` to `0.3` | Head regularization. | +| `axis` | `1` or `0` | Temporary unsqueeze axis before normalization. | ## When To Use diff --git a/docs/model_zoo/stable/mambattention.md b/docs/model_zoo/stable/mambattention.md index 892fb8a8..719a32df 100644 --- a/docs/model_zoo/stable/mambattention.md +++ b/docs/model_zoo/stable/mambattention.md @@ -1,5 +1,7 @@ # MambAttention +**Available as:** `MambAttentionClassifier`, `MambAttentionRegressor`, and `MambAttentionLSS` in `deeptab.models`. + ## Overview MambAttention is a hybrid model that alternates Mamba-style sequence processing with multi-head attention over feature tokens. It is useful for testing whether state-space layers and explicit attention provide complementary inductive biases. @@ -22,13 +24,13 @@ feature tokens -> optional shuffle -> Mamba/Attention hybrid stack -> pooling -> ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Builds one token per input feature. | -| Mamba blocks | `ResidualBlock` inside `MambAttn` | Local/selective state-space sequence processing. | -| Attention blocks | `nn.MultiheadAttention` | Explicit global token mixing. | -| Hybrid schedule | `n_mamba_per_attention`, `n_attention_layers`, `last_layer` | Controls where attention is inserted. | -| Head | `MLPhead` | Final task prediction. | +| Component | DeepTab implementation | Role | +| ---------------- | ----------------------------------------------------------- | ------------------------------------------------ | +| Tokenizer | `EmbeddingLayer` | Builds one token per input feature. | +| Mamba blocks | `ResidualBlock` inside `MambAttn` | Local/selective state-space sequence processing. | +| Attention blocks | `nn.MultiheadAttention` | Explicit global token mixing. | +| Hybrid schedule | `n_mamba_per_attention`, `n_attention_layers`, `last_layer` | Controls where attention is inserted. | +| Head | `MLPhead` | Final task prediction. | ## Implementation Notes @@ -59,13 +61,13 @@ model = MambAttentionClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `n_layers` | `2` to `6` | Mamba-block budget. | -| `n_attention_layers` | `1` to `3` | Number of explicit attention insertions. | -| `n_mamba_per_attention` | `1` to `3` | Frequency of attention layers. | -| `last_layer` | `"attn"` or `"mamba"` | Final mixing type. | -| `attn_dropout` | `0.0` to `0.3` | Attention regularization. | +| Setting | Typical range | Effect | +| ----------------------- | --------------------- | ---------------------------------------- | +| `n_layers` | `2` to `6` | Mamba-block budget. | +| `n_attention_layers` | `1` to `3` | Number of explicit attention insertions. | +| `n_mamba_per_attention` | `1` to `3` | Frequency of attention layers. | +| `last_layer` | `"attn"` or `"mamba"` | Final mixing type. | +| `attn_dropout` | `0.0` to `0.3` | Attention regularization. | ## When To Use diff --git a/docs/model_zoo/stable/mambular.md b/docs/model_zoo/stable/mambular.md index 03c5f185..3b1cb32c 100644 --- a/docs/model_zoo/stable/mambular.md +++ b/docs/model_zoo/stable/mambular.md @@ -1,5 +1,7 @@ # Mambular +**Available as:** `MambularClassifier`, `MambularRegressor`, and `MambularLSS` in `deeptab.models`. + ## Overview Mambular treats tabular columns as a sequence of feature tokens and processes that sequence with Mamba-style state-space blocks. It is DeepTab's main stable state-space model for tabular data. @@ -22,12 +24,12 @@ feature tokens -> optional shuffle -> Mamba/MambaOriginal -> pooling -> MLPhead ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Converts columns to a token sequence. | +| Component | DeepTab implementation | Role | +| -------------- | -------------------------- | -------------------------------------------------- | +| Tokenizer | `EmbeddingLayer` | Converts columns to a token sequence. | | Sequence block | `Mamba` or `MambaOriginal` | Applies selective state-space sequence processing. | -| Pooling | `pooling_method` | Reduces tokens to a row representation. | -| Head | `MLPhead` | Task-specific prediction. | +| Pooling | `pooling_method` | Reduces tokens to a row representation. | +| Head | `MLPhead` | Task-specific prediction. | ## Implementation Notes @@ -57,12 +59,12 @@ model = MambularClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `32` to `128` | Token width. | -| `n_layers` | `2` to `6` | Number of Mamba blocks. | -| `d_state` | `64` to `256` | State-space memory size. | -| `d_conv` | `2` to `8` | Local convolution width inside Mamba. | +| Setting | Typical range | Effect | +| --------------- | ----------------- | ---------------------------------------------------- | +| `d_model` | `32` to `128` | Token width. | +| `n_layers` | `2` to `6` | Number of Mamba blocks. | +| `d_state` | `64` to `256` | State-space memory size. | +| `d_conv` | `2` to `8` | Local convolution width inside Mamba. | | `bidirectional` | `False` or `True` | Whether to process feature order in both directions. | ## When To Use diff --git a/docs/model_zoo/stable/mlp.md b/docs/model_zoo/stable/mlp.md index 5fce8377..e2f449d3 100644 --- a/docs/model_zoo/stable/mlp.md +++ b/docs/model_zoo/stable/mlp.md @@ -1,5 +1,7 @@ # MLP +**Available as:** `MLPClassifier`, `MLPRegressor`, and `MLPLSS` in `deeptab.models`. + ## Overview MLP is DeepTab's plain feed-forward baseline for tabular data. It is the first model to include in most studies because it is fast, easy to tune, and makes very few assumptions beyond the quality of preprocessing and feature encoding. @@ -24,14 +26,14 @@ features -> optional EmbeddingLayer -> flatten/concat -> Linear blocks -> output ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Feature input | `torch.cat(...)` or `EmbeddingLayer` | Builds the vector consumed by the MLP. | -| Hidden stack | `nn.Linear` layers from `layer_sizes` | Learns nonlinear feature interactions. | -| Normalization | `batch_norm`, `layer_norm` | Stabilizes training when enabled. | -| Activation | `activation` or `nn.GLU()` | Controls nonlinear transformation. | -| Skip connections | `skip_connections` | Adds residual connections only when shapes match. | -| Output head | Final `nn.Linear` | Produces logits or regression outputs. | +| Component | DeepTab implementation | Role | +| ---------------- | ------------------------------------- | ------------------------------------------------- | +| Feature input | `torch.cat(...)` or `EmbeddingLayer` | Builds the vector consumed by the MLP. | +| Hidden stack | `nn.Linear` layers from `layer_sizes` | Learns nonlinear feature interactions. | +| Normalization | `batch_norm`, `layer_norm` | Stabilizes training when enabled. | +| Activation | `activation` or `nn.GLU()` | Controls nonlinear transformation. | +| Skip connections | `skip_connections` | Adds residual connections only when shapes match. | +| Output head | Final `nn.Linear` | Produces logits or regression outputs. | ## Implementation Notes @@ -51,7 +53,7 @@ model = MLPClassifier( dropout=0.2, skip_connections=False, ), - preprocessing_config=PreprocessingConfig(numerical_preprocessing="standard"), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="standardization"), trainer_config=TrainerConfig(lr=1e-3, batch_size=256, max_epochs=100), random_state=101, ) @@ -59,13 +61,13 @@ model = MLPClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `layer_sizes` | `[128, 64]` to `[512, 256, 128]` | Main capacity control. | -| `dropout` | `0.0` to `0.5` | Regularization; increase on small/noisy data. | -| `use_embeddings` | `False` or `True` | Enables feature token embeddings before flattening. | -| `d_model` | `16` to `128` | Embedding width when embeddings are used. | -| `batch_norm`, `layer_norm` | `False` or `True` | Try when optimization is unstable. | +| Setting | Typical range | Effect | +| -------------------------- | -------------------------------- | --------------------------------------------------- | +| `layer_sizes` | `[128, 64]` to `[512, 256, 128]` | Main capacity control. | +| `dropout` | `0.0` to `0.5` | Regularization; increase on small/noisy data. | +| `use_embeddings` | `False` or `True` | Enables feature token embeddings before flattening. | +| `d_model` | `16` to `128` | Embedding width when embeddings are used. | +| `batch_norm`, `layer_norm` | `False` or `True` | Try when optimization is unstable. | ## When To Use diff --git a/docs/model_zoo/stable/ndtf.md b/docs/model_zoo/stable/ndtf.md index 2bf443f8..2a414036 100644 --- a/docs/model_zoo/stable/ndtf.md +++ b/docs/model_zoo/stable/ndtf.md @@ -1,5 +1,7 @@ # NDTF +**Available as:** `NDTFClassifier`, `NDTFRegressor`, and `NDTFLSS` in `deeptab.models`. + ## Overview NDTF is DeepTab's neural decision tree forest. It builds an ensemble of differentiable decision trees, applies a convolutional feature interaction layer before the trees, and combines tree predictions with learnable ensemble weights. @@ -22,17 +24,17 @@ features -> Conv1d feature interaction -> NeuralDecisionTree x n_ensembles -> we ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Feature interaction | `nn.Conv1d` | Produces transformed feature inputs for trees. | -| Tree ensemble | `nn.ModuleList[NeuralDecisionTree]` | Differentiable forest members. | -| Random tree settings | sampled input dimensions, depths, temperatures | Adds diversity across trees. | -| Ensemble weights | learnable `tree_weights` | Combines member predictions. | -| Penalty path | `penalty_forward` | Returns prediction and scaled tree penalty. | +| Component | DeepTab implementation | Role | +| -------------------- | ---------------------------------------------- | ---------------------------------------------- | +| Feature interaction | `nn.Conv1d` | Produces transformed feature inputs for trees. | +| Tree ensemble | `nn.ModuleList[NeuralDecisionTree]` | Differentiable forest members. | +| Random tree settings | sampled input dimensions, depths, temperatures | Adds diversity across trees. | +| Ensemble weights | learnable `tree_weights` | Combines member predictions. | +| Penalty path | `penalty_forward` | Returns prediction and scaled tree penalty. | ## Implementation Notes -The first tree receives the full input dimension. Remaining trees receive randomly sampled prefix dimensions. Tree depths are sampled between `min_depth` and `max_depth`, and temperatures are jittered around the configured `temperature`. +The first tree receives the full input dimension. Remaining trees receive randomly sampled prefix dimensions. Tree depths are sampled with `np.random.randint(min_depth, max_depth)`, so the upper bound is exclusive: with the defaults `min_depth=4` and `max_depth=16`, sampled depths range from 4 to 15 (inclusive). Temperatures are jittered around the configured `temperature`. `penalty_forward` returns `(prediction, penalty_factor * penalty)`, which can be used by the training module when penalty-aware training is enabled. @@ -51,7 +53,7 @@ model = NDTFClassifier( node_sampling=0.3, lamda=0.3, ), - preprocessing_config=PreprocessingConfig(numerical_preprocessing="standard"), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="standardization"), trainer_config=TrainerConfig(lr=1e-3, batch_size=256, max_epochs=100), random_state=101, ) @@ -59,13 +61,13 @@ model = NDTFClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `n_ensembles` | `4` to `24` | Number of neural trees. | -| `min_depth`, `max_depth` | `3` to `16` | Tree depth distribution. | -| `temperature` | `0.05` to `0.5` | Soft routing sharpness. | -| `node_sampling` | `0.1` to `0.8` | Node-level sampling regularization. | -| `penalty_factor` | `1e-10` to `1e-6` | Strength of tree penalty term. | +| Setting | Typical range | Effect | +| ------------------------ | ----------------- | ----------------------------------- | +| `n_ensembles` | `4` to `24` | Number of neural trees. | +| `min_depth`, `max_depth` | `3` to `16` | Tree depth distribution. | +| `temperature` | `0.05` to `0.5` | Soft routing sharpness. | +| `node_sampling` | `0.1` to `0.8` | Node-level sampling regularization. | +| `penalty_factor` | `1e-10` to `1e-6` | Strength of tree penalty term. | ## When To Use diff --git a/docs/model_zoo/stable/node.md b/docs/model_zoo/stable/node.md index 7103dc5d..e7749a4e 100644 --- a/docs/model_zoo/stable/node.md +++ b/docs/model_zoo/stable/node.md @@ -1,5 +1,7 @@ # NODE +**Available as:** `NODEClassifier`, `NODERegressor`, and `NODELSS` in `deeptab.models`. + ## Overview NODE implements Neural Oblivious Decision Ensembles: differentiable oblivious decision trees trained inside a neural network. It is a useful bridge between tree-based inductive bias and gradient-based deep learning. @@ -21,13 +23,13 @@ features -> optional embeddings -> DenseBlock(num_layers, layer_dim, depth, tree ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Input representation | raw concatenation or `EmbeddingLayer` | Builds the vector consumed by trees. | -| Differentiable trees | `deeptab.nn.blocks.node.DenseBlock` | Stacks NODE-style tree layers. | -| Tree depth | `depth` | Controls number of soft splits per tree. | -| Layer width | `layer_dim` | Number of trees/features per dense layer. | -| Head | `MLPhead` | Maps tree representation to task output. | +| Component | DeepTab implementation | Role | +| -------------------- | ------------------------------------- | ----------------------------------------- | +| Input representation | raw concatenation or `EmbeddingLayer` | Builds the vector consumed by trees. | +| Differentiable trees | `deeptab.nn.blocks.node.DenseBlock` | Stacks NODE-style tree layers. | +| Tree depth | `depth` | Controls number of soft splits per tree. | +| Layer width | `layer_dim` | Number of trees/features per dense layer. | +| Head | `MLPhead` | Maps tree representation to task output. | ## Implementation Notes @@ -55,12 +57,12 @@ model = NODEClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `num_layers` | `2` to `6` | Number of dense tree layers. | -| `layer_dim` | `64` to `256` | Width of each tree layer. | -| `depth` | `4` to `8` | Soft decision depth. | -| `tree_dim` | `1` to `3` | Output dimension per tree. | +| Setting | Typical range | Effect | +| ------------------ | --------------- | ------------------------------- | +| `num_layers` | `2` to `6` | Number of dense tree layers. | +| `layer_dim` | `64` to `256` | Width of each tree layer. | +| `depth` | `4` to `8` | Soft decision depth. | +| `tree_dim` | `1` to `3` | Output dimension per tree. | | `head_layer_sizes` | `[]` to `[128]` | Extra prediction-head capacity. | ## When To Use diff --git a/docs/model_zoo/stable/resnet.md b/docs/model_zoo/stable/resnet.md index fd76ee23..b1b06cab 100644 --- a/docs/model_zoo/stable/resnet.md +++ b/docs/model_zoo/stable/resnet.md @@ -1,5 +1,7 @@ # ResNet +**Available as:** `ResNetClassifier`, `ResNetRegressor`, and `ResNetLSS` in `deeptab.models`. + ## Overview ResNet is DeepTab's residual feed-forward architecture for tabular data. It keeps the simplicity and speed of an MLP while adding residual blocks that make deeper nonlinear transformations easier to optimize. @@ -23,12 +25,12 @@ features -> optional embeddings -> initial Linear -> ResidualBlock x num_blocks ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Input representation | Raw concatenation or `EmbeddingLayer` | Converts heterogeneous columns to a tensor. | -| Initial projection | `nn.Linear(input_dim, layer_sizes[0])` | Sets hidden width. | -| Residual body | `ResidualBlock` | Learns transformations with skip paths. | -| Output layer | `nn.Linear(layer_sizes[-1], num_classes)` | Produces task outputs. | +| Component | DeepTab implementation | Role | +| -------------------- | ----------------------------------------- | ------------------------------------------- | +| Input representation | Raw concatenation or `EmbeddingLayer` | Converts heterogeneous columns to a tensor. | +| Initial projection | `nn.Linear(input_dim, layer_sizes[0])` | Sets hidden width. | +| Residual body | `ResidualBlock` | Learns transformations with skip paths. | +| Output layer | `nn.Linear(layer_sizes[-1], num_classes)` | Produces task outputs. | ## Implementation Notes @@ -47,7 +49,7 @@ model = ResNetRegressor( dropout=0.2, norm=True, ), - preprocessing_config=PreprocessingConfig(numerical_preprocessing="standard"), + preprocessing_config=PreprocessingConfig(numerical_preprocessing="standardization"), trainer_config=TrainerConfig(lr=1e-3, batch_size=256, max_epochs=100), random_state=101, ) @@ -55,13 +57,13 @@ model = ResNetRegressor( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `layer_sizes` | `[128, 64]` to `[512, 256, 128]` | Width schedule. | -| `num_blocks` | `2` to `5` | Depth of residual processing. | -| `dropout` | `0.0` to `0.5` | Regularization. | -| `norm` | `False` or `True` | Enables normalization inside residual blocks. | -| `use_embeddings` | `False` or `True` | Useful for categorical-heavy data. | +| Setting | Typical range | Effect | +| ---------------- | -------------------------------- | --------------------------------------------- | +| `layer_sizes` | `[128, 64]` to `[512, 256, 128]` | Width schedule. | +| `num_blocks` | `2` to `5` | Depth of residual processing. | +| `dropout` | `0.0` to `0.5` | Regularization. | +| `norm` | `False` or `True` | Enables normalization inside residual blocks. | +| `use_embeddings` | `False` or `True` | Useful for categorical-heavy data. | ## When To Use diff --git a/docs/model_zoo/stable/saint.md b/docs/model_zoo/stable/saint.md index 1a314864..72b4ee43 100644 --- a/docs/model_zoo/stable/saint.md +++ b/docs/model_zoo/stable/saint.md @@ -1,5 +1,7 @@ # SAINT +**Available as:** `SAINTClassifier`, `SAINTRegressor`, and `SAINTLSS` in `deeptab.models`. + ## Overview SAINT is an attention architecture for tabular data that combines feature-wise attention with row-wise attention. In DeepTab, SAINT embeds all supported feature types, applies a row/column Transformer block, pools the resulting sequence, and predicts with an MLP head. @@ -22,13 +24,13 @@ feature tokens -> RowColTransformer -> pooling -> optional norm -> MLPhead ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Converts each input feature to a token. | -| Column attention | `nn.MultiheadAttention` inside `RowColTransformer` | Models feature interactions within a row. | -| Row attention | Flattened row representation inside `RowColTransformer` | Mixes sample-level context within a batch. | -| Feed-forward blocks | LayerNorm + Linear + activation + dropout | Adds nonlinear token updates. | -| Prediction head | `MLPhead` | Produces final outputs. | +| Component | DeepTab implementation | Role | +| ------------------- | ------------------------------------------------------- | ------------------------------------------ | +| Tokenizer | `EmbeddingLayer` | Converts each input feature to a token. | +| Column attention | `nn.MultiheadAttention` inside `RowColTransformer` | Models feature interactions within a row. | +| Row attention | Flattened row representation inside `RowColTransformer` | Mixes sample-level context within a batch. | +| Feed-forward blocks | LayerNorm + Linear + activation + dropout | Adds nonlinear token updates. | +| Prediction head | `MLPhead` | Produces final outputs. | ## Implementation Notes @@ -60,13 +62,13 @@ model = SAINTClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `64` to `192` | Token width. | -| `n_layers` | `1` to `4` | Row/column attention depth. | -| `n_heads` | `2` to `8` | Number of attention heads. | -| `attn_dropout`, `ff_dropout` | `0.0` to `0.3` | Regularization. | -| `pooling_method`, `use_cls` | `"cls"`/`True` or `"avg"`/`False` | Token aggregation behavior. | +| Setting | Typical range | Effect | +| ---------------------------- | --------------------------------- | --------------------------- | +| `d_model` | `64` to `192` | Token width. | +| `n_layers` | `1` to `4` | Row/column attention depth. | +| `n_heads` | `2` to `8` | Number of attention heads. | +| `attn_dropout`, `ff_dropout` | `0.0` to `0.3` | Regularization. | +| `pooling_method`, `use_cls` | `"cls"`/`True` or `"avg"`/`False` | Token aggregation behavior. | ## When To Use diff --git a/docs/model_zoo/stable/tabm.md b/docs/model_zoo/stable/tabm.md index 25e3a7ed..3c15a896 100644 --- a/docs/model_zoo/stable/tabm.md +++ b/docs/model_zoo/stable/tabm.md @@ -1,5 +1,7 @@ # TabM +**Available as:** `TabMClassifier`, `TabMRegressor`, and `TabMLSS` in `deeptab.models`. + ## Overview TabM is a parameter-efficient ensemble model for tabular data. Instead of training many independent networks, it uses BatchEnsemble-style linear layers with shared weights and member-specific scaling factors. @@ -22,11 +24,11 @@ features -> optional embeddings -> BatchEnsemble MLP blocks -> ensemble output/h ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Feature path | `EmbeddingLayer` or raw concatenation | Builds model input. | -| Ensemble layers | `LinearBatchEnsembleLayer` | Shared weight matrix with member-specific scaling. | -| Final layer | `SNLinear` or `nn.Linear` | Produces per-member or averaged predictions. | +| Component | DeepTab implementation | Role | +| --------------- | ----------------------------------------- | ------------------------------------------------------ | +| Feature path | `EmbeddingLayer` or raw concatenation | Builds model input. | +| Ensemble layers | `LinearBatchEnsembleLayer` | Shared weight matrix with member-specific scaling. | +| Final layer | `SNLinear` or `nn.Linear` | Produces per-member or averaged predictions. | | Ensemble output | `returns_ensemble=True` when not averaged | Lets the training wrapper handle ensemble predictions. | ## Implementation Notes @@ -57,13 +59,13 @@ model = TabMClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `ensemble_size` | `8` to `64` | Number of virtual ensemble members. | -| `layer_sizes` | `[128, 128]` to `[512, 256, 128]` | Shared MLP capacity. | -| `model_type` | `"mini"` or `"full"` | Amount of member-specific scaling. | -| `average_ensembles` | `False` or `True` | Return per-member outputs or average internally. | -| `scaling_init` | `"ones"`, `"random-signs"`, `"normal"` | Diversity initialization for scaling factors. | +| Setting | Typical range | Effect | +| ------------------- | -------------------------------------- | ------------------------------------------------ | +| `ensemble_size` | `8` to `64` | Number of virtual ensemble members. | +| `layer_sizes` | `[128, 128]` to `[512, 256, 128]` | Shared MLP capacity. | +| `model_type` | `"mini"` or `"full"` | Amount of member-specific scaling. | +| `average_ensembles` | `False` or `True` | Return per-member outputs or average internally. | +| `scaling_init` | `"ones"`, `"random-signs"`, `"normal"` | Diversity initialization for scaling factors. | ## When To Use diff --git a/docs/model_zoo/stable/tabr.md b/docs/model_zoo/stable/tabr.md index 3b0cdc2a..757c682e 100644 --- a/docs/model_zoo/stable/tabr.md +++ b/docs/model_zoo/stable/tabr.md @@ -1,5 +1,7 @@ # TabR +**Available as:** `TabRClassifier`, `TabRRegressor`, and `TabRLSS` in `deeptab.models`. + ## Overview TabR is a retrieval-augmented tabular model. It encodes the current row and candidate training rows into a latent space, retrieves nearest candidate contexts with FAISS, mixes candidate labels into the representation, and predicts with a neural head. @@ -22,14 +24,14 @@ candidate labels + key differences -> retrieved context -> predictor -> output ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Optional tokenizer | `EmbeddingLayer` | Embeds features before retrieval when `use_embeddings=True`. | -| Encoder | `linear`, `blocks0`, `K` | Builds row representation and retrieval key. | -| Candidate search | `faiss.IndexFlatL2` or `GpuIndexFlatL2` | Retrieves nearest candidate keys. | -| Label encoder | `nn.Linear` or `nn.Embedding` | Converts candidate labels to vectors. | -| Context transform | `T(k - context_k)` | Adjusts retrieved values by query-context difference. | -| Predictor | `blocks1`, `head` | Produces task output. | +| Component | DeepTab implementation | Role | +| ------------------ | --------------------------------------- | ------------------------------------------------------------ | +| Optional tokenizer | `EmbeddingLayer` | Embeds features before retrieval when `use_embeddings=True`. | +| Encoder | `linear`, `blocks0`, `K` | Builds row representation and retrieval key. | +| Candidate search | `faiss.IndexFlatL2` or `GpuIndexFlatL2` | Retrieves nearest candidate keys. | +| Label encoder | `nn.Linear` or `nn.Embedding` | Converts candidate labels to vectors. | +| Context transform | `T(k - context_k)` | Adjusts retrieved values by query-context difference. | +| Predictor | `blocks1`, `head` | Produces task output. | ## Implementation Notes @@ -60,14 +62,14 @@ model = TabRRegressor( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_main` | `128` to `512` | Retrieval and predictor representation width. | -| `context_size` | `32` to `256` | Number of neighbors used per query. | -| `encoder_n_blocks` | `0` to `2` | Query/candidate encoder depth. | -| `predictor_n_blocks` | `1` to `3` | Post-retrieval predictor depth. | -| `candidate_encoding_batch_size` | `0` or positive int | Chunked candidate encoding. | -| `memory_efficient` | `False` or `True` | Reduces memory at extra compute cost. | +| Setting | Typical range | Effect | +| ------------------------------- | ------------------- | --------------------------------------------- | +| `d_main` | `128` to `512` | Retrieval and predictor representation width. | +| `context_size` | `32` to `256` | Number of neighbors used per query. | +| `encoder_n_blocks` | `0` to `2` | Query/candidate encoder depth. | +| `predictor_n_blocks` | `1` to `3` | Post-retrieval predictor depth. | +| `candidate_encoding_batch_size` | `0` or positive int | Chunked candidate encoding. | +| `memory_efficient` | `False` or `True` | Reduces memory at extra compute cost. | ## When To Use diff --git a/docs/model_zoo/stable/tabtransformer.md b/docs/model_zoo/stable/tabtransformer.md index 6bd89347..7b078b8b 100644 --- a/docs/model_zoo/stable/tabtransformer.md +++ b/docs/model_zoo/stable/tabtransformer.md @@ -1,5 +1,7 @@ # TabTransformer +**Available as:** `TabTransformerClassifier`, `TabTransformerRegressor`, and `TabTransformerLSS` in `deeptab.models`. + ## Overview TabTransformer uses self-attention to contextualize categorical feature embeddings. DeepTab's implementation follows that core idea: categorical and external embedding features pass through a Transformer encoder, while numerical features are normalized and concatenated afterward before the prediction head. @@ -25,13 +27,13 @@ numerical features -> LayerNorm ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Categorical tokenizer | `EmbeddingLayer(*({}, cat_feature_info, emb_feature_info))` | Embeds categorical columns only. | -| Transformer | `CustomTransformerEncoderLayer` in `nn.TransformerEncoder` | Contextualizes categorical tokens. | -| Numerical path | `nn.LayerNorm(num_input_dim)` | Normalizes raw numerical vector. | -| Pooling | `pool_sequence` | Reduces categorical tokens. | -| Head | `MLPhead` | Combines categorical and numerical representations. | +| Component | DeepTab implementation | Role | +| --------------------- | ----------------------------------------------------------- | --------------------------------------------------- | +| Categorical tokenizer | `EmbeddingLayer(*({}, cat_feature_info, emb_feature_info))` | Embeds categorical columns only. | +| Transformer | `CustomTransformerEncoderLayer` in `nn.TransformerEncoder` | Contextualizes categorical tokens. | +| Numerical path | `nn.LayerNorm(num_input_dim)` | Normalizes raw numerical vector. | +| Pooling | `pool_sequence` | Reduces categorical tokens. | +| Head | `MLPhead` | Combines categorical and numerical representations. | ## Implementation Notes @@ -55,7 +57,7 @@ model = TabTransformerClassifier( pooling_method="avg", ), preprocessing_config=PreprocessingConfig( - numerical_preprocessing="standard", + numerical_preprocessing="standardization", categorical_preprocessing="int", ), trainer_config=TrainerConfig(lr=3e-4, batch_size=128, max_epochs=100), @@ -65,12 +67,12 @@ model = TabTransformerClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `d_model` | `64` to `256` | Categorical token width. | -| `n_layers` | `2` to `6` | Contextualization depth. | -| `n_heads` | `4` to `8` | Attention heads. | -| `pooling_method` | `"avg"` or `"cls"` | How categorical tokens are reduced. | +| Setting | Typical range | Effect | +| ------------------ | ------------------- | ----------------------------------- | +| `d_model` | `64` to `256` | Categorical token width. | +| `n_layers` | `2` to `6` | Contextualization depth. | +| `n_heads` | `4` to `8` | Attention heads. | +| `pooling_method` | `"avg"` or `"cls"` | How categorical tokens are reduced. | | `head_layer_sizes` | `[]` to `[128, 64]` | Extra capacity after concatenation. | ## When To Use diff --git a/docs/model_zoo/stable/tabularnn.md b/docs/model_zoo/stable/tabularnn.md index db349500..a961655f 100644 --- a/docs/model_zoo/stable/tabularnn.md +++ b/docs/model_zoo/stable/tabularnn.md @@ -1,5 +1,7 @@ # TabulaRNN +**Available as:** `TabulaRNNClassifier`, `TabulaRNNRegressor`, and `TabulaRNNLSS` in `deeptab.models`. + ## Overview TabulaRNN treats tabular columns as a sequence and processes feature tokens with recurrent layers plus depthwise convolution. It is useful when you want a sequence-model baseline that is simpler than Mamba and different from self-attention. @@ -24,13 +26,13 @@ pooled recurrent state + projected mean -> optional norm -> MLPhead ## Main Building Blocks -| Component | DeepTab implementation | Role | -| --- | --- | --- | -| Tokenizer | `EmbeddingLayer` | Builds sequence tokens. | -| Local filter | depthwise `nn.Conv1d` inside `ConvRNN` | Adds local token mixing. | -| Recurrent block | `RNN`, `LSTM`, `GRU`, `mLSTM`, or `sLSTM` | Sequential feature processing. | -| Residual summary | `mean(x)` plus `linear` | Preserves direct feature-token information. | -| Head | `MLPhead` | Final prediction. | +| Component | DeepTab implementation | Role | +| ---------------- | ----------------------------------------- | ------------------------------------------- | +| Tokenizer | `EmbeddingLayer` | Builds sequence tokens. | +| Local filter | depthwise `nn.Conv1d` inside `ConvRNN` | Adds local token mixing. | +| Recurrent block | `RNN`, `LSTM`, `GRU`, `mLSTM`, or `sLSTM` | Sequential feature processing. | +| Residual summary | `mean(x)` plus `linear` | Preserves direct feature-token information. | +| Head | `MLPhead` | Final prediction. | ## Implementation Notes @@ -61,13 +63,13 @@ model = TabulaRNNClassifier( Key settings: -| Setting | Typical range | Effect | -| --- | --- | --- | -| `model_type` | `"RNN"`, `"GRU"`, `"LSTM"` | Recurrent cell family. | -| `d_model` | `64` to `192` | Feature-token width. | -| `n_layers` | `1` to `4` | Recurrent depth. | -| `dim_feedforward` | `128` to `512` | Hidden size consumed by the head. | -| `d_conv` | `2` to `8` | Depthwise convolution width. | +| Setting | Typical range | Effect | +| ----------------- | -------------------------- | --------------------------------- | +| `model_type` | `"RNN"`, `"GRU"`, `"LSTM"` | Recurrent cell family. | +| `d_model` | `64` to `192` | Feature-token width. | +| `n_layers` | `1` to `4` | Recurrent depth. | +| `dim_feedforward` | `128` to `512` | Hidden size consumed by the head. | +| `d_conv` | `2` to `8` | Depthwise convolution width. | ## When To Use diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md new file mode 100644 index 00000000..3e2f146b --- /dev/null +++ b/docs/tutorials/index.md @@ -0,0 +1,17 @@ +--- +orphan: true +--- + +# Tutorials + +End-to-end, runnable walkthroughs covering common modeling workflows with DeepTab. +Each tutorial is Colab-ready and works through a complete problem from data to results. + +- **[Skewed-Target Regression](skewed_regression)**: Regression on a right-skewed target +- **[Imbalanced Classification](imbalance_classification)**: An end-to-end classification workflow +- **[Uncertainty Quantification](uncertainty_quantification)**: Prediction intervals with LSS models +- **[Hyperparameter Optimization](hpo)**: Tuning models efficiently +- **[Advanced Training and Production Inference](advanced_training)**: Optimizers, schedulers, and production inference +- **[Observability: Logging, Tracking, and Run Directories](observability)**: Run directories and experiment trackers +- **[Model Efficiency Benchmarking](model_efficiency)**: Runtime and memory benchmarking +- **[Experimental Models: Evaluating Research-Stage Architectures](experimental)**: Working with cutting-edge architectures diff --git a/docs/tutorials/notebooks/advanced_training.ipynb b/docs/tutorials/notebooks/advanced_training.ipynb index 1414f5d1..a5d4b1ee 100644 --- a/docs/tutorials/notebooks/advanced_training.ipynb +++ b/docs/tutorials/notebooks/advanced_training.ipynb @@ -79,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "ca8e3e4d", "metadata": {}, "outputs": [], @@ -90,11 +90,7 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", + "warnings.filterwarnings(\"ignore\")\n", "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)" ] }, @@ -2078,7 +2074,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/docs/tutorials/notebooks/experimental.ipynb b/docs/tutorials/notebooks/experimental.ipynb index 212118ea..922d8091 100644 --- a/docs/tutorials/notebooks/experimental.ipynb +++ b/docs/tutorials/notebooks/experimental.ipynb @@ -124,7 +124,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "8c6c18d4", "metadata": {}, "outputs": [], @@ -135,11 +135,7 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", + "warnings.filterwarnings(\"ignore\")\n", "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)" ] }, @@ -668,7 +664,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/docs/tutorials/notebooks/hpo.ipynb b/docs/tutorials/notebooks/hpo.ipynb index c3516155..5a7bcda2 100644 --- a/docs/tutorials/notebooks/hpo.ipynb +++ b/docs/tutorials/notebooks/hpo.ipynb @@ -107,7 +107,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "6408eb44", "metadata": {}, "outputs": [], @@ -118,11 +118,7 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", + "warnings.filterwarnings(\"ignore\")\n", "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)" ] }, @@ -4196,7 +4192,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/docs/tutorials/notebooks/imbalance_classification.ipynb b/docs/tutorials/notebooks/imbalance_classification.ipynb index bccbcb6f..db285811 100644 --- a/docs/tutorials/notebooks/imbalance_classification.ipynb +++ b/docs/tutorials/notebooks/imbalance_classification.ipynb @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "30074ad7", "metadata": {}, "outputs": [], @@ -85,11 +85,7 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", + "warnings.filterwarnings(\"ignore\")\n", "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)" ] }, @@ -1586,7 +1582,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/docs/tutorials/notebooks/observability.ipynb b/docs/tutorials/notebooks/observability.ipynb index 78b60cff..5d21b7d0 100644 --- a/docs/tutorials/notebooks/observability.ipynb +++ b/docs/tutorials/notebooks/observability.ipynb @@ -71,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "6605b9f5", "metadata": {}, "outputs": [], @@ -82,27 +82,8 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*logging interval.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*IProgress not found.*\")\n", - "\n", - "# Lightning prints a device banner and a parameter-count table on every fit.\n", - "# They are useful in isolation but drown out the observability messages this\n", - "# tutorial is about, so raise these loggers to ERROR. DeepTab's own events are\n", - "# emitted separately and are unaffected.\n", - "for _name in (\n", - " \"lightning\",\n", - " \"lightning.pytorch\",\n", - " \"lightning.pytorch.callbacks.model_summary\",\n", - " \"lightning.pytorch.utilities.rank_zero\",\n", - " \"lightning.pytorch.accelerators\",\n", - " \"pytorch_lightning\",\n", - "):\n", - " logging.getLogger(_name).setLevel(logging.ERROR)" + "warnings.filterwarnings(\"ignore\")\n", + "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)\n" ] }, { @@ -1127,92 +1108,6 @@ "Your sink received the full event stream with its structured payloads, ready to forward to whatever backend you use. Because no `ObservabilityConfig` was attached, DeepTab created no run directory of its own: your code is in full control." ] }, - { - "cell_type": "markdown", - "id": "c9833541", - "metadata": {}, - "source": [ - "## 8. Side-by-side: what each configuration leaves on disk\n", - "\n", - "The trees below are the canonical shapes you can expect. Timestamps and ids vary per run; the structure does not.\n", - "\n", - "**No observability** — only the best-weights checkpoint:\n", - "\n", - "```text\n", - "01_no_observability/\n", - " checkpoints/\n", - " best_model.ckpt\n", - "```\n", - "\n", - "**Minimal `ObservabilityConfig`** — self-describing run directory:\n", - "\n", - "```text\n", - "02_minimal/\n", - " runs/demo/_/\n", - " config.yaml # full estimator configuration\n", - " summary.json # final metrics\n", - " artifacts/ # reserved for run artifacts\n", - " checkpoints/\n", - " best_model.ckpt\n", - "```\n", - "\n", - "**`structured_logging=True, log_to_file=True`** — adds the event log:\n", - "\n", - "```text\n", - "04_with_file/\n", - " runs/demo/_/\n", - " config.yaml\n", - " lifecycle.jsonl # one JSON event per line\n", - " summary.json\n", - " artifacts/\n", - " checkpoints/\n", - " best_model.ckpt\n", - "```\n", - "\n", - "**`experiment_trackers=[\"tensorboard\"]`** — adds a TensorBoard tree:\n", - "\n", - "```text\n", - "06_tensorboard/\n", - " runs/demo/_/\n", - " config.yaml\n", - " summary.json\n", - " artifacts/\n", - " checkpoints/best_model.ckpt\n", - " tensorboard/demo/_/\n", - " events.out.tfevents...\n", - " hparams.yaml\n", - "```\n", - "\n", - "**`experiment_trackers=[\"mlflow\"]`** — adds a local MLflow store:\n", - "\n", - "```text\n", - "07_mlflow/\n", - " runs/demo/_/\n", - " config.yaml\n", - " summary.json\n", - " artifacts/\n", - " checkpoints/best_model.ckpt\n", - " mlflow/\n", - " backend/mlflow.db # run metadata (SQLite)\n", - " artifacts//artifacts/\n", - " config.yaml\n", - " summary.json\n", - " best_model/... # logged model checkpoint\n", - " checkpoints/best_model.ckpt\n", - "```\n", - "\n", - "**`logger=...` + a tracker** — your Lightning logger sits beside DeepTab's trees:\n", - "\n", - "```text\n", - "08_byo_logger/\n", - " csv/mlp/version_0/\n", - " hparams.yaml\n", - " metrics.csv\n", - " runs/demo/_/...\n", - " tensorboard/demo/_/...\n", - "```" - ] - }, { "cell_type": "markdown", "id": "92b61374", @@ -1263,7 +1158,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/docs/tutorials/notebooks/skewed_regression.ipynb b/docs/tutorials/notebooks/skewed_regression.ipynb index 779734f0..5683c288 100644 --- a/docs/tutorials/notebooks/skewed_regression.ipynb +++ b/docs/tutorials/notebooks/skewed_regression.ipynb @@ -73,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "72490779", "metadata": {}, "outputs": [], @@ -84,11 +84,7 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", + "warnings.filterwarnings(\"ignore\")\n", "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)" ] }, @@ -1992,7 +1988,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/docs/tutorials/notebooks/uncertainty_quantification.ipynb b/docs/tutorials/notebooks/uncertainty_quantification.ipynb index c8519f9f..73905f67 100644 --- a/docs/tutorials/notebooks/uncertainty_quantification.ipynb +++ b/docs/tutorials/notebooks/uncertainty_quantification.ipynb @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "0d5afac0", "metadata": {}, "outputs": [], @@ -74,11 +74,7 @@ "# These tutorials use small synthetic datasets and short training runs, which\n", "# surfaces a few non-actionable framework messages. Quieten them so the output\n", "# stays focused on the tutorial; none of them affect correctness.\n", - "warnings.filterwarnings(\"ignore\", message=\".*n_quantiles.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*does not have many workers.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*have no logger configured.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*lr_patience.*\")\n", - "warnings.filterwarnings(\"ignore\", message=\".*Checkpoint directory.*\")\n", + "warnings.filterwarnings(\"ignore\")\n", "logging.getLogger(\"lightning.pytorch\").setLevel(logging.ERROR)" ] }, @@ -1846,7 +1842,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, diff --git a/justfile b/justfile index 0779b178..395cce41 100644 --- a/justfile +++ b/justfile @@ -41,6 +41,7 @@ test: # build HTML docs locally (warnings treated as errors) docs: + rm -rf docs/_build poetry run sphinx-build -b html docs/ docs/_build/html -W --keep-going # run all pre-commit hooks on all files including push-stage hooks (ruff, pyright, prettier) @@ -50,3 +51,42 @@ check: # create a conventional commit using commitizen commit: poetry run cz commit + +# audit installed dependencies for known vulnerabilities +# The advisories ignored below are not actionable for a release today. Review this +# list on every release and drop an entry the moment a fix lands within our pins. +# pip (PYSEC-2026-196, CVE-2026-3219, CVE-2026-6357): +# the installer itself, dev tooling only, never shipped as a dependency. +# msgpack / starlette (GHSA-6v7p-g79w-8964, CVE-2026-54283, CVE-2026-54282): +# only pulled in through the optional [mlflow] extra, not the core install. +# torch / pytorch-lightning (PYSEC-2026-139, CVE-2025-3000, CVE-2025-3001, +# CVE-2026-31221): no published fix, or a fix only in a release above our +# current torch <2.10 upper bound. +audit: + poetry run pip-audit \ + --ignore-vuln PYSEC-2026-196 \ + --ignore-vuln CVE-2026-3219 \ + --ignore-vuln CVE-2026-6357 \ + --ignore-vuln GHSA-6v7p-g79w-8964 \ + --ignore-vuln CVE-2026-54283 \ + --ignore-vuln CVE-2026-54282 \ + --ignore-vuln PYSEC-2026-139 \ + --ignore-vuln CVE-2025-3000 \ + --ignore-vuln CVE-2025-3001 \ + --ignore-vuln CVE-2026-31221 + +# preview the next stable version bump (pass extra cz args, e.g. `just bump-preview --increment MAJOR`) +bump-preview *args: + poetry run cz bump --dry-run {{ args }} + +# apply the next stable version bump (updates version, CHANGELOG, commit, and tag) +bump *args: + poetry run cz bump {{ args }} + +# preview the next release-candidate bump (pass extra cz args, e.g. `just bump-rc-preview --increment MAJOR`) +bump-rc-preview *args: + poetry run cz bump --prerelease rc --dry-run {{ args }} + +# apply the next release-candidate bump (rcN; updates version, CHANGELOG, commit, and tag) +bump-rc *args: + poetry run cz bump --prerelease rc {{ args }} diff --git a/poetry.lock b/poetry.lock index 854052ba..623ef1e4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,18 @@ # This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +[[package]] +name = "absl-py" +version = "2.4.0" +description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"tensorboard\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "absl_py-2.4.0-py3-none-any.whl", hash = "sha256:88476fd881ca8aab94ffa78b7b6c632a782ab3ba1cd19c9bd423abc4fb4cd28d"}, + {file = "absl_py-2.4.0.tar.gz", hash = "sha256:8c6af82722b35cf71e0f4d1d47dcaebfff286e27110a99fc359349b247dfb5d4"}, +] + [[package]] name = "accelerate" version = "1.4.0" @@ -65,132 +78,131 @@ files = [ [[package]] name = "aiohttp" -version = "3.13.5" +version = "3.14.1" description = "Async http client/server framework (asyncio)" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "aiohttp-3.13.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02222e7e233295f40e011c1b00e3b0bd451f22cf853a0304c3595633ee47da4b"}, - {file = "aiohttp-3.13.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bace460460ed20614fa6bc8cb09966c0b8517b8c58ad8046828c6078d25333b5"}, - {file = "aiohttp-3.13.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f546a4dc1e6a5edbb9fd1fd6ad18134550e096a5a43f4ad74acfbd834fc6670"}, - {file = "aiohttp-3.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c86969d012e51b8e415a8c6ce96f7857d6a87d6207303ab02d5d11ef0cad2274"}, - {file = "aiohttp-3.13.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b6f6cd1560c5fa427e3b6074bb24d2c64e225afbb7165008903bd42e4e33e28a"}, - {file = "aiohttp-3.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:636bc362f0c5bbc7372bc3ae49737f9e3030dbce469f0f422c8f38079780363d"}, - {file = "aiohttp-3.13.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6a7cbeb06d1070f1d14895eeeed4dac5913b22d7b456f2eb969f11f4b3993796"}, - {file = "aiohttp-3.13.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca9ef7517fd7874a1a08970ae88f497bf5c984610caa0bf40bd7e8450852b95"}, - {file = "aiohttp-3.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:019a67772e034a0e6b9b17c13d0a8fe56ad9fb150fc724b7f3ffd3724288d9e5"}, - {file = "aiohttp-3.13.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f34ecee82858e41dd217734f0c41a532bd066bcaab636ad830f03a30b2a96f2a"}, - {file = "aiohttp-3.13.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4eac02d9af4813ee289cd63a361576da36dba57f5a1ab36377bc2600db0cbb73"}, - {file = "aiohttp-3.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4beac52e9fe46d6abf98b0176a88154b742e878fdf209d2248e99fcdf73cd297"}, - {file = "aiohttp-3.13.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:c180f480207a9b2475f2b8d8bd7204e47aec952d084b2a2be58a782ffcf96074"}, - {file = "aiohttp-3.13.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2837fb92951564d6339cedae4a7231692aa9f73cbc4fb2e04263b96844e03b4e"}, - {file = "aiohttp-3.13.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9010032a0b9710f58012a1e9c222528763d860ba2ee1422c03473eab47703e7"}, - {file = "aiohttp-3.13.5-cp310-cp310-win32.whl", hash = "sha256:7c4b6668b2b2b9027f209ddf647f2a4407784b5d88b8be4efcc72036f365baf9"}, - {file = "aiohttp-3.13.5-cp310-cp310-win_amd64.whl", hash = "sha256:cd3db5927bf9167d5a6157ddb2f036f6b6b0ad001ac82355d43e97a4bde76d76"}, - {file = "aiohttp-3.13.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ab7229b6f9b5c1ba4910d6c41a9eb11f543eadb3f384df1b4c293f4e73d44d6"}, - {file = "aiohttp-3.13.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f14c50708bb156b3a3ca7230b3d820199d56a48e3af76fa21c2d6087190fe3d"}, - {file = "aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7d2f8616f0ff60bd332022279011776c3ac0faa0f1b463f7bb12326fbc97a1c"}, - {file = "aiohttp-3.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2567b72e1ffc3ab25510db43f355b29eeada56c0a622e58dcdb19530eb0a3cb"}, - {file = "aiohttp-3.13.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fb0540c854ac9c0c5ad495908fdfd3e332d553ec731698c0e29b1877ba0d2ec6"}, - {file = "aiohttp-3.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9883051c6972f58bfc4ebb2116345ee2aa151178e99c3f2b2bbe2af712abd13"}, - {file = "aiohttp-3.13.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2294172ce08a82fb7c7273485895de1fa1186cc8294cfeb6aef4af42ad261174"}, - {file = "aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a807cabd5115fb55af198b98178997a5e0e57dead43eb74a93d9c07d6d4a7dc"}, - {file = "aiohttp-3.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6d0d932e0f39c02b80744273cd5c388a2d9bc07760a03164f229c8e02662f6"}, - {file = "aiohttp-3.13.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60869c7ac4aaabe7110f26499f3e6e5696eae98144735b12a9c3d9eae2b51a49"}, - {file = "aiohttp-3.13.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:26d2f8546f1dfa75efa50c3488215a903c0168d253b75fba4210f57ab77a0fb8"}, - {file = "aiohttp-3.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1162a1492032c82f14271e831c8f4b49f2b6078f4f5fc74de2c912fa225d51d"}, - {file = "aiohttp-3.13.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:8b14eb3262fad0dc2f89c1a43b13727e709504972186ff6a99a3ecaa77102b6c"}, - {file = "aiohttp-3.13.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ca9ac61ac6db4eb6c2a0cd1d0f7e1357647b638ccc92f7e9d8d133e71ed3c6ac"}, - {file = "aiohttp-3.13.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7996023b2ed59489ae4762256c8516df9820f751cf2c5da8ed2fb20ee50abab3"}, - {file = "aiohttp-3.13.5-cp311-cp311-win32.whl", hash = "sha256:77dfa48c9f8013271011e51c00f8ada19851f013cde2c48fca1ba5e0caf5bb06"}, - {file = "aiohttp-3.13.5-cp311-cp311-win_amd64.whl", hash = "sha256:d3a4834f221061624b8887090637db9ad4f61752001eae37d56c52fddade2dc8"}, - {file = "aiohttp-3.13.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:023ecba036ddd840b0b19bf195bfae970083fd7024ce1ac22e9bba90464620e9"}, - {file = "aiohttp-3.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15c933ad7920b7d9a20de151efcd05a6e38302cbf0e10c9b2acb9a42210a2416"}, - {file = "aiohttp-3.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab2899f9fa2f9f741896ebb6fa07c4c883bfa5c7f2ddd8cf2aafa86fa981b2d2"}, - {file = "aiohttp-3.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60eaa2d440cd4707696b52e40ed3e2b0f73f65be07fd0ef23b6b539c9c0b0b4"}, - {file = "aiohttp-3.13.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:55b3bdd3292283295774ab585160c4004f4f2f203946997f49aac032c84649e9"}, - {file = "aiohttp-3.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c2b2355dc094e5f7d45a7bb262fe7207aa0460b37a0d87027dcf21b5d890e7d5"}, - {file = "aiohttp-3.13.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b38765950832f7d728297689ad78f5f2cf79ff82487131c4d26fe6ceecdc5f8e"}, - {file = "aiohttp-3.13.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b18f31b80d5a33661e08c89e202edabf1986e9b49c42b4504371daeaa11b47c1"}, - {file = "aiohttp-3.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:33add2463dde55c4f2d9635c6ab33ce154e5ecf322bd26d09af95c5f81cfa286"}, - {file = "aiohttp-3.13.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:327cc432fdf1356fb4fbc6fe833ad4e9f6aacb71a8acaa5f1855e4b25910e4a9"}, - {file = "aiohttp-3.13.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7c35b0bf0b48a70b4cb4fc5d7bed9b932532728e124874355de1a0af8ec4bc88"}, - {file = "aiohttp-3.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:df23d57718f24badef8656c49743e11a89fd6f5358fa8a7b96e728fda2abf7d3"}, - {file = "aiohttp-3.13.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:02e048037a6501a5ec1f6fc9736135aec6eb8a004ce48838cb951c515f32c80b"}, - {file = "aiohttp-3.13.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31cebae8b26f8a615d2b546fee45d5ffb76852ae6450e2a03f42c9102260d6fe"}, - {file = "aiohttp-3.13.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:888e78eb5ca55a615d285c3c09a7a91b42e9dd6fc699b166ebd5dee87c9ccf14"}, - {file = "aiohttp-3.13.5-cp312-cp312-win32.whl", hash = "sha256:8bd3ec6376e68a41f9f95f5ed170e2fcf22d4eb27a1f8cb361d0508f6e0557f3"}, - {file = "aiohttp-3.13.5-cp312-cp312-win_amd64.whl", hash = "sha256:110e448e02c729bcebb18c60b9214a87ba33bac4a9fa5e9a5f139938b56c6cb1"}, - {file = "aiohttp-3.13.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5029cc80718bbd545123cd8fe5d15025eccaaaace5d0eeec6bd556ad6163d61"}, - {file = "aiohttp-3.13.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4bb6bf5811620003614076bdc807ef3b5e38244f9d25ca5fe888eaccea2a9832"}, - {file = "aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a84792f8631bf5a94e52d9cc881c0b824ab42717165a5579c760b830d9392ac9"}, - {file = "aiohttp-3.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57653eac22c6a4c13eb22ecf4d673d64a12f266e72785ab1c8b8e5940d0e8090"}, - {file = "aiohttp-3.13.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5e5f7debc7a57af53fdf5c5009f9391d9f4c12867049d509bf7bb164a6e295b"}, - {file = "aiohttp-3.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c719f65bebcdf6716f10e9eff80d27567f7892d8988c06de12bbbd39307c6e3a"}, - {file = "aiohttp-3.13.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d97f93fdae594d886c5a866636397e2bcab146fd7a132fd6bb9ce182224452f8"}, - {file = "aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3df334e39d4c2f899a914f1dba283c1aadc311790733f705182998c6f7cae665"}, - {file = "aiohttp-3.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fe6970addfea9e5e081401bcbadf865d2b6da045472f58af08427e108d618540"}, - {file = "aiohttp-3.13.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7becdf835feff2f4f335d7477f121af787e3504b48b449ff737afb35869ba7bb"}, - {file = "aiohttp-3.13.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:676e5651705ad5d8a70aeb8eb6936c436d8ebbd56e63436cb7dd9bb36d2a9a46"}, - {file = "aiohttp-3.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:9b16c653d38eb1a611cc898c41e76859ca27f119d25b53c12875fd0474ae31a8"}, - {file = "aiohttp-3.13.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:999802d5fa0389f58decd24b537c54aa63c01c3219ce17d1214cbda3c2b22d2d"}, - {file = "aiohttp-3.13.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ec707059ee75732b1ba130ed5f9580fe10ff75180c812bc267ded039db5128c6"}, - {file = "aiohttp-3.13.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d6d44a5b48132053c2f6cd5c8cb14bc67e99a63594e336b0f2af81e94d5530c"}, - {file = "aiohttp-3.13.5-cp313-cp313-win32.whl", hash = "sha256:329f292ed14d38a6c4c435e465f48bebb47479fd676a0411936cc371643225cc"}, - {file = "aiohttp-3.13.5-cp313-cp313-win_amd64.whl", hash = "sha256:69f571de7500e0557801c0b51f4780482c0ec5fe2ac851af5a92cfce1af1cb83"}, - {file = "aiohttp-3.13.5-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:eb4639f32fd4a9904ab8fb45bf3383ba71137f3d9d4ba25b3b3f3109977c5b8c"}, - {file = "aiohttp-3.13.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:7e5dc4311bd5ac493886c63cbf76ab579dbe4641268e7c74e48e774c74b6f2be"}, - {file = "aiohttp-3.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:756c3c304d394977519824449600adaf2be0ccee76d206ee339c5e76b70ded25"}, - {file = "aiohttp-3.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecc26751323224cf8186efcf7fbcbc30f4e1d8c7970659daf25ad995e4032a56"}, - {file = "aiohttp-3.13.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10a75acfcf794edf9d8db50e5a7ec5fc818b2a8d3f591ce93bc7b1210df016d2"}, - {file = "aiohttp-3.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f7a18f258d124cd678c5fe072fe4432a4d5232b0657fca7c1847f599233c83a"}, - {file = "aiohttp-3.13.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df6104c009713d3a89621096f3e3e88cc323fd269dbd7c20afe18535094320be"}, - {file = "aiohttp-3.13.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:241a94f7de7c0c3b616627aaad530fe2cb620084a8b144d3be7b6ecfe95bae3b"}, - {file = "aiohttp-3.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c974fb66180e58709b6fc402846f13791240d180b74de81d23913abe48e96d94"}, - {file = "aiohttp-3.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6e27ea05d184afac78aabbac667450c75e54e35f62238d44463131bd3f96753d"}, - {file = "aiohttp-3.13.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a79a6d399cef33a11b6f004c67bb07741d91f2be01b8d712d52c75711b1e07c7"}, - {file = "aiohttp-3.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c632ce9c0b534fbe25b52c974515ed674937c5b99f549a92127c85f771a78772"}, - {file = "aiohttp-3.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fceedde51fbd67ee2bcc8c0b33d0126cc8b51ef3bbde2f86662bd6d5a6f10ec5"}, - {file = "aiohttp-3.13.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f92995dfec9420bb69ae629abf422e516923ba79ba4403bc750d94fb4a6c68c1"}, - {file = "aiohttp-3.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20ae0ff08b1f2c8788d6fb85afcb798654ae6ba0b747575f8562de738078457b"}, - {file = "aiohttp-3.13.5-cp314-cp314-win32.whl", hash = "sha256:b20df693de16f42b2472a9c485e1c948ee55524786a0a34345511afdd22246f3"}, - {file = "aiohttp-3.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:f85c6f327bf0b8c29da7d93b1cabb6363fb5e4e160a32fa241ed2dce21b73162"}, - {file = "aiohttp-3.13.5-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:1efb06900858bb618ff5cee184ae2de5828896c448403d51fb633f09e109be0a"}, - {file = "aiohttp-3.13.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fee86b7c4bd29bdaf0d53d14739b08a106fdda809ca5fe032a15f52fae5fe254"}, - {file = "aiohttp-3.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:20058e23909b9e65f9da62b396b77dfa95965cbe840f8def6e572538b1d32e36"}, - {file = "aiohttp-3.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cf20a8d6868cb15a73cab329ffc07291ba8c22b1b88176026106ae39aa6df0f"}, - {file = "aiohttp-3.13.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:330f5da04c987f1d5bdb8ae189137c77139f36bd1cb23779ca1a354a4b027800"}, - {file = "aiohttp-3.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f1cbf0c7926d315c3c26c2da41fd2b5d2fe01ac0e157b78caefc51a782196cf"}, - {file = "aiohttp-3.13.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:53fc049ed6390d05423ba33103ded7281fe897cf97878f369a527070bd95795b"}, - {file = "aiohttp-3.13.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:898703aa2667e3c5ca4c54ca36cd73f58b7a38ef87a5606414799ebce4d3fd3a"}, - {file = "aiohttp-3.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0494a01ca9584eea1e5fbd6d748e61ecff218c51b576ee1999c23db7066417d8"}, - {file = "aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6cf81fe010b8c17b09495cbd15c1d35afbc8fb405c0c9cf4738e5ae3af1d65be"}, - {file = "aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:c564dd5f09ddc9d8f2c2d0a301cd30a79a2cc1b46dd1a73bef8f0038863d016b"}, - {file = "aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2994be9f6e51046c4f864598fd9abeb4fba6e88f0b2152422c9666dcd4aea9c6"}, - {file = "aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:157826e2fa245d2ef46c83ea8a5faf77ca19355d278d425c29fda0beb3318037"}, - {file = "aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a8aca50daa9493e9e13c0f566201a9006f080e7c50e5e90d0b06f53146a54500"}, - {file = "aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3b13560160d07e047a93f23aaa30718606493036253d5430887514715b67c9d9"}, - {file = "aiohttp-3.13.5-cp314-cp314t-win32.whl", hash = "sha256:9a0f4474b6ea6818b41f82172d799e4b3d29e22c2c520ce4357856fced9af2f8"}, - {file = "aiohttp-3.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:18a2f6c1182c51baa1d28d68fea51513cb2a76612f038853c0ad3c145423d3d9"}, - {file = "aiohttp-3.13.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:347542f0ea3f95b2a955ee6656461fa1c776e401ac50ebce055a6c38454a0adf"}, - {file = "aiohttp-3.13.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:178c7b5e62b454c2bc790786e6058c3cc968613b4419251b478c153a4aec32b1"}, - {file = "aiohttp-3.13.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af545c2cffdb0967a96b6249e6f5f7b0d92cdfd267f9d5238d5b9ca63e8edb10"}, - {file = "aiohttp-3.13.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:206b7b3ef96e4ce211754f0cd003feb28b7d81f0ad26b8d077a5d5161436067f"}, - {file = "aiohttp-3.13.5-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ee5e86776273de1795947d17bddd6bb19e0365fd2af4289c0d2c5454b6b1d36b"}, - {file = "aiohttp-3.13.5-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:95d14ca7abefde230f7639ec136ade282655431fd5db03c343b19dda72dd1643"}, - {file = "aiohttp-3.13.5-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:912d4b6af530ddb1338a66229dac3a25ff11d4448be3ec3d6340583995f56031"}, - {file = "aiohttp-3.13.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e999f0c88a458c836d5fb521814e92ed2172c649200336a6df514987c1488258"}, - {file = "aiohttp-3.13.5-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:39380e12bd1f2fdab4285b6e055ad48efbaed5c836433b142ed4f5b9be71036a"}, - {file = "aiohttp-3.13.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9efcc0f11d850cefcafdd9275b9576ad3bfb539bed96807663b32ad99c4d4b88"}, - {file = "aiohttp-3.13.5-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:147b4f501d0292077f29d5268c16bb7c864a1f054d7001c4c1812c0421ea1ed0"}, - {file = "aiohttp-3.13.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d147004fede1b12f6013a6dbb2a26a986a671a03c6ea740ddc76500e5f1c399f"}, - {file = "aiohttp-3.13.5-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9277145d36a01653863899c665243871434694bcc3431922c3b35c978061bdb8"}, - {file = "aiohttp-3.13.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4e704c52438f66fdd89588346183d898bb42167cf88f8b7ff1c0f9fc957c348f"}, - {file = "aiohttp-3.13.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a8a4d3427e8de1312ddf309cc482186466c79895b3a139fed3259fc01dfa9a5b"}, - {file = "aiohttp-3.13.5-cp39-cp39-win32.whl", hash = "sha256:6f497a6876aa4b1a102b04996ce4c1170c7040d83faa9387dd921c16e30d5c83"}, - {file = "aiohttp-3.13.5-cp39-cp39-win_amd64.whl", hash = "sha256:cb979826071c0986a5f08333a36104153478ce6018c58cba7f9caddaf63d5d67"}, - {file = "aiohttp-3.13.5.tar.gz", hash = "sha256:9d98cc980ecc96be6eb4c1994ce35d28d8b1f5e5208a23b421187d1209dbb7d1"}, + {file = "aiohttp-3.14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8f6bb621e5863cfe8fe5ff5468002d200ec31f30f1280b259dc505b02595099e"}, + {file = "aiohttp-3.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f7215cb3933784f79ed20e5f050e15984f390424339b22375d5a53c933a0491"}, + {file = "aiohttp-3.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9d4e294455b23a68c9b8f042d0e8e377a265bcb15332753695f6e5b6819e0ce"}, + {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b238af795833d5731d049d82bc84b768ae6f8f97f0495963b3ed9935c5901cc3"}, + {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4e5e0ae56914ecdbf446493addefc0159053dd53962cef37d7839f37f73d505"}, + {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:092e4ce3619a7c6dee52a6bdabda973d9b34b66781f840ce93c7e0cec30cf521"}, + {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb33777ea21e8b7ecde0e6fc84f598be0a1192eab1a63bc746d75aa75d38e7bd"}, + {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23119f8fd4f5d16902ed459b63b100bcd269628075162bddac56cc7b5273b3fb"}, + {file = "aiohttp-3.14.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:57fc6745a4b7d0f5a9eb4f40a69718be6c0bc1b8368cc9fe89e90118719f4f42"}, + {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6fd35beba67c4183b09375c5fff9accb47524191a244a99f95fd4472f5402c2b"}, + {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:672b9d65f42eb877f5c3f234a4547e4e1a226ca8c2eed879bb34670a0ce51192"}, + {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:24ba13339fed9251d9b1a1bec8c7ab84c0d1675d79d33501e11f94f8b9a84e05"}, + {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:94da27378da0610e341c4d30de29a191672683cc82b8f9556e8f7c7212a020fe"}, + {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:52cdac9432d8b4a719f35094a818d95adcae0f0b4fe9b9b921909e0c87de9e7d"}, + {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:672ac254412a24d0d0cf00a9e6c238877e4be5e5fa2d188832c1244f45f31966"}, + {file = "aiohttp-3.14.1-cp310-cp310-win32.whl", hash = "sha256:2fe3607e71acc6ebb0ec8e492a247bf7a291226192dc0084236dfc12478916f6"}, + {file = "aiohttp-3.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:30099eda75a53c32efb0920e9c33c195314d2cc1c680fbfd30894932ac5f27df"}, + {file = "aiohttp-3.14.1-cp310-cp310-win_arm64.whl", hash = "sha256:5a837f49d901f9e368651b676912bff1104ed8c1a83b280bcd7b29adccef5c9c"}, + {file = "aiohttp-3.14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa00140699487bd435fde4342d85c94cb256b7cd3a5b9c3396c67f19922afda2"}, + {file = "aiohttp-3.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c1af67559445498b502030c35c59db59966f47041ca9de5b4e707f86bd10b5f"}, + {file = "aiohttp-3.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d44ec478e713ee7f29b439f7eb8dc2b9d4079e11ae114d2c2ac3d5daf30516c8"}, + {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3b1a184a9a8f548a6b73f1e26b96b052193e4b3175ed7342aaf1151a1f00a04"}, + {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5f2504bc0322437c9a1ff6d3333ca56c7477b727c995f036b976ae17b98372c8"}, + {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73f05ea02013e02512c3bf42714f1208c57168c779cc6fe23516e4543089d0a6"}, + {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:797457503c2d426bee06eef808d07b31ede30b65e054444e7de64cad0061b7af"}, + {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b821a1f7dedf7e37450654e620038ac3b2e81e8fa6ea269337e97101978ec730"}, + {file = "aiohttp-3.14.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4cd96b5ba05d67ed0cf00b5b405c8cd99586d8e3481e8ee0a831057591af7621"}, + {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d459b98a932296c6f0e94f87511a0b1b90a8a02c30a50e60a297619cd5a58ee"}, + {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:764457a7be60825fb770a644852ff717bcbb5042f189f2bd16df61a81b3f6573"}, + {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f7a16ef45b081454ef844502d87a848876c490c4cb5c650c230f6ec79ed2c1e7"}, + {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2fbc3ed048b3475b9f0cbcb9978e9d2d3511acd91ead203af26ed9f0056004cf"}, + {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bedb0cd073cc2dc035e30aeb99444389d3cd2113afe4ef9fcd23d439f5bade85"}, + {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b6feea921016eb3d4e04d65fc4e9ca402d1a3801f562aef94989f54694917af3"}, + {file = "aiohttp-3.14.1-cp311-cp311-win32.whl", hash = "sha256:313701e488100074ce99850404ee36e741abf6330179fec908a1944ecf570126"}, + {file = "aiohttp-3.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:03ab4530fdcb3a543a122ba4b65ac9919da9fe9f78a03d328a6e38ff962f7aa5"}, + {file = "aiohttp-3.14.1-cp311-cp311-win_arm64.whl", hash = "sha256:486f7d16ed54c39c2cbd7ca71fd8ba2b8bb7860df65bd7b6ed640bab96a38a8b"}, + {file = "aiohttp-3.14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d35143e27778b4bb0fb189562d7f275bff79c62ab8e98459717c0ea617ff2480"}, + {file = "aiohttp-3.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bcfb80a2cc36fba2534e5e5b5264dc7ae6fcd9bf15256da3e53d2f499e6fa29d"}, + {file = "aiohttp-3.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27fd7c91e51729b4f7e1577865fa6d34c9adccbc39aabe9000285b48af9f0ec2"}, + {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c567bf9eaf664280116a8688f63016e6b32db2505908e2bdaca1b6438142f2"}, + {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f5e6ff2bdbb8f4cd3fbe41f99e25bbcd58e3bf9f13d3dd31a11e7917251cc77a"}, + {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f73e01dc37122325caf079982621262f96d74823c179038a82fddfc50359264"}, + {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb2c0c80d431c0d03f2c7dbf125150fedd4f0de17366a7ca33f7ccb822391842"}, + {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e6fc1a85fa7194a1a7d19f44e8609180f4a8eb5fa4c7ed8b4355f080fad235c"}, + {file = "aiohttp-3.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:686b6c0d3911ec387b444ddf5dc62fb7f7c0a7d5186a7861626496a5ab4aff95"}, + {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c6fa4dc7ad6f8109c70bb1499e589f76b0b792baf39f9b017eb92c8a81d0a199"}, + {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:87a5eea1b2a5e21e1ebdbb33ad4165359189327e63fc4e4894693e7f821ac817"}, + {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c1421eb01d4fd608d88cc8290211d177a58532b55ad94076fb349c5bf467f0a"}, + {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:34b257ec41345c1e8f2df68fa908a7952f5de932723871eb633ecbbff396c9a4"}, + {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:de538791a80e5d862addbc183f70f0158ac9b9bb872bb147f1fd2a683691e087"}, + {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f71173be42d3241d428f760122febb748de0623f44308a6f120d0dd9ec572e3"}, + {file = "aiohttp-3.14.1-cp312-cp312-win32.whl", hash = "sha256:ec8dc383ee57ea3e883477dcca3f11b65d58199f1080acaf4cd6ad9a99698be4"}, + {file = "aiohttp-3.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2aa92c87868cd13674989f9ee83e5f9f7ea4237589b728048e1f0c8f6caa3271"}, + {file = "aiohttp-3.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:2c840c90759922cb5e6dda94596e079a30fb5a5ba548e7e0dc00574703940847"}, + {file = "aiohttp-3.14.1-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:b3a03285a7f9c7b016324574a6d92a1c895da6b978cb8f1deee3ac72bc6da178"}, + {file = "aiohttp-3.14.1-cp313-cp313-android_21_x86_64.whl", hash = "sha256:2a73f487ab8ef5abbb24b7aa9b73e98eaba9e9e031804ff2416f02eca315ccaf"}, + {file = "aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:915fbb7b41b115192259f8c9ae58f3ddc444d2b5579917270211858e606a4afd"}, + {file = "aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:7fb4bdf95b0561a79f259f9d28fbc109728c5ee7f27aff6391f0ca703a329abe"}, + {file = "aiohttp-3.14.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1b9748363260121d2927704f5d4fc498150669ca3ae93625986ee89c8f80dcd4"}, + {file = "aiohttp-3.14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:86a6dab78b0e43e2897a3bbe15745aa60dc5423ca437b7b0b164c069bf91b876"}, + {file = "aiohttp-3.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4dfd6e47d3c44c2279907607f73a4240b88c69eb8b90da7e2441a8045dfd21da"}, + {file = "aiohttp-3.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:317acd9f8602858dc7d59679812c376c7f0b97bcbbf16e0d6237f54141d8a8a6"}, + {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd869c427324e5cb15195793de951295710db28be7d818247f3097b4ab5d4b96"}, + {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93b032b5ec3255473c143627d21a69ac74ae12f7f33974cb587c564d11b1066f"}, + {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f234b4deb12f3ad59127e037bc57c40c21e45b45282df7d3a55a0f409f595296"}, + {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9af6779bfb46abf124068327abcdf9ce95c9ef8287a3e8da76ccf2d0f16c28fa"}, + {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:faccab372e66bc76d5731525e7f1143c922271725b9d38c9f97edcc66266b451"}, + {file = "aiohttp-3.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f380468b09d2a81633ee863b0ec5648d364bd17bb8ecfb8c2f387f7ac1faf42c"}, + {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:97e704dcd26271f5bda3fa07c3ce0fb76d6d3f8659f4baa1a24442cc9ba177ca"}, + {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:269b76ac5394092b95bc4a098f4fc6c191c083c3bd12775d1e30e663132f6a09"}, + {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0b3e614340c889d575451696374c9d17affd54cd607ca0babed8f8c37b9397"}, + {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5663ee9257cfa1add7253a7da3035a02f31b6600ec48261585e1800a81533080"}, + {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:603a2c834142172ffddc054067f5ec0ca65d57a0aa98a71bc81952573208e345"}, + {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cb21957bb8aca671c1765e32f58164cf0c50e6bf41c0bbbd16da20732ecaf588"}, + {file = "aiohttp-3.14.1-cp313-cp313-win32.whl", hash = "sha256:e509a55f681e6158c20f70f102f9cf61fb20fbc382272bc6d94b7343f2582780"}, + {file = "aiohttp-3.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:1ac8531b638959718e18c2207fbfe297819875da46a740b29dfa29beba64355a"}, + {file = "aiohttp-3.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:250d14af67f6b6a1a4a811049b1afa69d61d617fca6bf33149b3ab1a6dbcf7b8"}, + {file = "aiohttp-3.14.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:7c106c26852ca1c2047c6b80384f17100b4e439af276f21ef3d4e2f450ae7e15"}, + {file = "aiohttp-3.14.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:20205f7f5ade7aaec9f4b500549bbc071b046453aed72f9c06dcab87896a83e8"}, + {file = "aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:62a759436b29e677181a9e76bab8b8f689a29cb9c535f45f7c48c9c830d3f8c3"}, + {file = "aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:2964cbf553df4d7a57348da44d961d871895fc1ee4e8c322b2a95612c7b17fba"}, + {file = "aiohttp-3.14.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:237651caadc3a59badd39319c54642b5299e9cc98a3a194310e55d5bb9f5e397"}, + {file = "aiohttp-3.14.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:896e12dfdbbab9d8f7e16d2b28c6769a60126fa92095d1ebf9473d02593a2448"}, + {file = "aiohttp-3.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d03f281ed22579314ba00821ce20115a7c0ac430660b4cc05704a3f818b3e004"}, + {file = "aiohttp-3.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07eabb979d236335fed927e137a928c9adfb7df3b9ec7aa31726f133a62be983"}, + {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4fe1f1087cbadb280b5e1bb054a4f00d1423c74d6626c5e48400d871d34ecefe"}, + {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:367a9314fdc79dab0fac96e216cb41dd73c85bdca85306ce8999118ba7e0f333"}, + {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a24f677ebe83749039e7bdf862ff0bbb16818ae4193d4ef96505e269375bcce0"}, + {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c83afe0ba876be7e943d2e0ba645809ad441575d2840c895c21ee5de93b9377a"}, + {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:634e385930fb6d2d479cf3aa66515955863b77a5e3c2b5894ca259a25b308602"}, + {file = "aiohttp-3.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeea07c4397bbc57719c4eed8f9c284874d4f175f9b6d57f7a1546b976d455ca"}, + {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:335c0cc3e3545ce98dcb9cfcb836f40c3411f43fa03dab757597d80c89af8a35"}, + {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:ae6be797afdef264e8a84864a85b196ca06045586481b3df8a967322fd2fa844"}, + {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:8560b4d712474335d08907db7973f71912d3a9a8f1dee992ec06b5d2fe359496"}, + {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7edd08e0a5deb1e8564a2fcd8f4561014a3f05252334671bbf55ddd47db0e5"}, + {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:b6ff7fcee63287ae57b5df3e4f5957ce032122802509246dec1a5bcc55904c95"}, + {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6ffbb2f4ec1ceaff7e07d43922954da26b223d188bf30658e561b98e23089444"}, + {file = "aiohttp-3.14.1-cp314-cp314-win32.whl", hash = "sha256:a9875b46d910cff3ea2f5962f9d266b465459fe634e22556ab9bd6fc1192eea0"}, + {file = "aiohttp-3.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:af8b4b81a960eeaf1234971ac3cd0ba5901f3cd42eae42a46b4d089a8b492719"}, + {file = "aiohttp-3.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:cf4491381b1b57425c315a56a439251b1bdac07b2275f19a8c44bc57744532ec"}, + {file = "aiohttp-3.14.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:819c054312f1af92947e6a55883d1b66feefab11531a7fc45e0fb9b63880b5c2"}, + {file = "aiohttp-3.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10ee9c1753a8f706345b22496c79fbddb5be0599e0823f3738b1534058e25340"}, + {file = "aiohttp-3.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1601cc37baf5750ccacae618ec2daf020769581695550e3b654a911f859c563d"}, + {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d6e0ac9da31c9c04c84e1c0182ad8d6df35965a85cae29cd71d089621b3ae94"}, + {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e8f2d660c350b3d0e259c7a7e3d9b7fc8b41210cbcc3d4a7076ff0a5e5c2fdc"}, + {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4691802dda97be727f79d86818acaad7eb8e9252626a1d6b519fedbb92d5e251"}, + {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c389c482a7e9b9dc3ee2701ac46c4125297a3818875b9c305ddb603c04828fd1"}, + {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc0cacab7ba4e56f0f81c82a98c09bed2f39c940107b03a34b168bdf7597edd3"}, + {file = "aiohttp-3.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:979ed4717f59b8bb12e3963378fa285d93d367e15bcd66c721311826d3c44a6c"}, + {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:38e1e7daaea81df51c952e18483f323d878499a1e2bfe564790e0f9701d6f203"}, + {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:4132e72c608fe9fecb8f409113567605915b83e9bdd3ea56538d2f9cd35002f1"}, + {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:eefd9cc9b6d4a2db5f00a26bc3e4f9acf71926a6ec557cd56c9c6f27c290b665"}, + {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b165790117eea512d7f3fb22f1f6dad3d55a7189571993eb015591c1401276d1"}, + {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:ed09c7eb1c391271c2ed0314a51903e72a3acb653d5ccfc264cdf3ef11f8269d"}, + {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:99abd37084b82f5830c635fddd0b4993b9742a66eb746dacf433c8590e8f9e3c"}, + {file = "aiohttp-3.14.1-cp314-cp314t-win32.whl", hash = "sha256:47ddf841cdecc810749921d25606dee45857d12d2ad5ddb7b5bd7eab12e4b365"}, + {file = "aiohttp-3.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5e78b522b7a6e27e0b25d19b247b75039ac4c94f99823e3c9e53ae1603a9f7e9"}, + {file = "aiohttp-3.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:90d53f1609c29ccc2193945ef732428382a28f78d0456ae4d3daf0d48b74f0f6"}, + {file = "aiohttp-3.14.1.tar.gz", hash = "sha256:307f2cff90a764d329e77040603fa032db89c5c24fdad50c4c15334cba744035"}, ] [package.dependencies] @@ -201,10 +213,11 @@ attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" propcache = ">=0.2.0" +typing_extensions = {version = ">=4.4", markers = "python_version < \"3.13\""} yarl = ">=1.17.0,<2.0" [package.extras] -speedups = ["Brotli (>=1.2) ; platform_python_implementation == \"CPython\"", "aiodns (>=3.3.0)", "backports.zstd ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "brotlicffi (>=1.2) ; platform_python_implementation != \"CPython\""] +speedups = ["Brotli (>=1.2) ; platform_python_implementation == \"CPython\" and sys_platform != \"android\" and sys_platform != \"ios\"", "aiodns (>=3.3.0) ; sys_platform != \"android\" and sys_platform != \"ios\"", "backports.zstd ; platform_python_implementation == \"CPython\" and python_version < \"3.14\" and sys_platform != \"android\" and sys_platform != \"ios\"", "brotlicffi (>=1.2) ; platform_python_implementation != \"CPython\""] [[package]] name = "aiosignal" @@ -234,6 +247,75 @@ files = [ {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, ] +[[package]] +name = "alembic" +version = "1.18.4" +description = "A database migration tool for SQLAlchemy." +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "alembic-1.18.4-py3-none-any.whl", hash = "sha256:a5ed4adcf6d8a4cb575f3d759f071b03cd6e5c7618eb796cb52497be25bfe19a"}, + {file = "alembic-1.18.4.tar.gz", hash = "sha256:cb6e1fd84b6174ab8dbb2329f86d631ba9559dd78df550b57804d607672cedbc"}, +] + +[package.dependencies] +Mako = "*" +SQLAlchemy = ">=1.4.23" +tomli = {version = "*", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.12" + +[package.extras] +tz = ["tzdata"] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +description = "Document parameters, class attributes, return types, and variables inline, with Annotated." +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320"}, + {file = "annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.14.0" +description = "High-level concurrency and networking framework on top of asyncio or Trio" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "anyio-4.14.0-py3-none-any.whl", hash = "sha256:dd9b7a2a9799ed6552fde617b2c5df02b7fdd7d88392fc48101e51bae46164d9"}, + {file = "anyio-4.14.0.tar.gz", hash = "sha256:b47c1f9ccf73e67021df785332508f99379c68fa7d0684e8e3492cb1d4b23f89"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +trio = ["trio (>=0.32.0)"] + [[package]] name = "appnope" version = "0.1.4" @@ -369,23 +451,49 @@ lxml = ["lxml"] [[package]] name = "bleach" -version = "6.3.0" +version = "6.4.0" description = "An easy safelist-based HTML-sanitizing tool." optional = false python-versions = ">=3.10" groups = ["docs"] markers = "python_version >= \"3.12\"" files = [ - {file = "bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6"}, - {file = "bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22"}, + {file = "bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081"}, + {file = "bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452"}, ] [package.dependencies] -tinycss2 = {version = ">=1.1.0,<1.5", optional = true, markers = "extra == \"css\""} +tinycss2 = {version = ">=1.1.0", optional = true, markers = "extra == \"css\""} webencodings = "*" [package.extras] -css = ["tinycss2 (>=1.1.0,<1.5)"] +css = ["tinycss2 (>=1.1.0)"] + +[[package]] +name = "blinker" +version = "1.9.0" +description = "Fast, simple object-to-object and broadcast signaling" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"}, + {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"}, +] + +[[package]] +name = "cachetools" +version = "7.1.4" +description = "Extensible memoizing collections and decorators" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "cachetools-7.1.4-py3-none-any.whl", hash = "sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54"}, + {file = "cachetools-7.1.4.tar.gz", hash = "sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6"}, +] [[package]] name = "certifi" @@ -405,7 +513,7 @@ version = "2.0.0" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.9" -groups = ["dev", "docs"] +groups = ["main", "dev", "docs"] files = [ {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, @@ -492,7 +600,7 @@ files = [ {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, ] -markers = {dev = "implementation_name == \"pypy\" or platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\" and platform_python_implementation != \"PyPy\"", docs = "python_version >= \"3.12\" and implementation_name == \"pypy\""} +markers = {main = "platform_python_implementation != \"PyPy\" and (extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\")", dev = "implementation_name == \"pypy\" or platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\" and platform_python_implementation != \"PyPy\"", docs = "python_version >= \"3.12\" and implementation_name == \"pypy\""} [package.dependencies] pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} @@ -611,6 +719,35 @@ files = [ {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] +[[package]] +name = "click" +version = "8.4.1" +description = "Composable command line interface toolkit" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2"}, + {file = "click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "cloudpickle" +version = "3.1.2" +description = "Pickler class to extend the standard pickle.Pickler functionality" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a"}, + {file = "cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414"}, +] + [[package]] name = "colorama" version = "0.4.6" @@ -663,6 +800,177 @@ questionary = ">=2.0,<3.0" termcolor = ">=1.1,<3" tomlkit = ">=0.5.3,<1.0.0" +[[package]] +name = "contourpy" +version = "1.3.2" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version == \"3.10\" and (extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\")" +files = [ + {file = "contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934"}, + {file = "contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631"}, + {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f"}, + {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2"}, + {file = "contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0"}, + {file = "contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a"}, + {file = "contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445"}, + {file = "contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7"}, + {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83"}, + {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd"}, + {file = "contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f"}, + {file = "contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878"}, + {file = "contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2"}, + {file = "contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe"}, + {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441"}, + {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e"}, + {file = "contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912"}, + {file = "contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73"}, + {file = "contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb"}, + {file = "contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841"}, + {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422"}, + {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef"}, + {file = "contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f"}, + {file = "contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9"}, + {file = "contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f"}, + {file = "contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b"}, + {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52"}, + {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd"}, + {file = "contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1"}, + {file = "contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69"}, + {file = "contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c"}, + {file = "contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16"}, + {file = "contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad"}, + {file = "contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0"}, + {file = "contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5"}, + {file = "contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5"}, + {file = "contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54"}, +] + +[package.dependencies] +numpy = ">=1.23" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.15.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] + +[[package]] +name = "contourpy" +version = "1.3.3" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = true +python-versions = ">=3.11" +groups = ["main"] +markers = "python_version >= \"3.11\" and (extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\")" +files = [ + {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, + {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, + {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, + {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, + {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, + {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, + {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, + {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, + {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, + {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, + {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, + {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, + {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, + {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, + {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, + {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, + {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, +] + +[package.dependencies] +numpy = ">=1.25" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] + [[package]] name = "coverage" version = "7.6.12" @@ -748,8 +1056,7 @@ version = "47.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.8" -groups = ["dev"] -markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\"" +groups = ["main", "dev"] files = [ {file = "cryptography-47.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0"}, {file = "cryptography-47.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973"}, @@ -801,6 +1108,7 @@ files = [ {file = "cryptography-47.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8"}, {file = "cryptography-47.0.0.tar.gz", hash = "sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb"}, ] +markers = {main = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"", dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\""} [package.dependencies] cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} @@ -809,6 +1117,47 @@ typing-extensions = {version = ">=4.13.2", markers = "python_full_version < \"3. [package.extras] ssh = ["bcrypt (>=3.1.5)"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "databricks-sdk" +version = "0.118.0" +description = "Databricks SDK for Python (Beta)" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "databricks_sdk-0.118.0-py3-none-any.whl", hash = "sha256:7931c7147315902e4347863074c2e2bc1d389338e15d1b60bbf49bc5ebabcbe0"}, + {file = "databricks_sdk-0.118.0.tar.gz", hash = "sha256:cd049b7a9612d957e53d842631800f1974406fc3bec78bc51d429387046a0287"}, +] + +[package.dependencies] +google-auth = ">=2.0,<3.0" +protobuf = ">=4.25.8,<5.26.dev0 || >5.29.0,<5.29.1 || >5.29.1,<5.29.2 || >5.29.2,<5.29.3 || >5.29.3,<5.29.4 || >5.29.4,<6.30.0 || >6.30.0,<6.30.1 || >6.30.1,<6.31.0 || >6.31.0,<7.0" +requests = ">=2.28.1,<3" +urllib3 = ">=1.26,<3" + +[package.extras] +dev = ["build", "check-manifest", "databricks-connect", "httpx", "ipython", "ipywidgets", "langchain-openai", "openai", "pycodestyle", "pyfakefs", "pytest", "pytest-cov", "pytest-mock", "pytest-rerunfailures", "pytest-xdist (>=3.6.1,<4.0)", "requests-mock", "ruff (==0.5.6)", "wheel"] +notebook = ["ipython (>=8,<10)", "ipywidgets (>=8,<9)"] +openai = ["httpx", "langchain-openai", "openai"] + [[package]] name = "debugpy" version = "1.8.20" @@ -933,6 +1282,30 @@ untokenize = ">=0.1.1,<0.2.0" [package.extras] tomli = ["tomli (>=2.0.0,<3.0.0) ; python_version < \"3.11\""] +[[package]] +name = "docker" +version = "7.1.0" +description = "A Python library for the Docker Engine API." +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"}, + {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"}, +] + +[package.dependencies] +pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} +requests = ">=2.26.0" +urllib3 = ">=1.26.0" + +[package.extras] +dev = ["coverage (==7.2.7)", "pytest (==7.4.2)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.1.0)", "ruff (==0.1.8)"] +docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"] +ssh = ["paramiko (>=2.4.3)"] +websockets = ["websocket-client (>=1.3.0)"] + [[package]] name = "docutils" version = "0.19" @@ -977,12 +1350,12 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" -groups = ["dev", "docs"] -markers = "python_version == \"3.10\"" +groups = ["main", "dev", "docs"] files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] +markers = {main = "(extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") and python_version == \"3.10\"", dev = "python_version == \"3.10\"", docs = "python_version == \"3.10\""} [package.extras] test = ["pytest (>=6)"] @@ -1031,6 +1404,31 @@ files = [ numpy = ">=1.25.0,<3.0" packaging = "*" +[[package]] +name = "fastapi" +version = "0.138.0" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "fastapi-0.138.0-py3-none-any.whl", hash = "sha256:b6f54fd1bd72c80b0f899f172c61a600f6f7af9b43d4d772a018f35624048cb0"}, + {file = "fastapi-0.138.0.tar.gz", hash = "sha256:d445a4877636ad191e7053e08c9bf98cb921a6756776848400bb773d1740c061"}, +] + +[package.dependencies] +annotated-doc = ">=0.0.2" +pydantic = ">=2.9.0" +starlette = ">=0.46.0" +typing-extensions = ">=4.8.0" +typing-inspection = ">=0.4.2" + +[package.extras] +all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "fastar (>=0.9.0)", "httpx (>=0.23.0,<1.0.0)", "jinja2 (>=3.1.5)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] +standard-no-fastapi-cloud-cli = ["email-validator (>=2.0.0)", "fastapi-cli[standard-no-fastapi-cloud-cli] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "jinja2 (>=3.1.5)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] + [[package]] name = "fastjsonschema" version = "2.21.2" @@ -1059,6 +1457,123 @@ files = [ {file = "filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90"}, ] +[[package]] +name = "flask" +version = "3.1.3" +description = "A simple framework for building complex web applications." +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "flask-3.1.3-py3-none-any.whl", hash = "sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c"}, + {file = "flask-3.1.3.tar.gz", hash = "sha256:0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb"}, +] + +[package.dependencies] +blinker = ">=1.9.0" +click = ">=8.1.3" +itsdangerous = ">=2.2.0" +jinja2 = ">=3.1.2" +markupsafe = ">=2.1.1" +werkzeug = ">=3.1.0" + +[package.extras] +async = ["asgiref (>=3.2)"] +dotenv = ["python-dotenv"] + +[[package]] +name = "flask-cors" +version = "6.0.5" +description = "A Flask extension simplifying CORS support" +optional = true +python-versions = "<4.0,>=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "flask_cors-6.0.5-py3-none-any.whl", hash = "sha256:68fcf75693e961f3af26683b23c4b9a8fb6b64de17d20d0c37b95e8de7ab2ed8"}, + {file = "flask_cors-6.0.5.tar.gz", hash = "sha256:30c5031552cd59f620ac0c8211dac45b345d3b2df310e7721879e4f46ef9c601"}, +] + +[package.dependencies] +flask = ">=0.9" +typing_extensions = {version = ">=4.6.0", markers = "python_version < \"3.11\""} +Werkzeug = ">=0.7" + +[[package]] +name = "fonttools" +version = "4.63.0" +description = "Tools to manipulate font files" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "fonttools-4.63.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b"}, + {file = "fonttools-4.63.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94"}, + {file = "fonttools-4.63.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579"}, + {file = "fonttools-4.63.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22"}, + {file = "fonttools-4.63.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e"}, + {file = "fonttools-4.63.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69"}, + {file = "fonttools-4.63.0-cp310-cp310-win32.whl", hash = "sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e"}, + {file = "fonttools-4.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac"}, + {file = "fonttools-4.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f"}, + {file = "fonttools-4.63.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9"}, + {file = "fonttools-4.63.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b"}, + {file = "fonttools-4.63.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18"}, + {file = "fonttools-4.63.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0"}, + {file = "fonttools-4.63.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007"}, + {file = "fonttools-4.63.0-cp311-cp311-win32.whl", hash = "sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb"}, + {file = "fonttools-4.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c"}, + {file = "fonttools-4.63.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02"}, + {file = "fonttools-4.63.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0"}, + {file = "fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af"}, + {file = "fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8"}, + {file = "fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b"}, + {file = "fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78"}, + {file = "fonttools-4.63.0-cp312-cp312-win32.whl", hash = "sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263"}, + {file = "fonttools-4.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272"}, + {file = "fonttools-4.63.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd"}, + {file = "fonttools-4.63.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59"}, + {file = "fonttools-4.63.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d"}, + {file = "fonttools-4.63.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68"}, + {file = "fonttools-4.63.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be"}, + {file = "fonttools-4.63.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27"}, + {file = "fonttools-4.63.0-cp313-cp313-win32.whl", hash = "sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380"}, + {file = "fonttools-4.63.0-cp313-cp313-win_amd64.whl", hash = "sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b"}, + {file = "fonttools-4.63.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745"}, + {file = "fonttools-4.63.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03"}, + {file = "fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49"}, + {file = "fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b"}, + {file = "fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6"}, + {file = "fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4"}, + {file = "fonttools-4.63.0-cp314-cp314-win32.whl", hash = "sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616"}, + {file = "fonttools-4.63.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5"}, + {file = "fonttools-4.63.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001"}, + {file = "fonttools-4.63.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e"}, + {file = "fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096"}, + {file = "fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f"}, + {file = "fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40"}, + {file = "fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196"}, + {file = "fonttools-4.63.0-cp314-cp314t-win32.whl", hash = "sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8"}, + {file = "fonttools-4.63.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419"}, + {file = "fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d"}, + {file = "fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0"}, +] + +[package.extras] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.45.0)", "unicodedata2 (>=17.0.0) ; python_version <= \"3.14\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.45.0)"] +symfont = ["sympy"] +type1 = ["xattr ; sys_platform == \"darwin\""] +unicode = ["unicodedata2 (>=17.0.0) ; python_version <= \"3.14\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] + [[package]] name = "frozenlist" version = "1.5.0" @@ -1204,6 +1719,338 @@ test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask[dataframe,test]", "moto test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] tqdm = ["tqdm"] +[[package]] +name = "gitdb" +version = "4.0.12" +description = "Git Object Database" +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf"}, + {file = "gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571"}, +] + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.50" +description = "GitPython is a Python library used to interact with Git repositories" +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9"}, + {file = "gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc"}, +] + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.extras] +doc = ["sphinx (>=7.4.7,<8)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"] +test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock ; python_version < \"3.8\"", "mypy (==1.18.2) ; python_version >= \"3.9\"", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions ; python_version < \"3.11\""] + +[[package]] +name = "google-auth" +version = "2.55.0" +description = "Google Authentication Library" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "google_auth-2.55.0-py3-none-any.whl", hash = "sha256:a17cef9dedf98c4ebae2fb0c48c8f75952c877cbc2efe09f329ef16c2783d88a"}, + {file = "google_auth-2.55.0.tar.gz", hash = "sha256:fcd3a130f575fa36403d38774af1c64a4fbfbca09215f0589d2372b5119697cb"}, +] + +[package.dependencies] +cryptography = ">=38.0.3" +pyasn1-modules = ">=0.2.1" + +[package.extras] +aiohttp = ["aiohttp (>=3.8.0,<4.0.0)", "requests (>=2.20.0,<3.0.0)"] +cryptography = ["cryptography (>=38.0.3)"] +enterprise-cert = ["pyopenssl"] +pyjwt = ["pyjwt (>=2.0)"] +pyopenssl = ["pyopenssl (>=20.0.0)"] +reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0)"] +rsa = ["rsa (>=3.1.4,<5)"] +testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.8.0,<4.0.0)", "aioresponses", "flask", "freezegun", "grpcio", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"] +urllib3 = ["packaging", "urllib3"] + +[[package]] +name = "graphene" +version = "3.4.3" +description = "GraphQL Framework for Python" +optional = true +python-versions = "*" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "graphene-3.4.3-py2.py3-none-any.whl", hash = "sha256:820db6289754c181007a150db1f7fff544b94142b556d12e3ebc777a7bf36c71"}, + {file = "graphene-3.4.3.tar.gz", hash = "sha256:2a3786948ce75fe7e078443d37f609cbe5bb36ad8d6b828740ad3b95ed1a0aaa"}, +] + +[package.dependencies] +graphql-core = ">=3.1,<3.3" +graphql-relay = ">=3.1,<3.3" +python-dateutil = ">=2.7.0,<3" +typing-extensions = ">=4.7.1,<5" + +[package.extras] +dev = ["coveralls (>=3.3,<5)", "mypy (>=1.10,<2)", "pytest (>=8,<9)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=4,<5)", "pytest-cov (>=5,<6)", "pytest-mock (>=3,<4)", "ruff (==0.5.0)", "types-python-dateutil (>=2.8.1,<3)"] +test = ["coveralls (>=3.3,<5)", "pytest (>=8,<9)", "pytest-asyncio (>=0.16,<2)", "pytest-benchmark (>=4,<5)", "pytest-cov (>=5,<6)", "pytest-mock (>=3,<4)"] + +[[package]] +name = "graphql-core" +version = "3.2.11" +description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL." +optional = true +python-versions = "<4,>=3.7" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "graphql_core-3.2.11-py3-none-any.whl", hash = "sha256:0b3e35ff41e9adba53021ab0cef475eb18f57c7f53f0f2ca55567fbf3c537ea0"}, + {file = "graphql_core-3.2.11.tar.gz", hash = "sha256:e7e156d10beb127cab5c89ff0da71416fc73d27c484a4757d3b2d35633774802"}, +] + +[[package]] +name = "graphql-relay" +version = "3.2.0" +description = "Relay library for graphql-core" +optional = true +python-versions = ">=3.6,<4" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "graphql-relay-3.2.0.tar.gz", hash = "sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c"}, + {file = "graphql_relay-3.2.0-py3-none-any.whl", hash = "sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5"}, +] + +[package.dependencies] +graphql-core = ">=3.2,<3.3" + +[[package]] +name = "greenlet" +version = "3.5.2" +description = "Lightweight in-process concurrent programming" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "(extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") 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\")" +files = [ + {file = "greenlet-3.5.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9df9daae96848508450011d0d86ed7c95f8829a354ce438284a77b24896fd1f8"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01e32e9d2b1714a2b06184cb3071ff2a2fd9bc7d065e39198ab21f7253dad421"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0488ca77c94da5e09d1d9958f98b58cebba1b8fd9664c24898499133de927574"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bc18b8d33e6976804b9b792fe11cb3b1fee8b646e8a9e20bf521a429ddf73520"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d9e19257794e28821c9ebd5e23f86d7c267cd9d390089374f068d2049f949e3"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:2c6d6bfa4fdd7c39a0dbf112cdf28edbd19c517c810eefb6e4e71b0d55933a4c"}, + {file = "greenlet-3.5.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bf493b3c1c0a2324c49b0472e2280ba4665f3510d8115f6f807759a6163b15f7"}, + {file = "greenlet-3.5.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:561dd919c02236a613fbf226791cbd77ee5002cbd5cb7e838869aa3ac7a71e16"}, + {file = "greenlet-3.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:049827baab63dda8ab8ec5a6d07fc6eb0f418319cfc757fc8737a605e99ca1ad"}, + {file = "greenlet-3.5.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d7792398872f89466c6671d5d193537eff163ecf7fac78d82e6ddc25017fb4f5"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:711028c953cd6ce5dc01bbb5a1747e3ad6bd8b2f7ded73778bb936e8dab9e3b6"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5eba55076d79e8a5176e6925295cfb901ebc95dae493342ede22230f75d8bee2"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1724499fc08388208408681c53c5062e9803c334e5a0bdaeb616228ba882aac8"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1c1e5ad80f1f38ea479b83b39dccb20874cfe9ad5e52f87225fa294ba4d39a1"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:e976f9f6941f57d87a194c91868622c8b22a142a741d2fde31655c319133ade6"}, + {file = "greenlet-3.5.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e194b996aa1b89d933cfe136e5eb39b22a8b72ba59d376ef39a55bca4dbf47f"}, + {file = "greenlet-3.5.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4e554809538bd4867f24421b43abde170f9c9b8192149b30df5e164bcac6124f"}, + {file = "greenlet-3.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:e063263ce9047878480d7e536012fc8b7c8e1922989eb5f03b9ab998a2ee7b7e"}, + {file = "greenlet-3.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:a3f76a94e2d6e1fee8f302265679d8cc47d71a203936dd03c6e2ace0f9cfd46d"}, + {file = "greenlet-3.5.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:76dae33e97b52743a19210931ee3e78a88fe1438bc2fc4ee5e7512d289bfad4f"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30252d191d6959df1d040b559a38fc017139606c5ecc2ad00416557c0355d742"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1adc23c50f22b0f5979521909a8360ab4a3d3bef8b641ce633a04cf1b1c967ea"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87359c23eb4e8f1b16da68faad29bf5aeb80e3628d7d8e4aa2e41c36879ddedd"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f052fff492c52fdfa99bd3b3c1389a53de37dae76a0562741417f0d018f02b3"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:f4d67c1684db3f9782c37ee4bade3f86f5a23a8fcf3f8359224106018ca40728"}, + {file = "greenlet-3.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:120b77c2a18ebf629c3a7886f68c6d01e065654844ad468f15bb93ace66f2094"}, + {file = "greenlet-3.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a850f6224088ef7dcc70f1a545cb6b3d119c35d6dca63b925b9f35da0635cdad"}, + {file = "greenlet-3.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:89da99ee8345b458ea2f16831dad31c88ddcdec454b48704d569a0b8fb28f146"}, + {file = "greenlet-3.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:ca92411942154023c65851e6077d8ca0d00f19de5fa80bb2c6f196ff6c920ba9"}, + {file = "greenlet-3.5.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:0629377725977252159de1ebd3c6e49c170a63856e585446797bb3d66d4d9c34"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2ddf9eddc617681108dd071b3feabf3f4a4cd64846254aec4d4ceda098b639a"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f41feb9f2b59e2e61ac9bea4e344ddd9396bf3cacb2583f73a3595ed7df6f8e7"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9dc23f0e5ad76415457212a4b947d22ebe4dc80baf02adf7dd5647a90f38bb4e"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09201fa698768db245920b00fdc86ee3e73540f01ca6db162be9632642e1a473"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:423167363c510a75b649f5cd58d873c29498ea03598b9e4b1c3b73e0f899f3d5"}, + {file = "greenlet-3.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a1759fa4f14c398508cf20dc8037de55cc23ae8bd14c185c2718257837195ca5"}, + {file = "greenlet-3.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9318cdeb9abdbfdd8bc8464ee4a06dffde2c7846e1def138365a6240ab2c9a5"}, + {file = "greenlet-3.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:2c3b3311af72b3d3b03cc0f1ffd11f072e834be5d0444105cf715fc44434e39c"}, + {file = "greenlet-3.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:f9bbd6216c45a563c2a61e478e038b439d9f248bde44f775ea37d339da643af4"}, + {file = "greenlet-3.5.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:1c31219badba285858ba8ed117f403dea7fafee6bade9a1991875aae530c3ceb"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6f96ed6f4adc1066954ae95f45717657cb67468ef3b89e9a3632e14a625a8f39"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5795e883e915333c0d5648faaa691857fbc7180136883edc377f50f0d509c2a8"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6e9e49d732ee92a189bb7035e293029244aeba648297a9b856dc733d17ca7f0d"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26aed8d9503ca78889141a9739d71b383efea5f472a7c522b5410f7eb2a1b163"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:537c5c4f30395020bb9f48f53146070e3b997c3c75da14011ab732aaa19ce3ef"}, + {file = "greenlet-3.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dbebc038fcdda8f8f21cce985fd04e34e0f42007e7fc7ab7ad285caf77974b95"}, + {file = "greenlet-3.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a207023f1cf8695fd82580b8099c09c5809be18bc2282362cdfb965dd884a317"}, + {file = "greenlet-3.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:c674a1dd4fe41f6a93febe7ab366ceabf15080ea31a9307811c56dac5f435f73"}, + {file = "greenlet-3.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:3c417cd6c593bbbef6f7aa31a79f37d3db7d18832fc56b694a2150130bde784e"}, + {file = "greenlet-3.5.2-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:a96457a30384de52d9c5d2fd33abf6c1daae3db392cd556738f408b1a79a1cf0"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4af5d4961818ab651d09c1448a03b1ba2a1726a076266ebb62330bab9f3238c"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a1789a6244ea1ba61fd4386c9a6a31873e9b0234762103364be98ef87dcb19f3"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2ee6288f1933d698b4f098127ed17bda2910a75d2807915bd16294a972055d6c"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3be00501fb4a8c37f6b4b3c4773808ceb26ea65c7ea64fd5735d0f330b3786de"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:b4cad42662c796334c2d24607c411e3ed82481c1fb4e1e8ec3a5a8416060092e"}, + {file = "greenlet-3.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1d554cd96841a68d464d75a3736f8e87408a7b02b1930a75fa32feb408ad62f8"}, + {file = "greenlet-3.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3dff6cd3aac35f6cd3fc23460105acf576f5faf6c378de0bc088bf37c913864a"}, + {file = "greenlet-3.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:36cfea2aa075d544617176b2e84450480f0797070ad8799a8c41ada2fe449d32"}, + {file = "greenlet-3.5.2-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:a0314aa832c94633355dc6f3ee54f195159533355a323f26926fc63b98b2ccbb"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24c59cb7db9d5c694cb8fd0c76eef8e456b2123afdfa7e4b8f2a67a0860d7682"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7bb811753703739ad318112f16eccfaabdac050037b6d092debaa8b23566b4ce"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2debcd0ef9455b7d4879589903efc8e497d4b8fb8c0ae772309e44d1ca5e957f"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d78b5c1c178dad90447f1b8452262709d3eef4c98f825569e74c9d0b2260ac9"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:9558cae989faeab6fbb425cd98a0cfa4190a47fba6443973fbee0a1eb0b0b6c3"}, + {file = "greenlet-3.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0977af2df83136f81c1f76e76d4e2fe7d0dc56ea9c101a86af26a95190b9ca32"}, + {file = "greenlet-3.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f9ed777c6891d8253e54468576f55e27f8fc1a662a664f946a191003574c0a74"}, + {file = "greenlet-3.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:c0ea4eb3de23f0bac1d75205e10ccfa9b418b17b01a2d7bf19e3b69dda08900a"}, + {file = "greenlet-3.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:7a7bfc200be40d04961d7e80e8337d726c0c1a50777e588123c3ed8ba731dcb9"}, + {file = "greenlet-3.5.2-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:98a52d6a50d4deaba304331d83ee3e10ebbdc1517fcca40b2715d1de4534065c"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1587ff8b58fdf806993ed1490a06ac19c22d47b219c68b30954380029045d8d4"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:feb721811d2754bfd16b48de151dd6b1f222c048e625151f2ca44cfdfd69f59c"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a9476cbead736dc48ce89e3cd97acff95ecc48cbf21273603a438f9870c4a014"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fe6062b1f35534e1e8fb28dfed406cf4eeff3e0bca3a0d9f8ff69f20a4abb00"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:5930d3946ecae99fa7fc0e3f3ae515426ad85058ebd9bfc6c00cca8016e6206b"}, + {file = "greenlet-3.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b4ac902af825cbac8e9b2fccab8122236fd2ba6c8b71a080116d2c2ec72671b1"}, + {file = "greenlet-3.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:6f1e473c06ae8be00c9034c2bb10fa277b08a93287e3111c395b839f01d27e1f"}, + {file = "greenlet-3.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:3c2315045f9983e2e50d7e89d95405c21bddb8745f2da4487bc080ab3525f904"}, + {file = "greenlet-3.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:db548d5ab6c2a8ead82c013f875090d79b5d7d2b67fc513934ce6cf66492ad7f"}, + {file = "greenlet-3.5.2.tar.gz", hash = "sha256:c1b906220d83c140361cdd12eef970fb5881a168b98ee58a43786426173da14c"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil", "setuptools"] + +[[package]] +name = "grpcio" +version = "1.81.1" +description = "HTTP/2-based RPC framework" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"tensorboard\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "grpcio-1.81.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:6f9a0c9c1cc15c112d1c053064fd032b64917062292c3d70aea280e02ae10b77"}, + {file = "grpcio-1.81.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:69ef28e54fc85397f91b8c19592b8ef3d81952080366914823bd8572a2958120"}, + {file = "grpcio-1.81.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:15641444eca4a29358107b3dceb74c1c6305c55c822fd199b458aaea4068a7fb"}, + {file = "grpcio-1.81.1-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d4b2dddfc219f54f956ccd53cf76a1d338ffe68fc7f2849ec9c7feb9927ff692"}, + {file = "grpcio-1.81.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ca1cc11d82677b9662082e5478b7528e2b7db7beaa6bdff42bd62789d81be399"}, + {file = "grpcio-1.81.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa2ba7d2ad6df4d80127cea65e5b8d5e2c3adbf153ff4804452836328aca7c54"}, + {file = "grpcio-1.81.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:592b5fee597faa91cce2dd294dd7d9a1c83d76c4dbf877e33ec1adb866b2fbed"}, + {file = "grpcio-1.81.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62481553b1793a27e9b9c3cf9e5bd483ef045ca72462592074b46d42b0c4d9b9"}, + {file = "grpcio-1.81.1-cp310-cp310-win32.whl", hash = "sha256:bb693b1e3d9a2f3fd228e2110daf4b5aeedb36761ca1e4282f74725f6d89f611"}, + {file = "grpcio-1.81.1-cp310-cp310-win_amd64.whl", hash = "sha256:88268ca418cacea64cecb0d1d600d3c6b3a8038fcba02e1e205178c5b1f47661"}, + {file = "grpcio-1.81.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:d71d30f2d92f67d944631c523713934fee37292469e182ebcd2c1dd8a64ce53f"}, + {file = "grpcio-1.81.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b137f4bf3ada9dc44d411478decc6ff09a79ed30b306cd2abaa98408c3588137"}, + {file = "grpcio-1.81.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a3acb384427816dd5d470f47e62137b87f74da694faa8a50147012cf40df276a"}, + {file = "grpcio-1.81.1-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f9a0ebbe45c29b5e5866593c12b78bd9035f0f0f0d4bc8361680cd580d99db49"}, + {file = "grpcio-1.81.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a37165cc80b1a368384b383e63a4c38116a10467ae44c904d2d7468c4470ec2"}, + {file = "grpcio-1.81.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6282caffb41ec326d4cb67ca9cf53b739d1b2f975a2acb498c7418e9f7d9a416"}, + {file = "grpcio-1.81.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a35009284d0d3d5c2c9601c164a911b8b4331608d98a9a66d47d97bb2f522b70"}, + {file = "grpcio-1.81.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1b22c80559854b789a01fd89e8929b3798a156c0829b5282a8939f33ad4115ad"}, + {file = "grpcio-1.81.1-cp311-cp311-win32.whl", hash = "sha256:428bec0161b48d8cf583c068591bc0016d0d9cfff52462b72b3884861ea768c5"}, + {file = "grpcio-1.81.1-cp311-cp311-win_amd64.whl", hash = "sha256:30e825f6848d9f18bba350ed6c75c1b02a0b5184474a31db9a32b1fa66fd8c79"}, + {file = "grpcio-1.81.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8b39472beafc0bdcafc4c8c73ad082ebfdb449d566897a61e7acb4fa88089115"}, + {file = "grpcio-1.81.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:12b7524c88d4026d3dcb7b0ebe16b6714f3b4af402ddd0f0639ab064a00c87c3"}, + {file = "grpcio-1.81.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1e123f9b37edb8375fd74130d1f69c944bbf0a7b06761ae7211154b8759e94d2"}, + {file = "grpcio-1.81.1-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2c2e2ae6867c2966b8daccc836d54a13218e0007e9a490aeb81dd05be64d22d7"}, + {file = "grpcio-1.81.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:766bc7c9a9c340342f4c864ccbda8e78111e4751f13b895812b9c148fb79e9d0"}, + {file = "grpcio-1.81.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b259a04a737cb3496be0901328eb8b7552ed8df4865d8c8f1cf1bffcfc0776a3"}, + {file = "grpcio-1.81.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:85b10a45b8993d195c4f3ff57025b8d1e11834909ee475c403bfa60cb4caefaf"}, + {file = "grpcio-1.81.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8ea1936c26b99999b27479853039a7f34713f56c49375ad52b38535ec93a796c"}, + {file = "grpcio-1.81.1-cp312-cp312-win32.whl", hash = "sha256:a185a04039df6cae8648bc8ab6d6fde7bf94f7188ecf7828e76ac52eef1e41d6"}, + {file = "grpcio-1.81.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ad74f8bb1a18963914c5452d289422830b39459e8776ebbcd207be1fbfb1d94"}, + {file = "grpcio-1.81.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:b10e1ff4756ed27d5a29d7fc79cfce7ef1ff56ad20025b89bac7cf79e09abbbe"}, + {file = "grpcio-1.81.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:819edbdcb42ab8598b494bcf0222684bbb7a3c772bd1b1f0be7e029a6063c28e"}, + {file = "grpcio-1.81.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c5bf2dc311127d91230cc79b92188c082634a06cf66c5234db49a43b910183b0"}, + {file = "grpcio-1.81.1-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e8ca6a1fcdb2943c9cbc1804a1baf3acb6071d72a471591678ded84218006e14"}, + {file = "grpcio-1.81.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e64dd101d380a115cc5a0c7856788adb535f1a4e21fc543775602f8be95180ae"}, + {file = "grpcio-1.81.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:98a07f9bf591e3a8919797bee1c53f026ba4acd587e5a4404c8e57c9ec36b2a5"}, + {file = "grpcio-1.81.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c261d74b1a945cf895a9d6eccd1685a8e837531beaab782da4d630a8d12deffb"}, + {file = "grpcio-1.81.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58ad1131c300d3c9b933802b3cc4dc69d380822935ba50b28703156ea826fbf7"}, + {file = "grpcio-1.81.1-cp313-cp313-win32.whl", hash = "sha256:78e29211f26da2fdd0e9c6d2b79f489476140cf7029b6a64808ade7ca4156a42"}, + {file = "grpcio-1.81.1-cp313-cp313-win_amd64.whl", hash = "sha256:edb59506291b647a30884b1d51a599d605f40b20af4a7dc3d33786a47a31de60"}, + {file = "grpcio-1.81.1-cp314-cp314-linux_armv7l.whl", hash = "sha256:506f48f2f9c29b143fca3dad7b0d518c188b6c9648c75a2ae6e2d9f2c13a060b"}, + {file = "grpcio-1.81.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d865db4a6318e1c1bea83292e0ed231090538fc4ca45425b0f0480eb338bbc6e"}, + {file = "grpcio-1.81.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2aa72e3ce1770317ef534f63d397b55e130725f5149bd36077c3b539019db27"}, + {file = "grpcio-1.81.1-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0490c30c261eded63f3f354979f9dc4502a9fb944cccb60cd9dc85f5a7349854"}, + {file = "grpcio-1.81.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:410482da976329fe5f4067270401b12cf2bd552ff8020f054ecfaddb5475f9d6"}, + {file = "grpcio-1.81.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3657301562ac3cb8018d30d0d3ebfa39932239f7b5703422057ef14b69949f5"}, + {file = "grpcio-1.81.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:24c8e57504c8f45b237e40b99262d181071e5099a07053695b75d97bb53053a0"}, + {file = "grpcio-1.81.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b427c19380991a4eaab2f6144b64b99b412043314c6bf4ab544f97bb31ee4190"}, + {file = "grpcio-1.81.1-cp314-cp314-win32.whl", hash = "sha256:61233fe8951e5c85dff81c2458b6528624760166946b5b47ea150a589168411f"}, + {file = "grpcio-1.81.1-cp314-cp314-win_amd64.whl", hash = "sha256:3768a5ff1b2125e6f552e561b6b2dca0e64982d8949689b4df145cf8b98d7821"}, + {file = "grpcio-1.81.1.tar.gz", hash = "sha256:6fa10a767143a5e82e8eaab53918af0cd8909a57a27f8cb2288b80a613ac671b"}, +] + +[package.dependencies] +typing-extensions = ">=4.12,<5.0" + +[package.extras] +protobuf = ["grpcio-tools (>=1.81.1)"] + +[[package]] +name = "gunicorn" +version = "26.0.0" +description = "WSGI HTTP Server for UNIX" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "(extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") and platform_system != \"Windows\"" +files = [ + {file = "gunicorn-26.0.0-py3-none-any.whl", hash = "sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc"}, + {file = "gunicorn-26.0.0.tar.gz", hash = "sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +fast = ["gunicorn_h1c (>=0.6.5)"] +gevent = ["gevent (>=24.10.1)"] +http2 = ["h2 (>=4.1.0)"] +setproctitle = ["setproctitle"] +testing = ["coverage", "gevent (>=24.10.1)", "h2 (>=4.1.0)", "httpx[http2]", "pytest", "pytest-asyncio", "pytest-cov", "uvloop (>=0.19.0)"] +tornado = ["tornado (>=6.5.0)"] + +[[package]] +name = "h11" +version = "0.16.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, +] + +[[package]] +name = "huey" +version = "3.0.3" +description = "a little task queue" +optional = true +python-versions = "*" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "huey-3.0.3-py3-none-any.whl", hash = "sha256:d1c687734778b8282c035a943eead8368c1736bb28abc006596fbbc01bdc96dc"}, + {file = "huey-3.0.3.tar.gz", hash = "sha256:1a17fef95fc8432f75413f1b77439cef5f3493c1ddbfba9151756b31a1b2dad3"}, +] + +[package.extras] +backends = ["redis (>=3.0.0)"] + [[package]] name = "huggingface-hub" version = "0.29.1" @@ -1307,12 +2154,12 @@ version = "9.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.10" -groups = ["dev"] -markers = "python_version < \"3.12\" and platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +groups = ["main", "dev"] files = [ {file = "importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7"}, {file = "importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc"}, ] +markers = {main = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"", dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and python_version < \"3.12\""} [package.dependencies] zipp = ">=3.20" @@ -1463,6 +2310,19 @@ files = [ [package.dependencies] pygments = "*" +[[package]] +name = "itsdangerous" +version = "2.2.0" +description = "Safely pass data to untrusted environments and back." +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, + {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, +] + [[package]] name = "jaraco-classes" version = "3.4.0" @@ -1727,6 +2587,134 @@ enabler = ["pytest-enabler (>=3.4)"] test = ["pyfakefs", "pytest (>=6,!=8.1.*)"] type = ["pygobject-stubs", "pytest-mypy (>=1.0.1)", "shtab", "types-pywin32"] +[[package]] +name = "kiwisolver" +version = "1.5.0" +description = "A fast implementation of the Cassowary constraint solver" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374"}, + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd"}, + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede"}, + {file = "kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2"}, + {file = "kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4"}, + {file = "kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b"}, + {file = "kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9"}, + {file = "kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384"}, + {file = "kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0"}, + {file = "kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276"}, + {file = "kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796"}, + {file = "kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e"}, + {file = "kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1"}, + {file = "kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a"}, +] + [[package]] name = "lightning" version = "2.5.0.post0" @@ -1957,6 +2945,44 @@ files = [ [package.dependencies] lxml = ">=6.1.1" +[[package]] +name = "mako" +version = "1.3.12" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "mako-1.3.12-py3-none-any.whl", hash = "sha256:8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9"}, + {file = "mako-1.3.12.tar.gz", hash = "sha256:9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markdown" +version = "3.10.2" +description = "Python implementation of John Gruber's Markdown." +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"tensorboard\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36"}, + {file = "markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950"}, +] + +[package.extras] +docs = ["mdx_gh_links (>=0.2)", "mkdocs (>=1.6)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python] (>=0.28.3)"] +testing = ["coverage", "pyyaml"] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -2053,6 +3079,154 @@ files = [ {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] +[[package]] +name = "matplotlib" +version = "3.10.9" +description = "Python plotting package" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version == \"3.10\" and (extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\")" +files = [ + {file = "matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217"}, + {file = "matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b"}, + {file = "matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37"}, + {file = "matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294"}, + {file = "matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65"}, + {file = "matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda"}, + {file = "matplotlib-3.10.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb"}, + {file = "matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb"}, + {file = "matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb"}, + {file = "matplotlib-3.10.9-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9"}, + {file = "matplotlib-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb"}, + {file = "matplotlib-3.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f"}, + {file = "matplotlib-3.10.9-cp311-cp311-win_arm64.whl", hash = "sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80"}, + {file = "matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1"}, + {file = "matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320"}, + {file = "matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285"}, + {file = "matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2"}, + {file = "matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf"}, + {file = "matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6"}, + {file = "matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42"}, + {file = "matplotlib-3.10.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f"}, + {file = "matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e"}, + {file = "matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f"}, + {file = "matplotlib-3.10.9-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838"}, + {file = "matplotlib-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2"}, + {file = "matplotlib-3.10.9-cp313-cp313-win_amd64.whl", hash = "sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921"}, + {file = "matplotlib-3.10.9-cp313-cp313-win_arm64.whl", hash = "sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8"}, + {file = "matplotlib-3.10.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9"}, + {file = "matplotlib-3.10.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4"}, + {file = "matplotlib-3.10.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc"}, + {file = "matplotlib-3.10.9-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99"}, + {file = "matplotlib-3.10.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d"}, + {file = "matplotlib-3.10.9-cp313-cp313t-win_amd64.whl", hash = "sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8"}, + {file = "matplotlib-3.10.9-cp313-cp313t-win_arm64.whl", hash = "sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38"}, + {file = "matplotlib-3.10.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d"}, + {file = "matplotlib-3.10.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f"}, + {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b"}, + {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2"}, + {file = "matplotlib-3.10.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716"}, + {file = "matplotlib-3.10.9-cp314-cp314-win_amd64.whl", hash = "sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f"}, + {file = "matplotlib-3.10.9-cp314-cp314-win_arm64.whl", hash = "sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456"}, + {file = "matplotlib-3.10.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe"}, + {file = "matplotlib-3.10.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6"}, + {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c"}, + {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4"}, + {file = "matplotlib-3.10.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf"}, + {file = "matplotlib-3.10.9-cp314-cp314t-win_amd64.whl", hash = "sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39"}, + {file = "matplotlib-3.10.9-cp314-cp314t-win_arm64.whl", hash = "sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c"}, + {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b"}, + {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f"}, + {file = "matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585"}, + {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20"}, + {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba"}, + {file = "matplotlib-3.10.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4"}, + {file = "matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=3" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7,<10)"] + +[[package]] +name = "matplotlib" +version = "3.11.0" +description = "Python plotting package" +optional = true +python-versions = ">=3.11" +groups = ["main"] +markers = "python_version >= \"3.11\" and (extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\")" +files = [ + {file = "matplotlib-3.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f857524b442f0f36e641868ce2171aafa88cb0bc0644f4e1d8a5df9b32649fef"}, + {file = "matplotlib-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:57baa92fdc82948ed716eae6d2579d4d6f40965cd8d2f416755b4a72580a3233"}, + {file = "matplotlib-3.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:630eee0e67d35cce2019a0e670719f4816e3b86aff0fa72729f6c69786fceb45"}, + {file = "matplotlib-3.11.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5106c444d0bf966eee2853548c03772af4ab7199118e086c62fbac8ccb07c055"}, + {file = "matplotlib-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d7aea652b58e686444079be3376ef546bffa1eee9b9bb9c472b9fcf6cf410d3"}, + {file = "matplotlib-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:70a5b3e9a5dab708c0f039709ae7c68d5b4d254e291ef76492cdba230c8bb5e4"}, + {file = "matplotlib-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:3d68266213e73823ac3be90615bab0cf31f88851e114cdb1dd25dacf3b01e1a7"}, + {file = "matplotlib-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06b5872e9cf11adc8f589ded3ce11bc3e1061ad498259664fabc1f6615beb918"}, + {file = "matplotlib-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0515d495124be3124340e59f164d901ed4484e2246a5b74cfa483cac3b80bd97"}, + {file = "matplotlib-3.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be5f93a1d21981bfb802ded0d77a0caa92d4342a47d45754fac77e314a506344"}, + {file = "matplotlib-3.11.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41635d7909d19e52e924a521dde6d8f670b0f53ab1d0e8c331fa831554f681d1"}, + {file = "matplotlib-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:94f5000f67ca9faa300863ea17f8bce9175cb67b88bec4bc7780502d53dd7c9e"}, + {file = "matplotlib-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ac6f1ef39f3d0f9e2463303013094992cdbe0f85f43bc54155bc472b2042768e"}, + {file = "matplotlib-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:9dd11fb612ce7bc60b1de5b4fc87ff959d22317b5de42aabf392f66f97af22eb"}, + {file = "matplotlib-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce3b839b34ae1f430b4616893a2945a2999debaa7e94e7e29a2a8bbf286f7b5"}, + {file = "matplotlib-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:373db8f91214e8ccaf35ac833cc1dd59dd961e148bbd55dd027141591dde1313"}, + {file = "matplotlib-3.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be152b7570324dc8d01574cc9474dd2d803237acf528bcbb5b211fa347461a09"}, + {file = "matplotlib-3.11.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:126f256df600652d7e4b394cf3164ff75210a00038f287c95a012a6f58d0e83f"}, + {file = "matplotlib-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:03acfeddf87b0dddb11b081ef7740ad445a3ca8bcb6b8e3011b08f2cf802b75c"}, + {file = "matplotlib-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:ab3722f04f3ff34c23b5012c5873d2894174e06c3822fcdac3610965a5ac7d06"}, + {file = "matplotlib-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c945824670fb8915b4ac879e5e61f3c58e0913022f70a0de4c082b17372f8771"}, + {file = "matplotlib-3.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3489c3dc487669b4a980bc3068f87856de7a1564248d3f6c629efb2a58b03f24"}, + {file = "matplotlib-3.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6a98f5476ce784a50ce09998f4ae1e6a9f25043cef8a480c98949902eda74620"}, + {file = "matplotlib-3.11.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:565af866fd63e4bd3f987d580afe27c44c2552a3b3305f4ecbb85133601ea6f3"}, + {file = "matplotlib-3.11.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6b3e64dea5062c570f04358e2711859f3531b459f29516274fbad889079e4f3"}, + {file = "matplotlib-3.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:942b37c5db1899610bd1543ce8e13e4ecff9a4633e7f63bb6aa9205d2644ebd1"}, + {file = "matplotlib-3.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:c08e649a6313e1291e713623b97a38e5bb4aa580b2a100a94a3309bc6b9c8eb3"}, + {file = "matplotlib-3.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2746cd2c113742ff6ce37a864c5ac5fd7aa644568f445e66166e457ac78e40e0"}, + {file = "matplotlib-3.11.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3338e3e3de128cf50d0d2fb92a122815daf9c755bd882a474343c05f8fd7ec79"}, + {file = "matplotlib-3.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:25c2e5455efd8d99f41fb79871a31feb7d301569642e332ec58d72cfe9282bc3"}, + {file = "matplotlib-3.11.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9695457a467ff86d23f35037a43deb6f1134dd6d3e2ac8ce1e2087cff09ffb9"}, + {file = "matplotlib-3.11.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19c16c61dea63b3582918503e6b294193961261d9daa806d4ae2151f1ad05430"}, + {file = "matplotlib-3.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2d72ea8b7924f3cb955e61518d21e43b3df1e6c8a793b480a0c1214f185d30ba"}, + {file = "matplotlib-3.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:1c02da0a629dfa9debf52725ea06866b74c1fb70a895bae05e4493d34074f9f2"}, + {file = "matplotlib-3.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aa55d73b3117d4b07f959cd9eb6f69b375d8df3414139c479388e551aa5d999d"}, + {file = "matplotlib-3.11.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a9d8c6e7cd2f0ddf11d8d92e520dd1d9d2abb0cf6ac8831e338666c81e905847"}, + {file = "matplotlib-3.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:be050fcf32f729eda99f7f75a80bf67612ce16ab9ac1c23a387dcaede95cb70e"}, + {file = "matplotlib-3.11.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfabef0230d0697aa0d717385194dd41162e00207a68bf4abf94c2bf4c27dca0"}, + {file = "matplotlib-3.11.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1644db30e759199443493ac5e5caec24fdb775a8f6123021f85ba47c4133c3cb"}, + {file = "matplotlib-3.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15b0d160079cb10699a0e98b5989c70677b2df7cacdc62af67c30f2facec46d9"}, + {file = "matplotlib-3.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:446307e6b04b57b1f1239e228a1ec2af0d589a1008cebc3dfa3f5441d095cfb6"}, + {file = "matplotlib-3.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:652fb5696271d4c50f196d22a5ff4f8e4444c74f847423570d7dc0aa2bbd0159"}, + {file = "matplotlib-3.11.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:81ae77077a1e16d37a5b61096ccb07c8d90a99b518fa8256b8f21578932f2f62"}, + {file = "matplotlib-3.11.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ddef37840695f5eef65f9f070fe2d2f510f584c2156203f9f622a5b0584efffd"}, + {file = "matplotlib-3.11.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf662e5ac5707658cb931e19972c4bd99f7b4f8b7bf79d3c821d239fa6b71e64"}, + {file = "matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.25" +packaging = ">=20.0" +pillow = ">=9" +pyparsing = ">=3" +python-dateutil = ">=2.7" + [[package]] name = "matplotlib-inline" version = "0.2.1" @@ -2100,24 +3274,147 @@ optional = false python-versions = ">=3.7" groups = ["dev", "docs"] files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] +markers = {docs = "python_version >= \"3.12\""} + +[[package]] +name = "mistune" +version = "3.2.1" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +markers = "python_version >= \"3.12\"" +files = [ + {file = "mistune-3.2.1-py3-none-any.whl", hash = "sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048"}, + {file = "mistune-3.2.1.tar.gz", hash = "sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28"}, +] + +[[package]] +name = "mlflow" +version = "3.14.0" +description = "MLflow is an open source platform for the complete machine learning lifecycle" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "mlflow-3.14.0-py3-none-any.whl", hash = "sha256:dbf77f7cdb5b5c0ec59b4671c61730b1b914b4dff7a2892e267a547cb5454f56"}, + {file = "mlflow-3.14.0.tar.gz", hash = "sha256:5a1f818fa003035c724162096ce3ded7bc7bc47a1cae595df6173961983f4718"}, +] + +[package.dependencies] +aiohttp = ">=3.7.0,<4" +alembic = "<1.10.0 || >1.10.0,<2" +cryptography = ">=43.0.0,<49" +docker = ">=4.0.0,<8" +Flask = "<4" +Flask-CORS = "<7" +graphene = "<4" +gunicorn = {version = "<27", markers = "platform_system != \"Windows\""} +huey = ">=2.5.4,<4" +matplotlib = "<4" +mlflow-skinny = "3.14.0" +mlflow-tracing = "3.14.0" +numpy = "<3" +pandas = "<3" +pyarrow = ">=4.0.0,<25" +scikit-learn = "<2" +scipy = "<2" +skops = "<1" +sqlalchemy = ">=1.4.0,<3" +waitress = {version = "<4", markers = "platform_system == \"Windows\""} + +[package.extras] +aliyun-oss = ["aliyunstoreplugin"] +auth = ["Flask-WTF (<2)"] +azure = ["azure-identity (>=1.6.1)", "azure-storage-blob (>=12)"] +databricks = ["azure-storage-file-datalake (>12)", "boto3 (>1)", "botocore", "databricks-agents (>=1.2.0,<2.0)", "google-cloud-storage (>=1.30.0)"] +db = ["PyMySQL", "psycopg2-binary", "pymssql"] +extras = ["azureml-core (>=1.2.0)", "boto3", "botocore", "google-cloud-storage (>=1.30.0)", "kubernetes", "prometheus-flask-exporter", "pyarrow", "pysftp", "requests-auth-aws-sigv4"] +gateway = ["boto3 (>=1.28.56,<2)", "fastapi (<1)", "slowapi (>=0.1.9,<1)", "tiktoken (<1)", "uvicorn[standard] (<1)", "watchfiles (<2)"] +genai = ["boto3 (>=1.28.56,<2)", "fastapi (<1)", "slowapi (>=0.1.9,<1)", "tiktoken (<1)", "uvicorn[standard] (<1)", "watchfiles (<2)"] +jfrog = ["mlflow-jfrog-plugin"] +kubernetes = ["kubernetes"] +langchain = ["langchain (>=0.3.26,<=1.3.4)"] +mcp = ["click (!=8.3.0)", "fastmcp (>=2.7.0,<4)"] +sqlserver = ["mlflow-dbstore"] + +[[package]] +name = "mlflow-skinny" +version = "3.14.0" +description = "MLflow is an open source platform for the complete machine learning lifecycle" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "mlflow_skinny-3.14.0-py3-none-any.whl", hash = "sha256:a4880e086365871ef9d78e727a34ea5fb1ce615689579998d48e8c65ee1665a9"}, + {file = "mlflow_skinny-3.14.0.tar.gz", hash = "sha256:e50f4506422c7737157ae6643c165122af7898345f2e828fa93c4f10128653cf"}, ] -markers = {docs = "python_version >= \"3.12\""} -[[package]] -name = "mistune" -version = "3.2.1" -description = "A sane and fast Markdown parser with useful plugins and renderers" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -markers = "python_version >= \"3.12\"" +[package.dependencies] +cachetools = ">=5.0.0,<8" +click = ">=7.0,<9" +cloudpickle = "<4" +databricks-sdk = ">=0.20.0,<1" +fastapi = "<1" +gitpython = ">=3.1.9,<4" +importlib_metadata = ">=3.7.0,<4.7.0 || >4.7.0,<10" +opentelemetry-api = ">=1.9.0,<3" +opentelemetry-proto = ">=1.9.0,<3" +opentelemetry-sdk = ">=1.9.0,<3" +packaging = "<27" +protobuf = ">=3.12.0,<8" +pydantic = ">=2.0.0,<3" +python-dotenv = ">=0.19.0,<2" +pyyaml = ">=5.1,<7" +requests = ">=2.17.3,<3" +sqlparse = ">=0.4.0,<1" +starlette = "<2" +typing-extensions = ">=4.0.0,<5" +uvicorn = "<1" + +[package.extras] +aliyun-oss = ["aliyunstoreplugin"] +auth = ["Flask-WTF (<2)"] +azure = ["azure-identity (>=1.6.1)", "azure-storage-blob (>=12)"] +databricks = ["azure-storage-file-datalake (>12)", "boto3 (>1)", "botocore", "databricks-agents (>=1.2.0,<2.0)", "google-cloud-storage (>=1.30.0)"] +db = ["PyMySQL", "psycopg2-binary", "pymssql"] +extras = ["azureml-core (>=1.2.0)", "boto3", "botocore", "google-cloud-storage (>=1.30.0)", "kubernetes", "prometheus-flask-exporter", "pyarrow", "pysftp", "requests-auth-aws-sigv4"] +gateway = ["boto3 (>=1.28.56,<2)", "fastapi (<1)", "slowapi (>=0.1.9,<1)", "tiktoken (<1)", "uvicorn[standard] (<1)", "watchfiles (<2)"] +genai = ["boto3 (>=1.28.56,<2)", "fastapi (<1)", "slowapi (>=0.1.9,<1)", "tiktoken (<1)", "uvicorn[standard] (<1)", "watchfiles (<2)"] +jfrog = ["mlflow-jfrog-plugin"] +kubernetes = ["kubernetes"] +langchain = ["langchain (>=0.3.26,<=1.3.4)"] +mcp = ["click (!=8.3.0)", "fastmcp (>=2.7.0,<4)"] +sqlserver = ["mlflow-dbstore"] + +[[package]] +name = "mlflow-tracing" +version = "3.14.0" +description = "MLflow Tracing SDK is an open-source, lightweight Python package that only includes the minimum set of dependencies and functionality to instrument your code/models/agents with MLflow Tracing." +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" files = [ - {file = "mistune-3.2.1-py3-none-any.whl", hash = "sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048"}, - {file = "mistune-3.2.1.tar.gz", hash = "sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28"}, + {file = "mlflow_tracing-3.14.0-py3-none-any.whl", hash = "sha256:854488dd18068f15e2a56f1cc7b8868c611d09ea39068d0a691a3f07e0048cae"}, + {file = "mlflow_tracing-3.14.0.tar.gz", hash = "sha256:c2f701e001d35964f23fbbdfdda36c818a76c157b912ae83781199fd714be09a"}, ] +[package.dependencies] +cachetools = ">=5.0.0,<8" +databricks-sdk = ">=0.20.0,<1" +opentelemetry-api = ">=1.9.0,<3" +opentelemetry-proto = ">=1.9.0,<3" +opentelemetry-sdk = ">=1.9.0,<3" +packaging = "<27" +protobuf = ">=3.12.0,<8" +pydantic = ">=2.0.0,<3" + [[package]] name = "more-itertools" version = "11.0.2" @@ -2857,6 +4154,76 @@ files = [ {file = "nvidia_nvtx_cu12-12.8.90-py3-none-win_amd64.whl", hash = "sha256:619c8304aedc69f02ea82dd244541a83c3d9d40993381b3b590f1adaed3db41e"}, ] +[[package]] +name = "opentelemetry-api" +version = "1.42.1" +description = "OpenTelemetry Python API" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "opentelemetry_api-1.42.1-py3-none-any.whl", hash = "sha256:51a69edacadbc03a8950ace1c4c21099cacc538820ac2c9e36277e78cebba714"}, + {file = "opentelemetry_api-1.42.1.tar.gz", hash = "sha256:56c63bea9f77b62856be8c47600474acad853b2924b99b1687c4cb6297166716"}, +] + +[package.dependencies] +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-proto" +version = "1.42.1" +description = "OpenTelemetry Python Proto" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "opentelemetry_proto-1.42.1-py3-none-any.whl", hash = "sha256:dedb74cba2886c59c7789b227a7a670613025a07489040050aedff6e5c0fb43c"}, + {file = "opentelemetry_proto-1.42.1.tar.gz", hash = "sha256:c6a51e6b4f05ae63565f3a113217f3d2bfaec68f78c02d7a6c85f9010d1cfca6"}, +] + +[package.dependencies] +protobuf = ">=5.0,<7.0" + +[[package]] +name = "opentelemetry-sdk" +version = "1.42.1" +description = "OpenTelemetry Python SDK" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "opentelemetry_sdk-1.42.1-py3-none-any.whl", hash = "sha256:083cd4bbfaa5aa7b5a9e552430d9951219967cfb27aa61feb13a77aba1fc839d"}, + {file = "opentelemetry_sdk-1.42.1.tar.gz", hash = "sha256:8c834e8f8c9ba4171d4ec843d0cb8a67e4c7394d3f9e9297e582cbd9456ddbf7"}, +] + +[package.dependencies] +opentelemetry-api = "1.42.1" +opentelemetry-semantic-conventions = "0.63b1" +typing-extensions = ">=4.5.0" + +[package.extras] +file-configuration = ["jsonschema (>=4.0)", "pyyaml (>=6.0)"] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.63b1" +description = "OpenTelemetry Semantic Conventions" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "opentelemetry_semantic_conventions-0.63b1-py3-none-any.whl", hash = "sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682"}, + {file = "opentelemetry_semantic_conventions-0.63b1.tar.gz", hash = "sha256:3daf963611334b365e98a57438183eb012d3bfb40b2d931a9af613476b8701a9"}, +] + +[package.dependencies] +opentelemetry-api = "1.42.1" +typing-extensions = ">=4.5.0" + [[package]] name = "packaging" version = "24.2" @@ -3001,6 +4368,116 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" +[[package]] +name = "pillow" +version = "12.2.0" +description = "Python Imaging Library (fork)" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\" or extra == \"tensorboard\"" +files = [ + {file = "pillow-12.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a4e8f36e677d3336f35089648c8955c51c6d386a13cf6ee9c189c5f5bd713a9f"}, + {file = "pillow-12.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e589959f10d9824d39b350472b92f0ce3b443c0a3442ebf41c40cb8361c5b97"}, + {file = "pillow-12.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a52edc8bfff4429aaabdf4d9ee0daadbbf8562364f940937b941f87a4290f5ff"}, + {file = "pillow-12.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975385f4776fafde056abb318f612ef6285b10a1f12b8570f3647ad0d74b48ec"}, + {file = "pillow-12.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd9c0c7a0c681a347b3194c500cb1e6ca9cab053ea4d82a5cf45b6b754560136"}, + {file = "pillow-12.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88d387ff40b3ff7c274947ed3125dedf5262ec6919d83946753b5f3d7c67ea4c"}, + {file = "pillow-12.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c4167c34b0d8ba05b547a3bb23578d0ba17b80a5593f93bd8ecb123dd336a3"}, + {file = "pillow-12.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:34c0d99ecccea270c04882cb3b86e7b57296079c9a4aff88cb3b33563d95afaa"}, + {file = "pillow-12.2.0-cp310-cp310-win32.whl", hash = "sha256:b85f66ae9eb53e860a873b858b789217ba505e5e405a24b85c0464822fe88032"}, + {file = "pillow-12.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:673aa32138f3e7531ccdbca7b3901dba9b70940a19ccecc6a37c77d5fdeb05b5"}, + {file = "pillow-12.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:3e080565d8d7c671db5802eedfb438e5565ffa40115216eabb8cd52d0ecce024"}, + {file = "pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab"}, + {file = "pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65"}, + {file = "pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7"}, + {file = "pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e"}, + {file = "pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705"}, + {file = "pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176"}, + {file = "pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b"}, + {file = "pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909"}, + {file = "pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808"}, + {file = "pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60"}, + {file = "pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe"}, + {file = "pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5"}, + {file = "pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421"}, + {file = "pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987"}, + {file = "pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76"}, + {file = "pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005"}, + {file = "pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780"}, + {file = "pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5"}, + {file = "pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5"}, + {file = "pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940"}, + {file = "pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5"}, + {file = "pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414"}, + {file = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c"}, + {file = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2"}, + {file = "pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c"}, + {file = "pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795"}, + {file = "pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f"}, + {file = "pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed"}, + {file = "pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9"}, + {file = "pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed"}, + {file = "pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3"}, + {file = "pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9"}, + {file = "pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795"}, + {file = "pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e"}, + {file = "pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b"}, + {file = "pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06"}, + {file = "pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b"}, + {file = "pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f"}, + {file = "pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612"}, + {file = "pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c"}, + {file = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea"}, + {file = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4"}, + {file = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4"}, + {file = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea"}, + {file = "pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24"}, + {file = "pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98"}, + {file = "pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453"}, + {file = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8"}, + {file = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b"}, + {file = "pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295"}, + {file = "pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed"}, + {file = "pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae"}, + {file = "pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601"}, + {file = "pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be"}, + {file = "pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f"}, + {file = "pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286"}, + {file = "pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50"}, + {file = "pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104"}, + {file = "pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7"}, + {file = "pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150"}, + {file = "pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1"}, + {file = "pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463"}, + {file = "pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3"}, + {file = "pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166"}, + {file = "pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe"}, + {file = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd"}, + {file = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e"}, + {file = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06"}, + {file = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43"}, + {file = "pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354"}, + {file = "pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1"}, + {file = "pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1"}, + {file = "pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e"}, + {file = "pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] +xmp = ["defusedxml"] + [[package]] name = "platformdirs" version = "4.3.6" @@ -3072,6 +4549,25 @@ pandas = "*" scikit-learn = "*" scipy = "*" +[[package]] +name = "prettytable" +version = "3.17.0" +description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "prettytable-3.17.0-py3-none-any.whl", hash = "sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287"}, + {file = "prettytable-3.17.0.tar.gz", hash = "sha256:59f2590776527f3c9e8cf9fe7b66dd215837cca96a9c39567414cbc632e8ddb0"}, +] + +[package.dependencies] +wcwidth = "*" + +[package.extras] +tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"] + [[package]] name = "prompt-toolkit" version = "3.0.52" @@ -3211,6 +4707,46 @@ files = [ numpy = "*" scipy = "*" +[[package]] +name = "protobuf" +version = "6.33.6" +description = "" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\" or extra == \"tensorboard\"" +files = [ + {file = "protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3"}, + {file = "protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326"}, + {file = "protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a"}, + {file = "protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2"}, + {file = "protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3"}, + {file = "protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593"}, + {file = "protobuf-6.33.6-cp39-cp39-win32.whl", hash = "sha256:bd56799fb262994b2c2faa1799693c95cc2e22c62f56fb43af311cae45d26f0e"}, + {file = "protobuf-6.33.6-cp39-cp39-win_amd64.whl", hash = "sha256:f443a394af5ed23672bc6c486be138628fbe5c651ccbc536873d7da23d1868cf"}, + {file = "protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901"}, + {file = "protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135"}, +] + +[[package]] +name = "protobuf" +version = "7.35.1" +description = "" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"tensorboard\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "protobuf-7.35.1-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6"}, + {file = "protobuf-7.35.1-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799"}, + {file = "protobuf-7.35.1-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:b73f9489a4b8b1c9cb1f8ed951c736392592edb24b9d6819f36d2e10b171d5b4"}, + {file = "protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4"}, + {file = "protobuf-7.35.1-cp310-abi3-win32.whl", hash = "sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30"}, + {file = "protobuf-7.35.1-cp310-abi3-win_amd64.whl", hash = "sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87"}, + {file = "protobuf-7.35.1-py3-none-any.whl", hash = "sha256:4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9"}, + {file = "protobuf-7.35.1.tar.gz", hash = "sha256:ce115a26fe0c39a2c29973d914d327e516a6455464489fe3cd1e51a1b354f81a"}, +] + [[package]] name = "psutil" version = "7.0.0" @@ -3282,18 +4818,265 @@ PyYAML = "*" [package.extras] anchors = ["unidecode"] +[[package]] +name = "pyarrow" +version = "24.0.0" +description = "Python library for Apache Arrow" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "pyarrow-24.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:7c2b98645d576a0b9616892ead22b64a83a5f043c5e2ca15ebcefcb5b70c80cb"}, + {file = "pyarrow-24.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:644a246325b8c69c595ad1dd4b463eba4b0cdb731370e4a86137d433208d6147"}, + {file = "pyarrow-24.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:3a577bd840ca83f646f0a625dbc571dba7044c43c2d1503afc378b570954345c"}, + {file = "pyarrow-24.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:e3268e43984d0b1a185c89b4cfff282a7ead12fc93f56cfd7088bdbcbe727041"}, + {file = "pyarrow-24.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2392d954fcb920f42d230284b677605e4e2fbb11f2821e823e642abd67fbb491"}, + {file = "pyarrow-24.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bec9373df11544592b0ba7ec2af0e35059e5f0e7647c6183a854dedd193298f1"}, + {file = "pyarrow-24.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:c42ab9439498270139cc63e18847a02afe5c8b3ed9c931266533cfe378bd3591"}, + {file = "pyarrow-24.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b0e131f880cda8d04e076cee175a46fc0e8bc8b65c99c6c09dff6669335fde74"}, + {file = "pyarrow-24.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:1b2fe7f9a5566401a0ef2571f197eb92358925c1f0c8dba305d6e43ea0871bb3"}, + {file = "pyarrow-24.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:0b3537c00fb8d384f15ac1e79b6eb6db04a16514c8c1d22e59a9b95c8ba42868"}, + {file = "pyarrow-24.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:14e31a3c9e35f1ab6356c6378f6f72830e6d2d5f1791df3774a7b097d18a6a1e"}, + {file = "pyarrow-24.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7d9a514e73bc42711e6a35aaccf3587c520024fe0a25d830a1a8a27c15f4f57"}, + {file = "pyarrow-24.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b196eb3f931862af3fa84c2a253514d859c08e0d8fe020e07be12e75a5a9780c"}, + {file = "pyarrow-24.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:35405aecb474e683fb36af650618fd5340ee5471fc65a21b36076a18bbc6c981"}, + {file = "pyarrow-24.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810"}, + {file = "pyarrow-24.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a"}, + {file = "pyarrow-24.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66"}, + {file = "pyarrow-24.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb"}, + {file = "pyarrow-24.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e"}, + {file = "pyarrow-24.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6"}, + {file = "pyarrow-24.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826"}, + {file = "pyarrow-24.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba"}, + {file = "pyarrow-24.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68"}, + {file = "pyarrow-24.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2"}, + {file = "pyarrow-24.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0"}, + {file = "pyarrow-24.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495"}, + {file = "pyarrow-24.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f"}, + {file = "pyarrow-24.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91"}, + {file = "pyarrow-24.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275"}, + {file = "pyarrow-24.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b"}, + {file = "pyarrow-24.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42"}, + {file = "pyarrow-24.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b"}, + {file = "pyarrow-24.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37"}, + {file = "pyarrow-24.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca"}, + {file = "pyarrow-24.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d"}, + {file = "pyarrow-24.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838"}, + {file = "pyarrow-24.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b"}, + {file = "pyarrow-24.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795"}, + {file = "pyarrow-24.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26"}, + {file = "pyarrow-24.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde"}, + {file = "pyarrow-24.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76"}, + {file = "pyarrow-24.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e"}, + {file = "pyarrow-24.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05"}, + {file = "pyarrow-24.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a"}, + {file = "pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072"}, + {file = "pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931"}, + {file = "pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699"}, + {file = "pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136"}, + {file = "pyarrow-24.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19"}, + {file = "pyarrow-24.0.0.tar.gz", hash = "sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83"}, +] + +[[package]] +name = "pyasn1" +version = "0.6.3" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "pyasn1-0.6.3-py3-none-any.whl", hash = "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde"}, + {file = "pyasn1-0.6.3.tar.gz", hash = "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +description = "A collection of ASN.1-based protocols modules" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a"}, + {file = "pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"}, +] + +[package.dependencies] +pyasn1 = ">=0.6.1,<0.7.0" + [[package]] name = "pycparser" version = "3.0" description = "C parser in Python" optional = false python-versions = ">=3.10" -groups = ["dev", "docs"] +groups = ["main", "dev", "docs"] files = [ {file = "pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"}, {file = "pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29"}, ] -markers = {dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\" and platform_python_implementation != \"PyPy\" and implementation_name != \"PyPy\" or implementation_name == \"pypy\"", docs = "python_version >= \"3.12\" and implementation_name == \"pypy\""} +markers = {main = "platform_python_implementation != \"PyPy\" and (extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") and implementation_name != \"PyPy\"", dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\" and platform_python_implementation != \"PyPy\" and implementation_name != \"PyPy\" or implementation_name == \"pypy\"", docs = "python_version >= \"3.12\" and implementation_name == \"pypy\""} + +[[package]] +name = "pydantic" +version = "2.13.4" +description = "Data validation using Python type hints" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba"}, + {file = "pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.46.4" +typing-extensions = ">=4.14.1" +typing-inspection = ">=0.4.2" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +description = "Core functionality for Pydantic validation and serialization" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4"}, + {file = "pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01"}, + {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d"}, + {file = "pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4"}, + {file = "pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f"}, + {file = "pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39"}, + {file = "pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d"}, + {file = "pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf"}, + {file = "pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594"}, + {file = "pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398"}, + {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3"}, + {file = "pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848"}, + {file = "pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3"}, + {file = "pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109"}, + {file = "pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda"}, + {file = "pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33"}, + {file = "pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d"}, + {file = "pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2"}, + {file = "pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987"}, + {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b"}, + {file = "pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458"}, + {file = "pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b"}, + {file = "pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c"}, + {file = "pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894"}, + {file = "pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89"}, + {file = "pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a"}, + {file = "pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008"}, + {file = "pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262"}, + {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e"}, + {file = "pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd"}, + {file = "pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be"}, + {file = "pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d"}, + {file = "pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb"}, + {file = "pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292"}, + {file = "pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d"}, + {file = "pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb"}, + {file = "pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c"}, + {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb"}, + {file = "pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898"}, + {file = "pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e"}, + {file = "pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519"}, + {file = "pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4"}, + {file = "pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac"}, + {file = "pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5"}, + {file = "pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596"}, + {file = "pydantic_core-2.46.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae"}, + {file = "pydantic_core-2.46.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066"}, + {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6"}, + {file = "pydantic_core-2.46.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9"}, + {file = "pydantic_core-2.46.4-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29"}, + {file = "pydantic_core-2.46.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9"}, + {file = "pydantic_core-2.46.4-cp39-cp39-win32.whl", hash = "sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1"}, + {file = "pydantic_core-2.46.4-cp39-cp39-win_amd64.whl", hash = "sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac"}, + {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c"}, + {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b"}, + {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b"}, + {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea"}, + {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7"}, + {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df"}, + {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526"}, + {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc"}, + {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983"}, + {file = "pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1"}, +] + +[package.dependencies] +typing-extensions = ">=4.14.1" [[package]] name = "pydata-sphinx-theme" @@ -3338,6 +5121,22 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyparsing" +version = "3.3.2" +description = "pyparsing - Classes and methods to define and execute parsing grammars" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d"}, + {file = "pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pyright" version = "1.1.409" @@ -3438,6 +5237,22 @@ platformdirs = ">=4.3.6,<5" docs = ["furo (>=2025.12.19)", "sphinx (>=9.1)", "sphinx-autodoc-typehints (>=3.6.3)", "sphinxcontrib-mermaid (>=2)", "sphinxcontrib-towncrier (>=0.4)", "towncrier (>=25.8)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.5.4)", "pytest (>=8.3.5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"] +[[package]] +name = "python-dotenv" +version = "1.2.2" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a"}, + {file = "python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "pytorch-lightning" version = "2.5.0.post0" @@ -3481,6 +5296,38 @@ files = [ {file = "pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e"}, ] +[[package]] +name = "pywin32" +version = "312" +description = "Python for Windows Extensions" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "(extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") and sys_platform == \"win32\"" +files = [ + {file = "pywin32-312-cp310-cp310-win32.whl", hash = "sha256:772235332b5d1024c696f11cea1ae4be7930f0a8b894bb43db14e3f435f1ff7e"}, + {file = "pywin32-312-cp310-cp310-win_amd64.whl", hash = "sha256:5dbc35d2b5320dc07f25fa31269cfb767471002b17de5eb067d03da68c7cb2db"}, + {file = "pywin32-312-cp310-cp310-win_arm64.whl", hash = "sha256:3020656e34f1cf7faeb7bccd2b84653a607c6ff0c55ada85e6487d61716deabd"}, + {file = "pywin32-312-cp311-cp311-win32.whl", hash = "sha256:17948aeadbdb091f0ced6ef0841620794e68327b94ee415571c1203594b7215c"}, + {file = "pywin32-312-cp311-cp311-win_amd64.whl", hash = "sha256:d11417d84412f859b722fad0841b3614459ed0047f7542d8362e77884f6b6e8a"}, + {file = "pywin32-312-cp311-cp311-win_arm64.whl", hash = "sha256:b2200a054ca6d6625c4842fc56a4976a4b47f96b73dbe5538c3f813a80359f47"}, + {file = "pywin32-312-cp312-cp312-win32.whl", hash = "sha256:dab4f65ac9c4e48400a2a0530c46c3c579cd5905ecd11b80692373915269208b"}, + {file = "pywin32-312-cp312-cp312-win_amd64.whl", hash = "sha256:b457f6d628a47e8a7346ce22acb7e1a46a4a78b52e1d17e1af56871bd19a93bc"}, + {file = "pywin32-312-cp312-cp312-win_arm64.whl", hash = "sha256:6017c58e12f6809fbb0555b75df144c2922a9ffd18e4b9b5afa863b6c1a9d950"}, + {file = "pywin32-312-cp313-cp313-win32.whl", hash = "sha256:7a27df850933d16a8eabfbaeb73d52b273e2da667f80d70b01a89d1f6828d02c"}, + {file = "pywin32-312-cp313-cp313-win_amd64.whl", hash = "sha256:c53e878d15a1c44788082bfe712a905433473aa38f86375b7cf8b45e3acbaaf9"}, + {file = "pywin32-312-cp313-cp313-win_arm64.whl", hash = "sha256:59aba5d5940842075343a5ddc6b11f1cdf0d1567fe745290359dfbcc7c2eb831"}, + {file = "pywin32-312-cp314-cp314-win32.whl", hash = "sha256:a77a90fbb6881238d2ca9c6fd797b25817f3768fe78d214a90137ff055a75f5b"}, + {file = "pywin32-312-cp314-cp314-win_amd64.whl", hash = "sha256:a4dd3a848290ef724347b19f301045831d8e802fa4464f491b98b1e0a081432e"}, + {file = "pywin32-312-cp314-cp314-win_arm64.whl", hash = "sha256:9fce94568364e0155e6dfb781ac5d95903be8baf28670632beab1b523f300daa"}, + {file = "pywin32-312-cp315-cp315-win32.whl", hash = "sha256:5c1fbe4a937a73ae9297384a3da38518cbc694c68ad8a809b2e19acd350f03ed"}, + {file = "pywin32-312-cp315-cp315-win_amd64.whl", hash = "sha256:c2f03a0f73f804a13c2735b99392b0cd426bb4f2c4d0178e5ac966a0f21618d5"}, + {file = "pywin32-312-cp315-cp315-win_arm64.whl", hash = "sha256:a8597d28f267b39074aef51fa593530082b39cbe5a074226096857b1fed2dfb9"}, + {file = "pywin32-312-cp39-cp39-win32.whl", hash = "sha256:d620900033cc7531e50727c3c8333091df5dd3ffe6d68cdca38c03f5821408d5"}, + {file = "pywin32-312-cp39-cp39-win_amd64.whl", hash = "sha256:dc90147579a905b8635e1b0ec6514967dcb07e6e0d9c42f1477feef14cac23bb"}, + {file = "pywin32-312-cp39-cp39-win_arm64.whl", hash = "sha256:02ebca0f0242b75292e218065004310d6a477407c09fa449bfe4f6022bc0c0fc"}, +] + [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -4204,6 +6051,42 @@ files = [ ] markers = {docs = "python_version >= \"3.12\""} +[[package]] +name = "skops" +version = "0.14.0" +description = "A set of tools, related to machine learning in production." +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "skops-0.14.0-py3-none-any.whl", hash = "sha256:60a5db78a9db46ccee2139a0ba13ab5afb1c96f4749b382e75a371291bbe3e36"}, + {file = "skops-0.14.0.tar.gz", hash = "sha256:6c8c0e047f691a3a582c3258943eecafcbfd79c8c7eef66260f3703e363254f0"}, +] + +[package.dependencies] +numpy = ">=1.25.0" +packaging = ">=17.0" +prettytable = ">=3.9" +scikit-learn = ">=1.2" +scipy = ">=1.10.0" + +[package.extras] +rich = ["rich (>=12)"] + +[[package]] +name = "smmap" +version = "5.0.3" +description = "A pure Python implementation of a sliding window memory map manager" +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f"}, + {file = "smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c"}, +] + [[package]] name = "snowballstemmer" version = "3.0.1" @@ -4575,6 +6458,121 @@ Sphinx = ">=6.0" rtd = ["furo (>=2024)", "sphinx (>=8.1.0,<8.2.0)", "sphinx-design"] social-cards = ["matplotlib (>=3)"] +[[package]] +name = "sqlalchemy" +version = "2.0.51" +description = "Database Abstraction Library" +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "sqlalchemy-2.0.51-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e8203d2fbd5c6254692ef0a72c740d75b2f3c7ca345404f4c1a4604813c77c0"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1af05726b3d0cdba1c55284bf408fd3b792e690fe2399bfb8304565551cda652"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e54ff2dd657f2e3e0fbf2b097db1182f7bfea263eca4353f00065bae2a67c3d"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1e47b1199c2e832e325eacabc8d32d2487f58c9358f97e9a00f5eb93c5680d84"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c68568f3facf8f66fa76c60e0ced69b67666ffa9941d1d0a3756fda196049080"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-win32.whl", hash = "sha256:0592bdadf86ddcabfd72d9ab66ea8a5d8d2cc6be1cc51fa7e66c03868ac5eac1"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-win_amd64.whl", hash = "sha256:740cf6f35351b1ac3d82369152acf1d51d37e3dcf85d4dc0a22ca01410eabe2a"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1aa10c0daee6705294d181daadaa793221e1a59ed55000a3fab1d42b088ce4ba"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5b2ed6d828f1f09bd812861f4f59ca3bc3803f9df871f4555187f0faf018604"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:436728ce18a80f6951a1e11cc6112c2ede9faf20766f1a26195a7c441ca12dbd"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dc261707bf5739aea8a541593f3cc1d463c2701fb05fbcbba0ce031b69a21260"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a6d26094615306d116dd5e4a51b0304c99dd2356fc569eed6922a80a6bd3b265"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-win32.whl", hash = "sha256:ca8435d13829b92f4a97362d91975154a4015db3a2634154e1754e9a915e6b86"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-win_amd64.whl", hash = "sha256:4a011ea4510683319ce4ed274b56ee05194b39b6da9d09ca7a39388f0fa84dcc"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d78702b26ba1c18b2d0fb2ea940ba7f17a9581b42e8361ff93920ebbee1235a"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581921d849d6e6f994d560389192955e80e2950e18fcdfe2ccea863e01158e6e"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1d21ce524ab86c23046e992a5b81cb54c21079c6df6e78b8fc77d77cac70a6b9"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c5d98a2709840027f5a347c3af0a7c3d5f6c1ff93af2ca1c54494e23cba8f389"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1181256e0f16479691b5616d36375dc2620ad8332b25978763c3d206ad3f3f1d"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-win32.whl", hash = "sha256:9f380393be5abeb6815f68fd39271b95127173511b6706b0a630a9995d53f8f5"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-win_amd64.whl", hash = "sha256:2cf39aabdf48e87c1c2c2ed6d20d33ffa0733b3071ce9c5f66357947dd009080"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c2056838b6685b72fdb36c99996cf862753461a62f2e84f4196371d3b2d6a07"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483b11bd46bf35fc14c52faf338b04300c9e6ce554bce9b11be85bfec3bc3195"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1bed1ee8b01da6088210aa9412023326fb98a599ba502e6118308601dcbef77f"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:72ca54c952107ba5cd58854b67a5a6268631289d21651a1235396f3b98b47400"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e693d15533a45cd5906f0589f9c35090bef6ef45bf1e8195c424aa0ae06a8d"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-win32.whl", hash = "sha256:b93ab07b5292dbe7e6b8da89475275e7042744283921344b56105f3eeb0f828b"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-win_amd64.whl", hash = "sha256:0f053118c30e53161857a953e4de667d90e274980dccbe5dd3829bbbeece72a5"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6ea306caaae6bd5afd0a46050003c88f6bf33227377a49298c498c3cb88ff491"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c45a496d6bc05dec41dcd4c3a2b183723f47473255c159cd80b503c8f246424d"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4004ada0aafe8ae1991b2cd1d99c6d9146126e123bd6f883c260d974aa012e54"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f6bcad487aee1c638d707235682fc96f741de00663619881ab235400d03289e"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:39a76529db6305693d8d4affa58ad5b5e2e18edd62daea628b29b97930b3513d"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-win32.whl", hash = "sha256:08a204d8b5638717c26a24df18fcf40af45a6b22e35b70b1d62f0113c2e278e8"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-win_amd64.whl", hash = "sha256:96747bfbadb055466e5b46d572618170046b45ce5a4879167f50d70a5319a499"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1a213be1fcd5e49d9904c3b9939211ded90bc2a64e93f4c01963474285de"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c6b36ed71f41942bdcd2ad2522be46bfce09d5705be5640ecf19bbc7660e4b7"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c2c62877097e1a0db401fba5cb4debee33265e5b2a55c4ccb489c02c53b4f72"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0378d055e9e8cd6ce4d8dff683bdd3d7d413533c4ee51d67a2b1e0f9eacc0f23"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e46fc36029eff666391e0531e5387b62ce6c4f1d8e50b3fb3099eaca1b42522"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-win32.whl", hash = "sha256:9161cfc9efce70d1715f47d6ff40f79c6778c00d53be4fbc09d70301e4b83ba7"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-win_amd64.whl", hash = "sha256:159bb6ba32059f57ad7375a8f50d844dd2f19d14954ecf820cd33e20debd46b2"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bb1f5062f98b0b3290e72b707747fdd7e0f22d6956b236ba7ca7f5c9971d2da2"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:247acaa29ccef6250dfd6a3eedf8f94ddf23564180a39fe362e32ae9dbdbde46"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c95ef01f53233a305a874a44a63fbfb1d81cd79b49de0f8529b3548cde437e37"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fa268106c8987639a17a18514cfe0cd9bf17420ab887e1e1bf486da8836135b1"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b7f08588854bbb724041d9ae9d980d40040c922382e1d9a2ecb390edc4fd5032"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-win32.whl", hash = "sha256:6b588fd681ddf0c196b8df1ea49a8913514894b2b8f945a9511b4b48871f99c8"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-win_amd64.whl", hash = "sha256:ca216e8af5c05e326efc7e28716ac2381a7cf9791749f5ee1849dccdc99c9b00"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aa18ae738b5170e253ad0bb6c4b0f07585081e8a6e50893e4d911d47b39a0904"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:59cab3686b1bc039dd9cded2f8d0c08a246e84e76bd4ab5b4f18c7cdae293825"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:111604e637da87031255ddc26c7d7bc22bc6af6f5d459ccff3af1b4660233a85"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad30ae663711786303fbcd46a47516302d201ee49a877cb3fac61f672895110a"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b21f0e7efc7a5c509e953784e9d1575ebb8b4318960e7e7d7a93bb803626cf64"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-win32.whl", hash = "sha256:a42ad6afcbaaa777241e347aa2e29155993045a0d6b7db74da61053ffe875fe0"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-win_amd64.whl", hash = "sha256:2a97eaad21c84b4ef8010b11eeba9fe6153eb0b3df3ff8b6abc309df1b978ef7"}, + {file = "sqlalchemy-2.0.51-py3-none-any.whl", hash = "sha256:bb024d8b621d0be75f4f44ecc7c950450026e76d66dc8f791bb5331d7fed59d5"}, + {file = "sqlalchemy-2.0.51.tar.gz", hash = "sha256:804dccd8a4a6242c4e30ad961e540e18a588f6527202f2d6791b01845d59fdc9"}, +] + +[package.dependencies] +greenlet = {version = ">=1", markers = "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\""} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] +aioodbc = ["aioodbc", "greenlet (>=1)"] +aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (>=1)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "sqlparse" +version = "0.5.5" +description = "A non-validating SQL parser." +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba"}, + {file = "sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e"}, +] + +[package.extras] +dev = ["build"] +doc = ["sphinx"] + [[package]] name = "stack-data" version = "0.6.3" @@ -4595,6 +6593,42 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "starlette" +version = "1.3.1" +description = "The little ASGI library that shines." +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "starlette-1.3.1-py3-none-any.whl", hash = "sha256:c7372aae11c3c3f26a42df7bd626cec2f47d03483d261d369516a615a53714c6"}, + {file = "starlette-1.3.1.tar.gz", hash = "sha256:05d0213193f2fbaae60e2ecb593b4add4262ad4e46536b54abe36f11a71724e0"}, +] + +[package.dependencies] +anyio = ">=3.6.2,<5" +typing-extensions = {version = ">=4.10.0", markers = "python_version < \"3.13\""} + +[package.extras] +full = ["httpx (>=0.27.0,<0.29.0)", "httpx2 (>=2.0.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"] + +[[package]] +name = "structlog" +version = "26.1.0" +description = "Structured Logging for Python" +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"logs\" or extra == \"all\"" +files = [ + {file = "structlog-26.1.0-py3-none-any.whl", hash = "sha256:e081a26d6c373e6d201eca24eede26d8ffab07f88f477822e679183428d3d91e"}, + {file = "structlog-26.1.0.tar.gz", hash = "sha256:f63a716cbd1b1291cf7661de7794b455acfa4c43c5bcf1630e6ad5ddc1adb3b7"}, +] + +[package.dependencies] +typing-extensions = {version = "*", markers = "python_version < \"3.11\""} + [[package]] name = "sympy" version = "1.14.0" @@ -4613,6 +6647,44 @@ mpmath = ">=1.1.0,<1.4" [package.extras] dev = ["hypothesis (>=6.70.0)", "pytest (>=7.1.0)"] +[[package]] +name = "tensorboard" +version = "2.20.0" +description = "TensorBoard lets you watch Tensors Flow" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"tensorboard\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "tensorboard-2.20.0-py3-none-any.whl", hash = "sha256:9dc9f978cb84c0723acf9a345d96c184f0293d18f166bb8d59ee098e6cfaaba6"}, +] + +[package.dependencies] +absl-py = ">=0.4" +grpcio = ">=1.48.2" +markdown = ">=2.6.8" +numpy = ">=1.12.0" +packaging = "*" +pillow = "*" +protobuf = ">=3.19.6,<4.24.0 || >4.24.0" +setuptools = ">=41.0.0" +tensorboard-data-server = ">=0.7.0,<0.8.0" +werkzeug = ">=1.0.1" + +[[package]] +name = "tensorboard-data-server" +version = "0.7.2" +description = "Fast data loading for TensorBoard" +optional = true +python-versions = ">=3.7" +groups = ["main"] +markers = "extra == \"tensorboard\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "tensorboard_data_server-0.7.2-py3-none-any.whl", hash = "sha256:7e0610d205889588983836ec05dc098e80f97b7e7bbff7e994ebb78f578d0ddb"}, + {file = "tensorboard_data_server-0.7.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9fe5d24221b29625dbc7328b0436ca7fc1c23de4acf4d272f1180856e32f9f60"}, + {file = "tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl", hash = "sha256:ef687163c24185ae9754ed5650eb5bc4d84ff257aabdc33f0cc6f74d8ba54530"}, +] + [[package]] name = "termcolor" version = "2.5.0" @@ -4666,8 +6738,7 @@ version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" -groups = ["dev", "docs"] -markers = "python_version == \"3.10\"" +groups = ["main", "dev", "docs"] files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -4702,6 +6773,7 @@ files = [ {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] +markers = {main = "(extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") and python_version == \"3.10\"", dev = "python_version == \"3.10\"", docs = "python_version == \"3.10\""} [[package]] name = "tomlkit" @@ -4814,22 +6886,22 @@ visual = ["SciencePlots (>=2.0.0)", "matplotlib (>=3.6.0)"] [[package]] name = "tornado" -version = "6.5.5" +version = "6.5.7" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">=3.9" groups = ["dev", "docs"] files = [ - {file = "tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa"}, - {file = "tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521"}, - {file = "tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5"}, - {file = "tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07"}, - {file = "tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e"}, - {file = "tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca"}, - {file = "tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7"}, - {file = "tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b"}, - {file = "tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6"}, - {file = "tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9"}, + {file = "tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163"}, + {file = "tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100"}, + {file = "tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972"}, + {file = "tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b"}, + {file = "tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92"}, + {file = "tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5"}, + {file = "tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4"}, + {file = "tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4"}, + {file = "tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796"}, + {file = "tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2"}, ] markers = {docs = "python_version >= \"3.12\""} @@ -4939,6 +7011,22 @@ files = [ {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, ] +[[package]] +name = "typing-inspection" +version = "0.4.2" +description = "Runtime typing introspection tools" +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"}, + {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"}, +] + +[package.dependencies] +typing-extensions = ">=4.12.0" + [[package]] name = "tzdata" version = "2025.1" @@ -4980,6 +7068,27 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] +[[package]] +name = "uvicorn" +version = "0.49.0" +description = "The lightning-fast ASGI server." +optional = true +python-versions = ">=3.10" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"" +files = [ + {file = "uvicorn-0.49.0-py3-none-any.whl", hash = "sha256:ba3d14c3ee7e41c6c654c46c9eb489d33213cdd30aa1696eab1374337c13f68f"}, + {file = "uvicorn-0.49.0.tar.gz", hash = "sha256:ebf4271aa580d9de97f93192d4595176df6e91f9aae919ca73e4fc07df1e66a3"}, +] + +[package.dependencies] +click = ">=7.0" +h11 = ">=0.8" +typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} + +[package.extras] +standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.8.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.20)", "websockets (>=10.4)"] + [[package]] name = "virtualenv" version = "21.3.3" @@ -4999,17 +7108,35 @@ platformdirs = ">=3.9.1,<5" python-discovery = ">=1.3.1" typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} +[[package]] +name = "waitress" +version = "3.0.2" +description = "Waitress WSGI server" +optional = true +python-versions = ">=3.9.0" +groups = ["main"] +markers = "(extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\") and platform_system == \"Windows\"" +files = [ + {file = "waitress-3.0.2-py3-none-any.whl", hash = "sha256:c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e"}, + {file = "waitress-3.0.2.tar.gz", hash = "sha256:682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f"}, +] + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] +testing = ["coverage (>=7.6.0)", "pytest", "pytest-cov"] + [[package]] name = "wcwidth" version = "0.2.14" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = ">=3.6" -groups = ["dev", "docs"] +groups = ["main", "dev", "docs"] files = [ {file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"}, {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"}, ] +markers = {main = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\""} [[package]] name = "webencodings" @@ -5024,6 +7151,25 @@ files = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] +[[package]] +name = "werkzeug" +version = "3.1.8" +description = "The comprehensive WSGI web application library." +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\" or extra == \"tensorboard\"" +files = [ + {file = "werkzeug-3.1.8-py3-none-any.whl", hash = "sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50"}, + {file = "werkzeug-3.1.8.tar.gz", hash = "sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44"}, +] + +[package.dependencies] +markupsafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + [[package]] name = "wheel" version = "0.47.0" @@ -5142,12 +7288,12 @@ version = "3.23.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" -groups = ["dev"] -markers = "python_version < \"3.12\" and platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +groups = ["main", "dev"] files = [ {file = "zipp-3.23.1-py3-none-any.whl", hash = "sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc"}, {file = "zipp-3.23.1.tar.gz", hash = "sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110"}, ] +markers = {main = "extra == \"mlflow\" or extra == \"tracking\" or extra == \"all\"", dev = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and python_version < \"3.12\""} [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] @@ -5158,13 +7304,13 @@ test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_it type = ["pytest-mypy"] [extras] -all = [] -logs = [] -mlflow = [] -tensorboard = [] -tracking = [] +all = ["mlflow", "structlog", "tensorboard"] +logs = ["structlog"] +mlflow = ["mlflow"] +tensorboard = ["tensorboard"] +tracking = ["mlflow", "tensorboard"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.14" -content-hash = "79e5654b6ff2b98f77860532ade72fbdc5dc3385edae719782de1d6b3a95cb59" +content-hash = "581a49528a7bf187eb6a40a8c8275c34cdd584211d790ce7278a610d00dfc4a3" diff --git a/pyproject.toml b/pyproject.toml index 4fd50399..0a086cb3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,20 +1,37 @@ -[tool.poetry] +[project] name = "deeptab" +version = "2.0.0" +description = "Tabular deep learning made simple: a scikit-learn compatible model zoo built on PyTorch and Lightning." +authors = [ + { name = "Anton Thielmann" }, + { name = "Manish Kumar" }, + { name = "Christoph Weisser" }, +] +readme = "README.md" +requires-python = ">=3.10,<3.14" +dynamic = ["dependencies"] -version = "1.8.0" +[project.optional-dependencies] +logs = ["structlog>=24.0,<27.0"] +mlflow = ["mlflow>=2.10,<4.0"] +tensorboard = ["tensorboard>=2.14,<3.0"] +tracking = ["mlflow>=2.10,<4.0", "tensorboard>=2.14,<3.0"] +all = ["structlog>=24.0,<27.0", "mlflow>=2.10,<4.0", "tensorboard>=2.14,<3.0"] +[project.urls] +homepage = "https://github.com/OpenTabular/deeptab" +documentation = "https://deeptab.readthedocs.io/" +repository = "https://github.com/OpenTabular/deeptab" +package = "https://pypi.org/project/deeptab/" -description = "A python package for tabular deep learning." -authors = ["Anton Thielmann", "Manish Kumar", "Christoph Weisser"] -readme = "README.md" +[tool.poetry] packages = [{ include = "deeptab" }] [build-system] -requires = ["poetry-core"] +requires = ["poetry-core>=2.0"] build-backend = "poetry.core.masonry.api" [tool.poetry.dependencies] -python = ">=3.10,<3.14" numpy = "^2.0.0" pandas = "^2.0.3" lightning = "^2.3.3" @@ -31,13 +48,6 @@ pretab = "^0.0.1" delu = "*" faiss-cpu = "*" -[tool.poetry.extras] -logs = ["structlog"] -mlflow = ["mlflow"] -tensorboard = ["tensorboard"] -tracking = ["mlflow", "tensorboard"] -all = ["structlog", "mlflow", "tensorboard"] - [tool.poetry.group.dev.dependencies] pytest = "^9.0" pytest-cov = "^4.1" @@ -68,13 +78,6 @@ sphinxcontrib-mermaid = "*" sphinxext-opengraph = "*" -[tool.poetry.urls] -homepage = "https://github.com/OpenTabular/deeptab" -documentation = "https://deeptab.readthedocs.io/" -repository = "https://github.com/OpenTabular/deeptab" -package = "https://pypi.org/project/deeptab/" - - # test configuration [tool.pytest.ini_options] pythonpath = ["."] @@ -176,7 +179,9 @@ max-doc-length = 120 # Commitizen configuration [tool.commitizen] name = "cz_conventional_commits" -version_provider = "poetry" +version_provider = "pep621" tag_format = "v$version" update_changelog_on_bump = true major_version_zero = false +prerelease_offset = 1 +changelog_merge_prerelease = true diff --git a/tests/test_hardware.py b/tests/test_hardware.py new file mode 100644 index 00000000..b7123cdd --- /dev/null +++ b/tests/test_hardware.py @@ -0,0 +1,65 @@ +"""Tests for the hardware-detection utilities in :mod:`deeptab.core.hardware`. + +These verify the structured report shape, that the helpers never raise on a +machine without a GPU, and that ``detailed=True`` adds the expected keys. +""" + +from __future__ import annotations + +import torch + +from deeptab import print_hardware_info +from deeptab.core.hardware import get_hardware_info + + +def test_summary_has_expected_top_level_keys() -> None: + info = get_hardware_info() + assert set(info) == {"platform", "cpu", "cuda", "mps", "recommended_accelerator"} + + +def test_platform_and_cpu_fields_are_populated() -> None: + info = get_hardware_info() + assert info["platform"]["torch"] == torch.__version__ + assert isinstance(info["cpu"]["logical_cores"], int) + assert info["cpu"]["logical_cores"] >= 1 + + +def test_availability_flags_match_torch() -> None: + info = get_hardware_info() + assert info["cuda"]["available"] == torch.cuda.is_available() + assert info["cuda"]["device_count"] == (torch.cuda.device_count() if torch.cuda.is_available() else 0) + assert isinstance(info["mps"]["available"], bool) + + +def test_recommended_accelerator_is_consistent() -> None: + info = get_hardware_info() + accel = info["recommended_accelerator"] + assert accel in {"cuda", "mps", "cpu"} + if info["cuda"]["available"]: + assert accel == "cuda" + elif info["mps"]["available"]: + assert accel == "mps" + else: + assert accel == "cpu" + + +def test_detailed_adds_build_versions() -> None: + info = get_hardware_info(detailed=True) + assert "built_version" in info["cuda"] + assert "cudnn_version" in info["cuda"] + assert "processor" in info["platform"] + assert info["platform"]["executable"] + + +def test_detailed_cuda_devices_carry_memory_fields() -> None: + info = get_hardware_info(detailed=True) + for device in info["cuda"]["devices"]: + assert {"total_memory_gb", "free_memory_gb", "compute_capability"} <= set(device) + + +def test_print_does_not_raise(capsys) -> None: + print_hardware_info() + print_hardware_info(detailed=True) + out = capsys.readouterr().out + assert "DeepTab hardware report" in out + assert "Recommended accelerator:" in out diff --git a/tests/test_models.py b/tests/test_models.py index ce63a2cf..01332770 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -14,6 +14,7 @@ import pytest from sklearn.model_selection import train_test_split +from deeptab import set_seed from deeptab.models import ( ENODELSS, MLPLSS, @@ -434,6 +435,8 @@ def test_tabtransformer_fit_predict(cls, task, classification_data_with_cat, reg @pytest.mark.parametrize("cls", EXPERIMENTAL_CLASSIFIERS) def test_experimental_classifier_fit_predict_evaluate(cls, classification_data): + # Experimental models are numerically less stable; seed for deterministic CI. + set_seed(RANDOM_STATE) X_train, X_test, y_train, y_test = classification_data model = cls() model.fit(X_train, y_train, **FIT_KWARGS) @@ -460,6 +463,8 @@ def test_experimental_classifier_fit_predict_evaluate(cls, classification_data): @pytest.mark.parametrize("cls", EXPERIMENTAL_REGRESSORS) def test_experimental_regressor_fit_predict_evaluate(cls, regression_data): + # Experimental models are numerically less stable; seed for deterministic CI. + set_seed(RANDOM_STATE) X_train, X_test, y_train, y_test = regression_data model = cls() model.fit(X_train, y_train, **FIT_KWARGS) @@ -476,6 +481,8 @@ def test_experimental_regressor_fit_predict_evaluate(cls, regression_data): @pytest.mark.parametrize("cls", EXPERIMENTAL_LSS_MODELS) def test_experimental_lss_fit_predict_evaluate(cls, regression_data): + # Experimental models are numerically less stable; seed for deterministic CI. + set_seed(RANDOM_STATE) X_train, X_test, y_train, y_test = regression_data model = cls() model.fit(X_train, y_train, family="normal", **FIT_KWARGS) diff --git a/tests/test_observability.py b/tests/test_observability.py index e4613771..b6f7205c 100644 --- a/tests/test_observability.py +++ b/tests/test_observability.py @@ -158,24 +158,8 @@ def test_build_lightning_loggers_unknown_tracker_raises(): def test_build_lightning_loggers_mlflow_absent(monkeypatch): """ImportError with install hint when mlflow is not installed.""" - # Simulate mlflow being absent by blocking its import inside Lightning - real_import = __builtins__.__import__ if hasattr(__builtins__, "__import__") else __import__ # type: ignore[attr-defined] - - def _block_mlflow(name, *args, **kwargs): - if "MLFlowLogger" in name or (len(args) >= 3 and "MLFlowLogger" in str(args[2])): - raise ImportError("No module named 'mlflow'") - return real_import(name, *args, **kwargs) - - # Use monkeypatch on the lightning loggers module directly - mock_module = MagicMock() - mock_module.MLFlowLogger.side_effect = ImportError("No module named 'mlflow'") - - import lightning.pytorch.loggers as lpl - - original_MLFlowLogger = getattr(lpl, "MLFlowLogger", None) - - # Patch lightning.pytorch.loggers so that importing MLFlowLogger raises - monkeypatch.setitem(sys.modules, "lightning.pytorch.loggers", None) # type: ignore[arg-type] + # The guard checks the actual ``mlflow`` package, so simulate its absence. + monkeypatch.setitem(sys.modules, "mlflow", None) # type: ignore[arg-type] cfg = ObservabilityConfig(experiment_trackers=["mlflow"]) with pytest.raises(ImportError, match="pip install 'deeptab\\[mlflow\\]'"): build_lightning_loggers(cfg) @@ -183,7 +167,8 @@ def _block_mlflow(name, *args, **kwargs): def test_build_lightning_loggers_tensorboard_absent(monkeypatch): """ImportError with install hint when tensorboard is not installed.""" - monkeypatch.setitem(sys.modules, "lightning.pytorch.loggers", None) # type: ignore[arg-type] + # The guard checks ``torch.utils.tensorboard``, so simulate its absence. + monkeypatch.setitem(sys.modules, "torch.utils.tensorboard", None) # type: ignore[arg-type] cfg = ObservabilityConfig(experiment_trackers=["tensorboard"]) with pytest.raises(ImportError, match="pip install 'deeptab\\[tensorboard\\]'"): build_lightning_loggers(cfg) @@ -192,6 +177,11 @@ def test_build_lightning_loggers_tensorboard_absent(monkeypatch): def test_build_lightning_loggers_user_logger_does_not_replace(monkeypatch): """User-provided logger is appended alongside built-in trackers.""" user_logger = _FakeLogger() + # Stub the optional tensorboard import guard so the test does not depend on + # the 'tensorboard' package being installed in the environment. + fake_tb_mod = ModuleType("torch.utils.tensorboard") + fake_tb_mod.SummaryWriter = MagicMock() # type: ignore[attr-defined] + monkeypatch.setitem(sys.modules, "torch.utils.tensorboard", fake_tb_mod) # Mock TensorBoardLogger fake_tb = MagicMock() fake_lpl = MagicMock()