From 7b26c9af069db6554b0adaaff08abecfcee58259 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Tue, 11 Nov 2025 16:53:31 -0800 Subject: [PATCH 01/21] feat(sportsbooks): dockerized Airflow + Postgres pipeline --- src/sportsbook_webscraper_pipeline/Dockerfile | 18 + src/sportsbook_webscraper_pipeline/README.md | 73 + .../airflow/airflow.cfg | 2609 +++++++++++++++++ .../airflow/airflow.db | Bin 0 -> 1495040 bytes .../airflow/dags/migrate_to_postgres.py | 68 + .../airflow/dags/nba_props_dag.py | 59 + ...mple_auth_manager_passwords.json.generated | 1 + .../api_scripts/fetch_bettingpros.py | 228 ++ .../api_scripts/fetch_draftedge.py | 191 ++ .../api_scripts/fetch_prizepicks.py | 147 + .../test_scripts/bettingpros_webscraper.py | 189 ++ .../test_scripts/requests_webscrape.py | 92 + .../docker-compose.yml | 40 + .../requirements.txt | 13 + 14 files changed, 3728 insertions(+) create mode 100644 src/sportsbook_webscraper_pipeline/Dockerfile create mode 100644 src/sportsbook_webscraper_pipeline/README.md create mode 100644 src/sportsbook_webscraper_pipeline/airflow/airflow.cfg create mode 100644 src/sportsbook_webscraper_pipeline/airflow/airflow.db create mode 100644 src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py create mode 100644 src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py create mode 100644 src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated create mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py create mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py create mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py create mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py create mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py create mode 100644 src/sportsbook_webscraper_pipeline/docker-compose.yml create mode 100644 src/sportsbook_webscraper_pipeline/requirements.txt diff --git a/src/sportsbook_webscraper_pipeline/Dockerfile b/src/sportsbook_webscraper_pipeline/Dockerfile new file mode 100644 index 0000000..9e31413 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/Dockerfile @@ -0,0 +1,18 @@ +FROM apache/airflow:3.0.0-python3.10 + +USER root +RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/* + +USER airflow +WORKDIR /opt/airflow + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY airflow/dags /opt/airflow/dags +COPY airflow_pipeline /opt/airflow/airflow_pipeline + +ENV PYTHONPATH="/opt/airflow/airflow_pipeline:${PYTHONPATH}" +ENV AIRFLOW_HOME=/opt/airflow + +CMD ["airflow", "standalone"] diff --git a/src/sportsbook_webscraper_pipeline/README.md b/src/sportsbook_webscraper_pipeline/README.md new file mode 100644 index 0000000..e13060d --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/README.md @@ -0,0 +1,73 @@ +# webscrape +Dockerized Airflow pipeline that scrapes NBA player prop lines using scripts under airflow_pipeline/api_scripts, normalizes and appends the results into Postgres on docker +itself. Airflow scheduled to run the nba_props_dag daily. + +--- + +## Prerequisites +- Docker Desktop (or Docker Engine) with Compose v2 +- Optional: Python 3.10+ if you want to run the scraper scripts locally + +--- + +## Quick start (Docker) + +1. **Configure** + ```bash + git clone + cd webscrape + ``` + The Airflow container reads DB credentials from the environment (`DB_USERNAME`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT`, `DB_NAME`). Defaults target the Postgres service defined in `docker-compose.yml` (`line_dancer / sportsbook_data @ postgres:5432 / nba_deeplearning`). Update either `.env` or the compose file if you need different values. + +2. **Build and launch** + ```bash + docker compose down # don't dompose down -v: will wipe old containers/volumes, as + # well as the postgres database + docker compose up -d # no need to build + + docker ps # check container status + + ``` + This starts: + - `postgres`: stores the scraped data (volume `postgres_data` keeps rows between runs, exposed on `localhost:5433`) + - `airflow`: runs Airflow 3 with SequentialExecutor + SQLite metadata, but connects to the Postgres service for ETL output + +3. **Access Airflow** + - UI: http://localhost:8080 + - Credentials: `admin` / `M7fhanqeB2mUPSpe` (set in `docker-compose.yml`; rotate before sharing externally) + +4. **Trigger the DAG** + - In the UI, unpause `nba_sportsbook_pipeline` and click “Trigger DAG” + - Or via CLI: + ```bash + docker compose exec airflow airflow dags test nba_sportsbook_pipeline $(date +%Y-%m-%d) + ``` + The DAG imports `migrate_to_postgres.py`, which runs the BettingPros, PrizePicks, and DraftEdge scrapers, validates the schema, and appends rows into the `player_lines` table inside Postgres. + +5. **Inspect the database** + ```bash + psql -h localhost -p 5433 -U line_dancer -d nba_deeplearning + \dt + SELECT COUNT(*) FROM player_lines; + + + docker exec -it webscrape-postgres-1 psql -U line_dancer -d nba_deeplearning; + ``` + +6. **Stop / clean up** + ```bash + docker compose down # keep scraped data + docker compose down -v # remove containers + Postgres volume // DON'T DO THIS + ``` + +--- + +## Local development (optional) +- Install dependencies: `pip install -r requirements.txt` +- Export the same `DB_*` vars as the container and run `python airflow/dags/migrate_to_postgres.py` to append data without Airflow. + +--- + +## Notes +- Airflow metadata stays on SQLite (default) so Postgres holds only the scraper output. +- Update secrets (`DB_PASSWORD`, Airflow admin password) before committing or sharing the project. diff --git a/src/sportsbook_webscraper_pipeline/airflow/airflow.cfg b/src/sportsbook_webscraper_pipeline/airflow/airflow.cfg new file mode 100644 index 0000000..97fc37f --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow/airflow.cfg @@ -0,0 +1,2609 @@ +[core] +# The folder where your airflow pipelines live, most likely a +# subfolder in a code repository. This path must be absolute. +# +# Variable: AIRFLOW__CORE__DAGS_FOLDER +# +dags_folder = /Users/omkar/CursorProjects/webscrape/airflow/dags + +# Hostname by providing a path to a callable, which will resolve the hostname. +# The format is "package.function". +# +# For example, default value ``airflow.utils.net.getfqdn`` means that result from patched +# version of `socket.getfqdn() `__, +# see related `CPython Issue `__. +# +# No argument should be required in the function specified. +# If using IP address as hostname is preferred, use value ``airflow.utils.net.get_host_ip_address`` +# +# Variable: AIRFLOW__CORE__HOSTNAME_CALLABLE +# +hostname_callable = airflow.utils.net.getfqdn + +# A callable to check if a python file has airflow dags defined or not and should +# return ``True`` if it has dags otherwise ``False``. +# If this is not provided, Airflow uses its own heuristic rules. +# +# The function should have the following signature +# +# .. code-block:: python +# +# def func_name(file_path: str, zip_file: zipfile.ZipFile | None = None) -> bool: ... +# +# Variable: AIRFLOW__CORE__MIGHT_CONTAIN_DAG_CALLABLE +# +might_contain_dag_callable = airflow.utils.file.might_contain_dag_via_default_heuristic + +# Default timezone in case supplied date times are naive +# can be `UTC` (default), `system`, or any `IANA ` +# timezone string (e.g. Europe/Amsterdam) +# +# Variable: AIRFLOW__CORE__DEFAULT_TIMEZONE +# +default_timezone = utc + +# The executor class that airflow should use. Choices include +# ``LocalExecutor``, ``CeleryExecutor``, +# ``KubernetesExecutor`` or the full import path to the class when using a custom executor. +# +# Variable: AIRFLOW__CORE__EXECUTOR +# +executor = LocalExecutor + +# The auth manager class that airflow should use. Full import path to the auth manager class. +# +# Variable: AIRFLOW__CORE__AUTH_MANAGER +# +auth_manager = airflow.api_fastapi.auth.managers.simple.simple_auth_manager.SimpleAuthManager + +# The list of users and their associated role in simple auth manager. If the simple auth manager is +# used in your environment, this list controls who can access the environment. +# +# List of user-role delimited with a comma. Each user-role is a colon delimited couple of username and +# role. Roles are predefined in simple auth managers: viewer, user, op, admin. +# +# Example: simple_auth_manager_users = bob:admin,peter:viewer +# +# Variable: AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS +# +simple_auth_manager_users = admin:admin + +# Whether to disable authentication and allow everyone as admin in the environment. +# +# Variable: AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_ALL_ADMINS +# +simple_auth_manager_all_admins = False + +# The json file where the simple auth manager stores passwords for the configured users. +# By default this is ``AIRFLOW_HOME/simple_auth_manager_passwords.json.generated``. +# +# Example: simple_auth_manager_passwords_file = /path/to/passwords.json +# +# Variable: AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_PASSWORDS_FILE +# +# simple_auth_manager_passwords_file = + +# This defines the maximum number of task instances that can run concurrently per scheduler in +# Airflow, regardless of the worker count. Generally this value, multiplied by the number of +# schedulers in your cluster, is the maximum number of task instances with the running +# state in the metadata database. The value must be larger or equal 1. +# +# Variable: AIRFLOW__CORE__PARALLELISM +# +parallelism = 32 + +# The maximum number of task instances allowed to run concurrently in each DAG. To calculate +# the number of tasks that is running concurrently for a DAG, add up the number of running +# tasks for all DAG runs of the DAG. This is configurable at the DAG level with ``max_active_tasks``, +# which is defaulted as ``[core] max_active_tasks_per_dag``. +# +# An example scenario when this would be useful is when you want to stop a new dag with an early +# start date from stealing all the executor slots in a cluster. +# +# Variable: AIRFLOW__CORE__MAX_ACTIVE_TASKS_PER_DAG +# +max_active_tasks_per_dag = 16 + +# Are DAGs paused by default at creation +# +# Variable: AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION +# +dags_are_paused_at_creation = True + +# The maximum number of active DAG runs per DAG. The scheduler will not create more DAG runs +# if it reaches the limit. This is configurable at the DAG level with ``max_active_runs``, +# which is defaulted as ``[core] max_active_runs_per_dag``. +# +# Variable: AIRFLOW__CORE__MAX_ACTIVE_RUNS_PER_DAG +# +max_active_runs_per_dag = 16 + +# (experimental) The maximum number of consecutive DAG failures before DAG is automatically paused. +# This is also configurable per DAG level with ``max_consecutive_failed_dag_runs``, +# which is defaulted as ``[core] max_consecutive_failed_dag_runs_per_dag``. +# If not specified, then the value is considered as 0, +# meaning that the dags are never paused out by default. +# +# Variable: AIRFLOW__CORE__MAX_CONSECUTIVE_FAILED_DAG_RUNS_PER_DAG +# +max_consecutive_failed_dag_runs_per_dag = 0 + +# The name of the method used in order to start Python processes via the multiprocessing module. +# This corresponds directly with the options available in the Python docs: +# `multiprocessing.set_start_method +# `__ +# must be one of the values returned by `multiprocessing.get_all_start_methods() +# `__. +# +# Example: mp_start_method = fork +# +# Variable: AIRFLOW__CORE__MP_START_METHOD +# +# mp_start_method = + +# Whether to load the DAG examples that ship with Airflow. It's good to +# get started, but you probably want to set this to ``False`` in a production +# environment +# +# Variable: AIRFLOW__CORE__LOAD_EXAMPLES +# +load_examples = True + +# Path to the folder containing Airflow plugins +# +# Variable: AIRFLOW__CORE__PLUGINS_FOLDER +# +plugins_folder = /Users/omkar/CursorProjects/webscrape/airflow/plugins + +# Should tasks be executed via forking of the parent process +# +# * ``False``: Execute via forking of the parent process +# * ``True``: Spawning a new python process, slower than fork, but means plugin changes picked +# up by tasks straight away +# +# Variable: AIRFLOW__CORE__EXECUTE_TASKS_NEW_PYTHON_INTERPRETER +# +execute_tasks_new_python_interpreter = False + +# Secret key to save connection passwords in the db +# +# Variable: AIRFLOW__CORE__FERNET_KEY +# +fernet_key = slaA8QEKoU47l7d4DJ9soz43MBMdge7UhnA9m-Jzr2k= + +# Whether to disable pickling dags +# +# Variable: AIRFLOW__CORE__DONOT_PICKLE +# +donot_pickle = True + +# How long before timing out a python file import +# +# Variable: AIRFLOW__CORE__DAGBAG_IMPORT_TIMEOUT +# +dagbag_import_timeout = 30.0 + +# Should a traceback be shown in the UI for dagbag import errors, +# instead of just the exception message +# +# Variable: AIRFLOW__CORE__DAGBAG_IMPORT_ERROR_TRACEBACKS +# +dagbag_import_error_tracebacks = True + +# If tracebacks are shown, how many entries from the traceback should be shown +# +# Variable: AIRFLOW__CORE__DAGBAG_IMPORT_ERROR_TRACEBACK_DEPTH +# +dagbag_import_error_traceback_depth = 2 + +# If set, tasks without a ``run_as_user`` argument will be run with this user +# Can be used to de-elevate a sudo user running Airflow when executing tasks +# +# Variable: AIRFLOW__CORE__DEFAULT_IMPERSONATION +# +default_impersonation = + +# What security module to use (for example kerberos) +# +# Variable: AIRFLOW__CORE__SECURITY +# +security = + +# Turn unit test mode on (overwrites many configuration options with test +# values at runtime) +# +# Variable: AIRFLOW__CORE__UNIT_TEST_MODE +# +unit_test_mode = False + +# Space-separated list of classes that may be imported during deserialization. Items can be glob +# expressions. Python built-in classes (like dict) are always allowed. +# +# Example: allowed_deserialization_classes = airflow.* my_mod.my_other_mod.TheseClasses* +# +# Variable: AIRFLOW__CORE__ALLOWED_DESERIALIZATION_CLASSES +# +allowed_deserialization_classes = airflow.* + +# Space-separated list of classes that may be imported during deserialization. Items are processed +# as regex expressions. Python built-in classes (like dict) are always allowed. +# This is a secondary option to ``[core] allowed_deserialization_classes``. +# +# Variable: AIRFLOW__CORE__ALLOWED_DESERIALIZATION_CLASSES_REGEXP +# +allowed_deserialization_classes_regexp = + +# When a task is killed forcefully, this is the amount of time in seconds that +# it has to cleanup after it is sent a SIGTERM, before it is SIGKILLED +# +# Variable: AIRFLOW__CORE__KILLED_TASK_CLEANUP_TIME +# +killed_task_cleanup_time = 60 + +# Whether to override params with dag_run.conf. If you pass some key-value pairs +# through ``airflow dags backfill -c`` or +# ``airflow dags trigger -c``, the key-value pairs will override the existing ones in params. +# +# Variable: AIRFLOW__CORE__DAG_RUN_CONF_OVERRIDES_PARAMS +# +dag_run_conf_overrides_params = True + +# If enabled, Airflow will only scan files containing both ``DAG`` and ``airflow`` (case-insensitive). +# +# Variable: AIRFLOW__CORE__DAG_DISCOVERY_SAFE_MODE +# +dag_discovery_safe_mode = True + +# The pattern syntax used in the +# `.airflowignore +# `__ +# files in the DAG directories. Valid values are ``regexp`` or ``glob``. +# +# Variable: AIRFLOW__CORE__DAG_IGNORE_FILE_SYNTAX +# +dag_ignore_file_syntax = glob + +# The number of retries each task is going to have by default. Can be overridden at dag or task level. +# +# Variable: AIRFLOW__CORE__DEFAULT_TASK_RETRIES +# +default_task_retries = 0 + +# The number of seconds each task is going to wait by default between retries. Can be overridden at +# dag or task level. +# +# Variable: AIRFLOW__CORE__DEFAULT_TASK_RETRY_DELAY +# +default_task_retry_delay = 300 + +# The maximum delay (in seconds) each task is going to wait by default between retries. +# This is a global setting and cannot be overridden at task or DAG level. +# +# Variable: AIRFLOW__CORE__MAX_TASK_RETRY_DELAY +# +max_task_retry_delay = 86400 + +# The weighting method used for the effective total priority weight of the task +# +# Variable: AIRFLOW__CORE__DEFAULT_TASK_WEIGHT_RULE +# +default_task_weight_rule = downstream + +# Maximum possible time (in seconds) that task will have for execution of auxiliary processes +# (like listeners, mini scheduler...) after task is marked as success.. +# +# Variable: AIRFLOW__CORE__TASK_SUCCESS_OVERTIME +# +task_success_overtime = 20 + +# The default task execution_timeout value for the operators. Expected an integer value to +# be passed into timedelta as seconds. If not specified, then the value is considered as None, +# meaning that the operators are never timed out by default. +# +# Variable: AIRFLOW__CORE__DEFAULT_TASK_EXECUTION_TIMEOUT +# +default_task_execution_timeout = + +# Updating serialized DAG can not be faster than a minimum interval to reduce database write rate. +# +# Variable: AIRFLOW__CORE__MIN_SERIALIZED_DAG_UPDATE_INTERVAL +# +min_serialized_dag_update_interval = 30 + +# If ``True``, serialized DAGs are compressed before writing to DB. +# +# .. note:: +# +# This will disable the DAG dependencies view +# +# Variable: AIRFLOW__CORE__COMPRESS_SERIALIZED_DAGS +# +compress_serialized_dags = False + +# Fetching serialized DAG can not be faster than a minimum interval to reduce database +# read rate. This config controls when your DAGs are updated in the Webserver +# +# Variable: AIRFLOW__CORE__MIN_SERIALIZED_DAG_FETCH_INTERVAL +# +min_serialized_dag_fetch_interval = 10 + +# Maximum number of Rendered Task Instance Fields (Template Fields) per task to store +# in the Database. +# All the template_fields for each of Task Instance are stored in the Database. +# Keeping this number small may cause an error when you try to view ``Rendered`` tab in +# TaskInstance view for older tasks. +# +# Variable: AIRFLOW__CORE__MAX_NUM_RENDERED_TI_FIELDS_PER_TASK +# +max_num_rendered_ti_fields_per_task = 30 + +# Path to custom XCom class that will be used to store and resolve operators results +# +# Example: xcom_backend = path.to.CustomXCom +# +# Variable: AIRFLOW__CORE__XCOM_BACKEND +# +xcom_backend = airflow.sdk.execution_time.xcom.BaseXCom + +# By default Airflow plugins are lazily-loaded (only loaded when required). Set it to ``False``, +# if you want to load plugins whenever 'airflow' is invoked via cli or loaded from module. +# +# Variable: AIRFLOW__CORE__LAZY_LOAD_PLUGINS +# +lazy_load_plugins = True + +# By default Airflow providers are lazily-discovered (discovery and imports happen only when required). +# Set it to ``False``, if you want to discover providers whenever 'airflow' is invoked via cli or +# loaded from module. +# +# Variable: AIRFLOW__CORE__LAZY_DISCOVER_PROVIDERS +# +lazy_discover_providers = True + +# Hide sensitive **Variables** or **Connection extra json keys** from UI +# and task logs when set to ``True`` +# +# .. note:: +# +# Connection passwords are always hidden in logs +# +# Variable: AIRFLOW__CORE__HIDE_SENSITIVE_VAR_CONN_FIELDS +# +hide_sensitive_var_conn_fields = True + +# A comma-separated list of extra sensitive keywords to look for in variables names or connection's +# extra JSON. +# +# Variable: AIRFLOW__CORE__SENSITIVE_VAR_CONN_NAMES +# +sensitive_var_conn_names = + +# Task Slot counts for ``default_pool``. This setting would not have any effect in an existing +# deployment where the ``default_pool`` is already created. For existing deployments, users can +# change the number of slots using Webserver, API or the CLI +# +# Variable: AIRFLOW__CORE__DEFAULT_POOL_TASK_SLOT_COUNT +# +default_pool_task_slot_count = 128 + +# The maximum list/dict length an XCom can push to trigger task mapping. If the pushed list/dict has a +# length exceeding this value, the task pushing the XCom will be failed automatically to prevent the +# mapped tasks from clogging the scheduler. +# +# Variable: AIRFLOW__CORE__MAX_MAP_LENGTH +# +max_map_length = 1024 + +# The default umask to use for process when run in daemon mode (scheduler, worker, etc.) +# +# This controls the file-creation mode mask which determines the initial value of file permission bits +# for newly created files. +# +# This value is treated as an octal-integer. +# +# Variable: AIRFLOW__CORE__DAEMON_UMASK +# +daemon_umask = 0o077 + +# Class to use as asset manager. +# +# Example: asset_manager_class = airflow.assets.manager.AssetManager +# +# Variable: AIRFLOW__CORE__ASSET_MANAGER_CLASS +# +# asset_manager_class = + +# Kwargs to supply to asset manager. +# +# Example: asset_manager_kwargs = {"some_param": "some_value"} +# +# Variable: AIRFLOW__CORE__ASSET_MANAGER_KWARGS +# +# asset_manager_kwargs = + +# (experimental) Whether components should use Airflow Internal API for DB connectivity. +# +# Variable: AIRFLOW__CORE__DATABASE_ACCESS_ISOLATION +# +database_access_isolation = False + +# (experimental) Airflow Internal API url. +# Only used if ``[core] database_access_isolation`` is ``True``. +# +# Example: internal_api_url = http://localhost:8080 +# +# Variable: AIRFLOW__CORE__INTERNAL_API_URL +# +# internal_api_url = + +# Secret key used to authenticate internal API clients to core. It should be as random as possible. +# However, when running more than 1 instances of webserver / internal API services, make sure all +# of them use the same ``secret_key`` otherwise calls will fail on authentication. +# The authentication token generated using the secret key has a short expiry time though - make +# sure that time on ALL the machines that you run airflow components on is synchronized +# (for example using ntpd) otherwise you might get "forbidden" errors when the logs are accessed. +# +# Variable: AIRFLOW__CORE__INTERNAL_API_SECRET_KEY +# +internal_api_secret_key = PSKPtsKJdhE+HVzGrxSQBA== + +# The ability to allow testing connections across Airflow UI, API and CLI. +# Supported options: ``Disabled``, ``Enabled``, ``Hidden``. Default: Disabled +# Disabled - Disables the test connection functionality and disables the Test Connection button in UI. +# Enabled - Enables the test connection functionality and shows the Test Connection button in UI. +# Hidden - Disables the test connection functionality and hides the Test Connection button in UI. +# Before setting this to Enabled, make sure that you review the users who are able to add/edit +# connections and ensure they are trusted. Connection testing can be done maliciously leading to +# undesired and insecure outcomes. +# See `Airflow Security Model: Capabilities of authenticated UI users +# `__ +# for more details. +# +# Variable: AIRFLOW__CORE__TEST_CONNECTION +# +test_connection = Disabled + +# The maximum length of the rendered template field. If the value to be stored in the +# rendered template field exceeds this size, it's redacted. +# +# Variable: AIRFLOW__CORE__MAX_TEMPLATED_FIELD_LENGTH +# +max_templated_field_length = 4096 + +# The url of the execution api server. +# +# Variable: AIRFLOW__CORE__EXECUTION_API_SERVER_URL +# +execution_api_server_url = http://localhost:8080/execution/ + +[database] +# Path to the ``alembic.ini`` file. You can either provide the file path relative +# to the Airflow home directory or the absolute path if it is located elsewhere. +# +# Variable: AIRFLOW__DATABASE__ALEMBIC_INI_FILE_PATH +# +alembic_ini_file_path = alembic.ini + +# The SQLAlchemy connection string to the metadata database. +# SQLAlchemy supports many different database engines. +# See: `Set up a Database Backend: Database URI +# `__ +# for more details. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_CONN +# +sql_alchemy_conn = sqlite:////Users/omkar/CursorProjects/webscrape/airflow/airflow.db + +# Extra engine specific keyword args passed to SQLAlchemy's create_engine, as a JSON-encoded value +# +# Example: sql_alchemy_engine_args = {"arg1": true} +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_ENGINE_ARGS +# +# sql_alchemy_engine_args = + +# The encoding for the databases +# +# Variable: AIRFLOW__DATABASE__SQL_ENGINE_ENCODING +# +sql_engine_encoding = utf-8 + +# Collation for ``dag_id``, ``task_id``, ``key``, ``external_executor_id`` columns +# in case they have different encoding. +# By default this collation is the same as the database collation, however for ``mysql`` and ``mariadb`` +# the default is ``utf8mb3_bin`` so that the index sizes of our index keys will not exceed +# the maximum size of allowed index when collation is set to ``utf8mb4`` variant, see +# `GitHub Issue Comment `__ +# for more details. +# +# Variable: AIRFLOW__DATABASE__SQL_ENGINE_COLLATION_FOR_IDS +# +# sql_engine_collation_for_ids = + +# If SQLAlchemy should pool database connections. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_ENABLED +# +sql_alchemy_pool_enabled = True + +# The SQLAlchemy pool size is the maximum number of database connections +# in the pool. 0 indicates no limit. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_SIZE +# +sql_alchemy_pool_size = 5 + +# The maximum overflow size of the pool. +# When the number of checked-out connections reaches the size set in pool_size, +# additional connections will be returned up to this limit. +# When those additional connections are returned to the pool, they are disconnected and discarded. +# It follows then that the total number of simultaneous connections the pool will allow +# is **pool_size** + **max_overflow**, +# and the total number of "sleeping" connections the pool will allow is pool_size. +# max_overflow can be set to ``-1`` to indicate no overflow limit; +# no limit will be placed on the total number of concurrent connections. Defaults to ``10``. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_MAX_OVERFLOW +# +sql_alchemy_max_overflow = 10 + +# The SQLAlchemy pool recycle is the number of seconds a connection +# can be idle in the pool before it is invalidated. This config does +# not apply to sqlite. If the number of DB connections is ever exceeded, +# a lower config value will allow the system to recover faster. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_RECYCLE +# +sql_alchemy_pool_recycle = 1800 + +# Check connection at the start of each connection pool checkout. +# Typically, this is a simple statement like "SELECT 1". +# See `SQLAlchemy Pooling: Disconnect Handling - Pessimistic +# `__ +# for more details. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_PRE_PING +# +sql_alchemy_pool_pre_ping = True + +# The schema to use for the metadata database. +# SQLAlchemy supports databases with the concept of multiple schemas. +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_SCHEMA +# +sql_alchemy_schema = + +# Import path for connect args in SQLAlchemy. Defaults to an empty dict. +# This is useful when you want to configure db engine args that SQLAlchemy won't parse +# in connection string. This can be set by passing a dictionary containing the create engine parameters. +# For more details about passing create engine parameters (keepalives variables, timeout etc) +# in Postgres DB Backend see `Setting up a PostgreSQL Database +# `__ +# e.g ``connect_args={"timeout":30}`` can be defined in ``airflow_local_settings.py`` and +# can be imported as shown below +# +# Example: sql_alchemy_connect_args = airflow_local_settings.connect_args +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_CONNECT_ARGS +# +# sql_alchemy_connect_args = + +# Important Warning: Use of sql_alchemy_session_maker Highly Discouraged +# Import path for function which returns 'sqlalchemy.orm.sessionmaker'. +# Improper configuration of sql_alchemy_session_maker can lead to serious issues, +# including data corruption, unrecoverable application crashes. Please review the SQLAlchemy +# documentation for detailed guidance on proper configuration and best practices. +# +# Example: sql_alchemy_session_maker = airflow_local_settings._sessionmaker +# +# Variable: AIRFLOW__DATABASE__SQL_ALCHEMY_SESSION_MAKER +# +# sql_alchemy_session_maker = + +# Number of times the code should be retried in case of DB Operational Errors. +# Not all transactions will be retried as it can cause undesired state. +# Currently it is only used in ``DagFileProcessor.process_file`` to retry ``dagbag.sync_to_db``. +# +# Variable: AIRFLOW__DATABASE__MAX_DB_RETRIES +# +max_db_retries = 3 + +# Whether to run alembic migrations during Airflow start up. Sometimes this operation can be expensive, +# and the users can assert the correct version through other means (e.g. through a Helm chart). +# Accepts ``True`` or ``False``. +# +# Variable: AIRFLOW__DATABASE__CHECK_MIGRATIONS +# +check_migrations = True + +# List of DB managers to use to migrate external tables in airflow database. The managers must inherit +# from BaseDBManager. If ``FabAuthManager`` is configured in the environment, +# ``airflow.providers.fab.auth_manager.models.db.FABDBManager`` is automatically added. +# +# Example: external_db_managers = airflow.providers.fab.auth_manager.models.db.FABDBManager +# +# Variable: AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS +# +# external_db_managers = + +# The number of rows to process in each batch when performing a migration. +# This is useful for large tables to avoid locking and failure due to query timeouts. +# +# Variable: AIRFLOW__DATABASE__MIGRATION_BATCH_SIZE +# +migration_batch_size = 10000 + +[logging] +# The folder where airflow should store its log files. +# This path must be absolute. +# There are a few existing configurations that assume this is set to the default. +# If you choose to override this you may need to update the +# ``[logging] dag_processor_manager_log_location`` and +# ``[logging] dag_processor_child_process_log_directory settings`` as well. +# +# Variable: AIRFLOW__LOGGING__BASE_LOG_FOLDER +# +base_log_folder = /Users/omkar/CursorProjects/webscrape/airflow/logs + +# Airflow can store logs remotely in AWS S3, Google Cloud Storage or Elastic Search. +# Set this to ``True`` if you want to enable remote logging. +# +# Variable: AIRFLOW__LOGGING__REMOTE_LOGGING +# +remote_logging = False + +# Users must supply an Airflow connection id that provides access to the storage +# location. Depending on your remote logging service, this may only be used for +# reading logs, not writing them. +# +# Variable: AIRFLOW__LOGGING__REMOTE_LOG_CONN_ID +# +remote_log_conn_id = + +# Whether the local log files for GCS, S3, WASB, HDFS and OSS remote logging should be deleted after +# they are uploaded to the remote location. +# +# Variable: AIRFLOW__LOGGING__DELETE_LOCAL_LOGS +# +delete_local_logs = False + +# Path to Google Credential JSON file. If omitted, authorization based on `the Application Default +# Credentials +# `__ will +# be used. +# +# Variable: AIRFLOW__LOGGING__GOOGLE_KEY_PATH +# +google_key_path = + +# Storage bucket URL for remote logging +# S3 buckets should start with **s3://** +# Cloudwatch log groups should start with **cloudwatch://** +# GCS buckets should start with **gs://** +# WASB buckets should start with **wasb** just to help Airflow select correct handler +# Stackdriver logs should start with **stackdriver://** +# +# Variable: AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER +# +remote_base_log_folder = + +# The remote_task_handler_kwargs param is loaded into a dictionary and passed to the ``__init__`` +# of remote task handler and it overrides the values provided by Airflow config. For example if you set +# ``delete_local_logs=False`` and you provide ``{"delete_local_copy": true}``, then the local +# log files will be deleted after they are uploaded to remote location. +# +# Example: remote_task_handler_kwargs = {"delete_local_copy": true} +# +# Variable: AIRFLOW__LOGGING__REMOTE_TASK_HANDLER_KWARGS +# +remote_task_handler_kwargs = + +# Use server-side encryption for logs stored in S3 +# +# Variable: AIRFLOW__LOGGING__ENCRYPT_S3_LOGS +# +encrypt_s3_logs = False + +# Logging level. +# +# Supported values: ``CRITICAL``, ``ERROR``, ``WARNING``, ``INFO``, ``DEBUG``. +# +# Variable: AIRFLOW__LOGGING__LOGGING_LEVEL +# +logging_level = INFO + +# Logging level for celery. If not set, it uses the value of logging_level +# +# Supported values: ``CRITICAL``, ``ERROR``, ``WARNING``, ``INFO``, ``DEBUG``. +# +# Variable: AIRFLOW__LOGGING__CELERY_LOGGING_LEVEL +# +celery_logging_level = + +# Logging level for Flask-appbuilder UI. +# +# Supported values: ``CRITICAL``, ``ERROR``, ``WARNING``, ``INFO``, ``DEBUG``. +# +# Variable: AIRFLOW__LOGGING__FAB_LOGGING_LEVEL +# +fab_logging_level = WARNING + +# Logging class +# Specify the class that will specify the logging configuration +# This class has to be on the python classpath +# +# Example: logging_config_class = my.path.default_local_settings.LOGGING_CONFIG +# +# Variable: AIRFLOW__LOGGING__LOGGING_CONFIG_CLASS +# +logging_config_class = + +# Flag to enable/disable Colored logs in Console +# Colour the logs when the controlling terminal is a TTY. +# +# Variable: AIRFLOW__LOGGING__COLORED_CONSOLE_LOG +# +colored_console_log = True + +# Log format for when Colored logs is enabled +# +# Variable: AIRFLOW__LOGGING__COLORED_LOG_FORMAT +# +colored_log_format = [%%(blue)s%%(asctime)s%%(reset)s] {%%(blue)s%%(filename)s:%%(reset)s%%(lineno)d} %%(log_color)s%%(levelname)s%%(reset)s - %%(log_color)s%%(message)s%%(reset)s + +# Specifies the class utilized by Airflow to implement colored logging +# +# Variable: AIRFLOW__LOGGING__COLORED_FORMATTER_CLASS +# +colored_formatter_class = airflow.utils.log.colored_log.CustomTTYColoredFormatter + +# Format of Log line +# +# Variable: AIRFLOW__LOGGING__LOG_FORMAT +# +log_format = [%%(asctime)s] {%%(filename)s:%%(lineno)d} %%(levelname)s - %%(message)s + +# Defines the format of log messages for simple logging configuration +# +# Variable: AIRFLOW__LOGGING__SIMPLE_LOG_FORMAT +# +simple_log_format = %%(asctime)s %%(levelname)s - %%(message)s + +# Where to send dag parser logs. If "file", logs are sent to log files defined by child_process_log_directory. +# +# Variable: AIRFLOW__LOGGING__DAG_PROCESSOR_LOG_TARGET +# +dag_processor_log_target = file + +# Format of Dag Processor Log line +# +# Variable: AIRFLOW__LOGGING__DAG_PROCESSOR_LOG_FORMAT +# +dag_processor_log_format = [%%(asctime)s] [SOURCE:DAG_PROCESSOR] {%%(filename)s:%%(lineno)d} %%(levelname)s - %%(message)s + +# Determines the directory where logs for the child processes of the dag processor will be stored +# +# Variable: AIRFLOW__LOGGING__DAG_PROCESSOR_CHILD_PROCESS_LOG_DIRECTORY +# +dag_processor_child_process_log_directory = /Users/omkar/CursorProjects/webscrape/airflow/logs/dag_processor + +# Determines the formatter class used by Airflow for structuring its log messages +# The default formatter class is timezone-aware, which means that timestamps attached to log entries +# will be adjusted to reflect the local timezone of the Airflow instance +# +# Variable: AIRFLOW__LOGGING__LOG_FORMATTER_CLASS +# +log_formatter_class = airflow.utils.log.timezone_aware.TimezoneAware + +# An import path to a function to add adaptations of each secret added with +# ``airflow.sdk.execution_time.secrets_masker.mask_secret`` to be masked in log messages. +# The given function is expected to require a single parameter: the secret to be adapted. +# It may return a single adaptation of the secret or an iterable of adaptations to each be +# masked as secrets. The original secret will be masked as well as any adaptations returned. +# +# Example: secret_mask_adapter = urllib.parse.quote +# +# Variable: AIRFLOW__LOGGING__SECRET_MASK_ADAPTER +# +secret_mask_adapter = + +# The minimum length of a secret to be masked in log messages. +# Secrets shorter than this length will not be masked. +# +# Variable: AIRFLOW__LOGGING__MIN_LENGTH_MASKED_SECRET +# +min_length_masked_secret = 5 + +# Specify prefix pattern like mentioned below with stream handler ``TaskHandlerWithCustomFormatter`` +# +# Example: task_log_prefix_template = {{ti.dag_id}}-{{ti.task_id}}-{{logical_date}}-{{ti.try_number}} +# +# Variable: AIRFLOW__LOGGING__TASK_LOG_PREFIX_TEMPLATE +# +task_log_prefix_template = + +# Formatting for how airflow generates file names/paths for each task run. +# +# Variable: AIRFLOW__LOGGING__LOG_FILENAME_TEMPLATE +# +log_filename_template = dag_id={{ ti.dag_id }}/run_id={{ ti.run_id }}/task_id={{ ti.task_id }}/{%% if ti.map_index >= 0 %%}map_index={{ ti.map_index }}/{%% endif %%}attempt={{ try_number|default(ti.try_number) }}.log + +# Name of handler to read task instance logs. +# Defaults to use ``task`` handler. +# +# Variable: AIRFLOW__LOGGING__TASK_LOG_READER +# +task_log_reader = task + +# A comma\-separated list of third-party logger names that will be configured to print messages to +# consoles\. +# +# Example: extra_logger_names = fastapi,sqlalchemy +# +# Variable: AIRFLOW__LOGGING__EXTRA_LOGGER_NAMES +# +extra_logger_names = + +# When you start an Airflow worker, Airflow starts a tiny web server +# subprocess to serve the workers local log files to the airflow main +# web server, who then builds pages and sends them to users. This defines +# the port on which the logs are served. It needs to be unused, and open +# visible from the main web server to connect into the workers. +# +# Variable: AIRFLOW__LOGGING__WORKER_LOG_SERVER_PORT +# +worker_log_server_port = 8793 + +# Port to serve logs from for triggerer. +# See ``[logging] worker_log_server_port`` description for more info. +# +# Variable: AIRFLOW__LOGGING__TRIGGER_LOG_SERVER_PORT +# +trigger_log_server_port = 8794 + +# We must parse timestamps to interleave logs between trigger and task. To do so, +# we need to parse timestamps in log files. In case your log format is non-standard, +# you may provide import path to callable which takes a string log line and returns +# the timestamp (datetime.datetime compatible). +# +# Example: interleave_timestamp_parser = path.to.my_func +# +# Variable: AIRFLOW__LOGGING__INTERLEAVE_TIMESTAMP_PARSER +# +# interleave_timestamp_parser = + +# Permissions in the form or of octal string as understood by chmod. The permissions are important +# when you use impersonation, when logs are written by a different user than airflow. The most secure +# way of configuring it in this case is to add both users to the same group and make it the default +# group of both users. Group-writeable logs are default in airflow, but you might decide that you are +# OK with having the logs other-writeable, in which case you should set it to ``0o777``. You might +# decide to add more security if you do not use impersonation and change it to ``0o755`` to make it +# only owner-writeable. You can also make it just readable only for owner by changing it to ``0o700`` +# if all the access (read/write) for your logs happens from the same user. +# +# Example: file_task_handler_new_folder_permissions = 0o775 +# +# Variable: AIRFLOW__LOGGING__FILE_TASK_HANDLER_NEW_FOLDER_PERMISSIONS +# +file_task_handler_new_folder_permissions = 0o775 + +# Permissions in the form or of octal string as understood by chmod. The permissions are important +# when you use impersonation, when logs are written by a different user than airflow. The most secure +# way of configuring it in this case is to add both users to the same group and make it the default +# group of both users. Group-writeable logs are default in airflow, but you might decide that you are +# OK with having the logs other-writeable, in which case you should set it to ``0o666``. You might +# decide to add more security if you do not use impersonation and change it to ``0o644`` to make it +# only owner-writeable. You can also make it just readable only for owner by changing it to ``0o600`` +# if all the access (read/write) for your logs happens from the same user. +# +# Example: file_task_handler_new_file_permissions = 0o664 +# +# Variable: AIRFLOW__LOGGING__FILE_TASK_HANDLER_NEW_FILE_PERMISSIONS +# +file_task_handler_new_file_permissions = 0o664 + +# By default Celery sends all logs into stderr. +# If enabled any previous logging handlers will get *removed*. +# With this option AirFlow will create new handlers +# and send low level logs like INFO and WARNING to stdout, +# while sending higher severity logs to stderr. +# +# Variable: AIRFLOW__LOGGING__CELERY_STDOUT_STDERR_SEPARATION +# +celery_stdout_stderr_separation = False + +# A comma separated list of keywords related to errors whose presence should display the line in red +# color in UI +# +# Variable: AIRFLOW__LOGGING__COLOR_LOG_ERROR_KEYWORDS +# +color_log_error_keywords = error,exception + +# A comma separated list of keywords related to warning whose presence should display the line in yellow +# color in UI +# +# Variable: AIRFLOW__LOGGING__COLOR_LOG_WARNING_KEYWORDS +# +color_log_warning_keywords = warn + +[metrics] +# `StatsD `__ integration settings. + +# Configure an allow list (comma separated regex patterns to match) to send only certain metrics. +# +# Example: metrics_allow_list = "scheduler,executor,dagrun,pool,triggerer,celery" or "^scheduler,^executor,heartbeat|timeout" +# +# Variable: AIRFLOW__METRICS__METRICS_ALLOW_LIST +# +metrics_allow_list = + +# Configure a block list (comma separated regex patterns to match) to block certain metrics +# from being emitted. +# If ``[metrics] metrics_allow_list`` and ``[metrics] metrics_block_list`` are both configured, +# ``[metrics] metrics_block_list`` is ignored. +# +# Example: metrics_block_list = "scheduler,executor,dagrun,pool,triggerer,celery" or "^scheduler,^executor,heartbeat|timeout" +# +# Variable: AIRFLOW__METRICS__METRICS_BLOCK_LIST +# +metrics_block_list = + +# Enables sending metrics to StatsD. +# +# Variable: AIRFLOW__METRICS__STATSD_ON +# +statsd_on = False + +# Specifies the host address where the StatsD daemon (or server) is running +# +# Variable: AIRFLOW__METRICS__STATSD_HOST +# +statsd_host = localhost + +# Enables the statsd host to be resolved into IPv6 address +# +# Variable: AIRFLOW__METRICS__STATSD_IPV6 +# +statsd_ipv6 = False + +# Specifies the port on which the StatsD daemon (or server) is listening to +# +# Variable: AIRFLOW__METRICS__STATSD_PORT +# +statsd_port = 8125 + +# Defines the namespace for all metrics sent from Airflow to StatsD +# +# Variable: AIRFLOW__METRICS__STATSD_PREFIX +# +statsd_prefix = airflow + +# A function that validate the StatsD stat name, apply changes to the stat name if necessary and return +# the transformed stat name. +# +# The function should have the following signature +# +# .. code-block:: python +# +# def func_name(stat_name: str) -> str: ... +# +# Variable: AIRFLOW__METRICS__STAT_NAME_HANDLER +# +stat_name_handler = + +# To enable datadog integration to send airflow metrics. +# +# Variable: AIRFLOW__METRICS__STATSD_DATADOG_ENABLED +# +statsd_datadog_enabled = False + +# List of datadog tags attached to all metrics(e.g: ``key1:value1,key2:value2``) +# +# Variable: AIRFLOW__METRICS__STATSD_DATADOG_TAGS +# +statsd_datadog_tags = + +# Set to ``False`` to disable metadata tags for some of the emitted metrics +# +# Variable: AIRFLOW__METRICS__STATSD_DATADOG_METRICS_TAGS +# +statsd_datadog_metrics_tags = True + +# If you want to utilise your own custom StatsD client set the relevant +# module path below. +# Note: The module path must exist on your +# `PYTHONPATH ` +# for Airflow to pick it up +# +# Variable: AIRFLOW__METRICS__STATSD_CUSTOM_CLIENT_PATH +# +# statsd_custom_client_path = + +# If you want to avoid sending all the available metrics tags to StatsD, +# you can configure a block list of prefixes (comma separated) to filter out metric tags +# that start with the elements of the list (e.g: ``job_id,run_id``) +# +# Example: statsd_disabled_tags = job_id,run_id,dag_id,task_id +# +# Variable: AIRFLOW__METRICS__STATSD_DISABLED_TAGS +# +statsd_disabled_tags = job_id,run_id + +# To enable sending Airflow metrics with StatsD-Influxdb tagging convention. +# +# Variable: AIRFLOW__METRICS__STATSD_INFLUXDB_ENABLED +# +statsd_influxdb_enabled = False + +# Enables sending metrics to OpenTelemetry. +# +# Variable: AIRFLOW__METRICS__OTEL_ON +# +otel_on = False + +# Specifies the hostname or IP address of the OpenTelemetry Collector to which Airflow sends +# metrics and traces. +# +# Variable: AIRFLOW__METRICS__OTEL_HOST +# +otel_host = localhost + +# Specifies the port of the OpenTelemetry Collector that is listening to. +# +# Variable: AIRFLOW__METRICS__OTEL_PORT +# +otel_port = 8889 + +# The prefix for the Airflow metrics. +# +# Variable: AIRFLOW__METRICS__OTEL_PREFIX +# +otel_prefix = airflow + +# Defines the interval, in milliseconds, at which Airflow sends batches of metrics and traces +# to the configured OpenTelemetry Collector. +# +# Variable: AIRFLOW__METRICS__OTEL_INTERVAL_MILLISECONDS +# +otel_interval_milliseconds = 60000 + +# If ``True``, all metrics are also emitted to the console. Defaults to ``False``. +# +# Variable: AIRFLOW__METRICS__OTEL_DEBUGGING_ON +# +otel_debugging_on = False + +# The default service name of traces. +# +# Variable: AIRFLOW__METRICS__OTEL_SERVICE +# +otel_service = Airflow + +# If ``True``, SSL will be enabled. Defaults to ``False``. +# To establish an HTTPS connection to the OpenTelemetry collector, +# you need to configure the SSL certificate and key within the OpenTelemetry collector's +# ``config.yml`` file. +# +# Variable: AIRFLOW__METRICS__OTEL_SSL_ACTIVE +# +otel_ssl_active = False + +[traces] +# Distributed traces integration settings. + +# Enables sending traces to OpenTelemetry. +# +# Variable: AIRFLOW__TRACES__OTEL_ON +# +otel_on = False + +# Specifies the hostname or IP address of the OpenTelemetry Collector to which Airflow sends +# traces. +# +# Variable: AIRFLOW__TRACES__OTEL_HOST +# +otel_host = localhost + +# Specifies the port of the OpenTelemetry Collector that is listening to. +# +# Variable: AIRFLOW__TRACES__OTEL_PORT +# +otel_port = 8889 + +# The default service name of traces. +# +# Variable: AIRFLOW__TRACES__OTEL_SERVICE +# +otel_service = Airflow + +# If True, all traces are also emitted to the console. Defaults to False. +# +# Variable: AIRFLOW__TRACES__OTEL_DEBUGGING_ON +# +otel_debugging_on = False + +# If True, SSL will be enabled. Defaults to False. +# To establish an HTTPS connection to the OpenTelemetry collector, +# you need to configure the SSL certificate and key within the OpenTelemetry collector's +# config.yml file. +# +# Variable: AIRFLOW__TRACES__OTEL_SSL_ACTIVE +# +otel_ssl_active = False + +[secrets] +# Full class name of secrets backend to enable (will precede env vars and metastore in search path) +# +# Example: backend = airflow.providers.amazon.aws.secrets.systems_manager.SystemsManagerParameterStoreBackend +# +# Variable: AIRFLOW__SECRETS__BACKEND +# +backend = + +# The backend_kwargs param is loaded into a dictionary and passed to ``__init__`` +# of secrets backend class. See documentation for the secrets backend you are using. +# JSON is expected. +# +# Example for AWS Systems Manager ParameterStore: +# ``{"connections_prefix": "/airflow/connections", "profile_name": "default"}`` +# +# Variable: AIRFLOW__SECRETS__BACKEND_KWARGS +# +backend_kwargs = + +# .. note:: |experimental| +# +# Enables local caching of Variables, when parsing DAGs only. +# Using this option can make dag parsing faster if Variables are used in top level code, at the expense +# of longer propagation time for changes. +# Please note that this cache concerns only the DAG parsing step. There is no caching in place when DAG +# tasks are run. +# +# Variable: AIRFLOW__SECRETS__USE_CACHE +# +use_cache = False + +# .. note:: |experimental| +# +# When the cache is enabled, this is the duration for which we consider an entry in the cache to be +# valid. Entries are refreshed if they are older than this many seconds. +# It means that when the cache is enabled, this is the maximum amount of time you need to wait to see a +# Variable change take effect. +# +# Variable: AIRFLOW__SECRETS__CACHE_TTL_SECONDS +# +cache_ttl_seconds = 900 + +[api] +# The base url of the API server. Airflow cannot guess what domain or CNAME you are using. +# If the Airflow console (the front-end) and the API server are on a different domain, this config +# should contain the API server endpoint. +# +# Example: base_url = https://my-airflow.company.com +# +# Variable: AIRFLOW__API__BASE_URL +# +# base_url = + +# The ip specified when starting the api server +# +# Variable: AIRFLOW__API__HOST +# +host = 0.0.0.0 + +# The port on which to run the api server +# +# Variable: AIRFLOW__API__PORT +# +port = 8080 + +# Number of workers to run on the API server +# +# Variable: AIRFLOW__API__WORKERS +# +workers = 4 + +# Number of seconds the API server waits before timing out on a worker +# +# Variable: AIRFLOW__API__WORKER_TIMEOUT +# +worker_timeout = 120 + +# Log files for the api server. '-' means log to stderr. +# +# Variable: AIRFLOW__API__ACCESS_LOGFILE +# +access_logfile = - + +# Paths to the SSL certificate and key for the api server. When both are +# provided SSL will be enabled. This does not change the api server port. +# +# Variable: AIRFLOW__API__SSL_CERT +# +ssl_cert = + +# Paths to the SSL certificate and key for the api server. When both are +# provided SSL will be enabled. This does not change the api server port. +# +# Variable: AIRFLOW__API__SSL_KEY +# +ssl_key = + +# Used to set the maximum page limit for API requests. If limit passed as param +# is greater than maximum page limit, it will be ignored and maximum page limit value +# will be set as the limit +# +# Variable: AIRFLOW__API__MAXIMUM_PAGE_LIMIT +# +maximum_page_limit = 100 + +# Used to set the default page limit when limit param is zero or not provided in API +# requests. Otherwise if positive integer is passed in the API requests as limit, the +# smallest number of user given limit or maximum page limit is taken as limit. +# +# Variable: AIRFLOW__API__FALLBACK_PAGE_LIMIT +# +fallback_page_limit = 50 + +# Used in response to a preflight request to indicate which HTTP +# headers can be used when making the actual request. This header is +# the server side response to the browser's +# Access-Control-Request-Headers header. +# +# Variable: AIRFLOW__API__ACCESS_CONTROL_ALLOW_HEADERS +# +access_control_allow_headers = + +# Specifies the method or methods allowed when accessing the resource. +# +# Variable: AIRFLOW__API__ACCESS_CONTROL_ALLOW_METHODS +# +access_control_allow_methods = + +# Indicates whether the response can be shared with requesting code from the given origins. +# Separate URLs with space. +# +# Variable: AIRFLOW__API__ACCESS_CONTROL_ALLOW_ORIGINS +# +access_control_allow_origins = + +# Indicates whether the **xcomEntries** endpoint supports the **deserialize** +# flag. If set to ``False``, setting this flag in a request would result in a +# 400 Bad Request error. +# +# Variable: AIRFLOW__API__ENABLE_XCOM_DESERIALIZE_SUPPORT +# +enable_xcom_deserialize_support = False + +[workers] +# Configuration related to workers that run Airflow tasks. + +# Full class name of secrets backend to enable for workers (will precede env vars backend) +# +# Example: secrets_backend = airflow.providers.amazon.aws.secrets.systems_manager.SystemsManagerParameterStoreBackend +# +# Variable: AIRFLOW__WORKERS__SECRETS_BACKEND +# +secrets_backend = + +# The secrets_backend_kwargs param is loaded into a dictionary and passed to ``__init__`` +# of secrets backend class. See documentation for the secrets backend you are using. +# JSON is expected. +# +# Example for AWS Systems Manager ParameterStore: +# ``{"connections_prefix": "/airflow/connections", "profile_name": "default"}`` +# +# Variable: AIRFLOW__WORKERS__SECRETS_BACKEND_KWARGS +# +secrets_backend_kwargs = + +# The minimum interval (in seconds) at which the worker checks the task instance's +# heartbeat status with the API server to confirm it is still alive. +# +# Variable: AIRFLOW__WORKERS__MIN_HEARTBEAT_INTERVAL +# +min_heartbeat_interval = 5 + +# The maximum number of consecutive failed heartbeats before terminating the task instance process. +# +# Variable: AIRFLOW__WORKERS__MAX_FAILED_HEARTBEATS +# +max_failed_heartbeats = 3 + +# The maximum number of retry attempts to the execution API server. +# +# Variable: AIRFLOW__WORKERS__EXECUTION_API_RETRIES +# +execution_api_retries = 5 + +# The minimum amount of time (in seconds) to wait before retrying a failed API request. +# +# Variable: AIRFLOW__WORKERS__EXECUTION_API_RETRY_WAIT_MIN +# +execution_api_retry_wait_min = 1.0 + +# The maximum amount of time (in seconds) to wait before retrying a failed API request. +# +# Variable: AIRFLOW__WORKERS__EXECUTION_API_RETRY_WAIT_MAX +# +execution_api_retry_wait_max = 90.0 + +[api_auth] +# Settings relating to authentication on the Airflow APIs + +# The audience claim to use when generating and validating JWTs for the API. +# +# This variable can be a single value, or a comma-separated string, in which case the first value is the +# one that will be used when generating, and the others are accepted at validation time. +# +# Not required, but strongly encouraged. +# +# See also :ref:`config:execution_api__jwt_audience` +# +# Example: jwt_audience = my-unique-airflow-id +# +# Variable: AIRFLOW__API_AUTH__JWT_AUDIENCE +# +# jwt_audience = + +# Number in seconds until the JWTs used for authentication expires. When the token expires, +# all API calls using this token will fail on authentication. +# +# Make sure that time on ALL the machines that you run airflow components on is synchronized +# (for example using ntpd) otherwise you might get "forbidden" errors. +# +# See also :ref:`config:execution_api__jwt_expiration_time` +# +# Variable: AIRFLOW__API_AUTH__JWT_EXPIRATION_TIME +# +jwt_expiration_time = 86400 + +# Number in seconds until the JWTs used for authentication expires for CLI commands. +# When the token expires, all CLI calls using this token will fail on authentication. +# +# Make sure that time on ALL the machines that you run airflow components on is synchronized +# (for example using ntpd) otherwise you might get "forbidden" errors. +# +# Variable: AIRFLOW__API_AUTH__JWT_CLI_EXPIRATION_TIME +# +jwt_cli_expiration_time = 3600 + +# Secret key used to encode and decode JWTs to authenticate to public and private APIs. +# +# It should be as random as possible. However, when running more than 1 instances of API services, +# make sure all of them use the same ``jwt_secret`` otherwise calls will fail on authentication. +# +# Mutually exclusive with ``jwt_private_key_path``. +# +# Variable: AIRFLOW__API_AUTH__JWT_SECRET +# +jwt_secret = uJJX8wavge83TqtgJa+9eA== + +# The path to a file containing a PEM-encoded private key use when generating Task Identity tokens in +# the executor. +# +# Mutually exclusive with ``jwt_secret``. +# +# Example: jwt_private_key_path = /path/to/private_key.pem +# +# Variable: AIRFLOW__API_AUTH__JWT_PRIVATE_KEY_PATH +# +# jwt_private_key_path = + +# The algorithm name use when generating and validating JWT Task Identities. +# +# This value must be appropriate for the given private key type. +# +# If this is not specified Airflow makes some guesses as what algorithm is best based on the key type. +# +# ("HS512" if ``jwt_secret`` is set, otherwise a key-type specific guess) +# +# Example: jwt_algorithm = "EdDSA" or "HS512" +# +# Variable: AIRFLOW__API_AUTH__JWT_ALGORITHM +# +# jwt_algorithm = + +# The Key ID to place in header when generating JWTs. Not used in the validation path. +# +# If this is not specified the RFC7638 thumbprint of the private key will be used. +# +# Ignored when ``jwt_secret`` is used. +# +# Example: jwt_kid = my-key-id +# +# Variable: AIRFLOW__API_AUTH__JWT_KID +# +# jwt_kid = + +# The public signing keys of Task Execution token issuers to trust. It must contain the public key +# related to ``jwt_private_key_path`` else tasks will be unlikely to execute successfully. +# +# Can be a local file path (without the ``file://`` prefix) or an http or https URL. +# +# If a remote URL is given it will be polled periodically for changes. +# +# Mutually exclusive with ``jwt_secret``. +# +# If a ``jwt_private_key_path`` is given but this settings is not set then the private key will be +# trusted. If this is provided it is your responsibility to ensure that the private key used for +# generation is in this list. +# +# Example: trusted_jwks_url = "/path/to/public-jwks.json" or "https://my-issuer/.well-known/jwks.json" +# +# Variable: AIRFLOW__API_AUTH__TRUSTED_JWKS_URL +# +# trusted_jwks_url = + +# Issuer of the JWT. This becomes the ``iss`` claim of generated tokens, and is validated on incoming +# requests. +# +# Ideally this should be unique per individual airflow deployment +# +# Not required, but strongly recommended to be set. +# +# See also :ref:`config:api_auth__jwt_audience` +# +# Example: jwt_issuer = http://my-airflow.mycompany.com +# +# Variable: AIRFLOW__API_AUTH__JWT_ISSUER +# +# jwt_issuer = + +# Number of seconds leeway in validating expiry time of JWTs to account for clock skew between +# client and server +# +# Variable: AIRFLOW__API_AUTH__JWT_LEEWAY +# +jwt_leeway = 10 + +[execution_api] +# Settings related to the Execution API server. +# +# The ExecutionAPI also uses a lot of settings from the :ref:`config:api_auth` section. + +# Number in seconds until the JWT used for authentication expires. When the token expires, +# all API calls using this token will fail on authentication. +# +# Make sure that time on ALL the machines that you run airflow components on is synchronized +# (for example using ntpd) otherwise you might get "forbidden" errors. +# +# Variable: AIRFLOW__EXECUTION_API__JWT_EXPIRATION_TIME +# +jwt_expiration_time = 600 + +# The audience claim to use when generating and validating JWTs for the Execution API. +# +# This variable can be a single value, or a comma-separated string, in which case the first value is the +# one that will be used when generating, and the others are accepted at validation time. +# +# Not required, but strongly encouraged +# +# See also :ref:`config:api_auth__jwt_audience` +# +# Variable: AIRFLOW__EXECUTION_API__JWT_AUDIENCE +# +jwt_audience = urn:airflow.apache.org:task + +[lineage] +# what lineage backend to use +# +# Variable: AIRFLOW__LINEAGE__BACKEND +# +backend = + +[operators] +# The default owner assigned to each new operator, unless +# provided explicitly or passed via ``default_args`` +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_OWNER +# +default_owner = airflow + +# The default value of attribute "deferrable" in operators and sensors. +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_DEFERRABLE +# +default_deferrable = false + +# Indicates the default number of CPU units allocated to each operator when no specific CPU request +# is specified in the operator's configuration +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_CPUS +# +default_cpus = 1 + +# Indicates the default number of RAM allocated to each operator when no specific RAM request +# is specified in the operator's configuration +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_RAM +# +default_ram = 512 + +# Indicates the default number of disk storage allocated to each operator when no specific disk request +# is specified in the operator's configuration +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_DISK +# +default_disk = 512 + +# Indicates the default number of GPUs allocated to each operator when no specific GPUs request +# is specified in the operator's configuration +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_GPUS +# +default_gpus = 0 + +# Default queue that tasks get assigned to and that worker listen on. +# +# Variable: AIRFLOW__OPERATORS__DEFAULT_QUEUE +# +default_queue = default + +[webserver] +# The message displayed when a user attempts to execute actions beyond their authorised privileges. +# +# Variable: AIRFLOW__WEBSERVER__ACCESS_DENIED_MESSAGE +# +access_denied_message = Access is Denied + +# Secret key used to run your api server. It should be as random as possible. However, when running +# more than 1 instances of webserver, make sure all of them use the same ``secret_key`` otherwise +# one of them will error with "CSRF session token is missing". +# The webserver key is also used to authorize requests to Celery workers when logs are retrieved. +# The token generated using the secret key has a short expiry time though - make sure that time on +# ALL the machines that you run airflow components on is synchronized (for example using ntpd) +# otherwise you might get "forbidden" errors when the logs are accessed. +# +# Variable: AIRFLOW__WEBSERVER__SECRET_KEY +# +secret_key = PSKPtsKJdhE+HVzGrxSQBA== + +# Expose the configuration file in the web server. Set to ``non-sensitive-only`` to show all values +# except those that have security implications. ``True`` shows all values. ``False`` hides the +# configuration completely. +# +# Variable: AIRFLOW__WEBSERVER__EXPOSE_CONFIG +# +expose_config = False + +# Expose hostname in the web server +# +# Variable: AIRFLOW__WEBSERVER__EXPOSE_HOSTNAME +# +expose_hostname = False + +# Sorting order in grid view. Valid values are: ``topological``, ``hierarchical_alphabetical`` +# +# Variable: AIRFLOW__WEBSERVER__GRID_VIEW_SORTING_ORDER +# +grid_view_sorting_order = topological + +# The amount of time (in secs) webserver will wait for initial handshake +# while fetching logs from other worker machine +# +# Variable: AIRFLOW__WEBSERVER__LOG_FETCH_TIMEOUT_SEC +# +log_fetch_timeout_sec = 5 + +# By default, the webserver shows paused DAGs. Flip this to hide paused +# DAGs by default +# +# Variable: AIRFLOW__WEBSERVER__HIDE_PAUSED_DAGS_BY_DEFAULT +# +hide_paused_dags_by_default = False + +# Consistent page size across all listing views in the UI +# +# Variable: AIRFLOW__WEBSERVER__PAGE_SIZE +# +page_size = 50 + +# Define the color of navigation bar +# +# Variable: AIRFLOW__WEBSERVER__NAVBAR_COLOR +# +navbar_color = #fff + +# Define the color of text in the navigation bar +# +# Variable: AIRFLOW__WEBSERVER__NAVBAR_TEXT_COLOR +# +navbar_text_color = #51504f + +# Define the color of navigation bar links when hovered +# +# Variable: AIRFLOW__WEBSERVER__NAVBAR_HOVER_COLOR +# +navbar_hover_color = #eee + +# Define the color of text in the navigation bar when hovered +# +# Variable: AIRFLOW__WEBSERVER__NAVBAR_TEXT_HOVER_COLOR +# +navbar_text_hover_color = #51504f + +# Default setting for wrap toggle on DAG code and TI log views. +# +# Variable: AIRFLOW__WEBSERVER__DEFAULT_WRAP +# +default_wrap = False + +# Allow the UI to be rendered in a frame +# +# Variable: AIRFLOW__WEBSERVER__X_FRAME_ENABLED +# +x_frame_enabled = True + +# Sets a custom page title for the DAGs overview page and site title for all pages +# +# Variable: AIRFLOW__WEBSERVER__INSTANCE_NAME +# +# instance_name = + +# Whether the custom page title for the DAGs overview page contains any Markup language +# +# Variable: AIRFLOW__WEBSERVER__INSTANCE_NAME_HAS_MARKUP +# +instance_name_has_markup = False + +# How frequently, in seconds, the DAG data will auto-refresh in graph or grid view +# when auto-refresh is turned on +# +# Variable: AIRFLOW__WEBSERVER__AUTO_REFRESH_INTERVAL +# +auto_refresh_interval = 3 + +# Boolean for displaying warning for publicly viewable deployment +# +# Variable: AIRFLOW__WEBSERVER__WARN_DEPLOYMENT_EXPOSURE +# +warn_deployment_exposure = True + +# Comma separated string of view events to exclude from dag audit view. +# All other events will be added minus the ones passed here. +# The audit logs in the db will not be affected by this parameter. +# +# Example: audit_view_excluded_events = cli_task_run,running,success +# +# Variable: AIRFLOW__WEBSERVER__AUDIT_VIEW_EXCLUDED_EVENTS +# +# audit_view_excluded_events = + +# Comma separated string of view events to include in dag audit view. +# If passed, only these events will populate the dag audit view. +# The audit logs in the db will not be affected by this parameter. +# +# Example: audit_view_included_events = dagrun_cleared,failed +# +# Variable: AIRFLOW__WEBSERVER__AUDIT_VIEW_INCLUDED_EVENTS +# +# audit_view_included_events = + +# Boolean for running SwaggerUI in the webserver. +# +# Variable: AIRFLOW__WEBSERVER__ENABLE_SWAGGER_UI +# +enable_swagger_ui = True + +# Require confirmation when changing a DAG in the web UI. This is to prevent accidental changes +# to a DAG that may be running on sensitive environments like production. +# When set to ``True``, confirmation dialog will be shown when a user tries to Pause/Unpause, +# Trigger a DAG +# +# Variable: AIRFLOW__WEBSERVER__REQUIRE_CONFIRMATION_DAG_CHANGE +# +require_confirmation_dag_change = False + +[email] +# Configuration email backend and whether to +# send email alerts on retry or failure + +# Email backend to use +# +# Variable: AIRFLOW__EMAIL__EMAIL_BACKEND +# +email_backend = airflow.utils.email.send_email_smtp + +# Email connection to use +# +# Variable: AIRFLOW__EMAIL__EMAIL_CONN_ID +# +email_conn_id = smtp_default + +# Whether email alerts should be sent when a task is retried +# +# Variable: AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_RETRY +# +default_email_on_retry = True + +# Whether email alerts should be sent when a task failed +# +# Variable: AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_FAILURE +# +default_email_on_failure = True + +# File that will be used as the template for Email subject (which will be rendered using Jinja2). +# If not set, Airflow uses a base template. +# +# Example: subject_template = /path/to/my_subject_template_file +# +# Variable: AIRFLOW__EMAIL__SUBJECT_TEMPLATE +# +# subject_template = + +# File that will be used as the template for Email content (which will be rendered using Jinja2). +# If not set, Airflow uses a base template. +# +# Example: html_content_template = /path/to/my_html_content_template_file +# +# Variable: AIRFLOW__EMAIL__HTML_CONTENT_TEMPLATE +# +# html_content_template = + +# Email address that will be used as sender address. +# It can either be raw email or the complete address in a format ``Sender Name `` +# +# Example: from_email = Airflow +# +# Variable: AIRFLOW__EMAIL__FROM_EMAIL +# +# from_email = + +# ssl context to use when using SMTP and IMAP SSL connections. By default, the context is "default" +# which sets it to ``ssl.create_default_context()`` which provides the right balance between +# compatibility and security, it however requires that certificates in your operating system are +# updated and that SMTP/IMAP servers of yours have valid certificates that have corresponding public +# keys installed on your machines. You can switch it to "none" if you want to disable checking +# of the certificates, but it is not recommended as it allows MITM (man-in-the-middle) attacks +# if your infrastructure is not sufficiently secured. It should only be set temporarily while you +# are fixing your certificate configuration. This can be typically done by upgrading to newer +# version of the operating system you run Airflow components on,by upgrading/refreshing proper +# certificates in the OS or by updating certificates for your mail servers. +# +# Example: ssl_context = default +# +# Variable: AIRFLOW__EMAIL__SSL_CONTEXT +# +ssl_context = default + +[smtp] +# If you want airflow to send emails on retries, failure, and you want to use +# the airflow.utils.email.send_email_smtp function, you have to configure an +# smtp server here + +# Specifies the host server address used by Airflow when sending out email notifications via SMTP. +# +# Variable: AIRFLOW__SMTP__SMTP_HOST +# +smtp_host = localhost + +# Determines whether to use the STARTTLS command when connecting to the SMTP server. +# +# Variable: AIRFLOW__SMTP__SMTP_STARTTLS +# +smtp_starttls = True + +# Determines whether to use an SSL connection when talking to the SMTP server. +# +# Variable: AIRFLOW__SMTP__SMTP_SSL +# +smtp_ssl = False + +# Defines the port number on which Airflow connects to the SMTP server to send email notifications. +# +# Variable: AIRFLOW__SMTP__SMTP_PORT +# +smtp_port = 25 + +# Specifies the default **from** email address used when Airflow sends email notifications. +# +# Variable: AIRFLOW__SMTP__SMTP_MAIL_FROM +# +smtp_mail_from = airflow@example.com + +# Determines the maximum time (in seconds) the Apache Airflow system will wait for a +# connection to the SMTP server to be established. +# +# Variable: AIRFLOW__SMTP__SMTP_TIMEOUT +# +smtp_timeout = 30 + +# Defines the maximum number of times Airflow will attempt to connect to the SMTP server. +# +# Variable: AIRFLOW__SMTP__SMTP_RETRY_LIMIT +# +smtp_retry_limit = 5 + +[sentry] +# `Sentry `__ integration. Here you can supply +# additional configuration options based on the Python platform. +# See `Python / Configuration / Basic Options +# `__ for more details. +# Unsupported options: ``integrations``, ``in_app_include``, ``in_app_exclude``, +# ``ignore_errors``, ``before_breadcrumb``, ``transport``. + +# Enable error reporting to Sentry +# +# Variable: AIRFLOW__SENTRY__SENTRY_ON +# +sentry_on = false + +# +# Variable: AIRFLOW__SENTRY__SENTRY_DSN +# +sentry_dsn = + +# Dotted path to a before_send function that the sentry SDK should be configured to use. +# +# Variable: AIRFLOW__SENTRY__BEFORE_SEND +# +# before_send = + +[scheduler] +# Task instances listen for external kill signal (when you clear tasks +# from the CLI or the UI), this defines the frequency at which they should +# listen (in seconds). +# +# Variable: AIRFLOW__SCHEDULER__JOB_HEARTBEAT_SEC +# +job_heartbeat_sec = 5 + +# The scheduler constantly tries to trigger new tasks (look at the +# scheduler section in the docs for more information). This defines +# how often the scheduler should run (in seconds). +# +# Variable: AIRFLOW__SCHEDULER__SCHEDULER_HEARTBEAT_SEC +# +scheduler_heartbeat_sec = 5 + +# The frequency (in seconds) at which the LocalTaskJob should send heartbeat signals to the +# scheduler to notify it's still alive. If this value is set to 0, the heartbeat interval will default +# to the value of ``[scheduler] task_instance_heartbeat_timeout``. +# +# Variable: AIRFLOW__SCHEDULER__TASK_INSTANCE_HEARTBEAT_SEC +# +task_instance_heartbeat_sec = 0 + +# The number of times to try to schedule each DAG file +# -1 indicates unlimited number +# +# Variable: AIRFLOW__SCHEDULER__NUM_RUNS +# +num_runs = -1 + +# Controls how long the scheduler will sleep between loops, but if there was nothing to do +# in the loop. i.e. if it scheduled something then it will start the next loop +# iteration straight away. +# +# Variable: AIRFLOW__SCHEDULER__SCHEDULER_IDLE_SLEEP_TIME +# +scheduler_idle_sleep_time = 1 + +# How often (in seconds) to check for stale DAGs (DAGs which are no longer present in +# the expected files) which should be deactivated, as well as assets that are no longer +# referenced and should be marked as orphaned. +# +# Variable: AIRFLOW__SCHEDULER__PARSING_CLEANUP_INTERVAL +# +parsing_cleanup_interval = 60 + +# How often (in seconds) should pool usage stats be sent to StatsD (if statsd_on is enabled) +# +# Variable: AIRFLOW__SCHEDULER__POOL_METRICS_INTERVAL +# +pool_metrics_interval = 5.0 + +# How often (in seconds) should running task instance stats be sent to StatsD (if statsd_on is enabled) +# +# Variable: AIRFLOW__SCHEDULER__RUNNING_METRICS_INTERVAL +# +running_metrics_interval = 30.0 + +# If the last scheduler heartbeat happened more than ``[scheduler] scheduler_health_check_threshold`` +# ago (in seconds), scheduler is considered unhealthy. +# This is used by the health check in the **/health** endpoint and in ``airflow jobs check`` CLI +# for SchedulerJob. +# +# Variable: AIRFLOW__SCHEDULER__SCHEDULER_HEALTH_CHECK_THRESHOLD +# +scheduler_health_check_threshold = 30 + +# When you start a scheduler, airflow starts a tiny web server +# subprocess to serve a health check if this is set to ``True`` +# +# Variable: AIRFLOW__SCHEDULER__ENABLE_HEALTH_CHECK +# +enable_health_check = False + +# When you start a scheduler, airflow starts a tiny web server +# subprocess to serve a health check on this host +# +# Variable: AIRFLOW__SCHEDULER__SCHEDULER_HEALTH_CHECK_SERVER_HOST +# +scheduler_health_check_server_host = 0.0.0.0 + +# When you start a scheduler, airflow starts a tiny web server +# subprocess to serve a health check on this port +# +# Variable: AIRFLOW__SCHEDULER__SCHEDULER_HEALTH_CHECK_SERVER_PORT +# +scheduler_health_check_server_port = 8974 + +# How often (in seconds) should the scheduler check for orphaned tasks and SchedulerJobs +# +# Variable: AIRFLOW__SCHEDULER__ORPHANED_TASKS_CHECK_INTERVAL +# +orphaned_tasks_check_interval = 300.0 + +# Local task jobs periodically heartbeat to the DB. If the job has +# not heartbeat in this many seconds, the scheduler will mark the +# associated task instance as failed and will re-schedule the task. +# +# Variable: AIRFLOW__SCHEDULER__TASK_INSTANCE_HEARTBEAT_TIMEOUT +# +task_instance_heartbeat_timeout = 300 + +# How often (in seconds) should the scheduler check for task instances whose heartbeats have timed out. +# +# Variable: AIRFLOW__SCHEDULER__TASK_INSTANCE_HEARTBEAT_TIMEOUT_DETECTION_INTERVAL +# +task_instance_heartbeat_timeout_detection_interval = 10.0 + +# Turn on scheduler catchup by setting this to ``True``. +# Default behavior is unchanged and +# Command Line Backfills still work, but the scheduler +# will not do scheduler catchup if this is ``False``, +# however it can be set on a per DAG basis in the +# DAG definition (catchup) +# +# Variable: AIRFLOW__SCHEDULER__CATCHUP_BY_DEFAULT +# +catchup_by_default = False + +# Setting this to ``True`` will make first task instance of a task +# ignore depends_on_past setting. A task instance will be considered +# as the first task instance of a task when there is no task instance +# in the DB with a logical_date earlier than it., i.e. no manual marking +# success will be needed for a newly added task to be scheduled. +# +# Variable: AIRFLOW__SCHEDULER__IGNORE_FIRST_DEPENDS_ON_PAST_BY_DEFAULT +# +ignore_first_depends_on_past_by_default = True + +# This determines the number of task instances to be evaluated for scheduling +# during each scheduler loop. +# Set this to 0 to use the value of ``[core] parallelism`` +# +# Variable: AIRFLOW__SCHEDULER__MAX_TIS_PER_QUERY +# +max_tis_per_query = 16 + +# Should the scheduler issue ``SELECT ... FOR UPDATE`` in relevant queries. +# If this is set to ``False`` then you should not run more than a single +# scheduler at once +# +# Variable: AIRFLOW__SCHEDULER__USE_ROW_LEVEL_LOCKING +# +use_row_level_locking = True + +# Max number of DAGs to create DagRuns for per scheduler loop. +# +# Variable: AIRFLOW__SCHEDULER__MAX_DAGRUNS_TO_CREATE_PER_LOOP +# +max_dagruns_to_create_per_loop = 10 + +# How many DagRuns should a scheduler examine (and lock) when scheduling +# and queuing tasks. +# +# Variable: AIRFLOW__SCHEDULER__MAX_DAGRUNS_PER_LOOP_TO_SCHEDULE +# +max_dagruns_per_loop_to_schedule = 20 + +# The scheduler reads dag files to extract the airflow modules that are going to be used, +# and imports them ahead of time to avoid having to re-do it for each parsing process. +# This flag can be set to ``False`` to disable this behavior in case an airflow module needs +# to be freshly imported each time (at the cost of increased DAG parsing time). +# +# Variable: AIRFLOW__SCHEDULER__PARSING_PRE_IMPORT_MODULES +# +parsing_pre_import_modules = True + +# Time in seconds after which dags, which were not updated by Dag Processor are deactivated. +# +# Variable: AIRFLOW__SCHEDULER__DAG_STALE_NOT_SEEN_DURATION +# +dag_stale_not_seen_duration = 600 + +# Turn off scheduler use of cron intervals by setting this to ``False``. +# DAGs submitted manually in the web UI or with trigger_dag will still run. +# +# Variable: AIRFLOW__SCHEDULER__USE_JOB_SCHEDULE +# +use_job_schedule = True + +# How often to check for expired trigger requests that have not run yet. +# +# Variable: AIRFLOW__SCHEDULER__TRIGGER_TIMEOUT_CHECK_INTERVAL +# +trigger_timeout_check_interval = 15 + +# Amount of time a task can be in the queued state before being retried or set to failed. +# +# Variable: AIRFLOW__SCHEDULER__TASK_QUEUED_TIMEOUT +# +task_queued_timeout = 600.0 + +# How often to check for tasks that have been in the queued state for +# longer than ``[scheduler] task_queued_timeout``. +# +# Variable: AIRFLOW__SCHEDULER__TASK_QUEUED_TIMEOUT_CHECK_INTERVAL +# +task_queued_timeout_check_interval = 120.0 + +# The run_id pattern used to verify the validity of user input to the run_id parameter when +# triggering a DAG. This pattern cannot change the pattern used by scheduler to generate run_id +# for scheduled DAG runs or DAG runs triggered without changing the run_id parameter. +# +# Variable: AIRFLOW__SCHEDULER__ALLOWED_RUN_ID_PATTERN +# +allowed_run_id_pattern = ^[A-Za-z0-9_.~:+-]+$ + +# Whether to create DAG runs that span an interval or one single point in time for cron schedules, when +# a cron string is provided to ``schedule`` argument of a DAG. +# +# * ``True``: **CronDataIntervalTimetable** is used, which is suitable +# for DAGs with well-defined data interval. You get contiguous intervals from the end of the previous +# interval up to the scheduled datetime. +# * ``False``: **CronTriggerTimetable** is used, which is closer to the behavior of cron itself. +# +# Notably, for **CronTriggerTimetable**, the logical date is the same as the time the DAG Run will +# try to schedule, while for **CronDataIntervalTimetable**, the logical date is the beginning of +# the data interval, but the DAG Run will try to schedule at the end of the data interval. +# +# Variable: AIRFLOW__SCHEDULER__CREATE_CRON_DATA_INTERVALS +# +create_cron_data_intervals = False + +# Whether to create DAG runs that span an interval or one single point in time when a timedelta or +# relativedelta is provided to ``schedule`` argument of a DAG. +# +# * ``True``: **DeltaDataIntervalTimetable** is used, which is suitable for DAGs with well-defined data +# interval. You get contiguous intervals from the end of the previous interval up to the scheduled +# datetime. +# * ``False``: **DeltaTriggerTimetable** is used, which is suitable for DAGs that simply want to say +# e.g. "run this every day" and do not care about the data interval. +# +# Notably, for **DeltaTriggerTimetable**, the logical date is the same as the time the DAG Run will +# try to schedule, while for **DeltaDataIntervalTimetable**, the logical date is the beginning of +# the data interval, but the DAG Run will try to schedule at the end of the data interval. +# +# Variable: AIRFLOW__SCHEDULER__CREATE_DELTA_DATA_INTERVALS +# +create_delta_data_intervals = False + +# Whether to enable memory allocation tracing in the scheduler. If enabled, Airflow will start +# tracing memory allocation and log the top 10 memory usages at the error level upon receiving the +# signal SIGUSR1. +# This is an expensive operation and generally should not be used except for debugging purposes. +# +# Variable: AIRFLOW__SCHEDULER__ENABLE_TRACEMALLOC +# +enable_tracemalloc = False + +[triggerer] +# How many triggers a single Triggerer will run at once, by default. +# +# Variable: AIRFLOW__TRIGGERER__CAPACITY +# +capacity = 1000 + +# How often to heartbeat the Triggerer job to ensure it hasn't been killed. +# +# Variable: AIRFLOW__TRIGGERER__JOB_HEARTBEAT_SEC +# +job_heartbeat_sec = 5 + +# If the last triggerer heartbeat happened more than ``[triggerer] triggerer_health_check_threshold`` +# ago (in seconds), triggerer is considered unhealthy. +# This is used by the health check in the **/health** endpoint and in ``airflow jobs check`` CLI +# for TriggererJob. +# +# Variable: AIRFLOW__TRIGGERER__TRIGGERER_HEALTH_CHECK_THRESHOLD +# +triggerer_health_check_threshold = 30 + +[kerberos] +# Location of your ccache file once kinit has been performed. +# +# Variable: AIRFLOW__KERBEROS__CCACHE +# +ccache = /tmp/airflow_krb5_ccache + +# gets augmented with fqdn +# +# Variable: AIRFLOW__KERBEROS__PRINCIPAL +# +principal = airflow + +# Determines the frequency at which initialization or re-initialization processes occur. +# +# Variable: AIRFLOW__KERBEROS__REINIT_FREQUENCY +# +reinit_frequency = 3600 + +# Path to the kinit executable +# +# Variable: AIRFLOW__KERBEROS__KINIT_PATH +# +kinit_path = kinit + +# Designates the path to the Kerberos keytab file for the Airflow user +# +# Variable: AIRFLOW__KERBEROS__KEYTAB +# +keytab = airflow.keytab + +# Allow to disable ticket forwardability. +# +# Variable: AIRFLOW__KERBEROS__FORWARDABLE +# +forwardable = True + +# Allow to remove source IP from token, useful when using token behind NATted Docker host. +# +# Variable: AIRFLOW__KERBEROS__INCLUDE_IP +# +include_ip = True + +[sensors] +# Sensor default timeout, 7 days by default (7 * 24 * 60 * 60). +# +# Variable: AIRFLOW__SENSORS__DEFAULT_TIMEOUT +# +default_timeout = 604800 + +[dag_processor] +# Configuration for the Airflow DAG processor. This includes, for example: +# - DAG bundles, which allows Airflow to load DAGs from different sources +# - Parsing configuration, like: +# - how often to refresh DAGs from those sources +# - how many files to parse concurrently + +# String path to folder where Airflow bundles can store files locally. Not templated. +# If no path is provided, Airflow will use ``Path(tempfile.gettempdir()) / "airflow"``. +# This path must be absolute. +# +# Example: dag_bundle_storage_path = /tmp/some-place +# +# Variable: AIRFLOW__DAG_PROCESSOR__DAG_BUNDLE_STORAGE_PATH +# +# dag_bundle_storage_path = + +# List of backend configs. Must supply name, classpath, and kwargs for each backend. +# +# By default, ``refresh_interval`` is set to ``[dag_processor] refresh_interval``, but that can +# also be overridden in kwargs if desired. +# +# The default is the dags folder dag bundle. +# +# Note: As shown below, you can split your json config over multiple lines by indenting. +# See configparser documentation for an example: +# https://docs.python.org/3/library/configparser.html#supported-ini-file-structure. +# +# Example: dag_bundle_config_list = [ +# { +# "name": "my-git-repo", +# "classpath": "airflow.providers.git.bundles.git.GitDagBundle", +# "kwargs": { +# "subdir": "dags", +# "tracking_ref": "main", +# "refresh_interval": 0 +# } +# } +# ] +# +# Variable: AIRFLOW__DAG_PROCESSOR__DAG_BUNDLE_CONFIG_LIST +# +dag_bundle_config_list = [ + { + "name": "dags-folder", + "classpath": "airflow.dag_processing.bundles.local.LocalDagBundle", + "kwargs": {} + } + ] + + +# How often (in seconds) to refresh, or look for new files, in a DAG bundle. +# +# Variable: AIRFLOW__DAG_PROCESSOR__REFRESH_INTERVAL +# +refresh_interval = 300 + +# The DAG processor can run multiple processes in parallel to parse dags. +# This defines how many processes will run. +# +# Variable: AIRFLOW__DAG_PROCESSOR__PARSING_PROCESSES +# +parsing_processes = 2 + +# One of ``modified_time``, ``random_seeded_by_host`` and ``alphabetical``. +# The DAG processor will list and sort the dag files to decide the parsing order. +# +# * ``modified_time``: Sort by modified time of the files. This is useful on large scale to parse the +# recently modified DAGs first. +# * ``random_seeded_by_host``: Sort randomly across multiple DAG processors but with same order on the +# same host, allowing each processor to parse the files in a different order. +# * ``alphabetical``: Sort by filename +# +# Variable: AIRFLOW__DAG_PROCESSOR__FILE_PARSING_SORT_MODE +# +file_parsing_sort_mode = modified_time + +# The maximum number of callbacks that are fetched during a single loop. +# +# Variable: AIRFLOW__DAG_PROCESSOR__MAX_CALLBACKS_PER_LOOP +# +max_callbacks_per_loop = 20 + +# Number of seconds after which a DAG file is parsed. The DAG file is parsed every +# ``[dag_processor] min_file_process_interval`` number of seconds. Updates to DAGs are reflected after +# this interval. Keeping this number low will increase CPU usage. +# +# Variable: AIRFLOW__DAG_PROCESSOR__MIN_FILE_PROCESS_INTERVAL +# +min_file_process_interval = 30 + +# How long (in seconds) to wait after we have re-parsed a DAG file before deactivating stale +# DAGs (DAGs which are no longer present in the expected files). The reason why we need +# this threshold is to account for the time between when the file is parsed and when the +# DAG is loaded. The absolute maximum that this could take is +# ``[dag_processor] dag_file_processor_timeout``, but when you have a long timeout configured, +# it results in a significant delay in the deactivation of stale dags. +# +# Variable: AIRFLOW__DAG_PROCESSOR__STALE_DAG_THRESHOLD +# +stale_dag_threshold = 50 + +# How long before timing out a DagFileProcessor, which processes a dag file +# +# Variable: AIRFLOW__DAG_PROCESSOR__DAG_FILE_PROCESSOR_TIMEOUT +# +dag_file_processor_timeout = 50 + +# How often should DAG processor stats be printed to the logs. Setting to 0 will disable printing stats +# +# Variable: AIRFLOW__DAG_PROCESSOR__PRINT_STATS_INTERVAL +# +print_stats_interval = 30 + +# Always run tasks with the latest code. If set to True, the bundle version will not +# be stored on the dag run and therefore, the latest code will always be used. +# +# Variable: AIRFLOW__DAG_PROCESSOR__DISABLE_BUNDLE_VERSIONING +# +disable_bundle_versioning = False + +# How often the DAG processor should check if any DAG bundles are ready for a refresh, either by hitting +# the bundles refresh_interval or because another DAG processor has seen a newer version of the bundle. +# A low value means we check more frequently, and have a smaller window of time where DAG processors are +# out of sync with each other, parsing different versions of the same bundle. +# +# Variable: AIRFLOW__DAG_PROCESSOR__BUNDLE_REFRESH_CHECK_INTERVAL +# +bundle_refresh_check_interval = 5 + +# On shared workers, bundle copies accumulate in local storage as tasks run +# and version of the bundle changes. +# This setting represents the delta in seconds between checks for these stale bundles. +# Bundles which are older than `stale_bundle_cleanup_age_threshold` may be removed. But +# we always keep `stale_bundle_cleanup_min_versions` versions locally. +# Set to 0 or negative to disable. +# +# Variable: AIRFLOW__DAG_PROCESSOR__STALE_BUNDLE_CLEANUP_INTERVAL +# +stale_bundle_cleanup_interval = 1800 + +# Bundle versions used more recently than this threshold will not be removed. +# Recency of use is determined by when the task began running on the worker, +# that age is compared with this setting, given as time delta in seconds. +# +# Variable: AIRFLOW__DAG_PROCESSOR__STALE_BUNDLE_CLEANUP_AGE_THRESHOLD +# +stale_bundle_cleanup_age_threshold = 21600 + +# Minimum number of local bundle versions to retain on disk. +# Local bundle versions older than `stale_bundle_cleanup_age_threshold` will +# only be deleted we have more than `stale_bundle_cleanup_min_versions` versions +# accumulated on the worker. +# +# Variable: AIRFLOW__DAG_PROCESSOR__STALE_BUNDLE_CLEANUP_MIN_VERSIONS +# +stale_bundle_cleanup_min_versions = 10 + +[celery_kubernetes_executor] +# This section only applies if you are using the ``CeleryKubernetesExecutor`` in +# ``[core]`` section above + +# Define when to send a task to ``KubernetesExecutor`` when using ``CeleryKubernetesExecutor``. +# When the queue of a task is the value of ``kubernetes_queue`` (default ``kubernetes``), +# the task is executed via ``KubernetesExecutor``, +# otherwise via ``CeleryExecutor`` +# +# Variable: AIRFLOW__CELERY_KUBERNETES_EXECUTOR__KUBERNETES_QUEUE +# +kubernetes_queue = kubernetes + +[celery] +# This section only applies if you are using the CeleryExecutor in +# ``[core]`` section above + +# The app name that will be used by celery +# +# Variable: AIRFLOW__CELERY__CELERY_APP_NAME +# +celery_app_name = airflow.providers.celery.executors.celery_executor + +# The concurrency that will be used when starting workers with the +# ``airflow celery worker`` command. This defines the number of task instances that +# a worker will take, so size up your workers based on the resources on +# your worker box and the nature of your tasks +# +# Variable: AIRFLOW__CELERY__WORKER_CONCURRENCY +# +worker_concurrency = 16 + +# The maximum and minimum number of pool processes that will be used to dynamically resize +# the pool based on load.Enable autoscaling by providing max_concurrency,min_concurrency +# with the ``airflow celery worker`` command (always keep minimum processes, +# but grow to maximum if necessary). +# Pick these numbers based on resources on worker box and the nature of the task. +# If autoscale option is available, worker_concurrency will be ignored. +# https://docs.celeryq.dev/en/latest/reference/celery.bin.worker.html#cmdoption-celery-worker-autoscale +# +# Example: worker_autoscale = 16,12 +# +# Variable: AIRFLOW__CELERY__WORKER_AUTOSCALE +# +# worker_autoscale = + +# Used to increase the number of tasks that a worker prefetches which can improve performance. +# The number of processes multiplied by worker_prefetch_multiplier is the number of tasks +# that are prefetched by a worker. A value greater than 1 can result in tasks being unnecessarily +# blocked if there are multiple workers and one worker prefetches tasks that sit behind long +# running tasks while another worker has unutilized processes that are unable to process the already +# claimed blocked tasks. +# https://docs.celeryq.dev/en/stable/userguide/optimizing.html#prefetch-limits +# +# Variable: AIRFLOW__CELERY__WORKER_PREFETCH_MULTIPLIER +# +worker_prefetch_multiplier = 1 + +# Specify if remote control of the workers is enabled. +# In some cases when the broker does not support remote control, Celery creates lots of +# ``.*reply-celery-pidbox`` queues. You can prevent this by setting this to false. +# However, with this disabled Flower won't work. +# https://docs.celeryq.dev/en/stable/getting-started/backends-and-brokers/index.html#broker-overview +# +# Variable: AIRFLOW__CELERY__WORKER_ENABLE_REMOTE_CONTROL +# +worker_enable_remote_control = true + +# The Celery broker URL. Celery supports RabbitMQ, Redis and experimentally +# a sqlalchemy database. Refer to the Celery documentation for more information. +# +# Variable: AIRFLOW__CELERY__BROKER_URL +# +broker_url = redis://redis:6379/0 + +# The Celery result_backend. When a job finishes, it needs to update the +# metadata of the job. Therefore it will post a message on a message bus, +# or insert it into a database (depending of the backend) +# This status is used by the scheduler to update the state of the task +# The use of a database is highly recommended +# When not specified, sql_alchemy_conn with a db+ scheme prefix will be used +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#task-result-backend-settings +# +# Example: result_backend = db+postgresql://postgres:airflow@postgres/airflow +# +# Variable: AIRFLOW__CELERY__RESULT_BACKEND +# +# result_backend = + +# Optional configuration dictionary to pass to the Celery result backend SQLAlchemy engine. +# +# Example: result_backend_sqlalchemy_engine_options = {"pool_recycle": 1800} +# +# Variable: AIRFLOW__CELERY__RESULT_BACKEND_SQLALCHEMY_ENGINE_OPTIONS +# +result_backend_sqlalchemy_engine_options = + +# Celery Flower is a sweet UI for Celery. Airflow has a shortcut to start +# it ``airflow celery flower``. This defines the IP that Celery Flower runs on +# +# Variable: AIRFLOW__CELERY__FLOWER_HOST +# +flower_host = 0.0.0.0 + +# The root URL for Flower +# +# Example: flower_url_prefix = /flower +# +# Variable: AIRFLOW__CELERY__FLOWER_URL_PREFIX +# +flower_url_prefix = + +# This defines the port that Celery Flower runs on +# +# Variable: AIRFLOW__CELERY__FLOWER_PORT +# +flower_port = 5555 + +# Securing Flower with Basic Authentication +# Accepts user:password pairs separated by a comma +# +# Example: flower_basic_auth = user1:password1,user2:password2 +# +# Variable: AIRFLOW__CELERY__FLOWER_BASIC_AUTH +# +flower_basic_auth = + +# How many processes CeleryExecutor uses to sync task state. +# 0 means to use max(1, number of cores - 1) processes. +# +# Variable: AIRFLOW__CELERY__SYNC_PARALLELISM +# +sync_parallelism = 0 + +# Import path for celery configuration options +# +# Variable: AIRFLOW__CELERY__CELERY_CONFIG_OPTIONS +# +celery_config_options = airflow.providers.celery.executors.default_celery.DEFAULT_CELERY_CONFIG + +# +# Variable: AIRFLOW__CELERY__SSL_ACTIVE +# +ssl_active = False + +# Path to the client key. +# +# Variable: AIRFLOW__CELERY__SSL_KEY +# +ssl_key = + +# Path to the client certificate. +# +# Variable: AIRFLOW__CELERY__SSL_CERT +# +ssl_cert = + +# Path to the CA certificate. +# +# Variable: AIRFLOW__CELERY__SSL_CACERT +# +ssl_cacert = + +# Celery Pool implementation. +# Choices include: ``prefork`` (default), ``eventlet``, ``gevent`` or ``solo``. +# See: +# https://docs.celeryq.dev/en/latest/userguide/workers.html#concurrency +# https://docs.celeryq.dev/en/latest/userguide/concurrency/eventlet.html +# +# Variable: AIRFLOW__CELERY__POOL +# +pool = prefork + +# The number of seconds to wait before timing out ``send_task_to_executor`` or +# ``fetch_celery_task_state`` operations. +# +# Variable: AIRFLOW__CELERY__OPERATION_TIMEOUT +# +operation_timeout = 1.0 + +task_acks_late = True +# Celery task will report its status as 'started' when the task is executed by a worker. +# This is used in Airflow to keep track of the running tasks and if a Scheduler is restarted +# or run in HA mode, it can adopt the orphan tasks launched by previous SchedulerJob. +# +# Variable: AIRFLOW__CELERY__TASK_TRACK_STARTED +# +task_track_started = True + +# The Maximum number of retries for publishing task messages to the broker when failing +# due to ``AirflowTaskTimeout`` error before giving up and marking Task as failed. +# +# Variable: AIRFLOW__CELERY__TASK_PUBLISH_MAX_RETRIES +# +task_publish_max_retries = 3 + +# Extra celery configs to include in the celery worker. +# Any of the celery config can be added to this config and it +# will be applied while starting the celery worker. e.g. {"worker_max_tasks_per_child": 10} +# See also: +# https://docs.celeryq.dev/en/stable/userguide/configuration.html#configuration-and-defaults +# +# Variable: AIRFLOW__CELERY__EXTRA_CELERY_CONFIG +# +extra_celery_config = {} + +[celery_broker_transport_options] +# This section is for specifying options which can be passed to the +# underlying celery broker transport. See: +# https://docs.celeryq.dev/en/latest/userguide/configuration.html#std:setting-broker_transport_options + +# The visibility timeout defines the number of seconds to wait for the worker +# to acknowledge the task before the message is redelivered to another worker. +# Make sure to increase the visibility timeout to match the time of the longest +# ETA you're planning to use. +# visibility_timeout is only supported for Redis and SQS celery brokers. +# See: +# https://docs.celeryq.dev/en/stable/getting-started/backends-and-brokers/redis.html#visibility-timeout +# +# Example: visibility_timeout = 21600 +# +# Variable: AIRFLOW__CELERY_BROKER_TRANSPORT_OPTIONS__VISIBILITY_TIMEOUT +# +# visibility_timeout = + +# The sentinel_kwargs parameter allows passing additional options to the Sentinel client. +# In a typical scenario where Redis Sentinel is used as the broker and Redis servers are +# password-protected, the password needs to be passed through this parameter. Although its +# type is string, it is required to pass a string that conforms to the dictionary format. +# See: +# https://docs.celeryq.dev/en/stable/getting-started/backends-and-brokers/redis.html#configuration +# +# Example: sentinel_kwargs = {"password": "password_for_redis_server"} +# +# Variable: AIRFLOW__CELERY_BROKER_TRANSPORT_OPTIONS__SENTINEL_KWARGS +# +# sentinel_kwargs = + +[common.io] +# Common IO configuration section + +# Path to a location on object storage where XComs can be stored in url format. +# +# Example: xcom_objectstorage_path = s3://conn_id@bucket/path +# +# Variable: AIRFLOW__COMMON.IO__XCOM_OBJECTSTORAGE_PATH +# +xcom_objectstorage_path = + +# Threshold in bytes for storing XComs in object storage. -1 means always store in the +# database. 0 means always store in object storage. Any positive number means +# it will be stored in object storage if the size of the value is greater than the threshold. +# +# Example: xcom_objectstorage_threshold = 1000000 +# +# Variable: AIRFLOW__COMMON.IO__XCOM_OBJECTSTORAGE_THRESHOLD +# +xcom_objectstorage_threshold = -1 + +# Compression algorithm to use when storing XComs in object storage. Supported algorithms +# are a.o.: snappy, zip, gzip, bz2, and lzma. If not specified, no compression will be used. +# Note that the compression algorithm must be available in the Python installation (e.g. +# python-snappy for snappy). Zip, gz, bz2 are available by default. +# +# Example: xcom_objectstorage_compression = gz +# +# Variable: AIRFLOW__COMMON.IO__XCOM_OBJECTSTORAGE_COMPRESSION +# +xcom_objectstorage_compression = + +[standard] +# Options for the standard provider operators. + +# Which python tooling should be used to install the virtual environment. +# +# The following options are available: +# - ``auto``: Automatically select, use ``uv`` if available, otherwise use ``pip``. +# - ``pip``: Use pip to install the virtual environment. +# - ``uv``: Use uv to install the virtual environment. Must be available in environment PATH. +# +# Example: venv_install_method = uv +# +# Variable: AIRFLOW__STANDARD__VENV_INSTALL_METHOD +# +venv_install_method = auto + diff --git a/src/sportsbook_webscraper_pipeline/airflow/airflow.db b/src/sportsbook_webscraper_pipeline/airflow/airflow.db new file mode 100644 index 0000000000000000000000000000000000000000..e3f1ccbd8d683e085c04f7d0bb3374044127189f GIT binary patch literal 1495040 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
;H~g=l}0$s?`6b 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 Ln7RI6191NT3KYG` literal 0 HcmV?d00001 diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py new file mode 100644 index 0000000..5371687 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py @@ -0,0 +1,68 @@ +from sqlalchemy import create_engine, text as sql_text, Table, MetaData +import pandas as pd +import os +import sys +from dotenv import load_dotenv + +# Ensure project root is importable when executed by Airflow or standalone +PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from airflow_pipeline.api_scripts.fetch_bettingpros import get_bettingpros_df +from airflow_pipeline.api_scripts.fetch_prizepicks import get_prizepicks_df +from airflow_pipeline.api_scripts.fetch_draftedge import get_draftedge_df + +load_dotenv() +db_username = os.getenv("DB_USERNAME") +db_password = os.getenv("DB_PASSWORD") +db_host = os.getenv("DB_HOST", "localhost") +db_port = os.getenv("DB_PORT", "5432") +db_name = os.getenv("DB_NAME", "nba_deeplearning") + +connection_string = ( + f'postgresql+psycopg2://{db_username}:{db_password}@{db_host}:{db_port}/{db_name}' +) + +db_eng = create_engine(connection_string) +print("Successfully created db engine.") + +def append_to_postgres(df, table_name): + metadata = MetaData() + table = Table(table_name, metadata, autoload_with=db_eng) + + with db_eng.begin() as conn: # transaction automatically commits + for row in df.to_dict(orient='records'): + conn.execute(table.insert(), row) + +def check_if_table_exists(table_name): + query = sql_text( + "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name=:table)" + ) + with db_eng.connect() as conn: + result = conn.execute(query, {"table": table_name}) + return result.scalar() + +def check_df_columns(df): + table_columns = ['player_name', 'team', 'sportsbook', 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type'] + df_columns = df.columns.tolist() + return all(col in df_columns for col in table_columns) and len(df_columns) == len(table_columns) + +def __main__(table_name): + if not check_if_table_exists(table_name): + raise Exception(f"Table {table_name} does not exist.") + + dfs = [get_bettingpros_df(), get_prizepicks_df(), get_draftedge_df()] + for df in dfs: + if df.empty: + print(f"Skipping empty DataFrame...") + continue + if not check_df_columns(df): + raise Exception(f"df columns do not match WITH {table_name} attributes.") + append_to_postgres(df, table_name) + + print(f"Successfully appended dataframe of length {len(df)} to {table_name} in postgres.") + + +if __name__ == "__main__": + __main__('player_lines') diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py new file mode 100644 index 0000000..4193731 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py @@ -0,0 +1,59 @@ +""" +To run the dag in ../dag_setup + - set AIRFLOW_HOME=~/CursorProjects/webscrape/airflow + - airflow scheduler + +For airflow UI +airflow apiserver --port 8080 +""" +""" +To run the dag in ../dag_setup + - set AIRFLOW_HOME=~/CursorProjects/webscrape/airflow + - airflow standalone + +For airflow UI +airflow apiserver --port 8080 +""" + +from airflow.models.dag import DAG +from airflow.providers.standard.operators.python import PythonOperator +from datetime import datetime, timedelta +import sys, os + +API_SCRIPTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../airflow_pipeline/api_scripts')) +if API_SCRIPTS_PATH not in sys.path: + sys.path.insert(0, API_SCRIPTS_PATH) + +from migrate_to_postgres import __main__ as migrate_to_postgres_main + +default_args = { + 'owner': 'LineDancers', + 'depends_on_past': False, + 'start_date': datetime(2025, 11, 1), + 'email_on_failure': True, + 'email_on_retry': False, + 'retries': 3, + 'retry_delay': timedelta(minutes=5), +} + +dag = DAG( + dag_id='nba_sportsbook_pipeline', + default_args=default_args, + description='Daily NBA sportsbook data scraping and collection pipeline', + schedule="0 22 * * *", # <--- use cron string directly + catchup=False, + tags=['nba', 'betting', 'data-pipeline'], +) + +def migrate_to_postgres_task(): + table_name = 'player_lines' + migrate_to_postgres_main(table_name) + +task_migrate_to_postgres = PythonOperator( + task_id='migrate_to_postgres', + python_callable=migrate_to_postgres_task, + dag=dag, +) + +# Only one task now, no fetch tasks needed +print("File ran?") diff --git a/src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated b/src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated new file mode 100644 index 0000000..132cded --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated @@ -0,0 +1 @@ +{"admin": "PZrYMfcmHMNKypbp"} diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py new file mode 100644 index 0000000..4d50b17 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py @@ -0,0 +1,228 @@ +import requests +import json +import pandas as pd +from datetime import datetime +import sys + +def fetch_nba_props(): + """Fetch NBA props from BettingPros API""" + url = "https://api.bettingpros.com/v3/props" + + params = { + 'limit': 2000, + 'sport': 'NBA', + 'market_id': '', + 'event_id': '', + 'location': 'ALL', + 'sort': 'bet_rating', + 'include_events': 'true', + 'include_selections': 'false', + 'include_markets': 'true', + 'include_books': 'true' + } + + try: + response = requests.get(url, params=params, timeout=30) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"Error fetching data: {e}", file=sys.stderr) + return None + +def parse_props(data): + """ + Parse BettingPros API response and extract standardized prop data. + Only includes base lines for single-player stats. + """ + if not data or 'props' not in data: + return [] + + parsed_props = [] + time_scraped = datetime.now().isoformat() + + # Create lookup dictionaries for events and markets + events_dict = {event['id']: event for event in data.get('events', [])} + markets_dict = {market['id']: market for market in data.get('markets', [])} + books_dict = {book['id']: book for book in data.get('books', [])} + + + for prop in data['props']: + try: + prop_type = prop.get('type', '') + if any(keyword in prop_type.lower() for keyword in ['combo', 'parlay', 'sgp', 'same game']): + continue + + market_id = prop.get('market_id') + market = markets_dict.get(market_id) + line_type = market.get('meta', {}).get('short_label') + line_type = line_type.replace(' + ', '+') + + participants = prop.get('participants', []) + if isinstance(participants, list) and len(participants) > 1: + continue + + # FILTER 3: Skip alternate lines (only keep main/standard lines) + is_alternate = prop.get('is_alternate', False) + is_main = prop.get('is_main', True) + + if is_alternate or not is_main: + continue + + # FILTER 4: Skip boosted or promotional lines + is_boosted = prop.get('is_boosted', False) + is_promo = prop.get('is_promotional', False) + + if is_boosted or is_promo: + continue + + # Get player info from participant + participant = prop.get('participant', {}) + player_info = participant.get('player', {}) + player_name = participant.get('name', '') + + # FILTER 5: Ensure we have a single player name + if not player_name: + continue + + # Check if player_name contains multiple players + if any(separator in player_name for separator in [' & ', ' and ', ' + ', ',']): + continue + + # Get team info + team = player_info.get('team', '') + + # Get event info + event_id = prop.get('event_id') + event = events_dict.get(event_id) + game_start = None + opponent_team = None + + if event: + game_start = event.get('scheduled', '') + + # Get home and away teams + visitor_id = event.get('visitor') + home_id = event.get('home') + participants_list = event.get('participants', []) + + visitor = next((p for p in participants_list if p['id'] == visitor_id), None) + home = next((p for p in participants_list if p['id'] == home_id), None) + + if visitor and home: + visitor_team = visitor.get('team', {}).get('abbreviation', '') + home_team = home.get('team', {}).get('abbreviation', '') + + # Determine opponent based on player's team + if team and visitor_team and home_team: + opponent_team = home_team if team == visitor_team else visitor_team + + # Get line info from consensus (base line) + over_info = prop.get('over', {}) + line_score = over_info.get('consensus_line') + + # Get book-specific lines if available + book_lines = prop.get('books', []) + + if book_lines: + # Process each sportsbook separately + for book_data in book_lines: + # FILTER 6: Skip books with promotional or alternate lines + book_is_alternate = book_data.get('is_alternate', False) + book_is_promo = book_data.get('is_promo', False) + + if book_is_alternate or book_is_promo: + continue + + book_id = book_data.get('book_id') + book_info = books_dict.get(book_id, {}) + sportsbook = book_info.get('name', 'Unknown') + + book_line = book_data.get('line') + + parsed_prop = { + 'player_name': player_name, + 'team': team, + 'sportsbook': sportsbook, + 'line_score': float(book_line) if book_line is not None else None, + 'game_start': game_start, + 'time_scraped': time_scraped, + 'opponent_team': opponent_team, + 'line_type': line_type, + } + + parsed_props.append(parsed_prop) + else: + # Use consensus line if no book-specific lines + parsed_prop = { + 'player_name': player_name, + 'team': team, + 'sportsbook': 'BettingPros', + 'line_score': float(line_score) if line_score is not None else None, + 'game_start': game_start, + 'time_scraped': time_scraped, + 'opponent_team': opponent_team, + 'line_type': line_type + } + + parsed_props.append(parsed_prop) + + except Exception as e: + print(f"Error processing prop: {e}", file=sys.stderr) + continue + + return parsed_props + +def get_bettingpros_df(): + """ + Fetch BettingPros data and return as DataFrame with standardized schema. + + Returns: + pd.DataFrame: DataFrame with columns ['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team'] + """ + try: + data = fetch_nba_props() + + if not data: + print("Warning: No data retrieved from BettingPros") + return pd.DataFrame(columns=['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']) + + parsed_props = parse_props(data) + + if not parsed_props: + print("Warning: No props found after filtering") + return pd.DataFrame(columns=['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']) + + # Convert to DataFrame with explicit column order + df = pd.DataFrame(parsed_props) + df = df[['player_name', 'team', 'sportsbook', 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']] + + print(f"BettingPros: Successfully retrieved {len(df)} records") + return df + + except Exception as e: + print(f"Error fetching BettingPros data: {e}", file=sys.stderr) + return pd.DataFrame(columns=['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team','line_type']) + + + +def main(): + """ + Main execution function + """ + print("Fetching NBA player props from BettingPros...") + + # Fetch and parse data + df = get_bettingpros_df() + + print(df) + if df.empty: + print("No props found in response") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py new file mode 100644 index 0000000..a0db3be --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py @@ -0,0 +1,191 @@ +import requests +import json +import pandas as pd +from datetime import datetime +import sys + +DRAFTEDGE_API = "https://draftedge.com/draftedge-data/nbaprops1.json" + +def fetch_draftedge_data(): + """Fetch NBA props from DraftEdge API""" + try: + response = requests.get(DRAFTEDGE_API, timeout=30) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"Error fetching DraftEdge data: {e}", file=sys.stderr) + return None + +def parse_draftedge_props(data): + """ + Parse DraftEdge API response and extract standardized prop data. + Extracts all prop types (points, rebounds, assists, combos, etc.). + + Returns: + list: List of dictionaries with standardized schema + """ + if not data: + return [] + + parsed_props = [] + time_scraped = datetime.now().isoformat() + + for player_id, player_data in data.items(): + try: + # Get basic player info + player_name = player_data.get('Player') + team = player_data.get('DFS_Team') + opponent_team = player_data.get('Opp') + game_time = player_data.get('GameTime') + + # Skip if missing essential info + if not player_name or not team: + continue + + # Convert game time to ISO format if possible + game_start = None + if game_time: + try: + # Normalize spaces and remove any timezone abbreviation + clean_time = game_time.replace("EDT", "").replace("EST", "").strip() + # Expect format like "11-03 19:00" + current_year = datetime.now().year + parsed_dt = datetime.strptime(f"{current_year}-{clean_time}", "%Y-%m-%d %H:%M") + game_start = parsed_dt.isoformat() + except Exception: + # fallback: keep original string so we can inspect later + game_start = game_time + + # Get prop data + prop_data = player_data.get('PropData', {}) + + if not prop_data: + continue + + # Define sportsbooks that typically provide main lines only + # These books usually have 1-2 lines max and don't clutter with alternates + MAIN_LINE_BOOKS = { + 'fanduel', 'draftkings', 'betmgm', 'fanatics', + 'williamhill_us', 'betonlineag' + } + + # Map DraftEdge prop types to standardized line_type names + PROP_TYPE_MAPPING = { + 'PropPts': 'points', + 'PropReb': 'rebounds', + 'PropAst': 'assists', + 'PropFG3PM': '3-pointers', + 'PropPtsReb': 'points+rebounds', + 'PropPtsAst': 'points+assists', + 'PropPtsRebAst': 'points+rebounds+assists' + } + + # Process each prop type (points, rebounds, assists, etc.) + for prop_type_key, line_type in PROP_TYPE_MAPPING.items(): + props_list = prop_data.get(prop_type_key, []) + + if not props_list: + continue + + # Track unique lines per bookmaker for this stat type + bookmaker_lines = {} + + # Process each sportsbook's line for this stat + for prop in props_list: + bet_type = prop.get('BetType') + + # Only process "Over" lines (the line score is the same for Over/Under) + if bet_type != 'Over': + continue + + line_score = prop.get('Line') + bookmaker = prop.get('Bookmaker') + + # Skip if missing essential prop info + if line_score is None or not bookmaker: + continue + + # FILTER: Only include main line sportsbooks + if bookmaker.lower() not in MAIN_LINE_BOOKS: + continue + + # Track lines by bookmaker (use dict to avoid duplicates) + if bookmaker not in bookmaker_lines: + bookmaker_lines[bookmaker] = line_score + + # Create one row per bookmaker with their line for this stat type + for bookmaker, line_score in bookmaker_lines.items(): + # Format bookmaker name (capitalize first letter) + sportsbook = bookmaker.replace('_', ' ').title() + + parsed_prop = { + 'player_name': player_name, + 'team': team, + 'sportsbook': sportsbook, + 'line_score': float(line_score), + 'game_start': game_start, + 'time_scraped': time_scraped, + 'opponent_team': opponent_team, + 'line_type': line_type + } + + parsed_props.append(parsed_prop) + + except Exception as e: + print(f"Error processing player {player_id}: {e}", file=sys.stderr) + continue + + return parsed_props + +def get_draftedge_df(): + """ + Fetch DraftEdge data and return as DataFrame with standardized schema. + + Returns: + pd.DataFrame: DataFrame with columns ['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type'] + """ + try: + data = fetch_draftedge_data() + + if not data: + print("Warning: No data retrieved from DraftEdge") + return pd.DataFrame(columns=['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']) + + parsed_props = parse_draftedge_props(data) + + if not parsed_props: + print("Warning: No props found after filtering") + return pd.DataFrame(columns=['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']) + + # Convert to DataFrame with explicit column order + df = pd.DataFrame(parsed_props) + df = df[['player_name', 'team', 'sportsbook', 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']] + + print(f"DraftEdge: Successfully retrieved {len(df)} records from {df['sportsbook'].nunique()} sportsbooks") + return df + + except Exception as e: + print(f"Error fetching DraftEdge data: {e}", file=sys.stderr) + return pd.DataFrame(columns=['player_name', 'team', 'sportsbook', + 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type']) + +def main(): + """ + Main execution function + """ + print("Fetching NBA player props from DraftEdge...") + + # Fetch and parse data + df = get_draftedge_df() + + print(df.head(20)) + + if df.empty: + print("No props found in response") + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py new file mode 100644 index 0000000..5bb07d4 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py @@ -0,0 +1,147 @@ +import requests +import pandas as pd +from datetime import datetime +import sys + +PRIZEPICKS_API = "https://api.prizepicks.com/projections" + +NBA_TEAMS = { + 'ATL', 'BOS', 'BKN', 'BRK', 'CHA', 'CHI', 'CLE', 'DAL', 'DEN', 'DET', 'GSW', + 'HOU', 'IND', 'LAC', 'LAL', 'MEM', 'MIA', 'MIL', 'MIN', 'NOP', 'NYK', + 'OKC', 'ORL', 'PHI', 'PHX', 'POR', 'SAC', 'SAS', 'TOR', 'UTA', 'WAS' +} + +def get_prizepicks_data(): + """Fetch data from PrizePicks API""" + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', + 'Accept': 'application/json', + 'Referer': 'https://app.prizepicks.com/', + 'Origin': 'https://app.prizepicks.com', + 'Host': 'api.prizepicks.com', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site', + } + + try: + response = requests.get(PRIZEPICKS_API, headers=headers, timeout=30) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"Error: {e}", file=sys.stderr) + return None + + +def filter_projections(data): + """Filter and standardize PrizePicks projections""" + if not data: + return [] + + projections = data.get('data', []) + included = data.get('included', []) + + players = {p['id']: p for p in included if p['type'] == 'new_player'} + leagues = {l['id']: l for l in included if l['type'] == 'league'} + stat_types = {s['id']: s for s in included if s['type'] == 'stat_type'} + events = {e['id']: e for e in included if e['type'] == 'event'} + teams = {t['id']: t for t in included if t['type'] == 'team'} + + time_scraped = datetime.now().isoformat() + results = [] + + for proj in projections: + try: + attrs = proj.get('attributes', {}) + rels = proj.get('relationships', {}) + + # Check NBA league + league_id = rels.get('league', {}).get('data', {}).get('id') + if league_id: + league = leagues.get(league_id, {}) + if 'NBA' not in league.get('attributes', {}).get('name', '').upper(): + continue + + # Filter out special modes and non-base lines + if any([ + attrs.get('projection_type', '').lower() in ['goblin', 'demon', 'special', 'multiplier'], + any(k in attrs.get('board_name', '').lower() for k in ['goblin', 'demon', 'multiplier', 'combo', 'parlay']), + attrs.get('odds_type', '').lower() != 'standard', + attrs.get('is_promo', False), + attrs.get('is_boosted', False), + attrs.get('is_alternate', False) + ]): + continue + + # Get player info + player_id = rels.get('new_player', {}).get('data', {}).get('id') + if not player_id: + continue + + player_attrs = players.get(player_id, {}).get('attributes', {}) + player_name = player_attrs.get('name') or player_attrs.get('display_name') + team = player_attrs.get('team') + + # Validate single NBA player + if not player_name or team not in NBA_TEAMS: + continue + + if any(sep in player_name for sep in [' & ', ' and ', ' + ', ',']): + continue + + # Extract opponent + description = attrs.get('description', '') + + results.append({ + 'player_name': player_name, + 'team': team, + 'sportsbook': 'PrizePicks', + 'line_score': attrs.get('line_score'), + 'game_start': attrs.get('start_time'), + 'time_scraped': time_scraped, + 'opponent_team': attrs.get('description'), + 'line_type': attrs.get('stat_type') + }) + + except Exception as e: + continue + + return results + +def get_prizepicks_df(): + """ + Fetch PrizePicks NBA projections and return as DataFrame. + + Returns: + pd.DataFrame: Columns ['player_name', 'team', 'sportsbook', 'line_score', + 'line_type', 'game_start', 'time_scraped', 'opponent_team'] + """ + columns = ['player_name', 'team', 'sportsbook', 'line_score', + 'game_start', 'time_scraped', 'opponent_team', 'line_type'] + + try: + data = get_prizepicks_data() + if not data: + return pd.DataFrame(columns=columns) + + filtered = filter_projections(data) + if not filtered: + print("Warning: No NBA projections found") + return pd.DataFrame(columns=columns) + + df = pd.DataFrame(filtered)[columns] + print(f"PrizePicks: Retrieved {len(df)} NBA projections") + return df + + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + return pd.DataFrame(columns=columns) + +def main(): + """Main execution""" + df = get_prizepicks_df() + if df.empty: + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py new file mode 100644 index 0000000..f644d96 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py @@ -0,0 +1,189 @@ +import requests +import json +import pandas as pd +from datetime import datetime +import sys + +def fetch_nba_props(): + """ + Fetch NBA player props from BettingPros API + + Returns: + dict: JSON response from API + """ + url = "https://api.bettingpros.com/v3/props" + + params = { + 'limit': 250, + 'sport': 'NBA', + 'market_id': '', + 'event_id': '', + 'location': 'ALL', + 'sort': 'bet_rating', + 'include_events': 'true', + 'include_selections': 'false', + 'include_markets': 'true', + 'include_books': 'true' + } + + try: + response = requests.get(url, params=params, timeout=30) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"Error fetching data: {e}", file=sys.stderr) + return None + +def parse_props(data): + """ + Parse props data into a structured format + + Args: + data (dict): Raw API response + + Returns: + list: List of dictionaries containing parsed prop data + """ + if not data or 'props' not in data: + return [] + + parsed_props = [] + + # Create lookup dictionaries for events and markets + events_dict = {event['id']: event for event in data.get('events', [])} + markets_dict = {market['id']: market for market in data.get('markets', [])} + + for prop in data['props']: + # Get player info from participant + participant = prop.get('participant', {}) + player_info = participant.get('player', {}) + + # Get event info + event = events_dict.get(prop.get('event_id')) + event_name = None + if event: + visitor = next((p for p in event.get('participants', []) if p['id'] == event['visitor']), {}) + home = next((p for p in event.get('participants', []) if p['id'] == event['home']), {}) + event_name = f"{visitor.get('team', {}).get('city', '')} @ {home.get('team', {}).get('city', '')}" + + # Get market info + market = markets_dict.get(prop.get('market_id')) + market_name = market.get('meta', {}).get('short_label', 'Unknown') if market else 'Unknown' + + # Get over/under info + line_info = prop.get('over', {}) + projection = prop.get('projection', {}) + + parsed_prop = { + 'timestamp': datetime.now().isoformat(), + 'player_name': participant.get('name', 'Unknown'), + 'player_team': player_info.get('team', ''), + 'player_position': player_info.get('position', ''), + 'market_name': market_name, + 'event_name': event_name, + 'event_start_time': event.get('scheduled', '') if event else '', + 'line': line_info.get('consensus_line'), + } + + parsed_props.append(parsed_prop) + + return parsed_props + +def save_to_csv(props, filename=None): + """ + Save props data to CSV file + + Args: + props (list): List of parsed prop dictionaries + filename (str): Output filename (default: nba_props_YYYYMMDD_HHMMSS.csv) + """ + if not props: + print("No props to save", file=sys.stderr) + return + + if filename is None: + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + filename = f'nba_props_{timestamp}.csv' + + df = pd.DataFrame(props) + df.to_csv(filename, index=False) + print(f"Saved {len(props)} props to {filename}") + +def save_to_json(props, filename=None): + """ + Save props data to JSON file + + Args: + props (list): List of parsed prop dictionaries + filename (str): Output filename (default: nba_props_YYYYMMDD_HHMMSS.json) + """ + if not props: + print("No props to save", file=sys.stderr) + return + + if filename is None: + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + filename = f'nba_props_{timestamp}.json' + + with open(filename, 'w') as f: + json.dump(props, f, indent=2) + + print(f"Saved {len(props)} props to {filename}") + +def print_summary(props): + """ + Print a summary of the scraped props + + Args: + props (list): List of parsed prop dictionaries + """ + if not props: + print("No props found") + return + + df = pd.DataFrame(props) + + print("\n" + "="*80) + print(f"NBA PROPS SUMMARY - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + print("="*80) + print(f"\nTotal Props: {len(props)}") + print(f"\nUnique Players: {df['player_name'].nunique()}") + print(f"Unique Markets: {df['market_name'].nunique()}") + print(f"Unique Games: {df['event_name'].nunique()}") + + print("\nTop 5 Markets:") + print(df['market_name'].value_counts().head()) + + + print("="*80 + "\n") + +def main(): + """ + Main execution function + """ + print("Fetching NBA player props...") + + # Fetch data + data = fetch_nba_props() + + if not data: + sys.exit(1) + + # Parse props + props = parse_props(data) + + if not props: + print("No props found in response") + sys.exit(1) + + # Print summary + print_summary(props) + + # Save to files + save_to_csv(props) + save_to_json(props) + + print("Scraping completed successfully!") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py new file mode 100644 index 0000000..f460552 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py @@ -0,0 +1,92 @@ +import requests +import pandas as pd +from datetime import datetime, UTC + +def fetch_prizepicks_nba_baseline_points(): + url = "https://api.prizepicks.com/projections" + params = {"per_page": 500, "single_stat": "true"} + headers = { + "Accept": "application/json; charset=UTF-8", + "User-Agent": "Mozilla/5.0", + "Referer": "https://app.prizepicks.com/" + } + + resp = requests.get(url, headers=headers, params=params, timeout=15) + resp.raise_for_status() + data = resp.json() + + projections = pd.json_normalize(data["data"]) + included = pd.json_normalize(data["included"]) + + players = included[included["type"] == "new_player"] + stat_types = included[included["type"] == "stat_type"] + + players = players[ + ["id", "attributes.name", "attributes.league", "attributes.team_name"] + ].rename(columns={ + "id": "player_id", + "attributes.name": "player_name", + "attributes.league": "league", + "attributes.team_name": "team" + }) + + stat_types = stat_types[["id", "attributes.name"]].rename( + columns={"id": "stat_type_id", "attributes.name": "stat_type"} + ) + + projections["player_id"] = projections["relationships.new_player.data.id"] + projections["stat_type_id"] = projections["relationships.stat_type.data.id"] + + merged = ( + projections.merge(players, on="player_id", how="left") + .merge(stat_types, on="stat_type_id", how="left") + ) + + # --- Filter NBA + Points only --- + merged = merged[ + (merged["league"].str.upper() == "NBA") + & (merged["stat_type"].str.lower() == "points") + ] + + # --- Fill missing indicator columns with False --- + for col in [ + "attributes.is_promo", + "attributes.is_flex", + "attributes.is_alternate", + "attributes.odds_type", + ]: + if col not in merged.columns: + merged[col] = False + + # --- Keep baseline (standard) projections only --- + baseline_mask = ( + (merged["attributes.is_promo"] == False) + & (merged["attributes.is_flex"] == False) + & (merged["attributes.is_alternate"] == False) + & (merged["attributes.odds_type"].isin(["standard", None, False])) + ) + merged = merged[baseline_mask] + + # --- Deduplicate: one projection per player/stat type --- + merged = merged.sort_values("id").drop_duplicates(subset=["player_name", "stat_type"], keep="first") + + df = merged[[ + "player_name", "team", "league", + "attributes.line_score", "stat_type", + "attributes.start_time", "attributes.updated_at" + ]].rename(columns={ + "attributes.line_score": "line_score", + "attributes.start_time": "start_time", + "attributes.updated_at": "updated_at" + }) + + df["scrape_time"] = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S") + + filename = f"nba_points_baseline_{datetime.now(UTC).strftime('%Y%m%d_%H%M')}.csv" + df.to_csv(filename, index=False) + print(f"✅ Saved {len(df)} NBA baseline 'Points' projections to {filename}") + return df + +if __name__ == "__main__": + df = fetch_prizepicks_nba_baseline_points() + print(df.head(20)) diff --git a/src/sportsbook_webscraper_pipeline/docker-compose.yml b/src/sportsbook_webscraper_pipeline/docker-compose.yml new file mode 100644 index 0000000..feedbc0 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/docker-compose.yml @@ -0,0 +1,40 @@ +version: "3.9" + +services: + postgres: + image: postgres:15 + restart: always + environment: + POSTGRES_USER: line_dancer + POSTGRES_PASSWORD: sportsbook_data + POSTGRES_DB: nba_deeplearning + volumes: + - postgres_data:/var/lib/postgresql/data + ports: + - "5433:5432" + + airflow: + build: . + depends_on: + - postgres + restart: always + environment: + - DB_USERNAME=line_dancer + - DB_PASSWORD=sportsbook_data + - DB_HOST=postgres + - DB_PORT=5432 + - DB_NAME=nba_deeplearning + - AIRFLOW__CORE__EXECUTOR=SequentialExecutor + - AIRFLOW__CORE__LOAD_EXAMPLES=False + - AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION=False + - AIRFLOW__WEBSERVER__AUTHENTICATE=True + - AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_USERNAME=admin + - AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_PASSWORD=M7fhanqeB2mUPSpe + ports: + - "8080:8080" + volumes: + - ./airflow/dags:/opt/airflow/dags:ro + - ./airflow_pipeline:/opt/airflow/airflow_pipeline:ro + +volumes: + postgres_data: diff --git a/src/sportsbook_webscraper_pipeline/requirements.txt b/src/sportsbook_webscraper_pipeline/requirements.txt new file mode 100644 index 0000000..c5bdf13 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/requirements.txt @@ -0,0 +1,13 @@ +# NBA Sportsbook Pipeline Dependencies +requests==2.31.0 +pandas==2.1.4 + +# Airflow +# apache-airflow==2.8.0 + +# PostgreSQL +psycopg2-binary==2.9.9 +SQLAlchemy==1.4.52 +python-dotenv==1.0.1 + +python-dateutil==2.8.2 From 1c986b71e075fbb2a52995dfda7c43512212a453 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 12 Nov 2025 13:43:45 -0800 Subject: [PATCH 02/21] chore(sportsbooks): delete old requirements.txt --- .../requirements.txt | 13 - uv.lock | 908 +++++++++++------- 2 files changed, 582 insertions(+), 339 deletions(-) delete mode 100644 src/sportsbook_webscraper_pipeline/requirements.txt diff --git a/src/sportsbook_webscraper_pipeline/requirements.txt b/src/sportsbook_webscraper_pipeline/requirements.txt deleted file mode 100644 index c5bdf13..0000000 --- a/src/sportsbook_webscraper_pipeline/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -# NBA Sportsbook Pipeline Dependencies -requests==2.31.0 -pandas==2.1.4 - -# Airflow -# apache-airflow==2.8.0 - -# PostgreSQL -psycopg2-binary==2.9.9 -SQLAlchemy==1.4.52 -python-dotenv==1.0.1 - -python-dateutil==2.8.2 diff --git a/uv.lock b/uv.lock index 889a6b7..3a98de6 100644 --- a/uv.lock +++ b/uv.lock @@ -1,4 +1,5 @@ version = 1 +revision = 3 requires-python = ">=3.12" resolution-markers = [ "python_full_version < '3.13'", @@ -9,60 +10,60 @@ resolution-markers = [ name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] name = "certifi" version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286 }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655 }, - { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223 }, - { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366 }, - { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104 }, - { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830 }, - { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854 }, - { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670 }, - { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501 }, - { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173 }, - { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822 }, - { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543 }, - { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326 }, - { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008 }, - { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196 }, - { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819 }, - { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350 }, - { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644 }, - { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468 }, - { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187 }, - { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699 }, - { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580 }, - { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366 }, - { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342 }, - { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995 }, - { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640 }, - { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636 }, - { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939 }, - { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580 }, - { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870 }, - { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797 }, - { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224 }, - { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086 }, - { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400 }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175 }, +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, + { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, + { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, + { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, + { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, + { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, + { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, + { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, + { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, + { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, + { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, + { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, ] [[package]] @@ -70,47 +71,130 @@ name = "click" version = "8.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943 } +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295 }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.11.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d2/59/9698d57a3b11704c7b89b21d69e9d23ecf80d538cabb536c8b63f4a12322/coverage-7.11.3.tar.gz", hash = "sha256:0f59387f5e6edbbffec2281affb71cdc85e0776c1745150a3ab9b6c1d016106b", size = 815210, upload-time = "2025-11-10T00:13:17.18Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/39/af056ec7a27c487e25c7f6b6e51d2ee9821dba1863173ddf4dc2eebef4f7/coverage-7.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b771b59ac0dfb7f139f70c85b42717ef400a6790abb6475ebac1ecee8de782f", size = 216676, upload-time = "2025-11-10T00:11:11.566Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f8/21126d34b174d037b5d01bea39077725cbb9a0da94a95c5f96929c695433/coverage-7.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:603c4414125fc9ae9000f17912dcfd3d3eb677d4e360b85206539240c96ea76e", size = 217034, upload-time = "2025-11-10T00:11:13.12Z" }, + { url = "https://files.pythonhosted.org/packages/d5/3f/0fd35f35658cdd11f7686303214bd5908225838f374db47f9e457c8d6df8/coverage-7.11.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:77ffb3b7704eb7b9b3298a01fe4509cef70117a52d50bcba29cffc5f53dd326a", size = 248531, upload-time = "2025-11-10T00:11:15.023Z" }, + { url = "https://files.pythonhosted.org/packages/8f/59/0bfc5900fc15ce4fd186e092451de776bef244565c840c9c026fd50857e1/coverage-7.11.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4d4ca49f5ba432b0755ebb0fc3a56be944a19a16bb33802264bbc7311622c0d1", size = 251290, upload-time = "2025-11-10T00:11:16.628Z" }, + { url = "https://files.pythonhosted.org/packages/71/88/d5c184001fa2ac82edf1b8f2cd91894d2230d7c309e937c54c796176e35b/coverage-7.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05fd3fb6edff0c98874d752013588836f458261e5eba587afe4c547bba544afd", size = 252375, upload-time = "2025-11-10T00:11:18.249Z" }, + { url = "https://files.pythonhosted.org/packages/5c/29/f60af9f823bf62c7a00ce1ac88441b9a9a467e499493e5cc65028c8b8dd2/coverage-7.11.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0e920567f8c3a3ce68ae5a42cf7c2dc4bb6cc389f18bff2235dd8c03fa405de5", size = 248946, upload-time = "2025-11-10T00:11:20.202Z" }, + { url = "https://files.pythonhosted.org/packages/67/16/4662790f3b1e03fce5280cad93fd18711c35980beb3c6f28dca41b5230c6/coverage-7.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4bec8c7160688bd5a34e65c82984b25409563134d63285d8943d0599efbc448e", size = 250310, upload-time = "2025-11-10T00:11:21.689Z" }, + { url = "https://files.pythonhosted.org/packages/8f/75/dd6c2e28308a83e5fc1ee602f8204bd3aa5af685c104cb54499230cf56db/coverage-7.11.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:adb9b7b42c802bd8cb3927de8c1c26368ce50c8fdaa83a9d8551384d77537044", size = 248461, upload-time = "2025-11-10T00:11:23.384Z" }, + { url = "https://files.pythonhosted.org/packages/16/fe/b71af12be9f59dc9eb060688fa19a95bf3223f56c5af1e9861dfa2275d2c/coverage-7.11.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c8f563b245b4ddb591e99f28e3cd140b85f114b38b7f95b2e42542f0603eb7d7", size = 248039, upload-time = "2025-11-10T00:11:25.07Z" }, + { url = "https://files.pythonhosted.org/packages/11/b8/023b2003a2cd96bdf607afe03d9b96c763cab6d76e024abe4473707c4eb8/coverage-7.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e2a96fdc7643c9517a317553aca13b5cae9bad9a5f32f4654ce247ae4d321405", size = 249903, upload-time = "2025-11-10T00:11:26.992Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ee/5f1076311aa67b1fa4687a724cc044346380e90ce7d94fec09fd384aa5fd/coverage-7.11.3-cp312-cp312-win32.whl", hash = "sha256:e8feeb5e8705835f0622af0fe7ff8d5cb388948454647086494d6c41ec142c2e", size = 219201, upload-time = "2025-11-10T00:11:28.619Z" }, + { url = "https://files.pythonhosted.org/packages/4f/24/d21688f48fe9fcc778956680fd5aaf69f4e23b245b7c7a4755cbd421d25b/coverage-7.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:abb903ffe46bd319d99979cdba350ae7016759bb69f47882242f7b93f3356055", size = 220012, upload-time = "2025-11-10T00:11:30.234Z" }, + { url = "https://files.pythonhosted.org/packages/4f/9e/d5eb508065f291456378aa9b16698b8417d87cb084c2b597f3beb00a8084/coverage-7.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:1451464fd855d9bd000c19b71bb7dafea9ab815741fb0bd9e813d9b671462d6f", size = 218652, upload-time = "2025-11-10T00:11:32.165Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f6/d8572c058211c7d976f24dab71999a565501fb5b3cdcb59cf782f19c4acb/coverage-7.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84b892e968164b7a0498ddc5746cdf4e985700b902128421bb5cec1080a6ee36", size = 216694, upload-time = "2025-11-10T00:11:34.296Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f6/b6f9764d90c0ce1bce8d995649fa307fff21f4727b8d950fa2843b7b0de5/coverage-7.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f761dbcf45e9416ec4698e1a7649248005f0064ce3523a47402d1bff4af2779e", size = 217065, upload-time = "2025-11-10T00:11:36.281Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8d/a12cb424063019fd077b5be474258a0ed8369b92b6d0058e673f0a945982/coverage-7.11.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1410bac9e98afd9623f53876fae7d8a5db9f5a0ac1c9e7c5188463cb4b3212e2", size = 248062, upload-time = "2025-11-10T00:11:37.903Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9c/dab1a4e8e75ce053d14259d3d7485d68528a662e286e184685ea49e71156/coverage-7.11.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:004cdcea3457c0ea3233622cd3464c1e32ebba9b41578421097402bee6461b63", size = 250657, upload-time = "2025-11-10T00:11:39.509Z" }, + { url = "https://files.pythonhosted.org/packages/3f/89/a14f256438324f33bae36f9a1a7137729bf26b0a43f5eda60b147ec7c8c7/coverage-7.11.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f067ada2c333609b52835ca4d4868645d3b63ac04fb2b9a658c55bba7f667d3", size = 251900, upload-time = "2025-11-10T00:11:41.372Z" }, + { url = "https://files.pythonhosted.org/packages/04/07/75b0d476eb349f1296486b1418b44f2d8780cc8db47493de3755e5340076/coverage-7.11.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:07bc7745c945a6d95676953e86ba7cebb9f11de7773951c387f4c07dc76d03f5", size = 248254, upload-time = "2025-11-10T00:11:43.27Z" }, + { url = "https://files.pythonhosted.org/packages/5a/4b/0c486581fa72873489ca092c52792d008a17954aa352809a7cbe6cf0bf07/coverage-7.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8bba7e4743e37484ae17d5c3b8eb1ce78b564cb91b7ace2e2182b25f0f764cb5", size = 250041, upload-time = "2025-11-10T00:11:45.274Z" }, + { url = "https://files.pythonhosted.org/packages/af/a3/0059dafb240ae3e3291f81b8de00e9c511d3dd41d687a227dd4b529be591/coverage-7.11.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbffc22d80d86fbe456af9abb17f7a7766e7b2101f7edaacc3535501691563f7", size = 248004, upload-time = "2025-11-10T00:11:46.93Z" }, + { url = "https://files.pythonhosted.org/packages/83/93/967d9662b1eb8c7c46917dcc7e4c1875724ac3e73c3cb78e86d7a0ac719d/coverage-7.11.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:0dba4da36730e384669e05b765a2c49f39514dd3012fcc0398dd66fba8d746d5", size = 247828, upload-time = "2025-11-10T00:11:48.563Z" }, + { url = "https://files.pythonhosted.org/packages/4c/1c/5077493c03215701e212767e470b794548d817dfc6247a4718832cc71fac/coverage-7.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ae12fe90b00b71a71b69f513773310782ce01d5f58d2ceb2b7c595ab9d222094", size = 249588, upload-time = "2025-11-10T00:11:50.581Z" }, + { url = "https://files.pythonhosted.org/packages/7f/a5/77f64de461016e7da3e05d7d07975c89756fe672753e4cf74417fc9b9052/coverage-7.11.3-cp313-cp313-win32.whl", hash = "sha256:12d821de7408292530b0d241468b698bce18dd12ecaf45316149f53877885f8c", size = 219223, upload-time = "2025-11-10T00:11:52.184Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1c/ec51a3c1a59d225b44bdd3a4d463135b3159a535c2686fac965b698524f4/coverage-7.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:6bb599052a974bb6cedfa114f9778fedfad66854107cf81397ec87cb9b8fbcf2", size = 220033, upload-time = "2025-11-10T00:11:53.871Z" }, + { url = "https://files.pythonhosted.org/packages/01/ec/e0ce39746ed558564c16f2cc25fa95ce6fc9fa8bfb3b9e62855d4386b886/coverage-7.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:bb9d7efdb063903b3fdf77caec7b77c3066885068bdc0d44bc1b0c171033f944", size = 218661, upload-time = "2025-11-10T00:11:55.597Z" }, + { url = "https://files.pythonhosted.org/packages/46/cb/483f130bc56cbbad2638248915d97b185374d58b19e3cc3107359715949f/coverage-7.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:fb58da65e3339b3dbe266b607bb936efb983d86b00b03eb04c4ad5b442c58428", size = 217389, upload-time = "2025-11-10T00:11:57.59Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ae/81f89bae3afef75553cf10e62feb57551535d16fd5859b9ee5a2a97ddd27/coverage-7.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8d16bbe566e16a71d123cd66382c1315fcd520c7573652a8074a8fe281b38c6a", size = 217742, upload-time = "2025-11-10T00:11:59.519Z" }, + { url = "https://files.pythonhosted.org/packages/db/6e/a0fb897041949888191a49c36afd5c6f5d9f5fd757e0b0cd99ec198a324b/coverage-7.11.3-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8258f10059b5ac837232c589a350a2df4a96406d6d5f2a09ec587cbdd539655", size = 259049, upload-time = "2025-11-10T00:12:01.592Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/d13acc67eb402d91eb94b9bd60593411799aed09ce176ee8d8c0e39c94ca/coverage-7.11.3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4c5627429f7fbff4f4131cfdd6abd530734ef7761116811a707b88b7e205afd7", size = 261113, upload-time = "2025-11-10T00:12:03.639Z" }, + { url = "https://files.pythonhosted.org/packages/ea/07/a6868893c48191d60406df4356aa7f0f74e6de34ef1f03af0d49183e0fa1/coverage-7.11.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:465695268414e149bab754c54b0c45c8ceda73dd4a5c3ba255500da13984b16d", size = 263546, upload-time = "2025-11-10T00:12:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/24/e5/28598f70b2c1098332bac47925806353b3313511d984841111e6e760c016/coverage-7.11.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4ebcddfcdfb4c614233cff6e9a3967a09484114a8b2e4f2c7a62dc83676ba13f", size = 258260, upload-time = "2025-11-10T00:12:07.137Z" }, + { url = "https://files.pythonhosted.org/packages/0e/58/58e2d9e6455a4ed746a480c4b9cf96dc3cb2a6b8f3efbee5efd33ae24b06/coverage-7.11.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:13b2066303a1c1833c654d2af0455bb009b6e1727b3883c9964bc5c2f643c1d0", size = 261121, upload-time = "2025-11-10T00:12:09.138Z" }, + { url = "https://files.pythonhosted.org/packages/17/57/38803eefb9b0409934cbc5a14e3978f0c85cb251d2b6f6a369067a7105a0/coverage-7.11.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d8750dd20362a1b80e3cf84f58013d4672f89663aee457ea59336df50fab6739", size = 258736, upload-time = "2025-11-10T00:12:11.195Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/f94683167156e93677b3442be1d4ca70cb33718df32a2eea44a5898f04f6/coverage-7.11.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ab6212e62ea0e1006531a2234e209607f360d98d18d532c2fa8e403c1afbdd71", size = 257625, upload-time = "2025-11-10T00:12:12.843Z" }, + { url = "https://files.pythonhosted.org/packages/87/ed/42d0bf1bc6bfa7d65f52299a31daaa866b4c11000855d753857fe78260ac/coverage-7.11.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a6b17c2b5e0b9bb7702449200f93e2d04cb04b1414c41424c08aa1e5d352da76", size = 259827, upload-time = "2025-11-10T00:12:15.128Z" }, + { url = "https://files.pythonhosted.org/packages/d3/76/5682719f5d5fbedb0c624c9851ef847407cae23362deb941f185f489c54e/coverage-7.11.3-cp313-cp313t-win32.whl", hash = "sha256:426559f105f644b69290ea414e154a0d320c3ad8a2bb75e62884731f69cf8e2c", size = 219897, upload-time = "2025-11-10T00:12:17.274Z" }, + { url = "https://files.pythonhosted.org/packages/10/e0/1da511d0ac3d39e6676fa6cc5ec35320bbf1cebb9b24e9ee7548ee4e931a/coverage-7.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:90a96fcd824564eae6137ec2563bd061d49a32944858d4bdbae5c00fb10e76ac", size = 220959, upload-time = "2025-11-10T00:12:19.292Z" }, + { url = "https://files.pythonhosted.org/packages/e5/9d/e255da6a04e9ec5f7b633c54c0fdfa221a9e03550b67a9c83217de12e96c/coverage-7.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:1e33d0bebf895c7a0905fcfaff2b07ab900885fc78bba2a12291a2cfbab014cc", size = 219234, upload-time = "2025-11-10T00:12:21.251Z" }, + { url = "https://files.pythonhosted.org/packages/84/d6/634ec396e45aded1772dccf6c236e3e7c9604bc47b816e928f32ce7987d1/coverage-7.11.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fdc5255eb4815babcdf236fa1a806ccb546724c8a9b129fd1ea4a5448a0bf07c", size = 216746, upload-time = "2025-11-10T00:12:23.089Z" }, + { url = "https://files.pythonhosted.org/packages/28/76/1079547f9d46f9c7c7d0dad35b6873c98bc5aa721eeabceafabd722cd5e7/coverage-7.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fe3425dc6021f906c6325d3c415e048e7cdb955505a94f1eb774dafc779ba203", size = 217077, upload-time = "2025-11-10T00:12:24.863Z" }, + { url = "https://files.pythonhosted.org/packages/2d/71/6ad80d6ae0d7cb743b9a98df8bb88b1ff3dc54491508a4a97549c2b83400/coverage-7.11.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4ca5f876bf41b24378ee67c41d688155f0e54cdc720de8ef9ad6544005899240", size = 248122, upload-time = "2025-11-10T00:12:26.553Z" }, + { url = "https://files.pythonhosted.org/packages/20/1d/784b87270784b0b88e4beec9d028e8d58f73ae248032579c63ad2ac6f69a/coverage-7.11.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9061a3e3c92b27fd8036dafa26f25d95695b6aa2e4514ab16a254f297e664f83", size = 250638, upload-time = "2025-11-10T00:12:28.555Z" }, + { url = "https://files.pythonhosted.org/packages/f5/26/b6dd31e23e004e9de84d1a8672cd3d73e50f5dae65dbd0f03fa2cdde6100/coverage-7.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:abcea3b5f0dc44e1d01c27090bc32ce6ffb7aa665f884f1890710454113ea902", size = 251972, upload-time = "2025-11-10T00:12:30.246Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ef/f9c64d76faac56b82daa036b34d4fe9ab55eb37f22062e68e9470583e688/coverage-7.11.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:68c4eb92997dbaaf839ea13527be463178ac0ddd37a7ac636b8bc11a51af2428", size = 248147, upload-time = "2025-11-10T00:12:32.195Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/5b666f90a8f8053bd264a1ce693d2edef2368e518afe70680070fca13ecd/coverage-7.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:149eccc85d48c8f06547534068c41d69a1a35322deaa4d69ba1561e2e9127e75", size = 249995, upload-time = "2025-11-10T00:12:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/eb/7b/871e991ffb5d067f8e67ffb635dabba65b231d6e0eb724a4a558f4a702a5/coverage-7.11.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:08c0bcf932e47795c49f0406054824b9d45671362dfc4269e0bc6e4bff010704", size = 247948, upload-time = "2025-11-10T00:12:36.341Z" }, + { url = "https://files.pythonhosted.org/packages/0a/8b/ce454f0af9609431b06dbe5485fc9d1c35ddc387e32ae8e374f49005748b/coverage-7.11.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:39764c6167c82d68a2d8c97c33dba45ec0ad9172570860e12191416f4f8e6e1b", size = 247770, upload-time = "2025-11-10T00:12:38.167Z" }, + { url = "https://files.pythonhosted.org/packages/61/8f/79002cb58a61dfbd2085de7d0a46311ef2476823e7938db80284cedd2428/coverage-7.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3224c7baf34e923ffc78cb45e793925539d640d42c96646db62dbd61bbcfa131", size = 249431, upload-time = "2025-11-10T00:12:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/58/cc/d06685dae97468ed22999440f2f2f5060940ab0e7952a7295f236d98cce7/coverage-7.11.3-cp314-cp314-win32.whl", hash = "sha256:c713c1c528284d636cd37723b0b4c35c11190da6f932794e145fc40f8210a14a", size = 219508, upload-time = "2025-11-10T00:12:42.231Z" }, + { url = "https://files.pythonhosted.org/packages/5f/ed/770cd07706a3598c545f62d75adf2e5bd3791bffccdcf708ec383ad42559/coverage-7.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:c381a252317f63ca0179d2c7918e83b99a4ff3101e1b24849b999a00f9cd4f86", size = 220325, upload-time = "2025-11-10T00:12:44.065Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ac/6a1c507899b6fb1b9a56069954365f655956bcc648e150ce64c2b0ecbed8/coverage-7.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:3e33a968672be1394eded257ec10d4acbb9af2ae263ba05a99ff901bb863557e", size = 218899, upload-time = "2025-11-10T00:12:46.18Z" }, + { url = "https://files.pythonhosted.org/packages/9a/58/142cd838d960cd740654d094f7b0300d7b81534bb7304437d2439fb685fb/coverage-7.11.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f9c96a29c6d65bd36a91f5634fef800212dff69dacdb44345c4c9783943ab0df", size = 217471, upload-time = "2025-11-10T00:12:48.392Z" }, + { url = "https://files.pythonhosted.org/packages/bc/2c/2f44d39eb33e41ab3aba80571daad32e0f67076afcf27cb443f9e5b5a3ee/coverage-7.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2ec27a7a991d229213c8070d31e3ecf44d005d96a9edc30c78eaeafaa421c001", size = 217742, upload-time = "2025-11-10T00:12:50.182Z" }, + { url = "https://files.pythonhosted.org/packages/32/76/8ebc66c3c699f4de3174a43424c34c086323cd93c4930ab0f835731c443a/coverage-7.11.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:72c8b494bd20ae1c58528b97c4a67d5cfeafcb3845c73542875ecd43924296de", size = 259120, upload-time = "2025-11-10T00:12:52.451Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/78a3302b9595f331b86e4f12dfbd9252c8e93d97b8631500888f9a3a2af7/coverage-7.11.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:60ca149a446da255d56c2a7a813b51a80d9497a62250532598d249b3cdb1a926", size = 261229, upload-time = "2025-11-10T00:12:54.667Z" }, + { url = "https://files.pythonhosted.org/packages/07/59/1a9c0844dadef2a6efac07316d9781e6c5a3f3ea7e5e701411e99d619bfd/coverage-7.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb5069074db19a534de3859c43eec78e962d6d119f637c41c8e028c5ab3f59dd", size = 263642, upload-time = "2025-11-10T00:12:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/37/86/66c15d190a8e82eee777793cabde730640f555db3c020a179625a2ad5320/coverage-7.11.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac5d5329c9c942bbe6295f4251b135d860ed9f86acd912d418dce186de7c19ac", size = 258193, upload-time = "2025-11-10T00:12:58.687Z" }, + { url = "https://files.pythonhosted.org/packages/c7/c7/4a4aeb25cb6f83c3ec4763e5f7cc78da1c6d4ef9e22128562204b7f39390/coverage-7.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e22539b676fafba17f0a90ac725f029a309eb6e483f364c86dcadee060429d46", size = 261107, upload-time = "2025-11-10T00:13:00.502Z" }, + { url = "https://files.pythonhosted.org/packages/ed/91/b986b5035f23cf0272446298967ecdd2c3c0105ee31f66f7e6b6948fd7f8/coverage-7.11.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:2376e8a9c889016f25472c452389e98bc6e54a19570b107e27cde9d47f387b64", size = 258717, upload-time = "2025-11-10T00:13:02.747Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c7/6c084997f5a04d050c513545d3344bfa17bd3b67f143f388b5757d762b0b/coverage-7.11.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4234914b8c67238a3c4af2bba648dc716aa029ca44d01f3d51536d44ac16854f", size = 257541, upload-time = "2025-11-10T00:13:04.689Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c5/38e642917e406930cb67941210a366ccffa767365c8f8d9ec0f465a8b218/coverage-7.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f0b4101e2b3c6c352ff1f70b3a6fcc7c17c1ab1a91ccb7a33013cb0782af9820", size = 259872, upload-time = "2025-11-10T00:13:06.559Z" }, + { url = "https://files.pythonhosted.org/packages/b7/67/5e812979d20c167f81dbf9374048e0193ebe64c59a3d93d7d947b07865fa/coverage-7.11.3-cp314-cp314t-win32.whl", hash = "sha256:305716afb19133762e8cf62745c46c4853ad6f9eeba54a593e373289e24ea237", size = 220289, upload-time = "2025-11-10T00:13:08.635Z" }, + { url = "https://files.pythonhosted.org/packages/24/3a/b72573802672b680703e0df071faadfab7dcd4d659aaaffc4626bc8bbde8/coverage-7.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:9245bd392572b9f799261c4c9e7216bafc9405537d0f4ce3ad93afe081a12dc9", size = 221398, upload-time = "2025-11-10T00:13:10.734Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4e/649628f28d38bad81e4e8eb3f78759d20ac173e3c456ac629123815feb40/coverage-7.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:9a1d577c20b4334e5e814c3d5fe07fa4a8c3ae42a601945e8d7940bab811d0bd", size = 219435, upload-time = "2025-11-10T00:13:12.712Z" }, + { url = "https://files.pythonhosted.org/packages/19/8f/92bdd27b067204b99f396a1414d6342122f3e2663459baf787108a6b8b84/coverage-7.11.3-py3-none-any.whl", hash = "sha256:351511ae28e2509c8d8cae5311577ea7dd511ab8e746ffc8814a0896c3d33fbe", size = 208478, upload-time = "2025-11-10T00:13:14.908Z" }, ] [[package]] name = "distro" version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "joblib" version = "1.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/5d/447af5ea094b9e4c4054f82e223ada074c552335b9b4b2d14bd9b35a67c4/joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55", size = 331077 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/5d/447af5ea094b9e4c4054f82e223ada074c552335b9b4b2d14bd9b35a67c4/joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55", size = 331077, upload-time = "2025-08-27T12:15:46.575Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241", size = 308396 }, + { url = "https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241", size = 308396, upload-time = "2025-08-27T12:15:45.188Z" }, ] [[package]] @@ -121,9 +205,9 @@ dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "win32-setctime", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595 }, + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, ] [[package]] @@ -136,9 +220,9 @@ dependencies = [ { name = "typer" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/8a/c605f45df12864f37e8fd6b851d852a247267d0a0a6be946ba14007dd703/maison-2.0.1.tar.gz", hash = "sha256:15e6e77cab74db796526a4eefedf1c072de16323834c01b182e9b674cfdd8fcc", size = 16037 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/8a/c605f45df12864f37e8fd6b851d852a247267d0a0a6be946ba14007dd703/maison-2.0.1.tar.gz", hash = "sha256:15e6e77cab74db796526a4eefedf1c072de16323834c01b182e9b674cfdd8fcc", size = 16037, upload-time = "2025-10-07T08:01:41.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/b2/8b5e4a7457db0f313df6f0efb6eb11fb0d1c39fa6ab631233a96d875cea2/maison-2.0.1-py3-none-any.whl", hash = "sha256:8676af9dbe8878a9966aa9fdb3f22f99559dd2657a02693b64fbea5ed0c98704", size = 13492 }, + { url = "https://files.pythonhosted.org/packages/fc/b2/8b5e4a7457db0f313df6f0efb6eb11fb0d1c39fa6ab631233a96d875cea2/maison-2.0.1-py3-none-any.whl", hash = "sha256:8676af9dbe8878a9966aa9fdb3f22f99559dd2657a02693b64fbea5ed0c98704", size = 13492, upload-time = "2025-10-07T08:01:40.058Z" }, ] [[package]] @@ -148,18 +232,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321 }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] @@ -171,72 +255,81 @@ dependencies = [ { name = "pandas" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/bb/b3e75001debab67c9d0944e885b19d749902800fa030071b3b992fb244c8/nba_api-1.10.2.tar.gz", hash = "sha256:68ca205459e0e09ad633ef15c9417c14049d8ca196097a716317d82f71eb3815", size = 156148 } +sdist = { url = "https://files.pythonhosted.org/packages/4a/bb/b3e75001debab67c9d0944e885b19d749902800fa030071b3b992fb244c8/nba_api-1.10.2.tar.gz", hash = "sha256:68ca205459e0e09ad633ef15c9417c14049d8ca196097a716317d82f71eb3815", size = 156148, upload-time = "2025-09-30T20:51:05.181Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/b6/32f9837c63e18ba20ebc51a4e3970797e04d701fc02c73c64a7298c10143/nba_api-1.10.2-py3-none-any.whl", hash = "sha256:9aecc454aa54e273ce28f861b3f3d81ee557b3967adf4d97894dc49dbbe331b8", size = 286996 }, + { url = "https://files.pythonhosted.org/packages/18/b6/32f9837c63e18ba20ebc51a4e3970797e04d701fc02c73c64a7298c10143/nba_api-1.10.2-py3-none-any.whl", hash = "sha256:9aecc454aa54e273ce28f861b3f3d81ee557b3967adf4d97894dc49dbbe331b8", size = 286996, upload-time = "2025-09-30T20:51:04.092Z" }, ] [[package]] name = "numpy" version = "2.3.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/5d/bb7fc075b762c96329147799e1bcc9176ab07ca6375ea976c475482ad5b3/numpy-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cfdd09f9c84a1a934cde1eec2267f0a43a7cd44b2cca4ff95b7c0d14d144b0bf", size = 20957014 }, - { url = "https://files.pythonhosted.org/packages/6b/0e/c6211bb92af26517acd52125a237a92afe9c3124c6a68d3b9f81b62a0568/numpy-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb32e3cf0f762aee47ad1ddc6672988f7f27045b0783c887190545baba73aa25", size = 14185220 }, - { url = "https://files.pythonhosted.org/packages/22/f2/07bb754eb2ede9073f4054f7c0286b0d9d2e23982e090a80d478b26d35ca/numpy-2.3.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:396b254daeb0a57b1fe0ecb5e3cff6fa79a380fa97c8f7781a6d08cd429418fe", size = 5113918 }, - { url = "https://files.pythonhosted.org/packages/81/0a/afa51697e9fb74642f231ea36aca80fa17c8fb89f7a82abd5174023c3960/numpy-2.3.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:067e3d7159a5d8f8a0b46ee11148fc35ca9b21f61e3c49fbd0a027450e65a33b", size = 6647922 }, - { url = "https://files.pythonhosted.org/packages/5d/f5/122d9cdb3f51c520d150fef6e87df9279e33d19a9611a87c0d2cf78a89f4/numpy-2.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c02d0629d25d426585fb2e45a66154081b9fa677bc92a881ff1d216bc9919a8", size = 14281991 }, - { url = "https://files.pythonhosted.org/packages/51/64/7de3c91e821a2debf77c92962ea3fe6ac2bc45d0778c1cbe15d4fce2fd94/numpy-2.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9192da52b9745f7f0766531dcfa978b7763916f158bb63bdb8a1eca0068ab20", size = 16641643 }, - { url = "https://files.pythonhosted.org/packages/30/e4/961a5fa681502cd0d68907818b69f67542695b74e3ceaa513918103b7e80/numpy-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cd7de500a5b66319db419dc3c345244404a164beae0d0937283b907d8152e6ea", size = 16056787 }, - { url = "https://files.pythonhosted.org/packages/99/26/92c912b966e47fbbdf2ad556cb17e3a3088e2e1292b9833be1dfa5361a1a/numpy-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:93d4962d8f82af58f0b2eb85daaf1b3ca23fe0a85d0be8f1f2b7bb46034e56d7", size = 18579598 }, - { url = "https://files.pythonhosted.org/packages/17/b6/fc8f82cb3520768718834f310c37d96380d9dc61bfdaf05fe5c0b7653e01/numpy-2.3.3-cp312-cp312-win32.whl", hash = "sha256:5534ed6b92f9b7dca6c0a19d6df12d41c68b991cef051d108f6dbff3babc4ebf", size = 6320800 }, - { url = "https://files.pythonhosted.org/packages/32/ee/de999f2625b80d043d6d2d628c07d0d5555a677a3cf78fdf868d409b8766/numpy-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:497d7cad08e7092dba36e3d296fe4c97708c93daf26643a1ae4b03f6294d30eb", size = 12786615 }, - { url = "https://files.pythonhosted.org/packages/49/6e/b479032f8a43559c383acb20816644f5f91c88f633d9271ee84f3b3a996c/numpy-2.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:ca0309a18d4dfea6fc6262a66d06c26cfe4640c3926ceec90e57791a82b6eee5", size = 10195936 }, - { url = "https://files.pythonhosted.org/packages/7d/b9/984c2b1ee61a8b803bf63582b4ac4242cf76e2dbd663efeafcb620cc0ccb/numpy-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f5415fb78995644253370985342cd03572ef8620b934da27d77377a2285955bf", size = 20949588 }, - { url = "https://files.pythonhosted.org/packages/a6/e4/07970e3bed0b1384d22af1e9912527ecbeb47d3b26e9b6a3bced068b3bea/numpy-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d00de139a3324e26ed5b95870ce63be7ec7352171bc69a4cf1f157a48e3eb6b7", size = 14177802 }, - { url = "https://files.pythonhosted.org/packages/35/c7/477a83887f9de61f1203bad89cf208b7c19cc9fef0cebef65d5a1a0619f2/numpy-2.3.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9dc13c6a5829610cc07422bc74d3ac083bd8323f14e2827d992f9e52e22cd6a6", size = 5106537 }, - { url = "https://files.pythonhosted.org/packages/52/47/93b953bd5866a6f6986344d045a207d3f1cfbad99db29f534ea9cee5108c/numpy-2.3.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d79715d95f1894771eb4e60fb23f065663b2298f7d22945d66877aadf33d00c7", size = 6640743 }, - { url = "https://files.pythonhosted.org/packages/23/83/377f84aaeb800b64c0ef4de58b08769e782edcefa4fea712910b6f0afd3c/numpy-2.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:952cfd0748514ea7c3afc729a0fc639e61655ce4c55ab9acfab14bda4f402b4c", size = 14278881 }, - { url = "https://files.pythonhosted.org/packages/9a/a5/bf3db6e66c4b160d6ea10b534c381a1955dfab34cb1017ea93aa33c70ed3/numpy-2.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b83648633d46f77039c29078751f80da65aa64d5622a3cd62aaef9d835b6c93", size = 16636301 }, - { url = "https://files.pythonhosted.org/packages/a2/59/1287924242eb4fa3f9b3a2c30400f2e17eb2707020d1c5e3086fe7330717/numpy-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b001bae8cea1c7dfdb2ae2b017ed0a6f2102d7a70059df1e338e307a4c78a8ae", size = 16053645 }, - { url = "https://files.pythonhosted.org/packages/e6/93/b3d47ed882027c35e94ac2320c37e452a549f582a5e801f2d34b56973c97/numpy-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e9aced64054739037d42fb84c54dd38b81ee238816c948c8f3ed134665dcd86", size = 18578179 }, - { url = "https://files.pythonhosted.org/packages/20/d9/487a2bccbf7cc9d4bfc5f0f197761a5ef27ba870f1e3bbb9afc4bbe3fcc2/numpy-2.3.3-cp313-cp313-win32.whl", hash = "sha256:9591e1221db3f37751e6442850429b3aabf7026d3b05542d102944ca7f00c8a8", size = 6312250 }, - { url = "https://files.pythonhosted.org/packages/1b/b5/263ebbbbcede85028f30047eab3d58028d7ebe389d6493fc95ae66c636ab/numpy-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f0dadeb302887f07431910f67a14d57209ed91130be0adea2f9793f1a4f817cf", size = 12783269 }, - { url = "https://files.pythonhosted.org/packages/fa/75/67b8ca554bbeaaeb3fac2e8bce46967a5a06544c9108ec0cf5cece559b6c/numpy-2.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:3c7cf302ac6e0b76a64c4aecf1a09e51abd9b01fc7feee80f6c43e3ab1b1dbc5", size = 10195314 }, - { url = "https://files.pythonhosted.org/packages/11/d0/0d1ddec56b162042ddfafeeb293bac672de9b0cfd688383590090963720a/numpy-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:eda59e44957d272846bb407aad19f89dc6f58fecf3504bd144f4c5cf81a7eacc", size = 21048025 }, - { url = "https://files.pythonhosted.org/packages/36/9e/1996ca6b6d00415b6acbdd3c42f7f03ea256e2c3f158f80bd7436a8a19f3/numpy-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:823d04112bc85ef5c4fda73ba24e6096c8f869931405a80aa8b0e604510a26bc", size = 14301053 }, - { url = "https://files.pythonhosted.org/packages/05/24/43da09aa764c68694b76e84b3d3f0c44cb7c18cdc1ba80e48b0ac1d2cd39/numpy-2.3.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:40051003e03db4041aa325da2a0971ba41cf65714e65d296397cc0e32de6018b", size = 5229444 }, - { url = "https://files.pythonhosted.org/packages/bc/14/50ffb0f22f7218ef8af28dd089f79f68289a7a05a208db9a2c5dcbe123c1/numpy-2.3.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ee9086235dd6ab7ae75aba5662f582a81ced49f0f1c6de4260a78d8f2d91a19", size = 6738039 }, - { url = "https://files.pythonhosted.org/packages/55/52/af46ac0795e09657d45a7f4db961917314377edecf66db0e39fa7ab5c3d3/numpy-2.3.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94fcaa68757c3e2e668ddadeaa86ab05499a70725811e582b6a9858dd472fb30", size = 14352314 }, - { url = "https://files.pythonhosted.org/packages/a7/b1/dc226b4c90eb9f07a3fff95c2f0db3268e2e54e5cce97c4ac91518aee71b/numpy-2.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da1a74b90e7483d6ce5244053399a614b1d6b7bc30a60d2f570e5071f8959d3e", size = 16701722 }, - { url = "https://files.pythonhosted.org/packages/9d/9d/9d8d358f2eb5eced14dba99f110d83b5cd9a4460895230f3b396ad19a323/numpy-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2990adf06d1ecee3b3dcbb4977dfab6e9f09807598d647f04d385d29e7a3c3d3", size = 16132755 }, - { url = "https://files.pythonhosted.org/packages/b6/27/b3922660c45513f9377b3fb42240bec63f203c71416093476ec9aa0719dc/numpy-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ed635ff692483b8e3f0fcaa8e7eb8a75ee71aa6d975388224f70821421800cea", size = 18651560 }, - { url = "https://files.pythonhosted.org/packages/5b/8e/3ab61a730bdbbc201bb245a71102aa609f0008b9ed15255500a99cd7f780/numpy-2.3.3-cp313-cp313t-win32.whl", hash = "sha256:a333b4ed33d8dc2b373cc955ca57babc00cd6f9009991d9edc5ddbc1bac36bcd", size = 6442776 }, - { url = "https://files.pythonhosted.org/packages/1c/3a/e22b766b11f6030dc2decdeff5c2fb1610768055603f9f3be88b6d192fb2/numpy-2.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:4384a169c4d8f97195980815d6fcad04933a7e1ab3b530921c3fef7a1c63426d", size = 12927281 }, - { url = "https://files.pythonhosted.org/packages/7b/42/c2e2bc48c5e9b2a83423f99733950fbefd86f165b468a3d85d52b30bf782/numpy-2.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:75370986cc0bc66f4ce5110ad35aae6d182cc4ce6433c40ad151f53690130bf1", size = 10265275 }, - { url = "https://files.pythonhosted.org/packages/6b/01/342ad585ad82419b99bcf7cebe99e61da6bedb89e213c5fd71acc467faee/numpy-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cd052f1fa6a78dee696b58a914b7229ecfa41f0a6d96dc663c1220a55e137593", size = 20951527 }, - { url = "https://files.pythonhosted.org/packages/ef/d8/204e0d73fc1b7a9ee80ab1fe1983dd33a4d64a4e30a05364b0208e9a241a/numpy-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:414a97499480067d305fcac9716c29cf4d0d76db6ebf0bf3cbce666677f12652", size = 14186159 }, - { url = "https://files.pythonhosted.org/packages/22/af/f11c916d08f3a18fb8ba81ab72b5b74a6e42ead4c2846d270eb19845bf74/numpy-2.3.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:50a5fe69f135f88a2be9b6ca0481a68a136f6febe1916e4920e12f1a34e708a7", size = 5114624 }, - { url = "https://files.pythonhosted.org/packages/fb/11/0ed919c8381ac9d2ffacd63fd1f0c34d27e99cab650f0eb6f110e6ae4858/numpy-2.3.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:b912f2ed2b67a129e6a601e9d93d4fa37bef67e54cac442a2f588a54afe5c67a", size = 6642627 }, - { url = "https://files.pythonhosted.org/packages/ee/83/deb5f77cb0f7ba6cb52b91ed388b47f8f3c2e9930d4665c600408d9b90b9/numpy-2.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e318ee0596d76d4cb3d78535dc005fa60e5ea348cd131a51e99d0bdbe0b54fe", size = 14296926 }, - { url = "https://files.pythonhosted.org/packages/77/cc/70e59dcb84f2b005d4f306310ff0a892518cc0c8000a33d0e6faf7ca8d80/numpy-2.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce020080e4a52426202bdb6f7691c65bb55e49f261f31a8f506c9f6bc7450421", size = 16638958 }, - { url = "https://files.pythonhosted.org/packages/b6/5a/b2ab6c18b4257e099587d5b7f903317bd7115333ad8d4ec4874278eafa61/numpy-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e6687dc183aa55dae4a705b35f9c0f8cb178bcaa2f029b241ac5356221d5c021", size = 16071920 }, - { url = "https://files.pythonhosted.org/packages/b8/f1/8b3fdc44324a259298520dd82147ff648979bed085feeacc1250ef1656c0/numpy-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d8f3b1080782469fdc1718c4ed1d22549b5fb12af0d57d35e992158a772a37cf", size = 18577076 }, - { url = "https://files.pythonhosted.org/packages/f0/a1/b87a284fb15a42e9274e7fcea0dad259d12ddbf07c1595b26883151ca3b4/numpy-2.3.3-cp314-cp314-win32.whl", hash = "sha256:cb248499b0bc3be66ebd6578b83e5acacf1d6cb2a77f2248ce0e40fbec5a76d0", size = 6366952 }, - { url = "https://files.pythonhosted.org/packages/70/5f/1816f4d08f3b8f66576d8433a66f8fa35a5acfb3bbd0bf6c31183b003f3d/numpy-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:691808c2b26b0f002a032c73255d0bd89751425f379f7bcd22d140db593a96e8", size = 12919322 }, - { url = "https://files.pythonhosted.org/packages/8c/de/072420342e46a8ea41c324a555fa90fcc11637583fb8df722936aed1736d/numpy-2.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:9ad12e976ca7b10f1774b03615a2a4bab8addce37ecc77394d8e986927dc0dfe", size = 10478630 }, - { url = "https://files.pythonhosted.org/packages/d5/df/ee2f1c0a9de7347f14da5dd3cd3c3b034d1b8607ccb6883d7dd5c035d631/numpy-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9cc48e09feb11e1db00b320e9d30a4151f7369afb96bd0e48d942d09da3a0d00", size = 21047987 }, - { url = "https://files.pythonhosted.org/packages/d6/92/9453bdc5a4e9e69cf4358463f25e8260e2ffc126d52e10038b9077815989/numpy-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:901bf6123879b7f251d3631967fd574690734236075082078e0571977c6a8e6a", size = 14301076 }, - { url = "https://files.pythonhosted.org/packages/13/77/1447b9eb500f028bb44253105bd67534af60499588a5149a94f18f2ca917/numpy-2.3.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:7f025652034199c301049296b59fa7d52c7e625017cae4c75d8662e377bf487d", size = 5229491 }, - { url = "https://files.pythonhosted.org/packages/3d/f9/d72221b6ca205f9736cb4b2ce3b002f6e45cd67cd6a6d1c8af11a2f0b649/numpy-2.3.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:533ca5f6d325c80b6007d4d7fb1984c303553534191024ec6a524a4c92a5935a", size = 6737913 }, - { url = "https://files.pythonhosted.org/packages/3c/5f/d12834711962ad9c46af72f79bb31e73e416ee49d17f4c797f72c96b6ca5/numpy-2.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0edd58682a399824633b66885d699d7de982800053acf20be1eaa46d92009c54", size = 14352811 }, - { url = "https://files.pythonhosted.org/packages/a1/0d/fdbec6629d97fd1bebed56cd742884e4eead593611bbe1abc3eb40d304b2/numpy-2.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:367ad5d8fbec5d9296d18478804a530f1191e24ab4d75ab408346ae88045d25e", size = 16702689 }, - { url = "https://files.pythonhosted.org/packages/9b/09/0a35196dc5575adde1eb97ddfbc3e1687a814f905377621d18ca9bc2b7dd/numpy-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8f6ac61a217437946a1fa48d24c47c91a0c4f725237871117dea264982128097", size = 16133855 }, - { url = "https://files.pythonhosted.org/packages/7a/ca/c9de3ea397d576f1b6753eaa906d4cdef1bf97589a6d9825a349b4729cc2/numpy-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:179a42101b845a816d464b6fe9a845dfaf308fdfc7925387195570789bb2c970", size = 18652520 }, - { url = "https://files.pythonhosted.org/packages/fd/c2/e5ed830e08cd0196351db55db82f65bc0ab05da6ef2b72a836dcf1936d2f/numpy-2.3.3-cp314-cp314t-win32.whl", hash = "sha256:1250c5d3d2562ec4174bce2e3a1523041595f9b651065e4a4473f5f48a6bc8a5", size = 6515371 }, - { url = "https://files.pythonhosted.org/packages/47/c7/b0f6b5b67f6788a0725f744496badbb604d226bf233ba716683ebb47b570/numpy-2.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b37a0b2e5935409daebe82c1e42274d30d9dd355852529eab91dab8dcca7419f", size = 13112576 }, - { url = "https://files.pythonhosted.org/packages/06/b9/33bba5ff6fb679aa0b1f8a07e853f002a6b04b9394db3069a1270a7784ca/numpy-2.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:78c9f6560dc7e6b3990e32df7ea1a50bbd0e2a111e05209963f5ddcab7073b0b", size = 10545953 }, +sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648, upload-time = "2025-09-09T16:54:12.543Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/5d/bb7fc075b762c96329147799e1bcc9176ab07ca6375ea976c475482ad5b3/numpy-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cfdd09f9c84a1a934cde1eec2267f0a43a7cd44b2cca4ff95b7c0d14d144b0bf", size = 20957014, upload-time = "2025-09-09T15:56:29.966Z" }, + { url = "https://files.pythonhosted.org/packages/6b/0e/c6211bb92af26517acd52125a237a92afe9c3124c6a68d3b9f81b62a0568/numpy-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb32e3cf0f762aee47ad1ddc6672988f7f27045b0783c887190545baba73aa25", size = 14185220, upload-time = "2025-09-09T15:56:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/22/f2/07bb754eb2ede9073f4054f7c0286b0d9d2e23982e090a80d478b26d35ca/numpy-2.3.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:396b254daeb0a57b1fe0ecb5e3cff6fa79a380fa97c8f7781a6d08cd429418fe", size = 5113918, upload-time = "2025-09-09T15:56:34.175Z" }, + { url = "https://files.pythonhosted.org/packages/81/0a/afa51697e9fb74642f231ea36aca80fa17c8fb89f7a82abd5174023c3960/numpy-2.3.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:067e3d7159a5d8f8a0b46ee11148fc35ca9b21f61e3c49fbd0a027450e65a33b", size = 6647922, upload-time = "2025-09-09T15:56:36.149Z" }, + { url = "https://files.pythonhosted.org/packages/5d/f5/122d9cdb3f51c520d150fef6e87df9279e33d19a9611a87c0d2cf78a89f4/numpy-2.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c02d0629d25d426585fb2e45a66154081b9fa677bc92a881ff1d216bc9919a8", size = 14281991, upload-time = "2025-09-09T15:56:40.548Z" }, + { url = "https://files.pythonhosted.org/packages/51/64/7de3c91e821a2debf77c92962ea3fe6ac2bc45d0778c1cbe15d4fce2fd94/numpy-2.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9192da52b9745f7f0766531dcfa978b7763916f158bb63bdb8a1eca0068ab20", size = 16641643, upload-time = "2025-09-09T15:56:43.343Z" }, + { url = "https://files.pythonhosted.org/packages/30/e4/961a5fa681502cd0d68907818b69f67542695b74e3ceaa513918103b7e80/numpy-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cd7de500a5b66319db419dc3c345244404a164beae0d0937283b907d8152e6ea", size = 16056787, upload-time = "2025-09-09T15:56:46.141Z" }, + { url = "https://files.pythonhosted.org/packages/99/26/92c912b966e47fbbdf2ad556cb17e3a3088e2e1292b9833be1dfa5361a1a/numpy-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:93d4962d8f82af58f0b2eb85daaf1b3ca23fe0a85d0be8f1f2b7bb46034e56d7", size = 18579598, upload-time = "2025-09-09T15:56:49.844Z" }, + { url = "https://files.pythonhosted.org/packages/17/b6/fc8f82cb3520768718834f310c37d96380d9dc61bfdaf05fe5c0b7653e01/numpy-2.3.3-cp312-cp312-win32.whl", hash = "sha256:5534ed6b92f9b7dca6c0a19d6df12d41c68b991cef051d108f6dbff3babc4ebf", size = 6320800, upload-time = "2025-09-09T15:56:52.499Z" }, + { url = "https://files.pythonhosted.org/packages/32/ee/de999f2625b80d043d6d2d628c07d0d5555a677a3cf78fdf868d409b8766/numpy-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:497d7cad08e7092dba36e3d296fe4c97708c93daf26643a1ae4b03f6294d30eb", size = 12786615, upload-time = "2025-09-09T15:56:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/49/6e/b479032f8a43559c383acb20816644f5f91c88f633d9271ee84f3b3a996c/numpy-2.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:ca0309a18d4dfea6fc6262a66d06c26cfe4640c3926ceec90e57791a82b6eee5", size = 10195936, upload-time = "2025-09-09T15:56:56.541Z" }, + { url = "https://files.pythonhosted.org/packages/7d/b9/984c2b1ee61a8b803bf63582b4ac4242cf76e2dbd663efeafcb620cc0ccb/numpy-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f5415fb78995644253370985342cd03572ef8620b934da27d77377a2285955bf", size = 20949588, upload-time = "2025-09-09T15:56:59.087Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e4/07970e3bed0b1384d22af1e9912527ecbeb47d3b26e9b6a3bced068b3bea/numpy-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d00de139a3324e26ed5b95870ce63be7ec7352171bc69a4cf1f157a48e3eb6b7", size = 14177802, upload-time = "2025-09-09T15:57:01.73Z" }, + { url = "https://files.pythonhosted.org/packages/35/c7/477a83887f9de61f1203bad89cf208b7c19cc9fef0cebef65d5a1a0619f2/numpy-2.3.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9dc13c6a5829610cc07422bc74d3ac083bd8323f14e2827d992f9e52e22cd6a6", size = 5106537, upload-time = "2025-09-09T15:57:03.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/47/93b953bd5866a6f6986344d045a207d3f1cfbad99db29f534ea9cee5108c/numpy-2.3.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d79715d95f1894771eb4e60fb23f065663b2298f7d22945d66877aadf33d00c7", size = 6640743, upload-time = "2025-09-09T15:57:07.921Z" }, + { url = "https://files.pythonhosted.org/packages/23/83/377f84aaeb800b64c0ef4de58b08769e782edcefa4fea712910b6f0afd3c/numpy-2.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:952cfd0748514ea7c3afc729a0fc639e61655ce4c55ab9acfab14bda4f402b4c", size = 14278881, upload-time = "2025-09-09T15:57:11.349Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a5/bf3db6e66c4b160d6ea10b534c381a1955dfab34cb1017ea93aa33c70ed3/numpy-2.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b83648633d46f77039c29078751f80da65aa64d5622a3cd62aaef9d835b6c93", size = 16636301, upload-time = "2025-09-09T15:57:14.245Z" }, + { url = "https://files.pythonhosted.org/packages/a2/59/1287924242eb4fa3f9b3a2c30400f2e17eb2707020d1c5e3086fe7330717/numpy-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b001bae8cea1c7dfdb2ae2b017ed0a6f2102d7a70059df1e338e307a4c78a8ae", size = 16053645, upload-time = "2025-09-09T15:57:16.534Z" }, + { url = "https://files.pythonhosted.org/packages/e6/93/b3d47ed882027c35e94ac2320c37e452a549f582a5e801f2d34b56973c97/numpy-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e9aced64054739037d42fb84c54dd38b81ee238816c948c8f3ed134665dcd86", size = 18578179, upload-time = "2025-09-09T15:57:18.883Z" }, + { url = "https://files.pythonhosted.org/packages/20/d9/487a2bccbf7cc9d4bfc5f0f197761a5ef27ba870f1e3bbb9afc4bbe3fcc2/numpy-2.3.3-cp313-cp313-win32.whl", hash = "sha256:9591e1221db3f37751e6442850429b3aabf7026d3b05542d102944ca7f00c8a8", size = 6312250, upload-time = "2025-09-09T15:57:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b5/263ebbbbcede85028f30047eab3d58028d7ebe389d6493fc95ae66c636ab/numpy-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f0dadeb302887f07431910f67a14d57209ed91130be0adea2f9793f1a4f817cf", size = 12783269, upload-time = "2025-09-09T15:57:23.034Z" }, + { url = "https://files.pythonhosted.org/packages/fa/75/67b8ca554bbeaaeb3fac2e8bce46967a5a06544c9108ec0cf5cece559b6c/numpy-2.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:3c7cf302ac6e0b76a64c4aecf1a09e51abd9b01fc7feee80f6c43e3ab1b1dbc5", size = 10195314, upload-time = "2025-09-09T15:57:25.045Z" }, + { url = "https://files.pythonhosted.org/packages/11/d0/0d1ddec56b162042ddfafeeb293bac672de9b0cfd688383590090963720a/numpy-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:eda59e44957d272846bb407aad19f89dc6f58fecf3504bd144f4c5cf81a7eacc", size = 21048025, upload-time = "2025-09-09T15:57:27.257Z" }, + { url = "https://files.pythonhosted.org/packages/36/9e/1996ca6b6d00415b6acbdd3c42f7f03ea256e2c3f158f80bd7436a8a19f3/numpy-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:823d04112bc85ef5c4fda73ba24e6096c8f869931405a80aa8b0e604510a26bc", size = 14301053, upload-time = "2025-09-09T15:57:30.077Z" }, + { url = "https://files.pythonhosted.org/packages/05/24/43da09aa764c68694b76e84b3d3f0c44cb7c18cdc1ba80e48b0ac1d2cd39/numpy-2.3.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:40051003e03db4041aa325da2a0971ba41cf65714e65d296397cc0e32de6018b", size = 5229444, upload-time = "2025-09-09T15:57:32.733Z" }, + { url = "https://files.pythonhosted.org/packages/bc/14/50ffb0f22f7218ef8af28dd089f79f68289a7a05a208db9a2c5dcbe123c1/numpy-2.3.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ee9086235dd6ab7ae75aba5662f582a81ced49f0f1c6de4260a78d8f2d91a19", size = 6738039, upload-time = "2025-09-09T15:57:34.328Z" }, + { url = "https://files.pythonhosted.org/packages/55/52/af46ac0795e09657d45a7f4db961917314377edecf66db0e39fa7ab5c3d3/numpy-2.3.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94fcaa68757c3e2e668ddadeaa86ab05499a70725811e582b6a9858dd472fb30", size = 14352314, upload-time = "2025-09-09T15:57:36.255Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b1/dc226b4c90eb9f07a3fff95c2f0db3268e2e54e5cce97c4ac91518aee71b/numpy-2.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da1a74b90e7483d6ce5244053399a614b1d6b7bc30a60d2f570e5071f8959d3e", size = 16701722, upload-time = "2025-09-09T15:57:38.622Z" }, + { url = "https://files.pythonhosted.org/packages/9d/9d/9d8d358f2eb5eced14dba99f110d83b5cd9a4460895230f3b396ad19a323/numpy-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2990adf06d1ecee3b3dcbb4977dfab6e9f09807598d647f04d385d29e7a3c3d3", size = 16132755, upload-time = "2025-09-09T15:57:41.16Z" }, + { url = "https://files.pythonhosted.org/packages/b6/27/b3922660c45513f9377b3fb42240bec63f203c71416093476ec9aa0719dc/numpy-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ed635ff692483b8e3f0fcaa8e7eb8a75ee71aa6d975388224f70821421800cea", size = 18651560, upload-time = "2025-09-09T15:57:43.459Z" }, + { url = "https://files.pythonhosted.org/packages/5b/8e/3ab61a730bdbbc201bb245a71102aa609f0008b9ed15255500a99cd7f780/numpy-2.3.3-cp313-cp313t-win32.whl", hash = "sha256:a333b4ed33d8dc2b373cc955ca57babc00cd6f9009991d9edc5ddbc1bac36bcd", size = 6442776, upload-time = "2025-09-09T15:57:45.793Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3a/e22b766b11f6030dc2decdeff5c2fb1610768055603f9f3be88b6d192fb2/numpy-2.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:4384a169c4d8f97195980815d6fcad04933a7e1ab3b530921c3fef7a1c63426d", size = 12927281, upload-time = "2025-09-09T15:57:47.492Z" }, + { url = "https://files.pythonhosted.org/packages/7b/42/c2e2bc48c5e9b2a83423f99733950fbefd86f165b468a3d85d52b30bf782/numpy-2.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:75370986cc0bc66f4ce5110ad35aae6d182cc4ce6433c40ad151f53690130bf1", size = 10265275, upload-time = "2025-09-09T15:57:49.647Z" }, + { url = "https://files.pythonhosted.org/packages/6b/01/342ad585ad82419b99bcf7cebe99e61da6bedb89e213c5fd71acc467faee/numpy-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cd052f1fa6a78dee696b58a914b7229ecfa41f0a6d96dc663c1220a55e137593", size = 20951527, upload-time = "2025-09-09T15:57:52.006Z" }, + { url = "https://files.pythonhosted.org/packages/ef/d8/204e0d73fc1b7a9ee80ab1fe1983dd33a4d64a4e30a05364b0208e9a241a/numpy-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:414a97499480067d305fcac9716c29cf4d0d76db6ebf0bf3cbce666677f12652", size = 14186159, upload-time = "2025-09-09T15:57:54.407Z" }, + { url = "https://files.pythonhosted.org/packages/22/af/f11c916d08f3a18fb8ba81ab72b5b74a6e42ead4c2846d270eb19845bf74/numpy-2.3.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:50a5fe69f135f88a2be9b6ca0481a68a136f6febe1916e4920e12f1a34e708a7", size = 5114624, upload-time = "2025-09-09T15:57:56.5Z" }, + { url = "https://files.pythonhosted.org/packages/fb/11/0ed919c8381ac9d2ffacd63fd1f0c34d27e99cab650f0eb6f110e6ae4858/numpy-2.3.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:b912f2ed2b67a129e6a601e9d93d4fa37bef67e54cac442a2f588a54afe5c67a", size = 6642627, upload-time = "2025-09-09T15:57:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/ee/83/deb5f77cb0f7ba6cb52b91ed388b47f8f3c2e9930d4665c600408d9b90b9/numpy-2.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e318ee0596d76d4cb3d78535dc005fa60e5ea348cd131a51e99d0bdbe0b54fe", size = 14296926, upload-time = "2025-09-09T15:58:00.035Z" }, + { url = "https://files.pythonhosted.org/packages/77/cc/70e59dcb84f2b005d4f306310ff0a892518cc0c8000a33d0e6faf7ca8d80/numpy-2.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce020080e4a52426202bdb6f7691c65bb55e49f261f31a8f506c9f6bc7450421", size = 16638958, upload-time = "2025-09-09T15:58:02.738Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5a/b2ab6c18b4257e099587d5b7f903317bd7115333ad8d4ec4874278eafa61/numpy-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e6687dc183aa55dae4a705b35f9c0f8cb178bcaa2f029b241ac5356221d5c021", size = 16071920, upload-time = "2025-09-09T15:58:05.029Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f1/8b3fdc44324a259298520dd82147ff648979bed085feeacc1250ef1656c0/numpy-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d8f3b1080782469fdc1718c4ed1d22549b5fb12af0d57d35e992158a772a37cf", size = 18577076, upload-time = "2025-09-09T15:58:07.745Z" }, + { url = "https://files.pythonhosted.org/packages/f0/a1/b87a284fb15a42e9274e7fcea0dad259d12ddbf07c1595b26883151ca3b4/numpy-2.3.3-cp314-cp314-win32.whl", hash = "sha256:cb248499b0bc3be66ebd6578b83e5acacf1d6cb2a77f2248ce0e40fbec5a76d0", size = 6366952, upload-time = "2025-09-09T15:58:10.096Z" }, + { url = "https://files.pythonhosted.org/packages/70/5f/1816f4d08f3b8f66576d8433a66f8fa35a5acfb3bbd0bf6c31183b003f3d/numpy-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:691808c2b26b0f002a032c73255d0bd89751425f379f7bcd22d140db593a96e8", size = 12919322, upload-time = "2025-09-09T15:58:12.138Z" }, + { url = "https://files.pythonhosted.org/packages/8c/de/072420342e46a8ea41c324a555fa90fcc11637583fb8df722936aed1736d/numpy-2.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:9ad12e976ca7b10f1774b03615a2a4bab8addce37ecc77394d8e986927dc0dfe", size = 10478630, upload-time = "2025-09-09T15:58:14.64Z" }, + { url = "https://files.pythonhosted.org/packages/d5/df/ee2f1c0a9de7347f14da5dd3cd3c3b034d1b8607ccb6883d7dd5c035d631/numpy-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9cc48e09feb11e1db00b320e9d30a4151f7369afb96bd0e48d942d09da3a0d00", size = 21047987, upload-time = "2025-09-09T15:58:16.889Z" }, + { url = "https://files.pythonhosted.org/packages/d6/92/9453bdc5a4e9e69cf4358463f25e8260e2ffc126d52e10038b9077815989/numpy-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:901bf6123879b7f251d3631967fd574690734236075082078e0571977c6a8e6a", size = 14301076, upload-time = "2025-09-09T15:58:20.343Z" }, + { url = "https://files.pythonhosted.org/packages/13/77/1447b9eb500f028bb44253105bd67534af60499588a5149a94f18f2ca917/numpy-2.3.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:7f025652034199c301049296b59fa7d52c7e625017cae4c75d8662e377bf487d", size = 5229491, upload-time = "2025-09-09T15:58:22.481Z" }, + { url = "https://files.pythonhosted.org/packages/3d/f9/d72221b6ca205f9736cb4b2ce3b002f6e45cd67cd6a6d1c8af11a2f0b649/numpy-2.3.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:533ca5f6d325c80b6007d4d7fb1984c303553534191024ec6a524a4c92a5935a", size = 6737913, upload-time = "2025-09-09T15:58:24.569Z" }, + { url = "https://files.pythonhosted.org/packages/3c/5f/d12834711962ad9c46af72f79bb31e73e416ee49d17f4c797f72c96b6ca5/numpy-2.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0edd58682a399824633b66885d699d7de982800053acf20be1eaa46d92009c54", size = 14352811, upload-time = "2025-09-09T15:58:26.416Z" }, + { url = "https://files.pythonhosted.org/packages/a1/0d/fdbec6629d97fd1bebed56cd742884e4eead593611bbe1abc3eb40d304b2/numpy-2.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:367ad5d8fbec5d9296d18478804a530f1191e24ab4d75ab408346ae88045d25e", size = 16702689, upload-time = "2025-09-09T15:58:28.831Z" }, + { url = "https://files.pythonhosted.org/packages/9b/09/0a35196dc5575adde1eb97ddfbc3e1687a814f905377621d18ca9bc2b7dd/numpy-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8f6ac61a217437946a1fa48d24c47c91a0c4f725237871117dea264982128097", size = 16133855, upload-time = "2025-09-09T15:58:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ca/c9de3ea397d576f1b6753eaa906d4cdef1bf97589a6d9825a349b4729cc2/numpy-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:179a42101b845a816d464b6fe9a845dfaf308fdfc7925387195570789bb2c970", size = 18652520, upload-time = "2025-09-09T15:58:33.762Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c2/e5ed830e08cd0196351db55db82f65bc0ab05da6ef2b72a836dcf1936d2f/numpy-2.3.3-cp314-cp314t-win32.whl", hash = "sha256:1250c5d3d2562ec4174bce2e3a1523041595f9b651065e4a4473f5f48a6bc8a5", size = 6515371, upload-time = "2025-09-09T15:58:36.04Z" }, + { url = "https://files.pythonhosted.org/packages/47/c7/b0f6b5b67f6788a0725f744496badbb604d226bf233ba716683ebb47b570/numpy-2.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b37a0b2e5935409daebe82c1e42274d30d9dd355852529eab91dab8dcca7419f", size = 13112576, upload-time = "2025-09-09T15:58:37.927Z" }, + { url = "https://files.pythonhosted.org/packages/06/b9/33bba5ff6fb679aa0b1f8a07e853f002a6b04b9394db3069a1270a7784ca/numpy-2.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:78c9f6560dc7e6b3990e32df7ea1a50bbd0e2a111e05209963f5ddcab7073b0b", size = 10545953, upload-time = "2025-09-09T15:58:40.576Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] @@ -249,50 +342,90 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846 }, - { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618 }, - { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212 }, - { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693 }, - { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002 }, - { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971 }, - { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722 }, - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671 }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807 }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872 }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371 }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333 }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120 }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991 }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227 }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056 }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189 }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912 }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160 }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233 }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635 }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079 }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049 }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638 }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834 }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925 }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071 }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504 }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702 }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535 }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582 }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963 }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175 }, +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pastel" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/f1/4594f5e0fcddb6953e5b8fe00da8c317b8b41b547e2b3ae2da7512943c62/pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d", size = 7555, upload-time = "2020-09-16T19:21:12.43Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/18/a8444036c6dd65ba3624c63b734d3ba95ba63ace513078e1580590075d21/pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364", size = 5955, upload-time = "2020-09-16T19:21:11.409Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "platformdirs" version = "4.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632 } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651 }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "poethepoet" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pastel" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/f2/273fe54a78dc5c6c8dd63db71f5a6ceb95e4648516b5aeaeff4bde804e44/poethepoet-0.37.0.tar.gz", hash = "sha256:73edf458707c674a079baa46802e21455bda3a7f82a408e58c31b9f4fe8e933d", size = 68570, upload-time = "2025-08-11T18:00:29.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/1b/5337af1a6a478d25a3e3c56b9b4b42b0a160314e02f4a0498d5322c8dac4/poethepoet-0.37.0-py3-none-any.whl", hash = "sha256:861790276315abcc8df1b4bd60e28c3d48a06db273edd3092f3c94e1a46e5e22", size = 90062, upload-time = "2025-08-11T18:00:27.595Z" }, ] [[package]] @@ -305,9 +438,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/da/b8a7ee04378a53f6fefefc0c5e05570a3ebfdfa0523a878bcd3b475683ee/pydantic-2.12.0.tar.gz", hash = "sha256:c1a077e6270dbfb37bfd8b498b3981e2bb18f68103720e51fa6c306a5a9af563", size = 814760 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/da/b8a7ee04378a53f6fefefc0c5e05570a3ebfdfa0523a878bcd3b475683ee/pydantic-2.12.0.tar.gz", hash = "sha256:c1a077e6270dbfb37bfd8b498b3981e2bb18f68103720e51fa6c306a5a9af563", size = 814760, upload-time = "2025-10-07T15:58:03.467Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/9d/d5c855424e2e5b6b626fbc6ec514d8e655a600377ce283008b115abb7445/pydantic-2.12.0-py3-none-any.whl", hash = "sha256:f6a1da352d42790537e95e83a8bdfb91c7efbae63ffd0b86fa823899e807116f", size = 459730 }, + { url = "https://files.pythonhosted.org/packages/f4/9d/d5c855424e2e5b6b626fbc6ec514d8e655a600377ce283008b115abb7445/pydantic-2.12.0-py3-none-any.whl", hash = "sha256:f6a1da352d42790537e95e83a8bdfb91c7efbae63ffd0b86fa823899e807116f", size = 459730, upload-time = "2025-10-07T15:58:01.576Z" }, ] [[package]] @@ -317,73 +450,99 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/14/12b4a0d2b0b10d8e1d9a24ad94e7bbb43335eaf29c0c4e57860e8a30734a/pydantic_core-2.41.1.tar.gz", hash = "sha256:1ad375859a6d8c356b7704ec0f547a58e82ee80bb41baa811ad710e124bc8f2f", size = 454870 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/bc/5f520319ee1c9e25010412fac4154a72e0a40d0a19eb00281b1f200c0947/pydantic_core-2.41.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:db2f82c0ccbce8f021ad304ce35cbe02aa2f95f215cac388eed542b03b4d5eb4", size = 2099300 }, - { url = "https://files.pythonhosted.org/packages/31/14/010cd64c5c3814fb6064786837ec12604be0dd46df3327cf8474e38abbbd/pydantic_core-2.41.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47694a31c710ced9205d5f1e7e8af3ca57cbb8a503d98cb9e33e27c97a501601", size = 1910179 }, - { url = "https://files.pythonhosted.org/packages/8e/2e/23fc2a8a93efad52df302fdade0a60f471ecc0c7aac889801ac24b4c07d6/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e9decce94daf47baf9e9d392f5f2557e783085f7c5e522011545d9d6858e00", size = 1957225 }, - { url = "https://files.pythonhosted.org/packages/b9/b6/6db08b2725b2432b9390844852e11d320281e5cea8a859c52c68001975fa/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab0adafdf2b89c8b84f847780a119437a0931eca469f7b44d356f2b426dd9741", size = 2053315 }, - { url = "https://files.pythonhosted.org/packages/61/d9/4de44600f2d4514b44f3f3aeeda2e14931214b6b5bf52479339e801ce748/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5da98cc81873f39fd56882e1569c4677940fbc12bce6213fad1ead784192d7c8", size = 2224298 }, - { url = "https://files.pythonhosted.org/packages/7a/ae/dbe51187a7f35fc21b283c5250571a94e36373eb557c1cba9f29a9806dcf/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:209910e88afb01fd0fd403947b809ba8dba0e08a095e1f703294fda0a8fdca51", size = 2351797 }, - { url = "https://files.pythonhosted.org/packages/b5/a7/975585147457c2e9fb951c7c8dab56deeb6aa313f3aa72c2fc0df3f74a49/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365109d1165d78d98e33c5bfd815a9b5d7d070f578caefaabcc5771825b4ecb5", size = 2074921 }, - { url = "https://files.pythonhosted.org/packages/62/37/ea94d1d0c01dec1b7d236c7cec9103baab0021f42500975de3d42522104b/pydantic_core-2.41.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:706abf21e60a2857acdb09502bc853ee5bce732955e7b723b10311114f033115", size = 2187767 }, - { url = "https://files.pythonhosted.org/packages/d3/fe/694cf9fdd3a777a618c3afd210dba7b414cb8a72b1bd29b199c2e5765fee/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bf0bd5417acf7f6a7ec3b53f2109f587be176cb35f9cf016da87e6017437a72d", size = 2136062 }, - { url = "https://files.pythonhosted.org/packages/0f/ae/174aeabd89916fbd2988cc37b81a59e1186e952afd2a7ed92018c22f31ca/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2e71b1c6ceb9c78424ae9f63a07292fb769fb890a4e7efca5554c47f33a60ea5", size = 2317819 }, - { url = "https://files.pythonhosted.org/packages/65/e8/e9aecafaebf53fc456314f72886068725d6fba66f11b013532dc21259343/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80745b9770b4a38c25015b517451c817799bfb9d6499b0d13d8227ec941cb513", size = 2312267 }, - { url = "https://files.pythonhosted.org/packages/35/2f/1c2e71d2a052f9bb2f2df5a6a05464a0eb800f9e8d9dd800202fe31219e1/pydantic_core-2.41.1-cp312-cp312-win32.whl", hash = "sha256:83b64d70520e7890453f1aa21d66fda44e7b35f1cfea95adf7b4289a51e2b479", size = 1990927 }, - { url = "https://files.pythonhosted.org/packages/b1/78/562998301ff2588b9c6dcc5cb21f52fa919d6e1decc75a35055feb973594/pydantic_core-2.41.1-cp312-cp312-win_amd64.whl", hash = "sha256:377defd66ee2003748ee93c52bcef2d14fde48fe28a0b156f88c3dbf9bc49a50", size = 2034703 }, - { url = "https://files.pythonhosted.org/packages/b2/53/d95699ce5a5cdb44bb470bd818b848b9beadf51459fd4ea06667e8ede862/pydantic_core-2.41.1-cp312-cp312-win_arm64.whl", hash = "sha256:c95caff279d49c1d6cdfe2996e6c2ad712571d3b9caaa209a404426c326c4bde", size = 1972719 }, - { url = "https://files.pythonhosted.org/packages/27/8a/6d54198536a90a37807d31a156642aae7a8e1263ed9fe6fc6245defe9332/pydantic_core-2.41.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70e790fce5f05204ef4403159857bfcd587779da78627b0babb3654f75361ebf", size = 2105825 }, - { url = "https://files.pythonhosted.org/packages/4f/2e/4784fd7b22ac9c8439db25bf98ffed6853d01e7e560a346e8af821776ccc/pydantic_core-2.41.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9cebf1ca35f10930612d60bd0f78adfacee824c30a880e3534ba02c207cceceb", size = 1910126 }, - { url = "https://files.pythonhosted.org/packages/f3/92/31eb0748059ba5bd0aa708fb4bab9fcb211461ddcf9e90702a6542f22d0d/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:170406a37a5bc82c22c3274616bf6f17cc7df9c4a0a0a50449e559cb755db669", size = 1961472 }, - { url = "https://files.pythonhosted.org/packages/ab/91/946527792275b5c4c7dde4cfa3e81241bf6900e9fee74fb1ba43e0c0f1ab/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:12d4257fc9187a0ccd41b8b327d6a4e57281ab75e11dda66a9148ef2e1fb712f", size = 2063230 }, - { url = "https://files.pythonhosted.org/packages/31/5d/a35c5d7b414e5c0749f1d9f0d159ee2ef4bab313f499692896b918014ee3/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a75a33b4db105dd1c8d57839e17ee12db8d5ad18209e792fa325dbb4baeb00f4", size = 2229469 }, - { url = "https://files.pythonhosted.org/packages/21/4d/8713737c689afa57ecfefe38db78259d4484c97aa494979e6a9d19662584/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08a589f850803a74e0fcb16a72081cafb0d72a3cdda500106942b07e76b7bf62", size = 2347986 }, - { url = "https://files.pythonhosted.org/packages/f6/ec/929f9a3a5ed5cda767081494bacd32f783e707a690ce6eeb5e0730ec4986/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a97939d6ea44763c456bd8a617ceada2c9b96bb5b8ab3dfa0d0827df7619014", size = 2072216 }, - { url = "https://files.pythonhosted.org/packages/26/55/a33f459d4f9cc8786d9db42795dbecc84fa724b290d7d71ddc3d7155d46a/pydantic_core-2.41.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae423c65c556f09569524b80ffd11babff61f33055ef9773d7c9fabc11ed8d", size = 2193047 }, - { url = "https://files.pythonhosted.org/packages/77/af/d5c6959f8b089f2185760a2779079e3c2c411bfc70ea6111f58367851629/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:4dc703015fbf8764d6a8001c327a87f1823b7328d40b47ce6000c65918ad2b4f", size = 2140613 }, - { url = "https://files.pythonhosted.org/packages/58/e5/2c19bd2a14bffe7fabcf00efbfbd3ac430aaec5271b504a938ff019ac7be/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:968e4ffdfd35698a5fe659e5e44c508b53664870a8e61c8f9d24d3d145d30257", size = 2327641 }, - { url = "https://files.pythonhosted.org/packages/93/ef/e0870ccda798c54e6b100aff3c4d49df5458fd64217e860cb9c3b0a403f4/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:fff2b76c8e172d34771cd4d4f0ade08072385310f214f823b5a6ad4006890d32", size = 2318229 }, - { url = "https://files.pythonhosted.org/packages/b1/4b/c3b991d95f5deb24d0bd52e47bcf716098fa1afe0ce2d4bd3125b38566ba/pydantic_core-2.41.1-cp313-cp313-win32.whl", hash = "sha256:a38a5263185407ceb599f2f035faf4589d57e73c7146d64f10577f6449e8171d", size = 1997911 }, - { url = "https://files.pythonhosted.org/packages/a7/ce/5c316fd62e01f8d6be1b7ee6b54273214e871772997dc2c95e204997a055/pydantic_core-2.41.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42ae7fd6760782c975897e1fdc810f483b021b32245b0105d40f6e7a3803e4b", size = 2034301 }, - { url = "https://files.pythonhosted.org/packages/29/41/902640cfd6a6523194123e2c3373c60f19006447f2fb06f76de4e8466c5b/pydantic_core-2.41.1-cp313-cp313-win_arm64.whl", hash = "sha256:ad4111acc63b7384e205c27a2f15e23ac0ee21a9d77ad6f2e9cb516ec90965fb", size = 1977238 }, - { url = "https://files.pythonhosted.org/packages/04/04/28b040e88c1b89d851278478842f0bdf39c7a05da9e850333c6c8cbe7dfa/pydantic_core-2.41.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:440d0df7415b50084a4ba9d870480c16c5f67c0d1d4d5119e3f70925533a0edc", size = 1875626 }, - { url = "https://files.pythonhosted.org/packages/d6/58/b41dd3087505220bb58bc81be8c3e8cbc037f5710cd3c838f44f90bdd704/pydantic_core-2.41.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71eaa38d342099405dae6484216dcf1e8e4b0bebd9b44a4e08c9b43db6a2ab67", size = 2045708 }, - { url = "https://files.pythonhosted.org/packages/d7/b8/760f23754e40bf6c65b94a69b22c394c24058a0ef7e2aa471d2e39219c1a/pydantic_core-2.41.1-cp313-cp313t-win_amd64.whl", hash = "sha256:555ecf7e50f1161d3f693bc49f23c82cf6cdeafc71fa37a06120772a09a38795", size = 1997171 }, - { url = "https://files.pythonhosted.org/packages/41/12/cec246429ddfa2778d2d6301eca5362194dc8749ecb19e621f2f65b5090f/pydantic_core-2.41.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:05226894a26f6f27e1deb735d7308f74ef5fa3a6de3e0135bb66cdcaee88f64b", size = 2107836 }, - { url = "https://files.pythonhosted.org/packages/20/39/baba47f8d8b87081302498e610aefc37142ce6a1cc98b2ab6b931a162562/pydantic_core-2.41.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:85ff7911c6c3e2fd8d3779c50925f6406d770ea58ea6dde9c230d35b52b16b4a", size = 1904449 }, - { url = "https://files.pythonhosted.org/packages/50/32/9a3d87cae2c75a5178334b10358d631bd094b916a00a5993382222dbfd92/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47f1f642a205687d59b52dc1a9a607f45e588f5a2e9eeae05edd80c7a8c47674", size = 1961750 }, - { url = "https://files.pythonhosted.org/packages/27/42/a96c9d793a04cf2a9773bff98003bb154087b94f5530a2ce6063ecfec583/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df11c24e138876ace5ec6043e5cae925e34cf38af1a1b3d63589e8f7b5f5cdc4", size = 2063305 }, - { url = "https://files.pythonhosted.org/packages/3e/8d/028c4b7d157a005b1f52c086e2d4b0067886b213c86220c1153398dbdf8f/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f0bf7f5c8f7bf345c527e8a0d72d6b26eda99c1227b0c34e7e59e181260de31", size = 2228959 }, - { url = "https://files.pythonhosted.org/packages/08/f7/ee64cda8fcc9ca3f4716e6357144f9ee71166775df582a1b6b738bf6da57/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82b887a711d341c2c47352375d73b029418f55b20bd7815446d175a70effa706", size = 2345421 }, - { url = "https://files.pythonhosted.org/packages/13/c0/e8ec05f0f5ee7a3656973ad9cd3bc73204af99f6512c1a4562f6fb4b3f7d/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5f1d5d6bbba484bdf220c72d8ecd0be460f4bd4c5e534a541bb2cd57589fb8b", size = 2065288 }, - { url = "https://files.pythonhosted.org/packages/0a/25/d77a73ff24e2e4fcea64472f5e39b0402d836da9b08b5361a734d0153023/pydantic_core-2.41.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bf1917385ebe0f968dc5c6ab1375886d56992b93ddfe6bf52bff575d03662be", size = 2189759 }, - { url = "https://files.pythonhosted.org/packages/66/45/4a4ebaaae12a740552278d06fe71418c0f2869537a369a89c0e6723b341d/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:4f94f3ab188f44b9a73f7295663f3ecb8f2e2dd03a69c8f2ead50d37785ecb04", size = 2140747 }, - { url = "https://files.pythonhosted.org/packages/da/6d/b727ce1022f143194a36593243ff244ed5a1eb3c9122296bf7e716aa37ba/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:3925446673641d37c30bd84a9d597e49f72eacee8b43322c8999fa17d5ae5bc4", size = 2327416 }, - { url = "https://files.pythonhosted.org/packages/6f/8c/02df9d8506c427787059f87c6c7253435c6895e12472a652d9616ee0fc95/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:49bd51cc27adb980c7b97357ae036ce9b3c4d0bb406e84fbe16fb2d368b602a8", size = 2318138 }, - { url = "https://files.pythonhosted.org/packages/98/67/0cf429a7d6802536941f430e6e3243f6d4b68f41eeea4b242372f1901794/pydantic_core-2.41.1-cp314-cp314-win32.whl", hash = "sha256:a31ca0cd0e4d12ea0df0077df2d487fc3eb9d7f96bbb13c3c5b88dcc21d05159", size = 1998429 }, - { url = "https://files.pythonhosted.org/packages/38/60/742fef93de5d085022d2302a6317a2b34dbfe15258e9396a535c8a100ae7/pydantic_core-2.41.1-cp314-cp314-win_amd64.whl", hash = "sha256:1b5c4374a152e10a22175d7790e644fbd8ff58418890e07e2073ff9d4414efae", size = 2028870 }, - { url = "https://files.pythonhosted.org/packages/31/38/cdd8ccb8555ef7720bd7715899bd6cfbe3c29198332710e1b61b8f5dd8b8/pydantic_core-2.41.1-cp314-cp314-win_arm64.whl", hash = "sha256:4fee76d757639b493eb600fba668f1e17475af34c17dd61db7a47e824d464ca9", size = 1974275 }, - { url = "https://files.pythonhosted.org/packages/e7/7e/8ac10ccb047dc0221aa2530ec3c7c05ab4656d4d4bd984ee85da7f3d5525/pydantic_core-2.41.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f9b9c968cfe5cd576fdd7361f47f27adeb120517e637d1b189eea1c3ece573f4", size = 1875124 }, - { url = "https://files.pythonhosted.org/packages/c3/e4/7d9791efeb9c7d97e7268f8d20e0da24d03438a7fa7163ab58f1073ba968/pydantic_core-2.41.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1ebc7ab67b856384aba09ed74e3e977dded40e693de18a4f197c67d0d4e6d8e", size = 2043075 }, - { url = "https://files.pythonhosted.org/packages/2d/c3/3f6e6b2342ac11ac8cd5cb56e24c7b14afa27c010e82a765ffa5f771884a/pydantic_core-2.41.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8ae0dc57b62a762985bc7fbf636be3412394acc0ddb4ade07fe104230f1b9762", size = 1995341 }, - { url = "https://files.pythonhosted.org/packages/16/89/d0afad37ba25f5801735af1472e650b86baad9fe807a42076508e4824a2a/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:68f2251559b8efa99041bb63571ec7cdd2d715ba74cc82b3bc9eff824ebc8bf0", size = 2124001 }, - { url = "https://files.pythonhosted.org/packages/8e/c4/08609134b34520568ddebb084d9ed0a2a3f5f52b45739e6e22cb3a7112eb/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:c7bc140c596097cb53b30546ca257dbe3f19282283190b1b5142928e5d5d3a20", size = 1941841 }, - { url = "https://files.pythonhosted.org/packages/2a/43/94a4877094e5fe19a3f37e7e817772263e2c573c94f1e3fa2b1eee56ef3b/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2896510fce8f4725ec518f8b9d7f015a00db249d2fd40788f442af303480063d", size = 1961129 }, - { url = "https://files.pythonhosted.org/packages/a2/30/23a224d7e25260eb5f69783a63667453037e07eb91ff0e62dabaadd47128/pydantic_core-2.41.1-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ced20e62cfa0f496ba68fa5d6c7ee71114ea67e2a5da3114d6450d7f4683572a", size = 2148770 }, - { url = "https://files.pythonhosted.org/packages/2b/3e/a51c5f5d37b9288ba30683d6e96f10fa8f1defad1623ff09f1020973b577/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b04fa9ed049461a7398138c604b00550bc89e3e1151d84b81ad6dc93e39c4c06", size = 2115344 }, - { url = "https://files.pythonhosted.org/packages/5a/bd/389504c9e0600ef4502cd5238396b527afe6ef8981a6a15cd1814fc7b434/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:b3b7d9cfbfdc43c80a16638c6dc2768e3956e73031fca64e8e1a3ae744d1faeb", size = 1927994 }, - { url = "https://files.pythonhosted.org/packages/ff/9c/5111c6b128861cb792a4c082677e90dac4f2e090bb2e2fe06aa5b2d39027/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eec83fc6abef04c7f9bec616e2d76ee9a6a4ae2a359b10c21d0f680e24a247ca", size = 1959394 }, - { url = "https://files.pythonhosted.org/packages/14/3f/cfec8b9a0c48ce5d64409ec5e1903cb0b7363da38f14b41de2fcb3712700/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6771a2d9f83c4038dfad5970a3eef215940682b2175e32bcc817bdc639019b28", size = 2147365 }, +sdist = { url = "https://files.pythonhosted.org/packages/7d/14/12b4a0d2b0b10d8e1d9a24ad94e7bbb43335eaf29c0c4e57860e8a30734a/pydantic_core-2.41.1.tar.gz", hash = "sha256:1ad375859a6d8c356b7704ec0f547a58e82ee80bb41baa811ad710e124bc8f2f", size = 454870, upload-time = "2025-10-07T10:50:45.974Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/bc/5f520319ee1c9e25010412fac4154a72e0a40d0a19eb00281b1f200c0947/pydantic_core-2.41.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:db2f82c0ccbce8f021ad304ce35cbe02aa2f95f215cac388eed542b03b4d5eb4", size = 2099300, upload-time = "2025-10-06T21:10:30.463Z" }, + { url = "https://files.pythonhosted.org/packages/31/14/010cd64c5c3814fb6064786837ec12604be0dd46df3327cf8474e38abbbd/pydantic_core-2.41.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47694a31c710ced9205d5f1e7e8af3ca57cbb8a503d98cb9e33e27c97a501601", size = 1910179, upload-time = "2025-10-06T21:10:31.782Z" }, + { url = "https://files.pythonhosted.org/packages/8e/2e/23fc2a8a93efad52df302fdade0a60f471ecc0c7aac889801ac24b4c07d6/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e9decce94daf47baf9e9d392f5f2557e783085f7c5e522011545d9d6858e00", size = 1957225, upload-time = "2025-10-06T21:10:33.11Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b6/6db08b2725b2432b9390844852e11d320281e5cea8a859c52c68001975fa/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab0adafdf2b89c8b84f847780a119437a0931eca469f7b44d356f2b426dd9741", size = 2053315, upload-time = "2025-10-06T21:10:34.87Z" }, + { url = "https://files.pythonhosted.org/packages/61/d9/4de44600f2d4514b44f3f3aeeda2e14931214b6b5bf52479339e801ce748/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5da98cc81873f39fd56882e1569c4677940fbc12bce6213fad1ead784192d7c8", size = 2224298, upload-time = "2025-10-06T21:10:36.233Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ae/dbe51187a7f35fc21b283c5250571a94e36373eb557c1cba9f29a9806dcf/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:209910e88afb01fd0fd403947b809ba8dba0e08a095e1f703294fda0a8fdca51", size = 2351797, upload-time = "2025-10-06T21:10:37.601Z" }, + { url = "https://files.pythonhosted.org/packages/b5/a7/975585147457c2e9fb951c7c8dab56deeb6aa313f3aa72c2fc0df3f74a49/pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365109d1165d78d98e33c5bfd815a9b5d7d070f578caefaabcc5771825b4ecb5", size = 2074921, upload-time = "2025-10-06T21:10:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/62/37/ea94d1d0c01dec1b7d236c7cec9103baab0021f42500975de3d42522104b/pydantic_core-2.41.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:706abf21e60a2857acdb09502bc853ee5bce732955e7b723b10311114f033115", size = 2187767, upload-time = "2025-10-06T21:10:40.651Z" }, + { url = "https://files.pythonhosted.org/packages/d3/fe/694cf9fdd3a777a618c3afd210dba7b414cb8a72b1bd29b199c2e5765fee/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bf0bd5417acf7f6a7ec3b53f2109f587be176cb35f9cf016da87e6017437a72d", size = 2136062, upload-time = "2025-10-06T21:10:42.09Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/174aeabd89916fbd2988cc37b81a59e1186e952afd2a7ed92018c22f31ca/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2e71b1c6ceb9c78424ae9f63a07292fb769fb890a4e7efca5554c47f33a60ea5", size = 2317819, upload-time = "2025-10-06T21:10:43.974Z" }, + { url = "https://files.pythonhosted.org/packages/65/e8/e9aecafaebf53fc456314f72886068725d6fba66f11b013532dc21259343/pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80745b9770b4a38c25015b517451c817799bfb9d6499b0d13d8227ec941cb513", size = 2312267, upload-time = "2025-10-06T21:10:45.34Z" }, + { url = "https://files.pythonhosted.org/packages/35/2f/1c2e71d2a052f9bb2f2df5a6a05464a0eb800f9e8d9dd800202fe31219e1/pydantic_core-2.41.1-cp312-cp312-win32.whl", hash = "sha256:83b64d70520e7890453f1aa21d66fda44e7b35f1cfea95adf7b4289a51e2b479", size = 1990927, upload-time = "2025-10-06T21:10:46.738Z" }, + { url = "https://files.pythonhosted.org/packages/b1/78/562998301ff2588b9c6dcc5cb21f52fa919d6e1decc75a35055feb973594/pydantic_core-2.41.1-cp312-cp312-win_amd64.whl", hash = "sha256:377defd66ee2003748ee93c52bcef2d14fde48fe28a0b156f88c3dbf9bc49a50", size = 2034703, upload-time = "2025-10-06T21:10:48.524Z" }, + { url = "https://files.pythonhosted.org/packages/b2/53/d95699ce5a5cdb44bb470bd818b848b9beadf51459fd4ea06667e8ede862/pydantic_core-2.41.1-cp312-cp312-win_arm64.whl", hash = "sha256:c95caff279d49c1d6cdfe2996e6c2ad712571d3b9caaa209a404426c326c4bde", size = 1972719, upload-time = "2025-10-06T21:10:50.256Z" }, + { url = "https://files.pythonhosted.org/packages/27/8a/6d54198536a90a37807d31a156642aae7a8e1263ed9fe6fc6245defe9332/pydantic_core-2.41.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70e790fce5f05204ef4403159857bfcd587779da78627b0babb3654f75361ebf", size = 2105825, upload-time = "2025-10-06T21:10:51.719Z" }, + { url = "https://files.pythonhosted.org/packages/4f/2e/4784fd7b22ac9c8439db25bf98ffed6853d01e7e560a346e8af821776ccc/pydantic_core-2.41.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9cebf1ca35f10930612d60bd0f78adfacee824c30a880e3534ba02c207cceceb", size = 1910126, upload-time = "2025-10-06T21:10:53.145Z" }, + { url = "https://files.pythonhosted.org/packages/f3/92/31eb0748059ba5bd0aa708fb4bab9fcb211461ddcf9e90702a6542f22d0d/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:170406a37a5bc82c22c3274616bf6f17cc7df9c4a0a0a50449e559cb755db669", size = 1961472, upload-time = "2025-10-06T21:10:55.754Z" }, + { url = "https://files.pythonhosted.org/packages/ab/91/946527792275b5c4c7dde4cfa3e81241bf6900e9fee74fb1ba43e0c0f1ab/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:12d4257fc9187a0ccd41b8b327d6a4e57281ab75e11dda66a9148ef2e1fb712f", size = 2063230, upload-time = "2025-10-06T21:10:57.179Z" }, + { url = "https://files.pythonhosted.org/packages/31/5d/a35c5d7b414e5c0749f1d9f0d159ee2ef4bab313f499692896b918014ee3/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a75a33b4db105dd1c8d57839e17ee12db8d5ad18209e792fa325dbb4baeb00f4", size = 2229469, upload-time = "2025-10-06T21:10:59.409Z" }, + { url = "https://files.pythonhosted.org/packages/21/4d/8713737c689afa57ecfefe38db78259d4484c97aa494979e6a9d19662584/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08a589f850803a74e0fcb16a72081cafb0d72a3cdda500106942b07e76b7bf62", size = 2347986, upload-time = "2025-10-06T21:11:00.847Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ec/929f9a3a5ed5cda767081494bacd32f783e707a690ce6eeb5e0730ec4986/pydantic_core-2.41.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a97939d6ea44763c456bd8a617ceada2c9b96bb5b8ab3dfa0d0827df7619014", size = 2072216, upload-time = "2025-10-06T21:11:02.43Z" }, + { url = "https://files.pythonhosted.org/packages/26/55/a33f459d4f9cc8786d9db42795dbecc84fa724b290d7d71ddc3d7155d46a/pydantic_core-2.41.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae423c65c556f09569524b80ffd11babff61f33055ef9773d7c9fabc11ed8d", size = 2193047, upload-time = "2025-10-06T21:11:03.787Z" }, + { url = "https://files.pythonhosted.org/packages/77/af/d5c6959f8b089f2185760a2779079e3c2c411bfc70ea6111f58367851629/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:4dc703015fbf8764d6a8001c327a87f1823b7328d40b47ce6000c65918ad2b4f", size = 2140613, upload-time = "2025-10-06T21:11:05.607Z" }, + { url = "https://files.pythonhosted.org/packages/58/e5/2c19bd2a14bffe7fabcf00efbfbd3ac430aaec5271b504a938ff019ac7be/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:968e4ffdfd35698a5fe659e5e44c508b53664870a8e61c8f9d24d3d145d30257", size = 2327641, upload-time = "2025-10-06T21:11:07.143Z" }, + { url = "https://files.pythonhosted.org/packages/93/ef/e0870ccda798c54e6b100aff3c4d49df5458fd64217e860cb9c3b0a403f4/pydantic_core-2.41.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:fff2b76c8e172d34771cd4d4f0ade08072385310f214f823b5a6ad4006890d32", size = 2318229, upload-time = "2025-10-06T21:11:08.73Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/c3b991d95f5deb24d0bd52e47bcf716098fa1afe0ce2d4bd3125b38566ba/pydantic_core-2.41.1-cp313-cp313-win32.whl", hash = "sha256:a38a5263185407ceb599f2f035faf4589d57e73c7146d64f10577f6449e8171d", size = 1997911, upload-time = "2025-10-06T21:11:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/a7/ce/5c316fd62e01f8d6be1b7ee6b54273214e871772997dc2c95e204997a055/pydantic_core-2.41.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42ae7fd6760782c975897e1fdc810f483b021b32245b0105d40f6e7a3803e4b", size = 2034301, upload-time = "2025-10-06T21:11:12.113Z" }, + { url = "https://files.pythonhosted.org/packages/29/41/902640cfd6a6523194123e2c3373c60f19006447f2fb06f76de4e8466c5b/pydantic_core-2.41.1-cp313-cp313-win_arm64.whl", hash = "sha256:ad4111acc63b7384e205c27a2f15e23ac0ee21a9d77ad6f2e9cb516ec90965fb", size = 1977238, upload-time = "2025-10-06T21:11:14.1Z" }, + { url = "https://files.pythonhosted.org/packages/04/04/28b040e88c1b89d851278478842f0bdf39c7a05da9e850333c6c8cbe7dfa/pydantic_core-2.41.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:440d0df7415b50084a4ba9d870480c16c5f67c0d1d4d5119e3f70925533a0edc", size = 1875626, upload-time = "2025-10-06T21:11:15.69Z" }, + { url = "https://files.pythonhosted.org/packages/d6/58/b41dd3087505220bb58bc81be8c3e8cbc037f5710cd3c838f44f90bdd704/pydantic_core-2.41.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71eaa38d342099405dae6484216dcf1e8e4b0bebd9b44a4e08c9b43db6a2ab67", size = 2045708, upload-time = "2025-10-06T21:11:17.258Z" }, + { url = "https://files.pythonhosted.org/packages/d7/b8/760f23754e40bf6c65b94a69b22c394c24058a0ef7e2aa471d2e39219c1a/pydantic_core-2.41.1-cp313-cp313t-win_amd64.whl", hash = "sha256:555ecf7e50f1161d3f693bc49f23c82cf6cdeafc71fa37a06120772a09a38795", size = 1997171, upload-time = "2025-10-06T21:11:18.822Z" }, + { url = "https://files.pythonhosted.org/packages/41/12/cec246429ddfa2778d2d6301eca5362194dc8749ecb19e621f2f65b5090f/pydantic_core-2.41.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:05226894a26f6f27e1deb735d7308f74ef5fa3a6de3e0135bb66cdcaee88f64b", size = 2107836, upload-time = "2025-10-06T21:11:20.432Z" }, + { url = "https://files.pythonhosted.org/packages/20/39/baba47f8d8b87081302498e610aefc37142ce6a1cc98b2ab6b931a162562/pydantic_core-2.41.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:85ff7911c6c3e2fd8d3779c50925f6406d770ea58ea6dde9c230d35b52b16b4a", size = 1904449, upload-time = "2025-10-06T21:11:22.185Z" }, + { url = "https://files.pythonhosted.org/packages/50/32/9a3d87cae2c75a5178334b10358d631bd094b916a00a5993382222dbfd92/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47f1f642a205687d59b52dc1a9a607f45e588f5a2e9eeae05edd80c7a8c47674", size = 1961750, upload-time = "2025-10-06T21:11:24.348Z" }, + { url = "https://files.pythonhosted.org/packages/27/42/a96c9d793a04cf2a9773bff98003bb154087b94f5530a2ce6063ecfec583/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df11c24e138876ace5ec6043e5cae925e34cf38af1a1b3d63589e8f7b5f5cdc4", size = 2063305, upload-time = "2025-10-06T21:11:26.556Z" }, + { url = "https://files.pythonhosted.org/packages/3e/8d/028c4b7d157a005b1f52c086e2d4b0067886b213c86220c1153398dbdf8f/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f0bf7f5c8f7bf345c527e8a0d72d6b26eda99c1227b0c34e7e59e181260de31", size = 2228959, upload-time = "2025-10-06T21:11:28.426Z" }, + { url = "https://files.pythonhosted.org/packages/08/f7/ee64cda8fcc9ca3f4716e6357144f9ee71166775df582a1b6b738bf6da57/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82b887a711d341c2c47352375d73b029418f55b20bd7815446d175a70effa706", size = 2345421, upload-time = "2025-10-06T21:11:30.226Z" }, + { url = "https://files.pythonhosted.org/packages/13/c0/e8ec05f0f5ee7a3656973ad9cd3bc73204af99f6512c1a4562f6fb4b3f7d/pydantic_core-2.41.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5f1d5d6bbba484bdf220c72d8ecd0be460f4bd4c5e534a541bb2cd57589fb8b", size = 2065288, upload-time = "2025-10-06T21:11:32.019Z" }, + { url = "https://files.pythonhosted.org/packages/0a/25/d77a73ff24e2e4fcea64472f5e39b0402d836da9b08b5361a734d0153023/pydantic_core-2.41.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bf1917385ebe0f968dc5c6ab1375886d56992b93ddfe6bf52bff575d03662be", size = 2189759, upload-time = "2025-10-06T21:11:33.753Z" }, + { url = "https://files.pythonhosted.org/packages/66/45/4a4ebaaae12a740552278d06fe71418c0f2869537a369a89c0e6723b341d/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:4f94f3ab188f44b9a73f7295663f3ecb8f2e2dd03a69c8f2ead50d37785ecb04", size = 2140747, upload-time = "2025-10-06T21:11:35.781Z" }, + { url = "https://files.pythonhosted.org/packages/da/6d/b727ce1022f143194a36593243ff244ed5a1eb3c9122296bf7e716aa37ba/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:3925446673641d37c30bd84a9d597e49f72eacee8b43322c8999fa17d5ae5bc4", size = 2327416, upload-time = "2025-10-06T21:11:37.75Z" }, + { url = "https://files.pythonhosted.org/packages/6f/8c/02df9d8506c427787059f87c6c7253435c6895e12472a652d9616ee0fc95/pydantic_core-2.41.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:49bd51cc27adb980c7b97357ae036ce9b3c4d0bb406e84fbe16fb2d368b602a8", size = 2318138, upload-time = "2025-10-06T21:11:39.463Z" }, + { url = "https://files.pythonhosted.org/packages/98/67/0cf429a7d6802536941f430e6e3243f6d4b68f41eeea4b242372f1901794/pydantic_core-2.41.1-cp314-cp314-win32.whl", hash = "sha256:a31ca0cd0e4d12ea0df0077df2d487fc3eb9d7f96bbb13c3c5b88dcc21d05159", size = 1998429, upload-time = "2025-10-06T21:11:41.989Z" }, + { url = "https://files.pythonhosted.org/packages/38/60/742fef93de5d085022d2302a6317a2b34dbfe15258e9396a535c8a100ae7/pydantic_core-2.41.1-cp314-cp314-win_amd64.whl", hash = "sha256:1b5c4374a152e10a22175d7790e644fbd8ff58418890e07e2073ff9d4414efae", size = 2028870, upload-time = "2025-10-06T21:11:43.66Z" }, + { url = "https://files.pythonhosted.org/packages/31/38/cdd8ccb8555ef7720bd7715899bd6cfbe3c29198332710e1b61b8f5dd8b8/pydantic_core-2.41.1-cp314-cp314-win_arm64.whl", hash = "sha256:4fee76d757639b493eb600fba668f1e17475af34c17dd61db7a47e824d464ca9", size = 1974275, upload-time = "2025-10-06T21:11:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/e7/7e/8ac10ccb047dc0221aa2530ec3c7c05ab4656d4d4bd984ee85da7f3d5525/pydantic_core-2.41.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f9b9c968cfe5cd576fdd7361f47f27adeb120517e637d1b189eea1c3ece573f4", size = 1875124, upload-time = "2025-10-06T21:11:47.591Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e4/7d9791efeb9c7d97e7268f8d20e0da24d03438a7fa7163ab58f1073ba968/pydantic_core-2.41.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1ebc7ab67b856384aba09ed74e3e977dded40e693de18a4f197c67d0d4e6d8e", size = 2043075, upload-time = "2025-10-06T21:11:49.542Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c3/3f6e6b2342ac11ac8cd5cb56e24c7b14afa27c010e82a765ffa5f771884a/pydantic_core-2.41.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8ae0dc57b62a762985bc7fbf636be3412394acc0ddb4ade07fe104230f1b9762", size = 1995341, upload-time = "2025-10-06T21:11:51.497Z" }, + { url = "https://files.pythonhosted.org/packages/2b/3e/a51c5f5d37b9288ba30683d6e96f10fa8f1defad1623ff09f1020973b577/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b04fa9ed049461a7398138c604b00550bc89e3e1151d84b81ad6dc93e39c4c06", size = 2115344, upload-time = "2025-10-07T10:50:02.466Z" }, + { url = "https://files.pythonhosted.org/packages/5a/bd/389504c9e0600ef4502cd5238396b527afe6ef8981a6a15cd1814fc7b434/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:b3b7d9cfbfdc43c80a16638c6dc2768e3956e73031fca64e8e1a3ae744d1faeb", size = 1927994, upload-time = "2025-10-07T10:50:04.379Z" }, + { url = "https://files.pythonhosted.org/packages/ff/9c/5111c6b128861cb792a4c082677e90dac4f2e090bb2e2fe06aa5b2d39027/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eec83fc6abef04c7f9bec616e2d76ee9a6a4ae2a359b10c21d0f680e24a247ca", size = 1959394, upload-time = "2025-10-07T10:50:06.335Z" }, + { url = "https://files.pythonhosted.org/packages/14/3f/cfec8b9a0c48ce5d64409ec5e1903cb0b7363da38f14b41de2fcb3712700/pydantic_core-2.41.1-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6771a2d9f83c4038dfad5970a3eef215940682b2175e32bcc817bdc639019b28", size = 2147365, upload-time = "2025-10-07T10:50:07.978Z" }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217 }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/1d/eb34f286b164c5e431a810a38697409cca1112cee04b287bb56ac486730b/pytest-9.0.0.tar.gz", hash = "sha256:8f44522eafe4137b0f35c9ce3072931a788a21ee40a2ed279e817d3cc16ed21e", size = 1562764, upload-time = "2025-11-08T17:25:33.34Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/99/cafef234114a3b6d9f3aaed0723b437c40c57bdb7b3e4c3a575bc4890052/pytest-9.0.0-py3-none-any.whl", hash = "sha256:e5ccdf10b0bac554970ee88fc1a4ad0ee5d221f8ef22321f9b7e4584e19d7f96", size = 373364, upload-time = "2025-11-08T17:25:31.811Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] @@ -393,18 +552,64 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "pytz" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 }, +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] @@ -417,9 +622,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738 }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] @@ -430,9 +635,35 @@ dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/55/cccfca45157a2031dcbb5a462a67f7cf27f8b37d4b3b1cd7438f0f5c1df6/ruff-0.14.4.tar.gz", hash = "sha256:f459a49fe1085a749f15414ca76f61595f1a2cc8778ed7c279b6ca2e1fd19df3", size = 5587844, upload-time = "2025-11-06T22:07:45.033Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368 }, + { url = "https://files.pythonhosted.org/packages/17/b9/67240254166ae1eaa38dec32265e9153ac53645a6c6670ed36ad00722af8/ruff-0.14.4-py3-none-linux_armv6l.whl", hash = "sha256:e6604613ffbcf2297cd5dcba0e0ac9bd0c11dc026442dfbb614504e87c349518", size = 12606781, upload-time = "2025-11-06T22:07:01.841Z" }, + { url = "https://files.pythonhosted.org/packages/46/c8/09b3ab245d8652eafe5256ab59718641429f68681ee713ff06c5c549f156/ruff-0.14.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d99c0b52b6f0598acede45ee78288e5e9b4409d1ce7f661f0fa36d4cbeadf9a4", size = 12946765, upload-time = "2025-11-06T22:07:05.858Z" }, + { url = "https://files.pythonhosted.org/packages/14/bb/1564b000219144bf5eed2359edc94c3590dd49d510751dad26202c18a17d/ruff-0.14.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9358d490ec030f1b51d048a7fd6ead418ed0826daf6149e95e30aa67c168af33", size = 11928120, upload-time = "2025-11-06T22:07:08.023Z" }, + { url = "https://files.pythonhosted.org/packages/a3/92/d5f1770e9988cc0742fefaa351e840d9aef04ec24ae1be36f333f96d5704/ruff-0.14.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b40d27924f1f02dfa827b9c0712a13c0e4b108421665322218fc38caf615c2", size = 12370877, upload-time = "2025-11-06T22:07:10.015Z" }, + { url = "https://files.pythonhosted.org/packages/e2/29/e9282efa55f1973d109faf839a63235575519c8ad278cc87a182a366810e/ruff-0.14.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f5e649052a294fe00818650712083cddc6cc02744afaf37202c65df9ea52efa5", size = 12408538, upload-time = "2025-11-06T22:07:13.085Z" }, + { url = "https://files.pythonhosted.org/packages/8e/01/930ed6ecfce130144b32d77d8d69f5c610e6d23e6857927150adf5d7379a/ruff-0.14.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa082a8f878deeba955531f975881828fd6afd90dfa757c2b0808aadb437136e", size = 13141942, upload-time = "2025-11-06T22:07:15.386Z" }, + { url = "https://files.pythonhosted.org/packages/6a/46/a9c89b42b231a9f487233f17a89cbef9d5acd538d9488687a02ad288fa6b/ruff-0.14.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1043c6811c2419e39011890f14d0a30470f19d47d197c4858b2787dfa698f6c8", size = 14544306, upload-time = "2025-11-06T22:07:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/78/96/9c6cf86491f2a6d52758b830b89b78c2ae61e8ca66b86bf5a20af73d20e6/ruff-0.14.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a9f3a936ac27fb7c2a93e4f4b943a662775879ac579a433291a6f69428722649", size = 14210427, upload-time = "2025-11-06T22:07:19.832Z" }, + { url = "https://files.pythonhosted.org/packages/71/f4/0666fe7769a54f63e66404e8ff698de1dcde733e12e2fd1c9c6efb689cb5/ruff-0.14.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95643ffd209ce78bc113266b88fba3d39e0461f0cbc8b55fb92505030fb4a850", size = 13658488, upload-time = "2025-11-06T22:07:22.32Z" }, + { url = "https://files.pythonhosted.org/packages/ee/79/6ad4dda2cfd55e41ac9ed6d73ef9ab9475b1eef69f3a85957210c74ba12c/ruff-0.14.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:456daa2fa1021bc86ca857f43fe29d5d8b3f0e55e9f90c58c317c1dcc2afc7b5", size = 13354908, upload-time = "2025-11-06T22:07:24.347Z" }, + { url = "https://files.pythonhosted.org/packages/b5/60/f0b6990f740bb15c1588601d19d21bcc1bd5de4330a07222041678a8e04f/ruff-0.14.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:f911bba769e4a9f51af6e70037bb72b70b45a16db5ce73e1f72aefe6f6d62132", size = 13587803, upload-time = "2025-11-06T22:07:26.327Z" }, + { url = "https://files.pythonhosted.org/packages/c9/da/eaaada586f80068728338e0ef7f29ab3e4a08a692f92eb901a4f06bbff24/ruff-0.14.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:76158a7369b3979fa878612c623a7e5430c18b2fd1c73b214945c2d06337db67", size = 12279654, upload-time = "2025-11-06T22:07:28.46Z" }, + { url = "https://files.pythonhosted.org/packages/66/d4/b1d0e82cf9bf8aed10a6d45be47b3f402730aa2c438164424783ac88c0ed/ruff-0.14.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f3b8f3b442d2b14c246e7aeca2e75915159e06a3540e2f4bed9f50d062d24469", size = 12357520, upload-time = "2025-11-06T22:07:31.468Z" }, + { url = "https://files.pythonhosted.org/packages/04/f4/53e2b42cc82804617e5c7950b7079d79996c27e99c4652131c6a1100657f/ruff-0.14.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c62da9a06779deecf4d17ed04939ae8b31b517643b26370c3be1d26f3ef7dbde", size = 12719431, upload-time = "2025-11-06T22:07:33.831Z" }, + { url = "https://files.pythonhosted.org/packages/a2/94/80e3d74ed9a72d64e94a7b7706b1c1ebaa315ef2076fd33581f6a1cd2f95/ruff-0.14.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a443a83a1506c684e98acb8cb55abaf3ef725078be40237463dae4463366349", size = 13464394, upload-time = "2025-11-06T22:07:35.905Z" }, + { url = "https://files.pythonhosted.org/packages/54/1a/a49f071f04c42345c793d22f6cf5e0920095e286119ee53a64a3a3004825/ruff-0.14.4-py3-none-win32.whl", hash = "sha256:643b69cb63cd996f1fc7229da726d07ac307eae442dd8974dbc7cf22c1e18fff", size = 12493429, upload-time = "2025-11-06T22:07:38.43Z" }, + { url = "https://files.pythonhosted.org/packages/bc/22/e58c43e641145a2b670328fb98bc384e20679b5774258b1e540207580266/ruff-0.14.4-py3-none-win_amd64.whl", hash = "sha256:26673da283b96fe35fa0c939bf8411abec47111644aa9f7cfbd3c573fb125d2c", size = 13635380, upload-time = "2025-11-06T22:07:40.496Z" }, + { url = "https://files.pythonhosted.org/packages/30/bd/4168a751ddbbf43e86544b4de8b5c3b7be8d7167a2a5cb977d274e04f0a1/ruff-0.14.4-py3-none-win_arm64.whl", hash = "sha256:dd09c292479596b0e6fec8cd95c65c3a6dc68e9ad17b8f2382130f87ff6a75bb", size = 12663065, upload-time = "2025-11-06T22:07:42.603Z" }, ] [[package]] @@ -443,9 +674,9 @@ dependencies = [ { name = "distro" }, { name = "setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4b/75/abbc7eab08bad7f47887a0555d3ac9e3947f89d2416678c08e025e449fdc/ruyaml-0.91.0.tar.gz", hash = "sha256:6ce9de9f4d082d696d3bde264664d1bcdca8f5a9dff9d1a1f1a127969ab871ab", size = 239075 } +sdist = { url = "https://files.pythonhosted.org/packages/4b/75/abbc7eab08bad7f47887a0555d3ac9e3947f89d2416678c08e025e449fdc/ruyaml-0.91.0.tar.gz", hash = "sha256:6ce9de9f4d082d696d3bde264664d1bcdca8f5a9dff9d1a1f1a127969ab871ab", size = 239075, upload-time = "2021-12-07T16:19:58.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/9a/16ca152a04b231c179c626de40af1d5d0bc2bc57bc875c397706016ddb2b/ruyaml-0.91.0-py3-none-any.whl", hash = "sha256:50e0ee3389c77ad340e209472e0effd41ae0275246df00cdad0a067532171755", size = 108906 }, + { url = "https://files.pythonhosted.org/packages/1e/9a/16ca152a04b231c179c626de40af1d5d0bc2bc57bc875c397706016ddb2b/ruyaml-0.91.0-py3-none-any.whl", hash = "sha256:50e0ee3389c77ad340e209472e0effd41ae0275246df00cdad0a067532171755", size = 108906, upload-time = "2021-12-07T16:19:56.798Z" }, ] [[package]] @@ -458,28 +689,28 @@ dependencies = [ { name = "scipy" }, { name = "threadpoolctl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818 }, - { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997 }, - { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381 }, - { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296 }, - { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256 }, - { url = "https://files.pythonhosted.org/packages/ae/93/a3038cb0293037fd335f77f31fe053b89c72f17b1c8908c576c29d953e84/scikit_learn-1.7.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b7dacaa05e5d76759fb071558a8b5130f4845166d88654a0f9bdf3eb57851b7", size = 9212382 }, - { url = "https://files.pythonhosted.org/packages/40/dd/9a88879b0c1104259136146e4742026b52df8540c39fec21a6383f8292c7/scikit_learn-1.7.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:abebbd61ad9e1deed54cca45caea8ad5f79e1b93173dece40bb8e0c658dbe6fe", size = 8592042 }, - { url = "https://files.pythonhosted.org/packages/46/af/c5e286471b7d10871b811b72ae794ac5fe2989c0a2df07f0ec723030f5f5/scikit_learn-1.7.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502c18e39849c0ea1a5d681af1dbcf15f6cce601aebb657aabbfe84133c1907f", size = 9434180 }, - { url = "https://files.pythonhosted.org/packages/f1/fd/df59faa53312d585023b2da27e866524ffb8faf87a68516c23896c718320/scikit_learn-1.7.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a4c328a71785382fe3fe676a9ecf2c86189249beff90bf85e22bdb7efaf9ae0", size = 9283660 }, - { url = "https://files.pythonhosted.org/packages/a7/c7/03000262759d7b6f38c836ff9d512f438a70d8a8ddae68ee80de72dcfb63/scikit_learn-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:63a9afd6f7b229aad94618c01c252ce9e6fa97918c5ca19c9a17a087d819440c", size = 8702057 }, - { url = "https://files.pythonhosted.org/packages/55/87/ef5eb1f267084532c8e4aef98a28b6ffe7425acbfd64b5e2f2e066bc29b3/scikit_learn-1.7.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9acb6c5e867447b4e1390930e3944a005e2cb115922e693c08a323421a6966e8", size = 9558731 }, - { url = "https://files.pythonhosted.org/packages/93/f8/6c1e3fc14b10118068d7938878a9f3f4e6d7b74a8ddb1e5bed65159ccda8/scikit_learn-1.7.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:2a41e2a0ef45063e654152ec9d8bcfc39f7afce35b08902bfe290c2498a67a6a", size = 9038852 }, - { url = "https://files.pythonhosted.org/packages/83/87/066cafc896ee540c34becf95d30375fe5cbe93c3b75a0ee9aa852cd60021/scikit_learn-1.7.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98335fb98509b73385b3ab2bd0639b1f610541d3988ee675c670371d6a87aa7c", size = 9527094 }, - { url = "https://files.pythonhosted.org/packages/9c/2b/4903e1ccafa1f6453b1ab78413938c8800633988c838aa0be386cbb33072/scikit_learn-1.7.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191e5550980d45449126e23ed1d5e9e24b2c68329ee1f691a3987476e115e09c", size = 9367436 }, - { url = "https://files.pythonhosted.org/packages/b5/aa/8444be3cfb10451617ff9d177b3c190288f4563e6c50ff02728be67ad094/scikit_learn-1.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:57dc4deb1d3762c75d685507fbd0bc17160144b2f2ba4ccea5dc285ab0d0e973", size = 9275749 }, - { url = "https://files.pythonhosted.org/packages/d9/82/dee5acf66837852e8e68df6d8d3a6cb22d3df997b733b032f513d95205b7/scikit_learn-1.7.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fa8f63940e29c82d1e67a45d5297bdebbcb585f5a5a50c4914cc2e852ab77f33", size = 9208906 }, - { url = "https://files.pythonhosted.org/packages/3c/30/9029e54e17b87cb7d50d51a5926429c683d5b4c1732f0507a6c3bed9bf65/scikit_learn-1.7.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f95dc55b7902b91331fa4e5845dd5bde0580c9cd9612b1b2791b7e80c3d32615", size = 8627836 }, - { url = "https://files.pythonhosted.org/packages/60/18/4a52c635c71b536879f4b971c2cedf32c35ee78f48367885ed8025d1f7ee/scikit_learn-1.7.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9656e4a53e54578ad10a434dc1f993330568cfee176dff07112b8785fb413106", size = 9426236 }, - { url = "https://files.pythonhosted.org/packages/99/7e/290362f6ab582128c53445458a5befd471ed1ea37953d5bcf80604619250/scikit_learn-1.7.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96dc05a854add0e50d3f47a1ef21a10a595016da5b007c7d9cd9d0bffd1fcc61", size = 9312593 }, - { url = "https://files.pythonhosted.org/packages/8e/87/24f541b6d62b1794939ae6422f8023703bbf6900378b2b34e0b4384dfefd/scikit_learn-1.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:bb24510ed3f9f61476181e4db51ce801e2ba37541def12dc9333b946fc7a9cf8", size = 8820007 }, +sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" }, + { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" }, + { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" }, + { url = "https://files.pythonhosted.org/packages/ae/93/a3038cb0293037fd335f77f31fe053b89c72f17b1c8908c576c29d953e84/scikit_learn-1.7.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b7dacaa05e5d76759fb071558a8b5130f4845166d88654a0f9bdf3eb57851b7", size = 9212382, upload-time = "2025-09-09T08:20:54.731Z" }, + { url = "https://files.pythonhosted.org/packages/40/dd/9a88879b0c1104259136146e4742026b52df8540c39fec21a6383f8292c7/scikit_learn-1.7.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:abebbd61ad9e1deed54cca45caea8ad5f79e1b93173dece40bb8e0c658dbe6fe", size = 8592042, upload-time = "2025-09-09T08:20:57.313Z" }, + { url = "https://files.pythonhosted.org/packages/46/af/c5e286471b7d10871b811b72ae794ac5fe2989c0a2df07f0ec723030f5f5/scikit_learn-1.7.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502c18e39849c0ea1a5d681af1dbcf15f6cce601aebb657aabbfe84133c1907f", size = 9434180, upload-time = "2025-09-09T08:20:59.671Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fd/df59faa53312d585023b2da27e866524ffb8faf87a68516c23896c718320/scikit_learn-1.7.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a4c328a71785382fe3fe676a9ecf2c86189249beff90bf85e22bdb7efaf9ae0", size = 9283660, upload-time = "2025-09-09T08:21:01.71Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c7/03000262759d7b6f38c836ff9d512f438a70d8a8ddae68ee80de72dcfb63/scikit_learn-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:63a9afd6f7b229aad94618c01c252ce9e6fa97918c5ca19c9a17a087d819440c", size = 8702057, upload-time = "2025-09-09T08:21:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/55/87/ef5eb1f267084532c8e4aef98a28b6ffe7425acbfd64b5e2f2e066bc29b3/scikit_learn-1.7.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9acb6c5e867447b4e1390930e3944a005e2cb115922e693c08a323421a6966e8", size = 9558731, upload-time = "2025-09-09T08:21:06.381Z" }, + { url = "https://files.pythonhosted.org/packages/93/f8/6c1e3fc14b10118068d7938878a9f3f4e6d7b74a8ddb1e5bed65159ccda8/scikit_learn-1.7.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:2a41e2a0ef45063e654152ec9d8bcfc39f7afce35b08902bfe290c2498a67a6a", size = 9038852, upload-time = "2025-09-09T08:21:08.628Z" }, + { url = "https://files.pythonhosted.org/packages/83/87/066cafc896ee540c34becf95d30375fe5cbe93c3b75a0ee9aa852cd60021/scikit_learn-1.7.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98335fb98509b73385b3ab2bd0639b1f610541d3988ee675c670371d6a87aa7c", size = 9527094, upload-time = "2025-09-09T08:21:11.486Z" }, + { url = "https://files.pythonhosted.org/packages/9c/2b/4903e1ccafa1f6453b1ab78413938c8800633988c838aa0be386cbb33072/scikit_learn-1.7.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191e5550980d45449126e23ed1d5e9e24b2c68329ee1f691a3987476e115e09c", size = 9367436, upload-time = "2025-09-09T08:21:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/b5/aa/8444be3cfb10451617ff9d177b3c190288f4563e6c50ff02728be67ad094/scikit_learn-1.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:57dc4deb1d3762c75d685507fbd0bc17160144b2f2ba4ccea5dc285ab0d0e973", size = 9275749, upload-time = "2025-09-09T08:21:15.96Z" }, + { url = "https://files.pythonhosted.org/packages/d9/82/dee5acf66837852e8e68df6d8d3a6cb22d3df997b733b032f513d95205b7/scikit_learn-1.7.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fa8f63940e29c82d1e67a45d5297bdebbcb585f5a5a50c4914cc2e852ab77f33", size = 9208906, upload-time = "2025-09-09T08:21:18.557Z" }, + { url = "https://files.pythonhosted.org/packages/3c/30/9029e54e17b87cb7d50d51a5926429c683d5b4c1732f0507a6c3bed9bf65/scikit_learn-1.7.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f95dc55b7902b91331fa4e5845dd5bde0580c9cd9612b1b2791b7e80c3d32615", size = 8627836, upload-time = "2025-09-09T08:21:20.695Z" }, + { url = "https://files.pythonhosted.org/packages/60/18/4a52c635c71b536879f4b971c2cedf32c35ee78f48367885ed8025d1f7ee/scikit_learn-1.7.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9656e4a53e54578ad10a434dc1f993330568cfee176dff07112b8785fb413106", size = 9426236, upload-time = "2025-09-09T08:21:22.645Z" }, + { url = "https://files.pythonhosted.org/packages/99/7e/290362f6ab582128c53445458a5befd471ed1ea37953d5bcf80604619250/scikit_learn-1.7.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96dc05a854add0e50d3f47a1ef21a10a595016da5b007c7d9cd9d0bffd1fcc61", size = 9312593, upload-time = "2025-09-09T08:21:24.65Z" }, + { url = "https://files.pythonhosted.org/packages/8e/87/24f541b6d62b1794939ae6422f8023703bbf6900378b2b34e0b4384dfefd/scikit_learn-1.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:bb24510ed3f9f61476181e4db51ce801e2ba37541def12dc9333b946fc7a9cf8", size = 8820007, upload-time = "2025-09-09T08:21:26.713Z" }, ] [[package]] @@ -489,94 +720,94 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/8d/6396e00db1282279a4ddd507c5f5e11f606812b608ee58517ce8abbf883f/scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d", size = 36646259 }, - { url = "https://files.pythonhosted.org/packages/3b/93/ea9edd7e193fceb8eef149804491890bde73fb169c896b61aa3e2d1e4e77/scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371", size = 28888976 }, - { url = "https://files.pythonhosted.org/packages/91/4d/281fddc3d80fd738ba86fd3aed9202331180b01e2c78eaae0642f22f7e83/scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0", size = 20879905 }, - { url = "https://files.pythonhosted.org/packages/69/40/b33b74c84606fd301b2915f0062e45733c6ff5708d121dd0deaa8871e2d0/scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232", size = 23553066 }, - { url = "https://files.pythonhosted.org/packages/55/a7/22c739e2f21a42cc8f16bc76b47cff4ed54fbe0962832c589591c2abec34/scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1", size = 33336407 }, - { url = "https://files.pythonhosted.org/packages/53/11/a0160990b82999b45874dc60c0c183d3a3a969a563fffc476d5a9995c407/scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f", size = 35673281 }, - { url = "https://files.pythonhosted.org/packages/96/53/7ef48a4cfcf243c3d0f1643f5887c81f29fdf76911c4e49331828e19fc0a/scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef", size = 36004222 }, - { url = "https://files.pythonhosted.org/packages/49/7f/71a69e0afd460049d41c65c630c919c537815277dfea214031005f474d78/scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1", size = 38664586 }, - { url = "https://files.pythonhosted.org/packages/34/95/20e02ca66fb495a95fba0642fd48e0c390d0ece9b9b14c6e931a60a12dea/scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e", size = 38550641 }, - { url = "https://files.pythonhosted.org/packages/92/ad/13646b9beb0a95528ca46d52b7babafbe115017814a611f2065ee4e61d20/scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851", size = 25456070 }, - { url = "https://files.pythonhosted.org/packages/c1/27/c5b52f1ee81727a9fc457f5ac1e9bf3d6eab311805ea615c83c27ba06400/scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70", size = 36604856 }, - { url = "https://files.pythonhosted.org/packages/32/a9/15c20d08e950b540184caa8ced675ba1128accb0e09c653780ba023a4110/scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9", size = 28864626 }, - { url = "https://files.pythonhosted.org/packages/4c/fc/ea36098df653cca26062a627c1a94b0de659e97127c8491e18713ca0e3b9/scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5", size = 20855689 }, - { url = "https://files.pythonhosted.org/packages/dc/6f/d0b53be55727f3e6d7c72687ec18ea6d0047cf95f1f77488b99a2bafaee1/scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925", size = 23512151 }, - { url = "https://files.pythonhosted.org/packages/11/85/bf7dab56e5c4b1d3d8eef92ca8ede788418ad38a7dc3ff50262f00808760/scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9", size = 33329824 }, - { url = "https://files.pythonhosted.org/packages/da/6a/1a927b14ddc7714111ea51f4e568203b2bb6ed59bdd036d62127c1a360c8/scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7", size = 35681881 }, - { url = "https://files.pythonhosted.org/packages/c1/5f/331148ea5780b4fcc7007a4a6a6ee0a0c1507a796365cc642d4d226e1c3a/scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb", size = 36006219 }, - { url = "https://files.pythonhosted.org/packages/46/3a/e991aa9d2aec723b4a8dcfbfc8365edec5d5e5f9f133888067f1cbb7dfc1/scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e", size = 38682147 }, - { url = "https://files.pythonhosted.org/packages/a1/57/0f38e396ad19e41b4c5db66130167eef8ee620a49bc7d0512e3bb67e0cab/scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c", size = 38520766 }, - { url = "https://files.pythonhosted.org/packages/1b/a5/85d3e867b6822d331e26c862a91375bb7746a0b458db5effa093d34cdb89/scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104", size = 25451169 }, - { url = "https://files.pythonhosted.org/packages/09/d9/60679189bcebda55992d1a45498de6d080dcaf21ce0c8f24f888117e0c2d/scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1", size = 37012682 }, - { url = "https://files.pythonhosted.org/packages/83/be/a99d13ee4d3b7887a96f8c71361b9659ba4ef34da0338f14891e102a127f/scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a", size = 29389926 }, - { url = "https://files.pythonhosted.org/packages/bf/0a/130164a4881cec6ca8c00faf3b57926f28ed429cd6001a673f83c7c2a579/scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f", size = 21381152 }, - { url = "https://files.pythonhosted.org/packages/47/a6/503ffb0310ae77fba874e10cddfc4a1280bdcca1d13c3751b8c3c2996cf8/scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4", size = 23914410 }, - { url = "https://files.pythonhosted.org/packages/fa/c7/1147774bcea50d00c02600aadaa919facbd8537997a62496270133536ed6/scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21", size = 33481880 }, - { url = "https://files.pythonhosted.org/packages/6a/74/99d5415e4c3e46b2586f30cdbecb95e101c7192628a484a40dd0d163811a/scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7", size = 35791425 }, - { url = "https://files.pythonhosted.org/packages/1b/ee/a6559de7c1cc710e938c0355d9d4fbcd732dac4d0d131959d1f3b63eb29c/scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8", size = 36178622 }, - { url = "https://files.pythonhosted.org/packages/4e/7b/f127a5795d5ba8ece4e0dce7d4a9fb7cb9e4f4757137757d7a69ab7d4f1a/scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472", size = 38783985 }, - { url = "https://files.pythonhosted.org/packages/3e/9f/bc81c1d1e033951eb5912cd3750cc005943afa3e65a725d2443a3b3c4347/scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351", size = 38631367 }, - { url = "https://files.pythonhosted.org/packages/d6/5e/2cc7555fd81d01814271412a1d59a289d25f8b63208a0a16c21069d55d3e/scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d", size = 25787992 }, - { url = "https://files.pythonhosted.org/packages/8b/ac/ad8951250516db71619f0bd3b2eb2448db04b720a003dd98619b78b692c0/scipy-1.16.2-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:567e77755019bb7461513c87f02bb73fb65b11f049aaaa8ca17cfaa5a5c45d77", size = 36595109 }, - { url = "https://files.pythonhosted.org/packages/ff/f6/5779049ed119c5b503b0f3dc6d6f3f68eefc3a9190d4ad4c276f854f051b/scipy-1.16.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:17d9bb346194e8967296621208fcdfd39b55498ef7d2f376884d5ac47cec1a70", size = 28859110 }, - { url = "https://files.pythonhosted.org/packages/82/09/9986e410ae38bf0a0c737ff8189ac81a93b8e42349aac009891c054403d7/scipy-1.16.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:0a17541827a9b78b777d33b623a6dcfe2ef4a25806204d08ead0768f4e529a88", size = 20850110 }, - { url = "https://files.pythonhosted.org/packages/0d/ad/485cdef2d9215e2a7df6d61b81d2ac073dfacf6ae24b9ae87274c4e936ae/scipy-1.16.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:d7d4c6ba016ffc0f9568d012f5f1eb77ddd99412aea121e6fa8b4c3b7cbad91f", size = 23497014 }, - { url = "https://files.pythonhosted.org/packages/a7/74/f6a852e5d581122b8f0f831f1d1e32fb8987776ed3658e95c377d308ed86/scipy-1.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9702c4c023227785c779cba2e1d6f7635dbb5b2e0936cdd3a4ecb98d78fd41eb", size = 33401155 }, - { url = "https://files.pythonhosted.org/packages/d9/f5/61d243bbc7c6e5e4e13dde9887e84a5cbe9e0f75fd09843044af1590844e/scipy-1.16.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d1cdf0ac28948d225decdefcc45ad7dd91716c29ab56ef32f8e0d50657dffcc7", size = 35691174 }, - { url = "https://files.pythonhosted.org/packages/03/99/59933956331f8cc57e406cdb7a483906c74706b156998f322913e789c7e1/scipy-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70327d6aa572a17c2941cdfb20673f82e536e91850a2e4cb0c5b858b690e1548", size = 36070752 }, - { url = "https://files.pythonhosted.org/packages/c6/7d/00f825cfb47ee19ef74ecf01244b43e95eae74e7e0ff796026ea7cd98456/scipy-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5221c0b2a4b58aa7c4ed0387d360fd90ee9086d383bb34d9f2789fafddc8a936", size = 38701010 }, - { url = "https://files.pythonhosted.org/packages/e4/9f/b62587029980378304ba5a8563d376c96f40b1e133daacee76efdcae32de/scipy-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:f5a85d7b2b708025af08f060a496dd261055b617d776fc05a1a1cc69e09fe9ff", size = 39360061 }, - { url = "https://files.pythonhosted.org/packages/82/04/7a2f1609921352c7fbee0815811b5050582f67f19983096c4769867ca45f/scipy-1.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:2cc73a33305b4b24556957d5857d6253ce1e2dcd67fa0ff46d87d1670b3e1e1d", size = 26126914 }, - { url = "https://files.pythonhosted.org/packages/51/b9/60929ce350c16b221928725d2d1d7f86cf96b8bc07415547057d1196dc92/scipy-1.16.2-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:9ea2a3fed83065d77367775d689401a703d0f697420719ee10c0780bcab594d8", size = 37013193 }, - { url = "https://files.pythonhosted.org/packages/2a/41/ed80e67782d4bc5fc85a966bc356c601afddd175856ba7c7bb6d9490607e/scipy-1.16.2-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7280d926f11ca945c3ef92ba960fa924e1465f8d07ce3a9923080363390624c4", size = 29390172 }, - { url = "https://files.pythonhosted.org/packages/c4/a3/2f673ace4090452696ccded5f5f8efffb353b8f3628f823a110e0170b605/scipy-1.16.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:8afae1756f6a1fe04636407ef7dbece33d826a5d462b74f3d0eb82deabefd831", size = 21381326 }, - { url = "https://files.pythonhosted.org/packages/42/bf/59df61c5d51395066c35836b78136accf506197617c8662e60ea209881e1/scipy-1.16.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:5c66511f29aa8d233388e7416a3f20d5cae7a2744d5cee2ecd38c081f4e861b3", size = 23915036 }, - { url = "https://files.pythonhosted.org/packages/91/c3/edc7b300dc16847ad3672f1a6f3f7c5d13522b21b84b81c265f4f2760d4a/scipy-1.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efe6305aeaa0e96b0ccca5ff647a43737d9a092064a3894e46c414db84bc54ac", size = 33484341 }, - { url = "https://files.pythonhosted.org/packages/26/c7/24d1524e72f06ff141e8d04b833c20db3021020563272ccb1b83860082a9/scipy-1.16.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f3a337d9ae06a1e8d655ee9d8ecb835ea5ddcdcbd8d23012afa055ab014f374", size = 35790840 }, - { url = "https://files.pythonhosted.org/packages/aa/b7/5aaad984eeedd56858dc33d75efa59e8ce798d918e1033ef62d2708f2c3d/scipy-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bab3605795d269067d8ce78a910220262711b753de8913d3deeaedb5dded3bb6", size = 36174716 }, - { url = "https://files.pythonhosted.org/packages/fd/c2/e276a237acb09824822b0ada11b028ed4067fdc367a946730979feacb870/scipy-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b0348d8ddb55be2a844c518cd8cc8deeeb8aeba707cf834db5758fc89b476a2c", size = 38790088 }, - { url = "https://files.pythonhosted.org/packages/c6/b4/5c18a766e8353015439f3780f5fc473f36f9762edc1a2e45da3ff5a31b21/scipy-1.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:26284797e38b8a75e14ea6631d29bda11e76ceaa6ddb6fdebbfe4c4d90faf2f9", size = 39457455 }, - { url = "https://files.pythonhosted.org/packages/97/30/2f9a5243008f76dfc5dee9a53dfb939d9b31e16ce4bd4f2e628bfc5d89d2/scipy-1.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d2a4472c231328d4de38d5f1f68fdd6d28a615138f842580a8a321b5845cf779", size = 26448374 }, +sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599, upload-time = "2025-09-11T17:48:08.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/8d/6396e00db1282279a4ddd507c5f5e11f606812b608ee58517ce8abbf883f/scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d", size = 36646259, upload-time = "2025-09-11T17:40:39.329Z" }, + { url = "https://files.pythonhosted.org/packages/3b/93/ea9edd7e193fceb8eef149804491890bde73fb169c896b61aa3e2d1e4e77/scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371", size = 28888976, upload-time = "2025-09-11T17:40:46.82Z" }, + { url = "https://files.pythonhosted.org/packages/91/4d/281fddc3d80fd738ba86fd3aed9202331180b01e2c78eaae0642f22f7e83/scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0", size = 20879905, upload-time = "2025-09-11T17:40:52.545Z" }, + { url = "https://files.pythonhosted.org/packages/69/40/b33b74c84606fd301b2915f0062e45733c6ff5708d121dd0deaa8871e2d0/scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232", size = 23553066, upload-time = "2025-09-11T17:40:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/55/a7/22c739e2f21a42cc8f16bc76b47cff4ed54fbe0962832c589591c2abec34/scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1", size = 33336407, upload-time = "2025-09-11T17:41:06.796Z" }, + { url = "https://files.pythonhosted.org/packages/53/11/a0160990b82999b45874dc60c0c183d3a3a969a563fffc476d5a9995c407/scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f", size = 35673281, upload-time = "2025-09-11T17:41:15.055Z" }, + { url = "https://files.pythonhosted.org/packages/96/53/7ef48a4cfcf243c3d0f1643f5887c81f29fdf76911c4e49331828e19fc0a/scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef", size = 36004222, upload-time = "2025-09-11T17:41:23.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7f/71a69e0afd460049d41c65c630c919c537815277dfea214031005f474d78/scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1", size = 38664586, upload-time = "2025-09-11T17:41:31.021Z" }, + { url = "https://files.pythonhosted.org/packages/34/95/20e02ca66fb495a95fba0642fd48e0c390d0ece9b9b14c6e931a60a12dea/scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e", size = 38550641, upload-time = "2025-09-11T17:41:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/92/ad/13646b9beb0a95528ca46d52b7babafbe115017814a611f2065ee4e61d20/scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851", size = 25456070, upload-time = "2025-09-11T17:41:41.3Z" }, + { url = "https://files.pythonhosted.org/packages/c1/27/c5b52f1ee81727a9fc457f5ac1e9bf3d6eab311805ea615c83c27ba06400/scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70", size = 36604856, upload-time = "2025-09-11T17:41:47.695Z" }, + { url = "https://files.pythonhosted.org/packages/32/a9/15c20d08e950b540184caa8ced675ba1128accb0e09c653780ba023a4110/scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9", size = 28864626, upload-time = "2025-09-11T17:41:52.642Z" }, + { url = "https://files.pythonhosted.org/packages/4c/fc/ea36098df653cca26062a627c1a94b0de659e97127c8491e18713ca0e3b9/scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5", size = 20855689, upload-time = "2025-09-11T17:41:57.886Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6f/d0b53be55727f3e6d7c72687ec18ea6d0047cf95f1f77488b99a2bafaee1/scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925", size = 23512151, upload-time = "2025-09-11T17:42:02.303Z" }, + { url = "https://files.pythonhosted.org/packages/11/85/bf7dab56e5c4b1d3d8eef92ca8ede788418ad38a7dc3ff50262f00808760/scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9", size = 33329824, upload-time = "2025-09-11T17:42:07.549Z" }, + { url = "https://files.pythonhosted.org/packages/da/6a/1a927b14ddc7714111ea51f4e568203b2bb6ed59bdd036d62127c1a360c8/scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7", size = 35681881, upload-time = "2025-09-11T17:42:13.255Z" }, + { url = "https://files.pythonhosted.org/packages/c1/5f/331148ea5780b4fcc7007a4a6a6ee0a0c1507a796365cc642d4d226e1c3a/scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb", size = 36006219, upload-time = "2025-09-11T17:42:18.765Z" }, + { url = "https://files.pythonhosted.org/packages/46/3a/e991aa9d2aec723b4a8dcfbfc8365edec5d5e5f9f133888067f1cbb7dfc1/scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e", size = 38682147, upload-time = "2025-09-11T17:42:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/a1/57/0f38e396ad19e41b4c5db66130167eef8ee620a49bc7d0512e3bb67e0cab/scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c", size = 38520766, upload-time = "2025-09-11T17:43:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a5/85d3e867b6822d331e26c862a91375bb7746a0b458db5effa093d34cdb89/scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104", size = 25451169, upload-time = "2025-09-11T17:43:30.198Z" }, + { url = "https://files.pythonhosted.org/packages/09/d9/60679189bcebda55992d1a45498de6d080dcaf21ce0c8f24f888117e0c2d/scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1", size = 37012682, upload-time = "2025-09-11T17:42:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/83/be/a99d13ee4d3b7887a96f8c71361b9659ba4ef34da0338f14891e102a127f/scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a", size = 29389926, upload-time = "2025-09-11T17:42:35.845Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0a/130164a4881cec6ca8c00faf3b57926f28ed429cd6001a673f83c7c2a579/scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f", size = 21381152, upload-time = "2025-09-11T17:42:40.07Z" }, + { url = "https://files.pythonhosted.org/packages/47/a6/503ffb0310ae77fba874e10cddfc4a1280bdcca1d13c3751b8c3c2996cf8/scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4", size = 23914410, upload-time = "2025-09-11T17:42:44.313Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c7/1147774bcea50d00c02600aadaa919facbd8537997a62496270133536ed6/scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21", size = 33481880, upload-time = "2025-09-11T17:42:49.325Z" }, + { url = "https://files.pythonhosted.org/packages/6a/74/99d5415e4c3e46b2586f30cdbecb95e101c7192628a484a40dd0d163811a/scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7", size = 35791425, upload-time = "2025-09-11T17:42:54.711Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ee/a6559de7c1cc710e938c0355d9d4fbcd732dac4d0d131959d1f3b63eb29c/scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8", size = 36178622, upload-time = "2025-09-11T17:43:00.375Z" }, + { url = "https://files.pythonhosted.org/packages/4e/7b/f127a5795d5ba8ece4e0dce7d4a9fb7cb9e4f4757137757d7a69ab7d4f1a/scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472", size = 38783985, upload-time = "2025-09-11T17:43:06.661Z" }, + { url = "https://files.pythonhosted.org/packages/3e/9f/bc81c1d1e033951eb5912cd3750cc005943afa3e65a725d2443a3b3c4347/scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351", size = 38631367, upload-time = "2025-09-11T17:43:14.44Z" }, + { url = "https://files.pythonhosted.org/packages/d6/5e/2cc7555fd81d01814271412a1d59a289d25f8b63208a0a16c21069d55d3e/scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d", size = 25787992, upload-time = "2025-09-11T17:43:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ac/ad8951250516db71619f0bd3b2eb2448db04b720a003dd98619b78b692c0/scipy-1.16.2-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:567e77755019bb7461513c87f02bb73fb65b11f049aaaa8ca17cfaa5a5c45d77", size = 36595109, upload-time = "2025-09-11T17:43:35.713Z" }, + { url = "https://files.pythonhosted.org/packages/ff/f6/5779049ed119c5b503b0f3dc6d6f3f68eefc3a9190d4ad4c276f854f051b/scipy-1.16.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:17d9bb346194e8967296621208fcdfd39b55498ef7d2f376884d5ac47cec1a70", size = 28859110, upload-time = "2025-09-11T17:43:40.814Z" }, + { url = "https://files.pythonhosted.org/packages/82/09/9986e410ae38bf0a0c737ff8189ac81a93b8e42349aac009891c054403d7/scipy-1.16.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:0a17541827a9b78b777d33b623a6dcfe2ef4a25806204d08ead0768f4e529a88", size = 20850110, upload-time = "2025-09-11T17:43:44.981Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ad/485cdef2d9215e2a7df6d61b81d2ac073dfacf6ae24b9ae87274c4e936ae/scipy-1.16.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:d7d4c6ba016ffc0f9568d012f5f1eb77ddd99412aea121e6fa8b4c3b7cbad91f", size = 23497014, upload-time = "2025-09-11T17:43:49.074Z" }, + { url = "https://files.pythonhosted.org/packages/a7/74/f6a852e5d581122b8f0f831f1d1e32fb8987776ed3658e95c377d308ed86/scipy-1.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9702c4c023227785c779cba2e1d6f7635dbb5b2e0936cdd3a4ecb98d78fd41eb", size = 33401155, upload-time = "2025-09-11T17:43:54.661Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f5/61d243bbc7c6e5e4e13dde9887e84a5cbe9e0f75fd09843044af1590844e/scipy-1.16.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d1cdf0ac28948d225decdefcc45ad7dd91716c29ab56ef32f8e0d50657dffcc7", size = 35691174, upload-time = "2025-09-11T17:44:00.101Z" }, + { url = "https://files.pythonhosted.org/packages/03/99/59933956331f8cc57e406cdb7a483906c74706b156998f322913e789c7e1/scipy-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70327d6aa572a17c2941cdfb20673f82e536e91850a2e4cb0c5b858b690e1548", size = 36070752, upload-time = "2025-09-11T17:44:05.619Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7d/00f825cfb47ee19ef74ecf01244b43e95eae74e7e0ff796026ea7cd98456/scipy-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5221c0b2a4b58aa7c4ed0387d360fd90ee9086d383bb34d9f2789fafddc8a936", size = 38701010, upload-time = "2025-09-11T17:44:11.322Z" }, + { url = "https://files.pythonhosted.org/packages/e4/9f/b62587029980378304ba5a8563d376c96f40b1e133daacee76efdcae32de/scipy-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:f5a85d7b2b708025af08f060a496dd261055b617d776fc05a1a1cc69e09fe9ff", size = 39360061, upload-time = "2025-09-11T17:45:09.814Z" }, + { url = "https://files.pythonhosted.org/packages/82/04/7a2f1609921352c7fbee0815811b5050582f67f19983096c4769867ca45f/scipy-1.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:2cc73a33305b4b24556957d5857d6253ce1e2dcd67fa0ff46d87d1670b3e1e1d", size = 26126914, upload-time = "2025-09-11T17:45:14.73Z" }, + { url = "https://files.pythonhosted.org/packages/51/b9/60929ce350c16b221928725d2d1d7f86cf96b8bc07415547057d1196dc92/scipy-1.16.2-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:9ea2a3fed83065d77367775d689401a703d0f697420719ee10c0780bcab594d8", size = 37013193, upload-time = "2025-09-11T17:44:16.757Z" }, + { url = "https://files.pythonhosted.org/packages/2a/41/ed80e67782d4bc5fc85a966bc356c601afddd175856ba7c7bb6d9490607e/scipy-1.16.2-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7280d926f11ca945c3ef92ba960fa924e1465f8d07ce3a9923080363390624c4", size = 29390172, upload-time = "2025-09-11T17:44:21.783Z" }, + { url = "https://files.pythonhosted.org/packages/c4/a3/2f673ace4090452696ccded5f5f8efffb353b8f3628f823a110e0170b605/scipy-1.16.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:8afae1756f6a1fe04636407ef7dbece33d826a5d462b74f3d0eb82deabefd831", size = 21381326, upload-time = "2025-09-11T17:44:25.982Z" }, + { url = "https://files.pythonhosted.org/packages/42/bf/59df61c5d51395066c35836b78136accf506197617c8662e60ea209881e1/scipy-1.16.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:5c66511f29aa8d233388e7416a3f20d5cae7a2744d5cee2ecd38c081f4e861b3", size = 23915036, upload-time = "2025-09-11T17:44:30.527Z" }, + { url = "https://files.pythonhosted.org/packages/91/c3/edc7b300dc16847ad3672f1a6f3f7c5d13522b21b84b81c265f4f2760d4a/scipy-1.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efe6305aeaa0e96b0ccca5ff647a43737d9a092064a3894e46c414db84bc54ac", size = 33484341, upload-time = "2025-09-11T17:44:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/26/c7/24d1524e72f06ff141e8d04b833c20db3021020563272ccb1b83860082a9/scipy-1.16.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f3a337d9ae06a1e8d655ee9d8ecb835ea5ddcdcbd8d23012afa055ab014f374", size = 35790840, upload-time = "2025-09-11T17:44:41.76Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b7/5aaad984eeedd56858dc33d75efa59e8ce798d918e1033ef62d2708f2c3d/scipy-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bab3605795d269067d8ce78a910220262711b753de8913d3deeaedb5dded3bb6", size = 36174716, upload-time = "2025-09-11T17:44:47.316Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c2/e276a237acb09824822b0ada11b028ed4067fdc367a946730979feacb870/scipy-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b0348d8ddb55be2a844c518cd8cc8deeeb8aeba707cf834db5758fc89b476a2c", size = 38790088, upload-time = "2025-09-11T17:44:53.011Z" }, + { url = "https://files.pythonhosted.org/packages/c6/b4/5c18a766e8353015439f3780f5fc473f36f9762edc1a2e45da3ff5a31b21/scipy-1.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:26284797e38b8a75e14ea6631d29bda11e76ceaa6ddb6fdebbfe4c4d90faf2f9", size = 39457455, upload-time = "2025-09-11T17:44:58.899Z" }, + { url = "https://files.pythonhosted.org/packages/97/30/2f9a5243008f76dfc5dee9a53dfb939d9b31e16ce4bd4f2e628bfc5d89d2/scipy-1.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d2a4472c231328d4de38d5f1f68fdd6d28a615138f842580a8a321b5845cf779", size = 26448374, upload-time = "2025-09-11T17:45:03.45Z" }, ] [[package]] name = "setuptools" version = "80.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958 } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486 }, + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "threadpoolctl" version = "3.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638 }, + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, ] [[package]] @@ -590,7 +821,12 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "poethepoet" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, { name = "yamlfix" }, + { name = "yamllint" }, ] [package.metadata] @@ -600,7 +836,14 @@ requires-dist = [ ] [package.metadata.requires-dev] -dev = [{ name = "yamlfix", specifier = ">=1.18.0" }] +dev = [ + { name = "poethepoet", specifier = ">=0.37.0" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "ruff", specifier = ">=0.13.3" }, + { name = "yamlfix", specifier = ">=1.18.0" }, + { name = "yamllint", specifier = ">=1.37.1" }, +] [[package]] name = "typer" @@ -612,18 +855,18 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/21/ca/950278884e2ca20547ff3eb109478c6baf6b8cf219318e6bc4f666fad8e8/typer-0.19.2.tar.gz", hash = "sha256:9ad824308ded0ad06cc716434705f691d4ee0bfd0fb081839d2e426860e7fdca", size = 104755 } +sdist = { url = "https://files.pythonhosted.org/packages/21/ca/950278884e2ca20547ff3eb109478c6baf6b8cf219318e6bc4f666fad8e8/typer-0.19.2.tar.gz", hash = "sha256:9ad824308ded0ad06cc716434705f691d4ee0bfd0fb081839d2e426860e7fdca", size = 104755, upload-time = "2025-09-23T09:47:48.256Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/22/35617eee79080a5d071d0f14ad698d325ee6b3bf824fc0467c03b30e7fa8/typer-0.19.2-py3-none-any.whl", hash = "sha256:755e7e19670ffad8283db353267cb81ef252f595aa6834a0d1ca9312d9326cb9", size = 46748 }, + { url = "https://files.pythonhosted.org/packages/00/22/35617eee79080a5d071d0f14ad698d325ee6b3bf824fc0467c03b30e7fa8/typer-0.19.2-py3-none-any.whl", hash = "sha256:755e7e19670ffad8283db353267cb81ef252f595aa6834a0d1ca9312d9326cb9", size = 46748, upload-time = "2025-09-23T09:47:46.777Z" }, ] [[package]] name = "typing-extensions" version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] @@ -633,36 +876,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949 } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] name = "tzdata" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] [[package]] name = "urllib3" version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185 } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795 }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "win32-setctime" version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867 } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083 }, + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, ] [[package]] @@ -675,7 +918,20 @@ dependencies = [ { name = "pydantic" }, { name = "ruyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/df/75a9e3d05e56813d9ccc15db39627fc571bb7526586bbfb684ee9f488795/yamlfix-1.18.0.tar.gz", hash = "sha256:ae35891e08aa830e7be7abed6ca25e020aa5998551e4d76e2dc8909bf3c35d7e", size = 39287 } +sdist = { url = "https://files.pythonhosted.org/packages/55/df/75a9e3d05e56813d9ccc15db39627fc571bb7526586bbfb684ee9f488795/yamlfix-1.18.0.tar.gz", hash = "sha256:ae35891e08aa830e7be7abed6ca25e020aa5998551e4d76e2dc8909bf3c35d7e", size = 39287, upload-time = "2025-09-05T21:28:22.306Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/0e/9df7c88e17d5d25f89b4863eabd58268f31a8da509c0f6dde0f0c3bf389e/yamlfix-1.18.0-py3-none-any.whl", hash = "sha256:e4c676dcdf8134c76a69f9d0aad823679315e6cbe81da437022ba4e774e79a85", size = 28344, upload-time = "2025-09-05T21:28:20.188Z" }, +] + +[[package]] +name = "yamllint" +version = "1.37.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pathspec" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/f2/cd8b7584a48ee83f0bc94f8a32fea38734cefcdc6f7324c4d3bfc699457b/yamllint-1.37.1.tar.gz", hash = "sha256:81f7c0c5559becc8049470d86046b36e96113637bcbe4753ecef06977c00245d", size = 141613, upload-time = "2025-05-04T08:25:54.355Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/0e/9df7c88e17d5d25f89b4863eabd58268f31a8da509c0f6dde0f0c3bf389e/yamlfix-1.18.0-py3-none-any.whl", hash = "sha256:e4c676dcdf8134c76a69f9d0aad823679315e6cbe81da437022ba4e774e79a85", size = 28344 }, + { url = "https://files.pythonhosted.org/packages/dd/b9/be7a4cfdf47e03785f657f94daea8123e838d817be76c684298305bd789f/yamllint-1.37.1-py3-none-any.whl", hash = "sha256:364f0d79e81409f591e323725e6a9f4504c8699ddf2d7263d8d2b539cd66a583", size = 68813, upload-time = "2025-05-04T08:25:52.552Z" }, ] From c5847cf754952da445ba96e25cce9e7702e465f9 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 12 Nov 2025 20:57:50 -0800 Subject: [PATCH 03/21] chore(sportsbooks): update pyproject.toml with requirements --- pyproject.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8697379..d348beb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,9 +7,14 @@ requires-python = ">=3.12" dependencies = [ "nba-api>=1.10.2", "scikit-learn>=1.7.2", + "requests==2.31.0", + "pandas==2.1.4", + "psycopg2-binary==2.9.9", + "SQLAlchemy==1.4.52", + "python-dotenv==1.0.1", + "python-dateutil==2.8.2" ] - [tool.poe.tasks] # Python linting and formatting lint = "ruff check ." From ccd71eadfd8c7f509acbed1331d967df55575c35 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 12 Nov 2025 21:27:20 -0800 Subject: [PATCH 04/21] chore(sportsbooks): modify requests to >=2.32.3 for nba-api --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d348beb..a89088f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires-python = ">=3.12" dependencies = [ "nba-api>=1.10.2", "scikit-learn>=1.7.2", - "requests==2.31.0", + "requests>=2.32.3", "pandas==2.1.4", "psycopg2-binary==2.9.9", "SQLAlchemy==1.4.52", From ff50ec59b88c31ca3202ebd7d226e96c51911e64 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 12 Nov 2025 21:30:10 -0800 Subject: [PATCH 05/21] chore(sportsbooks): modify pandas to pandas>=2.2.0 for nba-api --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a89088f..596484b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dependencies = [ "nba-api>=1.10.2", "scikit-learn>=1.7.2", "requests>=2.32.3", - "pandas==2.1.4", + "pandas>=2.2.0",, "psycopg2-binary==2.9.9", "SQLAlchemy==1.4.52", "python-dotenv==1.0.1", From 03c807f94187966750bfe561ecf3425116cd8e98 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 12 Nov 2025 21:30:51 -0800 Subject: [PATCH 06/21] chore(sportsbooks): syntax error :( --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 596484b..0810b7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dependencies = [ "nba-api>=1.10.2", "scikit-learn>=1.7.2", "requests>=2.32.3", - "pandas>=2.2.0",, + "pandas>=2.2.0", "psycopg2-binary==2.9.9", "SQLAlchemy==1.4.52", "python-dotenv==1.0.1", From 5c7f96bec846d3ffa73076d93a8d83aa0a37bb95 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 12 Nov 2025 21:57:17 -0800 Subject: [PATCH 07/21] chore(sportsbook): autofixed issues using just fix-python --- .../airflow/dags/migrate_to_postgres.py | 3 +- .../airflow/dags/nba_props_dag.py | 3 +- .../api_scripts/fetch_bettingpros.py | 1 - .../api_scripts/fetch_draftedge.py | 1 - .../api_scripts/fetch_prizepicks.py | 2 +- uv.lock | 102 +++++++++++++++++- 6 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py index 5371687..fd0c375 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py @@ -1,5 +1,4 @@ from sqlalchemy import create_engine, text as sql_text, Table, MetaData -import pandas as pd import os import sys from dotenv import load_dotenv @@ -55,7 +54,7 @@ def __main__(table_name): dfs = [get_bettingpros_df(), get_prizepicks_df(), get_draftedge_df()] for df in dfs: if df.empty: - print(f"Skipping empty DataFrame...") + print("Skipping empty DataFrame...") continue if not check_df_columns(df): raise Exception(f"df columns do not match WITH {table_name} attributes.") diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py index 4193731..ba15042 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py @@ -18,7 +18,8 @@ from airflow.models.dag import DAG from airflow.providers.standard.operators.python import PythonOperator from datetime import datetime, timedelta -import sys, os +import sys +import os API_SCRIPTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../airflow_pipeline/api_scripts')) if API_SCRIPTS_PATH not in sys.path: diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py index 4d50b17..702a516 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py @@ -1,5 +1,4 @@ import requests -import json import pandas as pd from datetime import datetime import sys diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py index a0db3be..beb96db 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py @@ -1,5 +1,4 @@ import requests -import json import pandas as pd from datetime import datetime import sys diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py index 5bb07d4..47a1f74 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py @@ -103,7 +103,7 @@ def filter_projections(data): 'line_type': attrs.get('stat_type') }) - except Exception as e: + except Exception: continue return results diff --git a/uv.lock b/uv.lock index 3a98de6..b378401 100644 --- a/uv.lock +++ b/uv.lock @@ -170,6 +170,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] +[[package]] +name = "greenlet" +version = "3.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, + { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, + { url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" }, + { url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" }, + { url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" }, + { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, + { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, + { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, + { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" }, + { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, + { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, + { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, + { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, + { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, + { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, + { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, + { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, + { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, + { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, +] + [[package]] name = "idna" version = "3.10" @@ -428,6 +467,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/92/1b/5337af1a6a478d25a3e3c56b9b4b42b0a160314e02f4a0498d5322c8dac4/poethepoet-0.37.0-py3-none-any.whl", hash = "sha256:861790276315abcc8df1b4bd60e28c3d48a06db273edd3092f3c94e1a46e5e22", size = 90062, upload-time = "2025-08-11T18:00:27.595Z" }, ] +[[package]] +name = "psycopg2-binary" +version = "2.9.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/07/e720e53bfab016ebcc34241695ccc06a9e3d91ba19b40ca81317afbdc440/psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c", size = 384973, upload-time = "2023-10-03T12:48:55.128Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/d0/5f2db14e7b53552276ab613399a83f83f85b173a862d3f20580bc7231139/psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf", size = 2823784, upload-time = "2023-10-03T12:47:00.404Z" }, + { url = "https://files.pythonhosted.org/packages/18/ca/da384fd47233e300e3e485c90e7aab5d7def896d1281239f75901faf87d4/psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d", size = 2553308, upload-time = "2023-11-01T10:40:33.984Z" }, + { url = "https://files.pythonhosted.org/packages/50/66/fa53d2d3d92f6e1ef469d92afc6a4fe3f6e8a9a04b687aa28fb1f1d954ee/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212", size = 2851283, upload-time = "2023-10-03T12:47:02.736Z" }, + { url = "https://files.pythonhosted.org/packages/04/37/2429360ac5547378202db14eec0dde76edbe1f6627df5a43c7e164922859/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493", size = 3081839, upload-time = "2023-10-03T12:47:05.027Z" }, + { url = "https://files.pythonhosted.org/packages/62/2a/c0530b59d7e0d09824bc2102ecdcec0456b8ca4d47c0caa82e86fce3ed4c/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996", size = 3264488, upload-time = "2023-10-03T12:47:08.962Z" }, + { url = "https://files.pythonhosted.org/packages/19/57/9f172b900795ea37246c78b5f52e00f4779984370855b3e161600156906d/psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119", size = 3020700, upload-time = "2023-10-03T12:47:12.23Z" }, + { url = "https://files.pythonhosted.org/packages/94/68/1176fc14ea76861b7b8360be5176e87fb20d5091b137c76570eb4e237324/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba", size = 2355968, upload-time = "2023-10-03T12:47:14.817Z" }, + { url = "https://files.pythonhosted.org/packages/70/bb/aec2646a705a09079d008ce88073401cd61fc9b04f92af3eb282caa3a2ec/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07", size = 2536101, upload-time = "2023-10-03T12:47:17.454Z" }, + { url = "https://files.pythonhosted.org/packages/14/33/12818c157e333cb9d9e6753d1b2463b6f60dbc1fade115f8e4dc5c52cac4/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb", size = 2487064, upload-time = "2023-10-03T12:47:20.717Z" }, + { url = "https://files.pythonhosted.org/packages/56/a2/7851c68fe8768f3c9c246198b6356ee3e4a8a7f6820cc798443faada3400/psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe", size = 2456257, upload-time = "2023-10-03T12:47:23.004Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ee/3ba07c6dc7c3294e717e94720da1597aedc82a10b1b180203ce183d4631a/psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93", size = 1024709, upload-time = "2023-10-28T09:37:24.991Z" }, + { url = "https://files.pythonhosted.org/packages/7b/08/9c66c269b0d417a0af9fb969535f0371b8c538633535a7a6a5ca3f9231e2/psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab", size = 1163864, upload-time = "2023-10-28T09:37:28.155Z" }, +] + [[package]] name = "pydantic" version = "2.12.0" @@ -547,14 +606,23 @@ wheels = [ [[package]] name = "python-dateutil" -version = "2.9.0.post0" +version = "2.8.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/c4/13b4776ea2d76c115c1d1b84579f3764ee6d57204f6be27119f13a61d0a9/python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", size = 357324, upload-time = "2021-07-14T08:19:19.783Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/36/7a/87837f39d0296e723bb9b62bbb257d0355c7f6128853c78955f57342a56d/python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9", size = 247702, upload-time = "2021-07-14T08:19:18.161Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115, upload-time = "2024-01-23T06:33:00.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863, upload-time = "2024-01-23T06:32:58.246Z" }, ] [[package]] @@ -801,6 +869,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] +[[package]] +name = "sqlalchemy" +version = "1.4.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/a4/b5991829c34af0505e0f2b1ccf9588d1ba90f2d984ee208c90c985f1265a/SQLAlchemy-1.4.52.tar.gz", hash = "sha256:80e63bbdc5217dad3485059bdf6f65a7d43f33c8bde619df5c220edf03d87296", size = 8514200, upload-time = "2024-03-04T13:29:44.258Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/30/7e04f16d0508d4e57edd5c8def5810bb31bc73203beacd8bf83ed18ff0f1/SQLAlchemy-1.4.52-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:49e3772eb3380ac88d35495843daf3c03f094b713e66c7d017e322144a5c6b7c", size = 1589216, upload-time = "2024-03-04T13:35:43.622Z" }, + { url = "https://files.pythonhosted.org/packages/ce/e6/9da1e081321a514c0147a2e0b293f27ca93f0f299cbd5ba746a9422a9f07/SQLAlchemy-1.4.52-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:618827c1a1c243d2540314c6e100aee7af09a709bd005bae971686fab6723554", size = 1628827, upload-time = "2024-03-04T13:44:17.978Z" }, + { url = "https://files.pythonhosted.org/packages/10/c1/1613a8dcd05e6dacc9505554ce6c217a1cfda0da9c7592e258856945c6b6/SQLAlchemy-1.4.52-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de9acf369aaadb71a725b7e83a5ef40ca3de1cf4cdc93fa847df6b12d3cd924b", size = 1627867, upload-time = "2024-03-04T13:33:25.507Z" }, + { url = "https://files.pythonhosted.org/packages/0e/a7/97e7893673165b41dacfb07476df83a2fb5c9445feea5e54ad6ed3d27cb5/SQLAlchemy-1.4.52-cp312-cp312-win32.whl", hash = "sha256:763bd97c4ebc74136ecf3526b34808c58945023a59927b416acebcd68d1fc126", size = 1589871, upload-time = "2024-03-04T13:38:04.103Z" }, + { url = "https://files.pythonhosted.org/packages/49/62/d0e4502e27eaa10da35243d5241c3be3ed3974d607281e3b4ccc065d9853/SQLAlchemy-1.4.52-cp312-cp312-win_amd64.whl", hash = "sha256:f12aaf94f4d9679ca475975578739e12cc5b461172e04d66f7a3c39dd14ffc64", size = 1591783, upload-time = "2024-03-04T13:37:41.13Z" }, +] + [[package]] name = "threadpoolctl" version = "3.6.0" @@ -816,7 +900,13 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "nba-api" }, + { name = "pandas" }, + { name = "psycopg2-binary" }, + { name = "python-dateutil" }, + { name = "python-dotenv" }, + { name = "requests" }, { name = "scikit-learn" }, + { name = "sqlalchemy" }, ] [package.dev-dependencies] @@ -832,7 +922,13 @@ dev = [ [package.metadata] requires-dist = [ { name = "nba-api", specifier = ">=1.10.2" }, + { name = "pandas", specifier = ">=2.2.0" }, + { name = "psycopg2-binary", specifier = "==2.9.9" }, + { name = "python-dateutil", specifier = "==2.8.2" }, + { name = "python-dotenv", specifier = "==1.0.1" }, + { name = "requests", specifier = ">=2.32.3" }, { name = "scikit-learn", specifier = ">=1.7.2" }, + { name = "sqlalchemy", specifier = "==1.4.52" }, ] [package.metadata.requires-dev] From f92bc19dd67ca482e9565df414c3dfe0d49be981 Mon Sep 17 00:00:00 2001 From: Ryan Truong Date: Thu, 13 Nov 2025 15:08:13 -0800 Subject: [PATCH 08/21] fix: remove old test_scripts to fix build --- .../test_scripts/bettingpros_webscraper.py | 189 ------------------ .../test_scripts/requests_webscrape.py | 92 --------- 2 files changed, 281 deletions(-) delete mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py delete mode 100644 src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py deleted file mode 100644 index f644d96..0000000 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/bettingpros_webscraper.py +++ /dev/null @@ -1,189 +0,0 @@ -import requests -import json -import pandas as pd -from datetime import datetime -import sys - -def fetch_nba_props(): - """ - Fetch NBA player props from BettingPros API - - Returns: - dict: JSON response from API - """ - url = "https://api.bettingpros.com/v3/props" - - params = { - 'limit': 250, - 'sport': 'NBA', - 'market_id': '', - 'event_id': '', - 'location': 'ALL', - 'sort': 'bet_rating', - 'include_events': 'true', - 'include_selections': 'false', - 'include_markets': 'true', - 'include_books': 'true' - } - - try: - response = requests.get(url, params=params, timeout=30) - response.raise_for_status() - return response.json() - except requests.exceptions.RequestException as e: - print(f"Error fetching data: {e}", file=sys.stderr) - return None - -def parse_props(data): - """ - Parse props data into a structured format - - Args: - data (dict): Raw API response - - Returns: - list: List of dictionaries containing parsed prop data - """ - if not data or 'props' not in data: - return [] - - parsed_props = [] - - # Create lookup dictionaries for events and markets - events_dict = {event['id']: event for event in data.get('events', [])} - markets_dict = {market['id']: market for market in data.get('markets', [])} - - for prop in data['props']: - # Get player info from participant - participant = prop.get('participant', {}) - player_info = participant.get('player', {}) - - # Get event info - event = events_dict.get(prop.get('event_id')) - event_name = None - if event: - visitor = next((p for p in event.get('participants', []) if p['id'] == event['visitor']), {}) - home = next((p for p in event.get('participants', []) if p['id'] == event['home']), {}) - event_name = f"{visitor.get('team', {}).get('city', '')} @ {home.get('team', {}).get('city', '')}" - - # Get market info - market = markets_dict.get(prop.get('market_id')) - market_name = market.get('meta', {}).get('short_label', 'Unknown') if market else 'Unknown' - - # Get over/under info - line_info = prop.get('over', {}) - projection = prop.get('projection', {}) - - parsed_prop = { - 'timestamp': datetime.now().isoformat(), - 'player_name': participant.get('name', 'Unknown'), - 'player_team': player_info.get('team', ''), - 'player_position': player_info.get('position', ''), - 'market_name': market_name, - 'event_name': event_name, - 'event_start_time': event.get('scheduled', '') if event else '', - 'line': line_info.get('consensus_line'), - } - - parsed_props.append(parsed_prop) - - return parsed_props - -def save_to_csv(props, filename=None): - """ - Save props data to CSV file - - Args: - props (list): List of parsed prop dictionaries - filename (str): Output filename (default: nba_props_YYYYMMDD_HHMMSS.csv) - """ - if not props: - print("No props to save", file=sys.stderr) - return - - if filename is None: - timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') - filename = f'nba_props_{timestamp}.csv' - - df = pd.DataFrame(props) - df.to_csv(filename, index=False) - print(f"Saved {len(props)} props to {filename}") - -def save_to_json(props, filename=None): - """ - Save props data to JSON file - - Args: - props (list): List of parsed prop dictionaries - filename (str): Output filename (default: nba_props_YYYYMMDD_HHMMSS.json) - """ - if not props: - print("No props to save", file=sys.stderr) - return - - if filename is None: - timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') - filename = f'nba_props_{timestamp}.json' - - with open(filename, 'w') as f: - json.dump(props, f, indent=2) - - print(f"Saved {len(props)} props to {filename}") - -def print_summary(props): - """ - Print a summary of the scraped props - - Args: - props (list): List of parsed prop dictionaries - """ - if not props: - print("No props found") - return - - df = pd.DataFrame(props) - - print("\n" + "="*80) - print(f"NBA PROPS SUMMARY - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print("="*80) - print(f"\nTotal Props: {len(props)}") - print(f"\nUnique Players: {df['player_name'].nunique()}") - print(f"Unique Markets: {df['market_name'].nunique()}") - print(f"Unique Games: {df['event_name'].nunique()}") - - print("\nTop 5 Markets:") - print(df['market_name'].value_counts().head()) - - - print("="*80 + "\n") - -def main(): - """ - Main execution function - """ - print("Fetching NBA player props...") - - # Fetch data - data = fetch_nba_props() - - if not data: - sys.exit(1) - - # Parse props - props = parse_props(data) - - if not props: - print("No props found in response") - sys.exit(1) - - # Print summary - print_summary(props) - - # Save to files - save_to_csv(props) - save_to_json(props) - - print("Scraping completed successfully!") - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py deleted file mode 100644 index f460552..0000000 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/test_scripts/requests_webscrape.py +++ /dev/null @@ -1,92 +0,0 @@ -import requests -import pandas as pd -from datetime import datetime, UTC - -def fetch_prizepicks_nba_baseline_points(): - url = "https://api.prizepicks.com/projections" - params = {"per_page": 500, "single_stat": "true"} - headers = { - "Accept": "application/json; charset=UTF-8", - "User-Agent": "Mozilla/5.0", - "Referer": "https://app.prizepicks.com/" - } - - resp = requests.get(url, headers=headers, params=params, timeout=15) - resp.raise_for_status() - data = resp.json() - - projections = pd.json_normalize(data["data"]) - included = pd.json_normalize(data["included"]) - - players = included[included["type"] == "new_player"] - stat_types = included[included["type"] == "stat_type"] - - players = players[ - ["id", "attributes.name", "attributes.league", "attributes.team_name"] - ].rename(columns={ - "id": "player_id", - "attributes.name": "player_name", - "attributes.league": "league", - "attributes.team_name": "team" - }) - - stat_types = stat_types[["id", "attributes.name"]].rename( - columns={"id": "stat_type_id", "attributes.name": "stat_type"} - ) - - projections["player_id"] = projections["relationships.new_player.data.id"] - projections["stat_type_id"] = projections["relationships.stat_type.data.id"] - - merged = ( - projections.merge(players, on="player_id", how="left") - .merge(stat_types, on="stat_type_id", how="left") - ) - - # --- Filter NBA + Points only --- - merged = merged[ - (merged["league"].str.upper() == "NBA") - & (merged["stat_type"].str.lower() == "points") - ] - - # --- Fill missing indicator columns with False --- - for col in [ - "attributes.is_promo", - "attributes.is_flex", - "attributes.is_alternate", - "attributes.odds_type", - ]: - if col not in merged.columns: - merged[col] = False - - # --- Keep baseline (standard) projections only --- - baseline_mask = ( - (merged["attributes.is_promo"] == False) - & (merged["attributes.is_flex"] == False) - & (merged["attributes.is_alternate"] == False) - & (merged["attributes.odds_type"].isin(["standard", None, False])) - ) - merged = merged[baseline_mask] - - # --- Deduplicate: one projection per player/stat type --- - merged = merged.sort_values("id").drop_duplicates(subset=["player_name", "stat_type"], keep="first") - - df = merged[[ - "player_name", "team", "league", - "attributes.line_score", "stat_type", - "attributes.start_time", "attributes.updated_at" - ]].rename(columns={ - "attributes.line_score": "line_score", - "attributes.start_time": "start_time", - "attributes.updated_at": "updated_at" - }) - - df["scrape_time"] = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S") - - filename = f"nba_points_baseline_{datetime.now(UTC).strftime('%Y%m%d_%H%M')}.csv" - df.to_csv(filename, index=False) - print(f"✅ Saved {len(df)} NBA baseline 'Points' projections to {filename}") - return df - -if __name__ == "__main__": - df = fetch_prizepicks_nba_baseline_points() - print(df.head(20)) From 0cd7c9d77f0118a168c1be5b85ab109aa65f3b8f Mon Sep 17 00:00:00 2001 From: Ryan Truong Date: Thu, 13 Nov 2025 19:08:21 -0800 Subject: [PATCH 09/21] fix(sportsbooks): removed unused variables --- .../airflow_pipeline/api_scripts/fetch_prizepicks.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py index 47a1f74..34e01d4 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py @@ -43,9 +43,6 @@ def filter_projections(data): players = {p['id']: p for p in included if p['type'] == 'new_player'} leagues = {l['id']: l for l in included if l['type'] == 'league'} - stat_types = {s['id']: s for s in included if s['type'] == 'stat_type'} - events = {e['id']: e for e in included if e['type'] == 'event'} - teams = {t['id']: t for t in included if t['type'] == 'team'} time_scraped = datetime.now().isoformat() results = [] @@ -89,9 +86,6 @@ def filter_projections(data): if any(sep in player_name for sep in [' & ', ' and ', ' + ', ',']): continue - # Extract opponent - description = attrs.get('description', '') - results.append({ 'player_name': player_name, 'team': team, From 9b0b6171824bc04fe87ad90195d326585f8dced3 Mon Sep 17 00:00:00 2001 From: Ryan Truong Date: Thu, 13 Nov 2025 19:11:14 -0800 Subject: [PATCH 10/21] fix(sportsbooks): moved import to top of file --- .../airflow/dags/migrate_to_postgres.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py index fd0c375..14fa2d1 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py @@ -2,15 +2,16 @@ import os import sys from dotenv import load_dotenv +from airflow_pipeline.api_scripts.fetch_bettingpros import get_bettingpros_df +from airflow_pipeline.api_scripts.fetch_prizepicks import get_prizepicks_df +from airflow_pipeline.api_scripts.fetch_draftedge import get_draftedge_df # Ensure project root is importable when executed by Airflow or standalone PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')) if PROJECT_ROOT not in sys.path: sys.path.insert(0, PROJECT_ROOT) -from airflow_pipeline.api_scripts.fetch_bettingpros import get_bettingpros_df -from airflow_pipeline.api_scripts.fetch_prizepicks import get_prizepicks_df -from airflow_pipeline.api_scripts.fetch_draftedge import get_draftedge_df + load_dotenv() db_username = os.getenv("DB_USERNAME") From 38c79197134b75190bf6d90a5573798678051400 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Fri, 14 Nov 2025 01:19:11 -0800 Subject: [PATCH 11/21] fix(sportsbook): fix lint errors in DAG + prizepicks script --- .../airflow/dags/nba_props_dag.py | 19 +------------------ .../api_scripts/fetch_prizepicks.py | 4 ++-- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py index ba15042..1710ad6 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py @@ -1,20 +1,3 @@ -""" -To run the dag in ../dag_setup - - set AIRFLOW_HOME=~/CursorProjects/webscrape/airflow - - airflow scheduler - -For airflow UI -airflow apiserver --port 8080 -""" -""" -To run the dag in ../dag_setup - - set AIRFLOW_HOME=~/CursorProjects/webscrape/airflow - - airflow standalone - -For airflow UI -airflow apiserver --port 8080 -""" - from airflow.models.dag import DAG from airflow.providers.standard.operators.python import PythonOperator from datetime import datetime, timedelta @@ -25,7 +8,7 @@ if API_SCRIPTS_PATH not in sys.path: sys.path.insert(0, API_SCRIPTS_PATH) -from migrate_to_postgres import __main__ as migrate_to_postgres_main +from migrate_to_postgres import __main__ as migrate_to_postgres_main # noqa: E402 default_args = { 'owner': 'LineDancers', diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py index 34e01d4..2406dc8 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py @@ -41,8 +41,8 @@ def filter_projections(data): projections = data.get('data', []) included = data.get('included', []) - players = {p['id']: p for p in included if p['type'] == 'new_player'} - leagues = {l['id']: l for l in included if l['type'] == 'league'} + players = {player['id']: player for player in included if player['type'] == 'new_player'} + leagues = {league["id"]: league for league in included if league["type"] == "league"} time_scraped = datetime.now().isoformat() results = [] From c2a416acc64f318e45c6a3242b1eaabca1459573 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 19 Nov 2025 01:36:08 -0800 Subject: [PATCH 12/21] chore(sportsbook): resolved requested changes in pr --- .env.example | 10 ++++++ src/practice_nn/small_neural_network.ipynb | 26 ++++++++++++++ src/sportsbook_webscraper_pipeline/Dockerfile | 5 +-- .../airflow/dags/migrate_to_postgres.py | 21 +++++++----- .../airflow/dags/nba_props_dag.py | 16 ++++++--- ...mple_auth_manager_passwords.json.generated | 1 - .../api_scripts/fetch_bettingpros.py | 21 ++++++++---- .../docker-compose.yml | 34 ++++++++++--------- 8 files changed, 95 insertions(+), 39 deletions(-) create mode 100644 .env.example create mode 100644 src/practice_nn/small_neural_network.ipynb delete mode 100644 src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e47e74c --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +# Postgres +POSTGRES_USER= +POSTGRES_PASSWORD= +POSTGRES_DB= +POSTGRES_EXTERNAL_PORT=5433 + +# Airflow +AIRFLOW_ADMIN_USERNAME= +AIRFLOW_ADMIN_PASSWORD= +AIRFLOW_PORT=8080 \ No newline at end of file diff --git a/src/practice_nn/small_neural_network.ipynb b/src/practice_nn/small_neural_network.ipynb new file mode 100644 index 0000000..ddd1a74 --- /dev/null +++ b/src/practice_nn/small_neural_network.ipynb @@ -0,0 +1,26 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "fea6f137", + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "import torch\n", + "inport torchvision " + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/sportsbook_webscraper_pipeline/Dockerfile b/src/sportsbook_webscraper_pipeline/Dockerfile index 9e31413..b4a262b 100644 --- a/src/sportsbook_webscraper_pipeline/Dockerfile +++ b/src/sportsbook_webscraper_pipeline/Dockerfile @@ -6,8 +6,9 @@ RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/* USER airflow WORKDIR /opt/airflow -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +COPY pyproject.toml . +COPY uv.lock . +RUN pip install uv && uv pip install --system . COPY airflow/dags /opt/airflow/dags COPY airflow_pipeline /opt/airflow/airflow_pipeline diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py index 14fa2d1..dede639 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py @@ -1,4 +1,5 @@ from sqlalchemy import create_engine, text as sql_text, Table, MetaData +from sqlalchemy.engine import URL import os import sys from dotenv import load_dotenv @@ -6,32 +7,35 @@ from airflow_pipeline.api_scripts.fetch_prizepicks import get_prizepicks_df from airflow_pipeline.api_scripts.fetch_draftedge import get_draftedge_df -# Ensure project root is importable when executed by Airflow or standalone PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')) if PROJECT_ROOT not in sys.path: sys.path.insert(0, PROJECT_ROOT) - - load_dotenv() + db_username = os.getenv("DB_USERNAME") db_password = os.getenv("DB_PASSWORD") db_host = os.getenv("DB_HOST", "localhost") db_port = os.getenv("DB_PORT", "5432") db_name = os.getenv("DB_NAME", "nba_deeplearning") -connection_string = ( - f'postgresql+psycopg2://{db_username}:{db_password}@{db_host}:{db_port}/{db_name}' +url = URL.create( + drivername="postgresql+psycopg2", + username=db_username, + password=db_password, + host=db_host, + port=db_port, + database=db_name, ) -db_eng = create_engine(connection_string) -print("Successfully created db engine.") +db_eng = create_engine(url) +print("Successfully created DB engine.") def append_to_postgres(df, table_name): metadata = MetaData() table = Table(table_name, metadata, autoload_with=db_eng) - with db_eng.begin() as conn: # transaction automatically commits + with db_eng.begin() as conn: for row in df.to_dict(orient='records'): conn.execute(table.insert(), row) @@ -43,6 +47,7 @@ def check_if_table_exists(table_name): result = conn.execute(query, {"table": table_name}) return result.scalar() + def check_df_columns(df): table_columns = ['player_name', 'team', 'sportsbook', 'line_score', 'game_start', 'time_scraped', 'opponent_team', 'line_type'] df_columns = df.columns.tolist() diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py index 1710ad6..3aa238a 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/nba_props_dag.py @@ -3,12 +3,16 @@ from datetime import datetime, timedelta import sys import os +import logging -API_SCRIPTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../airflow_pipeline/api_scripts')) +API_SCRIPTS_PATH = os.path.abspath( + os.path.join(os.path.dirname(__file__), "../../airflow_pipeline/api_scripts") +) if API_SCRIPTS_PATH not in sys.path: sys.path.insert(0, API_SCRIPTS_PATH) -from migrate_to_postgres import __main__ as migrate_to_postgres_main # noqa: E402 +# `# noqa: E402` tells the linter to ignore this specific rule here (need API_SCRIPTS_PATH before importing) +from migrate_to_postgres import __main__ as migrate_to_postgres_main # noqa: E402 default_args = { 'owner': 'LineDancers', @@ -24,7 +28,7 @@ dag_id='nba_sportsbook_pipeline', default_args=default_args, description='Daily NBA sportsbook data scraping and collection pipeline', - schedule="0 22 * * *", # <--- use cron string directly + schedule="0 22 * * *", catchup=False, tags=['nba', 'betting', 'data-pipeline'], ) @@ -39,5 +43,7 @@ def migrate_to_postgres_task(): dag=dag, ) -# Only one task now, no fetch tasks needed -print("File ran?") +check = logging.getLogger(__name__) + +check.info("NBA props DAG initialized.") +check.debug("DAG file loaded successfully.") \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated b/src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated deleted file mode 100644 index 132cded..0000000 --- a/src/sportsbook_webscraper_pipeline/airflow/simple_auth_manager_passwords.json.generated +++ /dev/null @@ -1 +0,0 @@ -{"admin": "PZrYMfcmHMNKypbp"} diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py index 702a516..7b99bab 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py @@ -2,6 +2,7 @@ import pandas as pd from datetime import datetime import sys +import time def fetch_nba_props(): """Fetch NBA props from BettingPros API""" @@ -19,14 +20,20 @@ def fetch_nba_props(): 'include_markets': 'true', 'include_books': 'true' } + + RETRIES = 5 - try: - response = requests.get(url, params=params, timeout=30) - response.raise_for_status() - return response.json() - except requests.exceptions.RequestException as e: - print(f"Error fetching data: {e}", file=sys.stderr) - return None + for attempt in range(1, RETRIES + 1): + try: + response = requests.get(url, params=params, timeout=30) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"Attempt {attempt} failed: {e}", file=sys.stderr) + if attempt == RETRIES: + print("All retries failed.", file=sys.stderr) + return None + time.sleep(attempt * 2) def parse_props(data): """ diff --git a/src/sportsbook_webscraper_pipeline/docker-compose.yml b/src/sportsbook_webscraper_pipeline/docker-compose.yml index feedbc0..24acf85 100644 --- a/src/sportsbook_webscraper_pipeline/docker-compose.yml +++ b/src/sportsbook_webscraper_pipeline/docker-compose.yml @@ -5,13 +5,13 @@ services: image: postgres:15 restart: always environment: - POSTGRES_USER: line_dancer - POSTGRES_PASSWORD: sportsbook_data - POSTGRES_DB: nba_deeplearning + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data ports: - - "5433:5432" + - "${POSTGRES_EXTERNAL_PORT}:5432" airflow: build: . @@ -19,19 +19,21 @@ services: - postgres restart: always environment: - - DB_USERNAME=line_dancer - - DB_PASSWORD=sportsbook_data - - DB_HOST=postgres - - DB_PORT=5432 - - DB_NAME=nba_deeplearning - - AIRFLOW__CORE__EXECUTOR=SequentialExecutor - - AIRFLOW__CORE__LOAD_EXAMPLES=False - - AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION=False - - AIRFLOW__WEBSERVER__AUTHENTICATE=True - - AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_USERNAME=admin - - AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_PASSWORD=M7fhanqeB2mUPSpe + DB_USERNAME=${POSTGRES_USER} + DB_PASSWORD=${POSTGRES_PASSWORD} + DB_HOST=postgres + DB_PORT=5432 + DB_NAME=${POSTGRES_DB} + + AIRFLOW__CORE__EXECUTOR=SequentialExecutor + AIRFLOW__CORE__LOAD_EXAMPLES=False + AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION=False + + AIRFLOW__WEBSERVER__AUTHENTICATE=True + AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_USERNAME=${AIRFLOW_ADMIN_USERNAME} + AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_PASSWORD=${AIRFLOW_ADMIN_PASSWORD} ports: - - "8080:8080" + - "${AIRFLOW_PORT}:8080" volumes: - ./airflow/dags:/opt/airflow/dags:ro - ./airflow_pipeline:/opt/airflow/airflow_pipeline:ro From 4435edc36aed354b264e704f9049bec4f6796ad7 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 19 Nov 2025 01:47:22 -0800 Subject: [PATCH 13/21] chore(sportsbook): more requested changes resolved + env changes --- .../airflow/dags/migrate_to_postgres.py | 8 ++++---- .../airflow_pipeline/api_scripts/fetch_bettingpros.py | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py index dede639..b54f0dc 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py @@ -13,11 +13,11 @@ load_dotenv() -db_username = os.getenv("DB_USERNAME") -db_password = os.getenv("DB_PASSWORD") +db_username = os.getenv("POSTGRES_USER") +db_password = os.getenv("POSTGRES_PASSWORD") db_host = os.getenv("DB_HOST", "localhost") -db_port = os.getenv("DB_PORT", "5432") -db_name = os.getenv("DB_NAME", "nba_deeplearning") +db_port = os.getenv("POSTGRES_EXTERNAL_PORT", "5432") +db_name = os.getenv("POSTGRES_DB") url = URL.create( drivername="postgresql+psycopg2", diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py index 7b99bab..592ab95 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py @@ -3,10 +3,14 @@ from datetime import datetime import sys import time +import os +from dotenv import load_dotenv + +load_dotenv() def fetch_nba_props(): """Fetch NBA props from BettingPros API""" - url = "https://api.bettingpros.com/v3/props" + url = BETTINGPROS_API_URL params = { 'limit': 2000, From 1c0f17f6e094a53801335a2ebdb30ec3d5ff4d30 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 19 Nov 2025 01:50:50 -0800 Subject: [PATCH 14/21] fix(sportsbook): forgot to actually load the env variable (brain fog) --- .../airflow_pipeline/api_scripts/fetch_bettingpros.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py index 592ab95..0c69c30 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py @@ -7,6 +7,7 @@ from dotenv import load_dotenv load_dotenv() +BETTINGPROS_API_URL = os.getenv("BETTINGPROS_API_URL") def fetch_nba_props(): """Fetch NBA props from BettingPros API""" From c4d27eaccdfd1487b71d82af42a9e024f24cd184 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Wed, 19 Nov 2025 12:25:11 -0800 Subject: [PATCH 15/21] chore(sportsbook): branch cleanup --- .env.example | 5 ++++- src/practice_nn/small_neural_network.ipynb | 26 ---------------------- 2 files changed, 4 insertions(+), 27 deletions(-) delete mode 100644 src/practice_nn/small_neural_network.ipynb diff --git a/.env.example b/.env.example index e47e74c..a8a9830 100644 --- a/.env.example +++ b/.env.example @@ -7,4 +7,7 @@ POSTGRES_EXTERNAL_PORT=5433 # Airflow AIRFLOW_ADMIN_USERNAME= AIRFLOW_ADMIN_PASSWORD= -AIRFLOW_PORT=8080 \ No newline at end of file +AIRFLOW_PORT=8080 + +#API links +BETTINGPROS_API_URL= \ No newline at end of file diff --git a/src/practice_nn/small_neural_network.ipynb b/src/practice_nn/small_neural_network.ipynb deleted file mode 100644 index ddd1a74..0000000 --- a/src/practice_nn/small_neural_network.ipynb +++ /dev/null @@ -1,26 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "fea6f137", - "metadata": { - "vscode": { - "languageId": "plaintext" - } - }, - "outputs": [], - "source": [ - "import torch\n", - "inport torchvision " - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 1288745d76f742bc2ea19c2856dc3ecd66df1555 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Sun, 11 Jan 2026 18:01:21 -0800 Subject: [PATCH 16/21] feat(sportsbook): sql schema files --- src/sportsbook_webscraper_pipeline/down.sql | 1 + src/sportsbook_webscraper_pipeline/up.sql | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/sportsbook_webscraper_pipeline/down.sql create mode 100644 src/sportsbook_webscraper_pipeline/up.sql diff --git a/src/sportsbook_webscraper_pipeline/down.sql b/src/sportsbook_webscraper_pipeline/down.sql new file mode 100644 index 0000000..2fa05a8 --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS player_lines; \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/up.sql b/src/sportsbook_webscraper_pipeline/up.sql new file mode 100644 index 0000000..4fe0e0e --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/up.sql @@ -0,0 +1,14 @@ +CREATE TABLE IF NOT EXISTS player_lines ( + id BIGSERIAL PRIMARY KEY, + + player_name TEXT NOT NULL, + team TEXT, + sportsbook TEXT NOT NULL, + + line_score DOUBLE PRECISION, + game_start TIMESTAMPTZ, + time_scraped TIMESTAMPTZ NOT NULL DEFAULT NOW(), + + opponent_team TEXT, + line_type TEXT NOT NULL +); From ea0dea993a40e95873a1f8c77d806c2d7c9a23f4 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Mon, 12 Jan 2026 11:15:37 -0800 Subject: [PATCH 17/21] feat(sportsbook): sql schema files migration --- .../docker-compose.yml | 15 +++++++++++++++ src/sportsbook_webscraper_pipeline/down.sql | 1 - src/sportsbook_webscraper_pipeline/sql/down.sql | 2 ++ .../{ => sql}/up.sql | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) delete mode 100644 src/sportsbook_webscraper_pipeline/down.sql create mode 100644 src/sportsbook_webscraper_pipeline/sql/down.sql rename src/sportsbook_webscraper_pipeline/{ => sql}/up.sql (85%) diff --git a/src/sportsbook_webscraper_pipeline/docker-compose.yml b/src/sportsbook_webscraper_pipeline/docker-compose.yml index 24acf85..a42af8d 100644 --- a/src/sportsbook_webscraper_pipeline/docker-compose.yml +++ b/src/sportsbook_webscraper_pipeline/docker-compose.yml @@ -38,5 +38,20 @@ services: - ./airflow/dags:/opt/airflow/dags:ro - ./airflow_pipeline:/opt/airflow/airflow_pipeline:ro + db-migrate: + image: postgres:15 + depends_on: + - postgres + restart: "no" + environment: + PGPASSWORD: ${POSTGRES_PASSWORD} + volumes: + - ./sql:/sql:ro + entrypoint: ["/bin/bash","-lc"] + command: > + psql -h postgres -U ${POSTGRES_USER} -d ${POSTGRES_DB} -f /sql/up.sql + profiles: ["migrate"] + + volumes: postgres_data: diff --git a/src/sportsbook_webscraper_pipeline/down.sql b/src/sportsbook_webscraper_pipeline/down.sql deleted file mode 100644 index 2fa05a8..0000000 --- a/src/sportsbook_webscraper_pipeline/down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE IF EXISTS player_lines; \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/sql/down.sql b/src/sportsbook_webscraper_pipeline/sql/down.sql new file mode 100644 index 0000000..d27e1bd --- /dev/null +++ b/src/sportsbook_webscraper_pipeline/sql/down.sql @@ -0,0 +1,2 @@ +/* don't really need this, but just in case (don't want to delete existing data) +DROP TABLE IF EXISTS player_lines; */ \ No newline at end of file diff --git a/src/sportsbook_webscraper_pipeline/up.sql b/src/sportsbook_webscraper_pipeline/sql/up.sql similarity index 85% rename from src/sportsbook_webscraper_pipeline/up.sql rename to src/sportsbook_webscraper_pipeline/sql/up.sql index 4fe0e0e..0975715 100644 --- a/src/sportsbook_webscraper_pipeline/up.sql +++ b/src/sportsbook_webscraper_pipeline/sql/up.sql @@ -1,3 +1,5 @@ +/* docker compose --profile migrate run --rm db-migrate */ + CREATE TABLE IF NOT EXISTS player_lines ( id BIGSERIAL PRIMARY KEY, From 24d8af9f3de6b249a2184fc8f0ffb4c098a65865 Mon Sep 17 00:00:00 2001 From: Ryan Truong Date: Sat, 24 Jan 2026 16:00:51 -0800 Subject: [PATCH 18/21] refactor(sportsbook): moved hard-coded numbers to yml --- pyproject.toml | 2 +- .../api_scripts/fetch_bettingpros.py | 12 +++++++----- .../airflow_pipeline/api_scripts/fetch_draftedge.py | 4 +++- .../airflow_pipeline/api_scripts/fetch_prizepicks.py | 4 +++- .../docker-compose.yml | 7 +++++++ 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 90cc881..9082e24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "psycopg2-binary==2.9.9", "SQLAlchemy==1.4.52", "python-dotenv==1.0.1", - "python-dateutil==2.8.2" + "python-dateutil==2.8.2", "torch>=2.9.0", ] diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py index 0c69c30..8827a42 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_bettingpros.py @@ -4,17 +4,19 @@ import sys import time import os -from dotenv import load_dotenv -load_dotenv() BETTINGPROS_API_URL = os.getenv("BETTINGPROS_API_URL") +API_LIMIT = int(os.getenv("BETTINGPROS_LIMIT", 2000)) +API_TIMEOUT = int(os.getenv("API_TIMEOUT", 30)) +MAX_RETRIES = int(os.getenv("API_RETRIES", 5)) +RETRY_DELAY_MULT = int(os.getenv("API_RETRY_DELAY_MULTIPLIER", 2)) def fetch_nba_props(): """Fetch NBA props from BettingPros API""" url = BETTINGPROS_API_URL params = { - 'limit': 2000, + 'limit': API_LIMIT, 'sport': 'NBA', 'market_id': '', 'event_id': '', @@ -30,7 +32,7 @@ def fetch_nba_props(): for attempt in range(1, RETRIES + 1): try: - response = requests.get(url, params=params, timeout=30) + response = requests.get(url, params=params, timeout=API_TIMEOUT) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: @@ -38,7 +40,7 @@ def fetch_nba_props(): if attempt == RETRIES: print("All retries failed.", file=sys.stderr) return None - time.sleep(attempt * 2) + time.sleep(attempt * RETRY_DELAY_MULT) def parse_props(data): """ diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py index beb96db..527b579 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_draftedge.py @@ -2,13 +2,15 @@ import pandas as pd from datetime import datetime import sys +import os DRAFTEDGE_API = "https://draftedge.com/draftedge-data/nbaprops1.json" +API_TIMEOUT = int(os.getenv("API_TIMEOUT", 30)) def fetch_draftedge_data(): """Fetch NBA props from DraftEdge API""" try: - response = requests.get(DRAFTEDGE_API, timeout=30) + response = requests.get(DRAFTEDGE_API, timeout=API_TIMEOUT) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: diff --git a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py index 2406dc8..d1e26b1 100644 --- a/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py +++ b/src/sportsbook_webscraper_pipeline/airflow_pipeline/api_scripts/fetch_prizepicks.py @@ -2,8 +2,10 @@ import pandas as pd from datetime import datetime import sys +import os PRIZEPICKS_API = "https://api.prizepicks.com/projections" +API_TIMEOUT = int(os.getenv("API_TIMEOUT", 30)) NBA_TEAMS = { 'ATL', 'BOS', 'BKN', 'BRK', 'CHA', 'CHI', 'CLE', 'DAL', 'DEN', 'DET', 'GSW', @@ -25,7 +27,7 @@ def get_prizepicks_data(): } try: - response = requests.get(PRIZEPICKS_API, headers=headers, timeout=30) + response = requests.get(PRIZEPICKS_API, headers=headers, timeout=API_TIMEOUT) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: diff --git a/src/sportsbook_webscraper_pipeline/docker-compose.yml b/src/sportsbook_webscraper_pipeline/docker-compose.yml index a42af8d..8bee6f0 100644 --- a/src/sportsbook_webscraper_pipeline/docker-compose.yml +++ b/src/sportsbook_webscraper_pipeline/docker-compose.yml @@ -32,6 +32,13 @@ services: AIRFLOW__WEBSERVER__AUTHENTICATE=True AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_USERNAME=${AIRFLOW_ADMIN_USERNAME} AIRFLOW__SIMPLE_AUTH_MANAGER__ADMIN_PASSWORD=${AIRFLOW_ADMIN_PASSWORD} + + BETTINGPROS_API_URL= ${BETTINGPROS_API_URL} + BETTINGPROS_LIMIT= 2000 + API_TIMEOUT= 30 + API_RETRIES= 5 + API_RETRY_DELAY_MULTIPLIER= 2 + ports: - "${AIRFLOW_PORT}:8080" volumes: From efbac562b9e3a22c20983d53167d6af128715b46 Mon Sep 17 00:00:00 2001 From: Ryan Truong Date: Sat, 24 Jan 2026 16:05:41 -0800 Subject: [PATCH 19/21] feat(sportsbook): added db verifier --- .../airflow/dags/migrate_to_postgres.py | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py index b54f0dc..f6c39ad 100644 --- a/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py +++ b/src/sportsbook_webscraper_pipeline/airflow/dags/migrate_to_postgres.py @@ -35,9 +35,19 @@ def append_to_postgres(df, table_name): metadata = MetaData() table = Table(table_name, metadata, autoload_with=db_eng) + records = df.to_dict(orient='records') + expected_count = len(records) + with db_eng.begin() as conn: - for row in df.to_dict(orient='records'): - conn.execute(table.insert(), row) + result = conn.execute(table.insert(), records) + if result.rowcount != -1: + if result.rowcount != expected_count: + raise Exception( + f"DB Verification Failed: Expected to write {expected_count} rows, " + f"but DB reported {result.rowcount} rows affected." + ) + + return expected_count def check_if_table_exists(table_name): query = sql_text( @@ -64,9 +74,14 @@ def __main__(table_name): continue if not check_df_columns(df): raise Exception(f"df columns do not match WITH {table_name} attributes.") - append_to_postgres(df, table_name) + + rows_inserted = append_to_postgres(df, table_name) + + if rows_inserted != len(df): + raise Exception(f"Verification Mismatch: DataFrame had {len(df)} rows but function reported {rows_inserted}.") + + print(f"Successfully appended {rows_inserted} records to {table_name} in postgres.") - print(f"Successfully appended dataframe of length {len(df)} to {table_name} in postgres.") if __name__ == "__main__": From b2788e0f33e80571d1817e8f63225b18e64c6c33 Mon Sep 17 00:00:00 2001 From: Ryan Truong Date: Mon, 2 Feb 2026 10:30:32 -0800 Subject: [PATCH 20/21] fix(sportsbook): fixing urllib3 trivy error --- pyproject.toml | 1 + uv.lock | 324 +++++++++++++++++++++++-------------------------- 2 files changed, 154 insertions(+), 171 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9082e24..0bde284 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "python-dotenv==1.0.1", "python-dateutil==2.8.2", "torch>=2.9.0", + "urllib3>=2.6.0", ] [tool.poe.tasks] diff --git a/uv.lock b/uv.lock index eb28aa6..22083a0 100644 --- a/uv.lock +++ b/uv.lock @@ -170,6 +170,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +] + +[[package]] +name = "fsspec" +version = "2025.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/7f/2747c0d332b9acfa75dc84447a066fdf812b5a6b8d30472b74d309bfe8cb/fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59", size = 309285, upload-time = "2025-10-30T14:58:44.036Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/02/a6b21098b1d5d6249b7c5ab69dde30108a71e4e819d4a9778f1de1d5b70d/fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d", size = 200966, upload-time = "2025-10-30T14:58:42.53Z" }, +] + [[package]] name = "greenlet" version = "3.2.4" @@ -209,24 +227,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, ] -[[package]] -name = "filelock" -version = "3.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054 }, -] - -[[package]] -name = "fsspec" -version = "2025.10.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/7f/2747c0d332b9acfa75dc84447a066fdf812b5a6b8d30472b74d309bfe8cb/fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59", size = 309285 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/02/a6b21098b1d5d6249b7c5ab69dde30108a71e4e819d4a9778f1de1d5b70d/fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d", size = 200966 }, -] - [[package]] name = "idna" version = "3.10" @@ -252,9 +252,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] @@ -310,63 +310,63 @@ wheels = [ name = "markupsafe" version = "3.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615 }, - { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020 }, - { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332 }, - { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947 }, - { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962 }, - { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760 }, - { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529 }, - { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015 }, - { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540 }, - { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105 }, - { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906 }, - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619 }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029 }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408 }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005 }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048 }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821 }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606 }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043 }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747 }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341 }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073 }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661 }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069 }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670 }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598 }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261 }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835 }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733 }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672 }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819 }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426 }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146 }, +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] @@ -382,9 +382,9 @@ wheels = [ name = "mpmath" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] [[package]] @@ -405,9 +405,9 @@ wheels = [ name = "networkx" version = "3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406 }, + { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, ] [[package]] @@ -473,22 +473,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/06/b9/33bba5ff6fb679aa0b1f8a07e853f002a6b04b9394db3069a1270a7784ca/numpy-2.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:78c9f6560dc7e6b3990e32df7ea1a50bbd0e2a111e05209963f5ddcab7073b0b", size = 10545953, upload-time = "2025-09-09T15:58:40.576Z" }, ] -[[package]] -name = "packaging" -version = "25.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, -] - [[package]] name = "nvidia-cublas-cu12" version = "12.8.4.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/99/db44d685f0e257ff0e213ade1964fc459b4a690a73293220e98feb3307cf/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b86f6dd8935884615a0683b663891d43781b819ac4f2ba2b0c9604676af346d0", size = 590537124 }, - { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921 }, + { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, ] [[package]] @@ -496,8 +486,7 @@ name = "nvidia-cuda-cupti-cu12" version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/1f/b3bd73445e5cb342727fd24fe1f7b748f690b460acadc27ea22f904502c8/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4412396548808ddfed3f17a467b104ba7751e6b58678a4b840675c56d21cf7ed", size = 9533318 }, - { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621 }, + { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, ] [[package]] @@ -505,8 +494,7 @@ name = "nvidia-cuda-nvrtc-cu12" version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029 }, - { url = "https://files.pythonhosted.org/packages/eb/d1/e50d0acaab360482034b84b6e27ee83c6738f7d32182b987f9c7a4e32962/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fc1fec1e1637854b4c0a65fb9a8346b51dd9ee69e61ebaccc82058441f15bce8", size = 43106076 }, + { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, ] [[package]] @@ -514,8 +502,7 @@ name = "nvidia-cuda-runtime-cu12" version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/75/f865a3b236e4647605ea34cc450900854ba123834a5f1598e160b9530c3a/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:52bf7bbee900262ffefe5e9d5a2a69a30d97e2bc5bb6cc866688caa976966e3d", size = 965265 }, - { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765 }, + { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, ] [[package]] @@ -526,8 +513,7 @@ dependencies = [ { name = "nvidia-cublas-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/41/e79269ce215c857c935fd86bcfe91a451a584dfc27f1e068f568b9ad1ab7/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:c9132cc3f8958447b4910a1720036d9eff5928cc3179b0a51fb6d167c6cc87d8", size = 705026878 }, - { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467 }, + { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, ] [[package]] @@ -538,8 +524,7 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/60/bc/7771846d3a0272026c416fbb7e5f4c1f146d6d80704534d0b187dd6f4800/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:848ef7224d6305cdb2a4df928759dca7b1201874787083b6e7550dd6765ce69a", size = 193109211 }, - { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695 }, + { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, ] [[package]] @@ -547,8 +532,7 @@ name = "nvidia-cufile-cu12" version = "1.13.1.3" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834 }, - { url = "https://files.pythonhosted.org/packages/1e/f5/5607710447a6fe9fd9b3283956fceeee8a06cda1d2f56ce31371f595db2a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:4beb6d4cce47c1a0f1013d72e02b0994730359e17801d395bdcbf20cfb3bb00a", size = 1120705 }, + { url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834, upload-time = "2025-03-07T01:45:50.723Z" }, ] [[package]] @@ -556,8 +540,7 @@ name = "nvidia-curand-cu12" version = "10.3.9.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/5e/92aa15eca622a388b80fbf8375d4760738df6285b1e92c43d37390a33a9a/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:dfab99248034673b779bc6decafdc3404a8a6f502462201f2f31f11354204acd", size = 63625754 }, - { url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976 }, + { url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976, upload-time = "2025-03-07T01:46:23.323Z" }, ] [[package]] @@ -570,8 +553,7 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/32/f7cd6ce8a7690544d084ea21c26e910a97e077c9b7f07bf5de623ee19981/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:db9ed69dbef9715071232caa9b69c52ac7de3a95773c2db65bdba85916e4e5c0", size = 267229841 }, - { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905 }, + { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, ] [[package]] @@ -582,8 +564,7 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/f7/cd777c4109681367721b00a106f491e0d0d15cfa1fd59672ce580ce42a97/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b6c161cb130be1a07a27ea6923df8141f3c295852f4b260c65f18f3e0a091dc", size = 288117129 }, - { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466 }, + { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, ] [[package]] @@ -591,8 +572,7 @@ name = "nvidia-cusparselt-cu12" version = "0.7.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/b9/598f6ff36faaece4b3c50d26f50e38661499ff34346f00e057760b35cc9d/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8878dce784d0fac90131b6817b607e803c36e629ba34dc5b433471382196b6a5", size = 283835557 }, - { url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691 }, + { url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691, upload-time = "2025-02-26T00:15:44.104Z" }, ] [[package]] @@ -600,8 +580,7 @@ name = "nvidia-nccl-cu12" version = "2.27.5" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/1c/857979db0ef194ca5e21478a0612bcdbbe59458d7694361882279947b349/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:31432ad4d1fb1004eb0c56203dc9bc2178a1ba69d1d9e02d64a6938ab5e40e7a", size = 322400625 }, - { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229 }, + { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, ] [[package]] @@ -609,8 +588,7 @@ name = "nvidia-nvjitlink-cu12" version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836 }, - { url = "https://files.pythonhosted.org/packages/2a/a2/8cee5da30d13430e87bf99bb33455d2724d0a4a9cb5d7926d80ccb96d008/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:adccd7161ace7261e01bb91e44e88da350895c270d23f744f0820c818b7229e7", size = 38386204 }, + { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, ] [[package]] @@ -618,8 +596,7 @@ name = "nvidia-nvshmem-cu12" version = "3.3.20" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/9d/3dd98852568fb845ec1f7902c90a22b240fe1cbabda411ccedf2fd737b7b/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b0b960da3842212758e4fa4696b94f129090b30e5122fea3c5345916545cff0", size = 124484616 }, - { url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145 }, + { url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145, upload-time = "2025-08-04T20:25:19.995Z" }, ] [[package]] @@ -627,8 +604,16 @@ name = "nvidia-nvtx-cu12" version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/c0/1b303feea90d296f6176f32a2a70b5ef230f9bdeb3a72bddb0dc922dc137/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d7ad891da111ebafbf7e015d34879f7112832fc239ff0d7d776b6cb685274615", size = 91161 }, - { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954 }, + { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] @@ -1152,9 +1137,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mpmath" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921 } +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353 }, + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] [[package]] @@ -1175,47 +1160,47 @@ dependencies = [ { name = "fsspec" }, { name = "jinja2" }, { name = "networkx" }, - { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools" }, { name = "sympy" }, - { name = "triton", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d3/3985739f3b8e88675127bf70f82b3a48ae083e39cda56305dbd90398fec0/torch-2.9.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e5f7af1dc4c0a7c4a260c2534f41ddaf209714f7c89145e644c44712fbd6b642", size = 104107898 }, - { url = "https://files.pythonhosted.org/packages/a5/4b/f4bb2e6c25d0272f798cd6d7a04ed315da76cec68c602d87040c7847287f/torch-2.9.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:01cff95ecd9a212ea2f141db28acccdceb6a4c54f64e6c51091146f5e2a772c6", size = 899738273 }, - { url = "https://files.pythonhosted.org/packages/66/11/c1c5ba6691cda6279087c35bd626536e4fd29521fe740abf5008377a9a02/torch-2.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:4582b162f541651f0cb184d3e291c05c2f556c7117c64a9873e2ee158d40062b", size = 109280887 }, - { url = "https://files.pythonhosted.org/packages/dd/5f/b85bd8c05312d71de9402bf5868d217c38827cfd09d8f8514e5be128a52b/torch-2.9.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:33f58e9a102a91259af289d50525c30323b5c9ae1d31322b6447c0814da68695", size = 74478983 }, - { url = "https://files.pythonhosted.org/packages/c2/1c/90eb13833cdf4969ea9707586d7b57095c3b6e2b223a7256bf111689bcb8/torch-2.9.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c30a17fc83eeab346913e237c64b15b5ba6407fff812f6c541e322e19bc9ea0e", size = 104111330 }, - { url = "https://files.pythonhosted.org/packages/0e/21/2254c54b8d523592c25ef4434769aa23e29b1e6bf5f4c0ad9e27bf442927/torch-2.9.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:8f25033b8667b57857dfd01458fbf2a9e6a6df1f8def23aef0dc46292f6aa642", size = 899750243 }, - { url = "https://files.pythonhosted.org/packages/b7/a5/5cb94fa4fd1e78223455c23c200f30f6dc10c6d4a2bcc8f6e7f2a2588370/torch-2.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:d037f1b4ffd25013be4a7bf3651a0a910c68554956c7b2c92ebe87c76475dece", size = 109284513 }, - { url = "https://files.pythonhosted.org/packages/66/e8/fc414d8656250ee46120b44836ffbb3266343db424b3e18ca79ebbf69d4f/torch-2.9.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e4e5b5cba837a2a8d1a497ba9a58dae46fa392593eaa13b871c42f71847503a5", size = 74830362 }, - { url = "https://files.pythonhosted.org/packages/ed/5f/9474c98fc5ae0cd04b9466035428cd360e6611a86b8352a0fc2fa504acdc/torch-2.9.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:64693568f5dc4dbd5f880a478b1cea0201cc6b510d91d1bc54fea86ac5d1a637", size = 104144940 }, - { url = "https://files.pythonhosted.org/packages/2d/5a/8e0c1cf57830172c109d4bd6be2708cabeaf550983eee7029291322447a0/torch-2.9.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:f8ed31ddd7d10bfb3fbe0b9fe01b1243577f13d75e6f4a0839a283915ce3791e", size = 899744054 }, - { url = "https://files.pythonhosted.org/packages/6d/28/82c28b30fcb4b7c9cdd995763d18bbb830d6521356712faebbad92ffa61d/torch-2.9.0-cp313-cp313t-win_amd64.whl", hash = "sha256:eff527d4e4846e6f70d2afd8058b73825761203d66576a7e04ea2ecfebcb4ab8", size = 109517546 }, - { url = "https://files.pythonhosted.org/packages/ff/c3/a91f96ec74347fa5fd24453fa514bc61c61ecc79196fa760b012a1873d96/torch-2.9.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:f8877779cf56d1ce431a7636703bdb13307f5960bb1af49716d8b179225e0e6a", size = 74480732 }, - { url = "https://files.pythonhosted.org/packages/5c/73/9f70af34b334a7e0ef496ceec96b7ec767bd778ea35385ce6f77557534d1/torch-2.9.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7e614fae699838038d888729f82b687c03413c5989ce2a9481f9a7e7a396e0bb", size = 74433037 }, - { url = "https://files.pythonhosted.org/packages/b7/84/37cf88625901934c97109e583ecc21777d21c6f54cda97a7e5bbad1ee2f2/torch-2.9.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:dfb5b8cd310ba3436c7e14e8b7833ef658cf3045e50d2bdaed23c8fc517065eb", size = 104116482 }, - { url = "https://files.pythonhosted.org/packages/56/8e/ca8b17866943a8d4f4664d402ea84210aa274588b4c5d89918f5caa24eec/torch-2.9.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:b3d29524993a478e46f5d598b249cd824b7ed98d7fba538bd9c4cde6c803948f", size = 899746916 }, - { url = "https://files.pythonhosted.org/packages/43/65/3b17c0fbbdab6501c5b320a52a648628d0d44e7379f64e27d9eef701b6bf/torch-2.9.0-cp314-cp314-win_amd64.whl", hash = "sha256:71c7578984f5ec0eb645eb4816ac8435fcf3e3e2ae1901bcd2f519a9cafb5125", size = 109275151 }, - { url = "https://files.pythonhosted.org/packages/83/36/74f8c051f785500396e42f93542422422dfd874a174f21f8d955d36e5d64/torch-2.9.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:71d9309aee457bbe0b164bce2111cd911c4ed4e847e65d5077dbbcd3aba6befc", size = 74823353 }, - { url = "https://files.pythonhosted.org/packages/62/51/dc3b4e2f9ba98ae27238f0153ca098bf9340b2dafcc67fde645d496dfc2a/torch-2.9.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c08fb654d783899e204a32cca758a7ce8a45b2d78eeb89517cc937088316f78e", size = 104140340 }, - { url = "https://files.pythonhosted.org/packages/c0/8d/b00657f8141ac16af7bb6cda2e67de18499a3263b78d516b9a93fcbc98e3/torch-2.9.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ec8feb0099b2daa5728fbc7abb0b05730fd97e0f359ff8bda09865aaa7bd7d4b", size = 899731750 }, - { url = "https://files.pythonhosted.org/packages/fc/29/bd361e0cbb2c79ce6450f42643aaf6919956f89923a50571b0ebfe92d142/torch-2.9.0-cp314-cp314t-win_amd64.whl", hash = "sha256:695ba920f234ad4170c9c50e28d56c848432f8f530e6bc7f88fcb15ddf338e75", size = 109503850 }, + { url = "https://files.pythonhosted.org/packages/d1/d3/3985739f3b8e88675127bf70f82b3a48ae083e39cda56305dbd90398fec0/torch-2.9.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e5f7af1dc4c0a7c4a260c2534f41ddaf209714f7c89145e644c44712fbd6b642", size = 104107898, upload-time = "2025-10-15T15:46:20.883Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4b/f4bb2e6c25d0272f798cd6d7a04ed315da76cec68c602d87040c7847287f/torch-2.9.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:01cff95ecd9a212ea2f141db28acccdceb6a4c54f64e6c51091146f5e2a772c6", size = 899738273, upload-time = "2025-10-15T15:50:04.188Z" }, + { url = "https://files.pythonhosted.org/packages/66/11/c1c5ba6691cda6279087c35bd626536e4fd29521fe740abf5008377a9a02/torch-2.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:4582b162f541651f0cb184d3e291c05c2f556c7117c64a9873e2ee158d40062b", size = 109280887, upload-time = "2025-10-15T15:46:26.228Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5f/b85bd8c05312d71de9402bf5868d217c38827cfd09d8f8514e5be128a52b/torch-2.9.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:33f58e9a102a91259af289d50525c30323b5c9ae1d31322b6447c0814da68695", size = 74478983, upload-time = "2025-10-15T15:46:39.406Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1c/90eb13833cdf4969ea9707586d7b57095c3b6e2b223a7256bf111689bcb8/torch-2.9.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c30a17fc83eeab346913e237c64b15b5ba6407fff812f6c541e322e19bc9ea0e", size = 104111330, upload-time = "2025-10-15T15:46:35.238Z" }, + { url = "https://files.pythonhosted.org/packages/0e/21/2254c54b8d523592c25ef4434769aa23e29b1e6bf5f4c0ad9e27bf442927/torch-2.9.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:8f25033b8667b57857dfd01458fbf2a9e6a6df1f8def23aef0dc46292f6aa642", size = 899750243, upload-time = "2025-10-15T15:48:57.459Z" }, + { url = "https://files.pythonhosted.org/packages/b7/a5/5cb94fa4fd1e78223455c23c200f30f6dc10c6d4a2bcc8f6e7f2a2588370/torch-2.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:d037f1b4ffd25013be4a7bf3651a0a910c68554956c7b2c92ebe87c76475dece", size = 109284513, upload-time = "2025-10-15T15:46:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/66/e8/fc414d8656250ee46120b44836ffbb3266343db424b3e18ca79ebbf69d4f/torch-2.9.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e4e5b5cba837a2a8d1a497ba9a58dae46fa392593eaa13b871c42f71847503a5", size = 74830362, upload-time = "2025-10-15T15:46:48.983Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5f/9474c98fc5ae0cd04b9466035428cd360e6611a86b8352a0fc2fa504acdc/torch-2.9.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:64693568f5dc4dbd5f880a478b1cea0201cc6b510d91d1bc54fea86ac5d1a637", size = 104144940, upload-time = "2025-10-15T15:47:29.076Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5a/8e0c1cf57830172c109d4bd6be2708cabeaf550983eee7029291322447a0/torch-2.9.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:f8ed31ddd7d10bfb3fbe0b9fe01b1243577f13d75e6f4a0839a283915ce3791e", size = 899744054, upload-time = "2025-10-15T15:48:29.864Z" }, + { url = "https://files.pythonhosted.org/packages/6d/28/82c28b30fcb4b7c9cdd995763d18bbb830d6521356712faebbad92ffa61d/torch-2.9.0-cp313-cp313t-win_amd64.whl", hash = "sha256:eff527d4e4846e6f70d2afd8058b73825761203d66576a7e04ea2ecfebcb4ab8", size = 109517546, upload-time = "2025-10-15T15:47:33.395Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a91f96ec74347fa5fd24453fa514bc61c61ecc79196fa760b012a1873d96/torch-2.9.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:f8877779cf56d1ce431a7636703bdb13307f5960bb1af49716d8b179225e0e6a", size = 74480732, upload-time = "2025-10-15T15:47:38.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/73/9f70af34b334a7e0ef496ceec96b7ec767bd778ea35385ce6f77557534d1/torch-2.9.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7e614fae699838038d888729f82b687c03413c5989ce2a9481f9a7e7a396e0bb", size = 74433037, upload-time = "2025-10-15T15:47:41.894Z" }, + { url = "https://files.pythonhosted.org/packages/b7/84/37cf88625901934c97109e583ecc21777d21c6f54cda97a7e5bbad1ee2f2/torch-2.9.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:dfb5b8cd310ba3436c7e14e8b7833ef658cf3045e50d2bdaed23c8fc517065eb", size = 104116482, upload-time = "2025-10-15T15:47:46.266Z" }, + { url = "https://files.pythonhosted.org/packages/56/8e/ca8b17866943a8d4f4664d402ea84210aa274588b4c5d89918f5caa24eec/torch-2.9.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:b3d29524993a478e46f5d598b249cd824b7ed98d7fba538bd9c4cde6c803948f", size = 899746916, upload-time = "2025-10-15T15:50:40.294Z" }, + { url = "https://files.pythonhosted.org/packages/43/65/3b17c0fbbdab6501c5b320a52a648628d0d44e7379f64e27d9eef701b6bf/torch-2.9.0-cp314-cp314-win_amd64.whl", hash = "sha256:71c7578984f5ec0eb645eb4816ac8435fcf3e3e2ae1901bcd2f519a9cafb5125", size = 109275151, upload-time = "2025-10-15T15:49:20.715Z" }, + { url = "https://files.pythonhosted.org/packages/83/36/74f8c051f785500396e42f93542422422dfd874a174f21f8d955d36e5d64/torch-2.9.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:71d9309aee457bbe0b164bce2111cd911c4ed4e847e65d5077dbbcd3aba6befc", size = 74823353, upload-time = "2025-10-15T15:49:16.59Z" }, + { url = "https://files.pythonhosted.org/packages/62/51/dc3b4e2f9ba98ae27238f0153ca098bf9340b2dafcc67fde645d496dfc2a/torch-2.9.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c08fb654d783899e204a32cca758a7ce8a45b2d78eeb89517cc937088316f78e", size = 104140340, upload-time = "2025-10-15T15:50:19.67Z" }, + { url = "https://files.pythonhosted.org/packages/c0/8d/b00657f8141ac16af7bb6cda2e67de18499a3263b78d516b9a93fcbc98e3/torch-2.9.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ec8feb0099b2daa5728fbc7abb0b05730fd97e0f359ff8bda09865aaa7bd7d4b", size = 899731750, upload-time = "2025-10-15T15:49:36.673Z" }, + { url = "https://files.pythonhosted.org/packages/fc/29/bd361e0cbb2c79ce6450f42643aaf6919956f89923a50571b0ebfe92d142/torch-2.9.0-cp314-cp314t-win_amd64.whl", hash = "sha256:695ba920f234ad4170c9c50e28d56c848432f8f530e6bc7f88fcb15ddf338e75", size = 109503850, upload-time = "2025-10-15T15:50:24.118Z" }, ] [[package]] @@ -1232,6 +1217,7 @@ dependencies = [ { name = "scikit-learn" }, { name = "sqlalchemy" }, { name = "torch" }, + { name = "urllib3" }, ] [package.dev-dependencies] @@ -1255,6 +1241,7 @@ requires-dist = [ { name = "scikit-learn", specifier = ">=1.7.2" }, { name = "sqlalchemy", specifier = "==1.4.52" }, { name = "torch", specifier = ">=2.9.0" }, + { name = "urllib3", specifier = ">=2.6.0" }, ] [package.metadata.requires-dev] @@ -1272,16 +1259,11 @@ name = "triton" version = "3.5.0" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/9b/30988039e1e84df7554fba24e6a734d2d0e847af33cabdf9b532b3c51456/triton-3.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da21fccceafc163e3a5e857abe34351ef76345af06cabf9637a914742671f0b", size = 159946647 }, - { url = "https://files.pythonhosted.org/packages/f5/3a/e991574f3102147b642e49637e0281e9bb7c4ba254edb2bab78247c85e01/triton-3.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9e71db82261c4ffa3921cd050cd5faa18322d2d405c30eb56084afaff3b0833", size = 170476535 }, - { url = "https://files.pythonhosted.org/packages/cd/85/e37f1197acb04c8f3d83851d23d5d6ed5060ef74580668b112e23fdfa203/triton-3.5.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:188da5b81fa2f8322c27fec1627703eac24cb9bb7ab0dfbe9925973bc1b070d3", size = 159958970 }, - { url = "https://files.pythonhosted.org/packages/6c/29/10728de8a6e932e517c10773486b8e99f85d1b1d9dd87d9a9616e1fef4a1/triton-3.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e6bb9aa5519c084a333acdba443789e50012a4b851cd486c54f0b8dc2a8d3a12", size = 170487289 }, - { url = "https://files.pythonhosted.org/packages/b8/1d/38258f05010ac17a7b058c022911c9cae6526e149b7397134a048cf5a6c2/triton-3.5.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03127d9b33aaf979c856676b394bc059ec1d68cb6da68ae03f62dd8ad77a04ae", size = 160073012 }, - { url = "https://files.pythonhosted.org/packages/5c/38/db80e48b9220c9bce872b0f616ad0446cdf554a40b85c7865cbca99ab3c2/triton-3.5.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c83f2343e1a220a716c7b3ab9fccfcbe3ad4020d189549200e2d2e8d5868bed9", size = 170577179 }, - { url = "https://files.pythonhosted.org/packages/91/fe/8f5771d00227f4eb1ee034f218ed427102b989366d2275fe3b3c105a3921/triton-3.5.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468936651d383f4a6d10068d34a627505e13af55be5d002b9f27b987e7a5f0ac", size = 159957460 }, - { url = "https://files.pythonhosted.org/packages/ff/60/1810655d1d856c9a4fcc90ee8966d85f552d98c53a6589f95ab2cbe27bb8/triton-3.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da0fa67ccd76c3dcfb0bffe1b1c57c685136a6bd33d141c24d9655d4185b1289", size = 170487949 }, - { url = "https://files.pythonhosted.org/packages/78/59/99edd103958fe6e42b50b9ad8ce4f223ddf4ccf475259cf7d2b53381dc6c/triton-3.5.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7ceef21410229ac23173a28eee5cfc0e37c1dfdb8b4bc11ecda2e3ecec7c686", size = 160075629 }, - { url = "https://files.pythonhosted.org/packages/fb/b7/1dec8433ac604c061173d0589d99217fe7bf90a70bdc375e745d044b8aad/triton-3.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:317fe477ea8fd4524a6a8c499fb0a36984a56d0b75bf9c9cb6133a1c56d5a6e7", size = 170580176 }, + { url = "https://files.pythonhosted.org/packages/f5/3a/e991574f3102147b642e49637e0281e9bb7c4ba254edb2bab78247c85e01/triton-3.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9e71db82261c4ffa3921cd050cd5faa18322d2d405c30eb56084afaff3b0833", size = 170476535, upload-time = "2025-10-13T16:38:05.18Z" }, + { url = "https://files.pythonhosted.org/packages/6c/29/10728de8a6e932e517c10773486b8e99f85d1b1d9dd87d9a9616e1fef4a1/triton-3.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e6bb9aa5519c084a333acdba443789e50012a4b851cd486c54f0b8dc2a8d3a12", size = 170487289, upload-time = "2025-10-13T16:38:11.662Z" }, + { url = "https://files.pythonhosted.org/packages/5c/38/db80e48b9220c9bce872b0f616ad0446cdf554a40b85c7865cbca99ab3c2/triton-3.5.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c83f2343e1a220a716c7b3ab9fccfcbe3ad4020d189549200e2d2e8d5868bed9", size = 170577179, upload-time = "2025-10-13T16:38:17.865Z" }, + { url = "https://files.pythonhosted.org/packages/ff/60/1810655d1d856c9a4fcc90ee8966d85f552d98c53a6589f95ab2cbe27bb8/triton-3.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da0fa67ccd76c3dcfb0bffe1b1c57c685136a6bd33d141c24d9655d4185b1289", size = 170487949, upload-time = "2025-10-13T16:38:24.881Z" }, + { url = "https://files.pythonhosted.org/packages/fb/b7/1dec8433ac604c061173d0589d99217fe7bf90a70bdc375e745d044b8aad/triton-3.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:317fe477ea8fd4524a6a8c499fb0a36984a56d0b75bf9c9cb6133a1c56d5a6e7", size = 170580176, upload-time = "2025-10-13T16:38:31.14Z" }, ] [[package]] @@ -1331,11 +1313,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, ] [[package]] From 98abe2741ddc3eb87eb49708641046b4625573c2 Mon Sep 17 00:00:00 2001 From: Omkar Kulkarni Date: Thu, 5 Mar 2026 14:03:20 -0800 Subject: [PATCH 21/21] fix(sportsbook): airflow creds hidden --- model_state.pt | Bin 0 -> 72395 bytes preproc.joblib | Bin 0 -> 4983 bytes src/sportsbook_webscraper_pipeline/README.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 model_state.pt create mode 100644 preproc.joblib diff --git a/model_state.pt b/model_state.pt new file mode 100644 index 0000000000000000000000000000000000000000..066bf07bce74e4b62d65587d2c4057eff9b51113 GIT binary patch literal 72395 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