From 5fef607f178bdf58d58791867ef290954b2a982f Mon Sep 17 00:00:00 2001 From: Helmut Hoffer von Ankershoffen Date: Wed, 19 Nov 2025 20:54:35 +0100 Subject: [PATCH 1/4] feat(platform,application): configureable pipeline --- src/aignostics/application/_cli.py | 54 +++++++- .../_gui/_page_application_describe.py | 94 +++++++++++++- src/aignostics/platform/_sdk_metadata.py | 63 ++++++++- tests/aignostics/platform/e2e_test.py | 14 ++ .../aignostics/platform/sdk_metadata_test.py | 121 ++++++++++++++++++ tests/constants_test.py | 12 ++ 6 files changed, 355 insertions(+), 3 deletions(-) diff --git a/src/aignostics/application/_cli.py b/src/aignostics/application/_cli.py index e2d6bef8..02bf3be6 100644 --- a/src/aignostics/application/_cli.py +++ b/src/aignostics/application/_cli.py @@ -366,6 +366,22 @@ def run_execute( # noqa: PLR0913, PLR0917 validate_only: Annotated[ bool, typer.Option(help="If True, cancel the run post validation, before analysis.") ] = False, + gpu_type: Annotated[ + str, + typer.Option(help="GPU type to use for processing (L4 or A100)."), + ] = "A100", + gpu_provisioning_mode: Annotated[ + str, + typer.Option(help="GPU provisioning mode (SPOT or ON_DEMAND)."), + ] = "ON_DEMAND", + max_gpus_per_slide: Annotated[ + int, + typer.Option(help="Maximum number of GPUs to allocate per slide (1-8).", min=1, max=8), + ] = 1, + cpu_provisioning_mode: Annotated[ + str, + typer.Option(help="CPU provisioning mode (SPOT or ON_DEMAND)."), + ] = "ON_DEMAND", ) -> None: """Prepare metadata, upload data to platform, and submit an application run, then incrementally download results. @@ -401,10 +417,15 @@ def run_execute( # noqa: PLR0913, PLR0917 metadata_csv_file=metadata_csv_file, application_version=application_version, note=note, + tags=None, due_date=due_date, deadline=deadline, onboard_to_aignostics_portal=onboard_to_aignostics_portal, validate_only=validate_only, + gpu_type=gpu_type, + gpu_provisioning_mode=gpu_provisioning_mode, + max_gpus_per_slide=max_gpus_per_slide, + cpu_provisioning_mode=cpu_provisioning_mode, ) result_download( run_id=run_id, @@ -652,6 +673,22 @@ def run_submit( # noqa: PLR0913, PLR0917 validate_only: Annotated[ bool, typer.Option(help="If True, cancel the run post validation, before analysis.") ] = False, + gpu_type: Annotated[ + str, + typer.Option(help="GPU type to use for processing (L4 or A100)."), + ] = "A100", + gpu_provisioning_mode: Annotated[ + str, + typer.Option(help="GPU provisioning mode (SPOT or ON_DEMAND)."), + ] = "ON_DEMAND", + max_gpus_per_slide: Annotated[ + int, + typer.Option(help="Maximum number of GPUs to allocate per slide (1-8).", min=1, max=8), + ] = 1, + cpu_provisioning_mode: Annotated[ + str, + typer.Option(help="CPU provisioning mode (SPOT or ON_DEMAND)."), + ] = "ON_DEMAND", ) -> str: """Submit run by referencing the metadata CSV file. @@ -701,11 +738,26 @@ def run_submit( # noqa: PLR0913, PLR0917 app_version.version_number, metadata_dict, ) + + # Build custom metadata with pipeline configuration + custom_metadata = { + "pipeline": { + "gpu": { + "gpu_type": gpu_type, + "provisioning_mode": gpu_provisioning_mode, + "max_gpus_per_slide": max_gpus_per_slide, + }, + "cpu": { + "provisioning_mode": cpu_provisioning_mode, + }, + }, + } + application_run = Service().application_run_submit_from_metadata( application_id=application_id, metadata=metadata_dict, application_version=application_version, - custom_metadata=None, # TODO(Helmut): Add support for custom metadata + custom_metadata=custom_metadata, note=note, tags={tag.strip() for tag in tags.split(",") if tag.strip()} if tags else None, due_date=due_date, diff --git a/src/aignostics/application/_gui/_page_application_describe.py b/src/aignostics/application/_gui/_page_application_describe.py index 825b0cdc..dcf8f127 100644 --- a/src/aignostics/application/_gui/_page_application_describe.py +++ b/src/aignostics/application/_gui/_page_application_describe.py @@ -50,6 +50,10 @@ class SubmitForm: deadline: str = (datetime.now().astimezone() + timedelta(hours=24)).strftime("%Y-%m-%d %H:%M") validate_only: bool = False onboard_to_aignostics_portal: bool = False + gpu_type: str = "A100" + gpu_provisioning_mode: str = "ON_DEMAND" + max_gpus_per_slide: int = 1 + cpu_provisioning_mode: str = "ON_DEMAND" submit_form = SubmitForm() @@ -702,11 +706,25 @@ def _submit() -> None: """Submit the application run.""" ui.notify("Submitting application run ...", type="info") try: + # Build custom metadata with pipeline configuration + custom_metadata = { + "pipeline": { + "gpu": { + "gpu_type": submit_form.gpu_type, + "provisioning_mode": submit_form.gpu_provisioning_mode, + "max_gpus_per_slide": submit_form.max_gpus_per_slide, + }, + "cpu": { + "provisioning_mode": submit_form.cpu_provisioning_mode, + }, + }, + } + run = service.application_run_submit_from_metadata( application_id=str(submit_form.application_id), metadata=submit_form.metadata or [], application_version=str(submit_form.application_version), - custom_metadata=None, # TODO(Helmut): Allow user to edit custom metadata + custom_metadata=custom_metadata, note=submit_form.note, tags=set(submit_form.tags) if submit_form.tags else None, due_date=datetime.strptime(submit_form.due_date, "%Y-%m-%d %H:%M") @@ -816,6 +834,80 @@ def _update_upload_progress() -> None: break _upload_ui.refresh(submit_form.metadata) + with ui.step("Pipeline"): + user_info: UserInfo | None = app.storage.tab.get("user_info", None) + can_configure_pipeline = ( + user_info + and user_info.organization + and user_info.organization.name + and user_info.organization.name.lower() in {"aignostics", "pre-alpha-org", "lmu", "charite"} + ) + + if can_configure_pipeline: + with ui.column(align_items="start").classes("w-full"): + ui.label("GPU Configuration").classes("text-h6 mb-0 pb-0") + ui.label( + "Configure GPU resources for processing your whole slide images. " + "These settings control the type and provisioning mode of GPUs used during AI analysis." + ).classes("text-sm mt-0 pt-0 mb-4") + + with ui.row().classes("w-full gap-4"): + ui.select( + label="GPU Type", + options={"L4": "L4", "A100": "A100"}, + value=submit_form.gpu_type, + ).bind_value(submit_form, "gpu_type").mark("SELECT_GPU_TYPE").classes("w-1/3") + + ui.number( + label="Max GPUs per Slide", + value=submit_form.max_gpus_per_slide, + min=1, + max=8, + step=1, + ).bind_value(submit_form, "max_gpus_per_slide").mark("NUMBER_MAX_GPUS_PER_SLIDE").classes( + "w-1/3" + ) + + ui.select( + label="GPU Provisioning Mode", + options={ + "SPOT": "Spot nodes (lower cost, better availability, might be preempted and retried)", + "ON_DEMAND": ( + "On demand nodes (higher cost, limited availability, processing might be delayed)" + ), + }, + value=submit_form.gpu_provisioning_mode, + ).bind_value(submit_form, "gpu_provisioning_mode").mark("SELECT_GPU_PROVISIONING_MODE").classes( + "w-1/3" + ) + + ui.separator().classes("my-4") + + ui.label("CPU Configuration").classes("text-h6 mb-0 pb-0") + ui.label("Configure CPU resources for algorithms that do not require GPU acceleration.").classes( + "text-sm mt-0 pt-0 mb-4" + ) + + with ui.row().classes("w-full gap-4"): + ui.select( + label="CPU Provisioning Mode", + options={ + "SPOT": "Spot nodes (lower cost, better availability, might be preempted and retried)", + "ON_DEMAND": "On demand nodes (higher cost, limited availability, might be delayed)", + }, + value=submit_form.cpu_provisioning_mode, + ).bind_value(submit_form, "cpu_provisioning_mode").mark("SELECT_CPU_PROVISIONING_MODE").classes( + "w-1/2" + ) + else: + ui.label( + "Pipeline configuration is not available for your organization. Default settings will be used." + ).classes("text-body1") + + with ui.stepper_navigation(): + ui.button("Next", on_click=stepper.next).mark("BUTTON_PIPELINE_NEXT") + ui.button("Back", on_click=stepper.previous).props("flat") + with ui.step("Submit"): _upload_ui([]) ui.timer(0.1, callback=_update_upload_progress) diff --git a/src/aignostics/platform/_sdk_metadata.py b/src/aignostics/platform/_sdk_metadata.py index 99a78f40..2a2ff2ef 100644 --- a/src/aignostics/platform/_sdk_metadata.py +++ b/src/aignostics/platform/_sdk_metadata.py @@ -7,16 +7,76 @@ import os import sys from datetime import UTC, datetime +from enum import StrEnum from typing import Any, Literal from loguru import logger -from pydantic import BaseModel, Field, ValidationError +from pydantic import BaseModel, Field, PositiveInt, ValidationError from aignostics.utils import user_agent SDK_METADATA_SCHEMA_VERSION = "0.0.4" ITEM_SDK_METADATA_SCHEMA_VERSION = "0.0.3" +# Pipeline orchestration defaults +DEFAULT_GPU_TYPE = "A100" +DEFAULT_MAX_GPUS_PER_SLIDE = 1 +DEFAULT_GPU_PROVISIONING_MODE = "ON_DEMAND" +DEFAULT_CPU_PROVISIONING_MODE = "ON_DEMAND" + + +class GPUType(StrEnum): + """Type of GPU to use for processing.""" + + L4 = "L4" + A100 = "A100" + + +class ProvisioningMode(StrEnum): + """Provisioning mode for resources.""" + + SPOT = "SPOT" + ON_DEMAND = "ON_DEMAND" + + +class CPUConfig(BaseModel): + """Configuration for CPU resources.""" + + provisioning_mode: ProvisioningMode = Field( + default_factory=lambda: ProvisioningMode(DEFAULT_CPU_PROVISIONING_MODE), + description="The provisioning mode for CPU resources (SPOT or ON_DEMAND)", + ) + + +class GPUConfig(BaseModel): + """Configuration for GPU resources.""" + + gpu_type: GPUType = Field( + default_factory=lambda: GPUType(DEFAULT_GPU_TYPE), + description="The type of GPU to use (L4 or A100)", + ) + provisioning_mode: ProvisioningMode = Field( + default_factory=lambda: ProvisioningMode(DEFAULT_GPU_PROVISIONING_MODE), + description="The provisioning mode for GPU resources (SPOT or ON_DEMAND)", + ) + max_gpus_per_slide: PositiveInt = Field( + default=DEFAULT_MAX_GPUS_PER_SLIDE, + description="The maximum number of GPUs to allocate per slide", + ) + + +class PipelineConfig(BaseModel): + """Pipeline configuration for dynamic orchestration.""" + + gpu: GPUConfig = Field( + default_factory=GPUConfig, + description="GPU resource configuration", + ) + cpu: CPUConfig = Field( + default_factory=CPUConfig, + description="CPU resource configuration", + ) + class SubmissionMetadata(BaseModel): """Metadata about how the SDK was invoked.""" @@ -121,6 +181,7 @@ class RunSdkMetadata(BaseModel): note: str | None = Field(None, description="Optional user note for the run") workflow: WorkflowMetadata | None = Field(None, description="Workflow control flags") scheduling: SchedulingMetadata | None = Field(None, description="Scheduling information") + pipeline: PipelineConfig | None = Field(None, description="Pipeline orchestration configuration") model_config = {"extra": "forbid"} # Reject unknown fields diff --git a/tests/aignostics/platform/e2e_test.py b/tests/aignostics/platform/e2e_test.py index 7096cc33..4e5a8222 100644 --- a/tests/aignostics/platform/e2e_test.py +++ b/tests/aignostics/platform/e2e_test.py @@ -28,6 +28,10 @@ from tests.constants_test import ( HETA_APPLICATION_ID, HETA_APPLICATION_VERSION, + PIPELINE_CPU_PROVISIONING_MODE, + PIPELINE_GPU_PROVISIONING_MODE, + PIPELINE_GPU_TYPE, + PIPELINE_MAX_GPUS_PER_SLIDE, SPOT_0_CRC32C, SPOT_0_GS_URL, SPOT_0_HEIGHT, @@ -209,6 +213,16 @@ def _submit_and_validate( # noqa: PLR0913, PLR0917 "due_date": (datetime.now(tz=UTC) + timedelta(seconds=due_date_seconds)).isoformat(), "deadline": deadline.isoformat(), }, + "pipeline": { + "gpu": { + "gpu_type": PIPELINE_GPU_TYPE, + "provisioning_mode": PIPELINE_GPU_PROVISIONING_MODE, + "max_gpus_per_slide": PIPELINE_MAX_GPUS_PER_SLIDE, + }, + "cpu": { + "provisioning_mode": PIPELINE_CPU_PROVISIONING_MODE, + }, + }, } }, ) diff --git a/tests/aignostics/platform/sdk_metadata_test.py b/tests/aignostics/platform/sdk_metadata_test.py index b01038ec..336585d3 100644 --- a/tests/aignostics/platform/sdk_metadata_test.py +++ b/tests/aignostics/platform/sdk_metadata_test.py @@ -892,3 +892,124 @@ def test_validate_item_metadata_tags_non_string() -> None: with pytest.raises(ValidationError): validate_item_sdk_metadata(metadata) + + +class TestPipelineConfiguration: + """Test cases for pipeline configuration models.""" + + @pytest.mark.unit + @staticmethod + def test_pipeline_config_defaults() -> None: + """Test that pipeline configuration uses correct defaults.""" + from aignostics.platform._sdk_metadata import ( + DEFAULT_CPU_PROVISIONING_MODE, + DEFAULT_GPU_PROVISIONING_MODE, + DEFAULT_GPU_TYPE, + DEFAULT_MAX_GPUS_PER_SLIDE, + PipelineConfig, + ) + + config = PipelineConfig() + + assert config.gpu.gpu_type.value == DEFAULT_GPU_TYPE + assert config.gpu.provisioning_mode.value == DEFAULT_GPU_PROVISIONING_MODE + assert config.gpu.max_gpus_per_slide == DEFAULT_MAX_GPUS_PER_SLIDE + assert config.cpu.provisioning_mode.value == DEFAULT_CPU_PROVISIONING_MODE + + @pytest.mark.unit + @staticmethod + def test_pipeline_config_custom_values() -> None: + """Test pipeline configuration with custom values.""" + from aignostics.platform._sdk_metadata import GPUType, PipelineConfig, ProvisioningMode + + config = PipelineConfig( + gpu={ + "gpu_type": GPUType.L4, + "provisioning_mode": ProvisioningMode.SPOT, + "max_gpus_per_slide": 4, + }, + cpu={"provisioning_mode": ProvisioningMode.SPOT}, + ) + + assert config.gpu.gpu_type == GPUType.L4 + assert config.gpu.provisioning_mode == ProvisioningMode.SPOT + assert config.gpu.max_gpus_per_slide == 4 + assert config.cpu.provisioning_mode == ProvisioningMode.SPOT + + @pytest.mark.unit + @staticmethod + def test_gpu_type_enum() -> None: + """Test GPUType enum values.""" + from aignostics.platform._sdk_metadata import GPUType + + assert GPUType.L4.value == "L4" + assert GPUType.A100.value == "A100" + assert len(GPUType) == 2 + + @pytest.mark.unit + @staticmethod + def test_provisioning_mode_enum() -> None: + """Test ProvisioningMode enum values.""" + from aignostics.platform._sdk_metadata import ProvisioningMode + + assert ProvisioningMode.SPOT.value == "SPOT" + assert ProvisioningMode.ON_DEMAND.value == "ON_DEMAND" + assert len(ProvisioningMode) == 2 + + @pytest.mark.unit + @staticmethod + def test_metadata_with_pipeline_config() -> None: + """Test that metadata validates with pipeline configuration.""" + from aignostics.platform._sdk_metadata import GPUType, ProvisioningMode + + metadata = { + "schema_version": SDK_METADATA_SCHEMA_VERSION, + "created_at": "2025-10-19T12:00:00+00:00", + "updated_at": "2025-10-19T12:00:00+00:00", + "submission": { + "date": "2025-10-19T12:00:00+00:00", + "interface": "script", + "initiator": "user", + }, + "user_agent": "aignostics-sdk/1.0.0", + "pipeline": { + "gpu": { + "gpu_type": GPUType.L4.value, + "provisioning_mode": ProvisioningMode.SPOT.value, + "max_gpus_per_slide": 2, + }, + "cpu": {"provisioning_mode": ProvisioningMode.ON_DEMAND.value}, + }, + } + + assert validate_run_sdk_metadata(metadata) is True + + @pytest.mark.unit + @staticmethod + def test_metadata_without_pipeline_config() -> None: + """Test that metadata validates without pipeline configuration (optional field).""" + metadata = { + "schema_version": SDK_METADATA_SCHEMA_VERSION, + "created_at": "2025-10-19T12:00:00+00:00", + "updated_at": "2025-10-19T12:00:00+00:00", + "submission": { + "date": "2025-10-19T12:00:00+00:00", + "interface": "script", + "initiator": "user", + }, + "user_agent": "aignostics-sdk/1.0.0", + } + + assert validate_run_sdk_metadata(metadata) is True + + @pytest.mark.unit + @staticmethod + def test_gpu_config_invalid_max_gpus() -> None: + """Test that invalid max_gpus_per_slide value is rejected.""" + from aignostics.platform._sdk_metadata import GPUConfig + + with pytest.raises(ValidationError): + GPUConfig(max_gpus_per_slide=0) # Must be positive + + with pytest.raises(ValidationError): + GPUConfig(max_gpus_per_slide=-1) # Must be positive diff --git a/tests/constants_test.py b/tests/constants_test.py index 3176f681..b7dd2696 100644 --- a/tests/constants_test.py +++ b/tests/constants_test.py @@ -47,6 +47,11 @@ HETA_APPLICATION_VERSION = "1.0.0-sl.4" TEST_APPLICATION_VERSION_USE_LATEST_FALLBACK_SKIP = False + PIPELINE_GPU_TYPE = "A100" + PIPELINE_GPU_PROVISIONING_MODE = "ON_DEMAND" + PIPELINE_MAX_GPUS_PER_SLIDE = 1 + PIPELINE_CPU_PROVISIONING_MODE = "ON_DEMAND" + SPOT_0_EXPECTED_RESULT_FILES = [ ("tissue_qc_segmentation_map_image.tiff", 1540764, 10), ("tissue_qc_geojson_polygons.json", 160668, 10), @@ -80,6 +85,13 @@ HETA_APPLICATION_VERSION = "1.0.0-sl.4" TEST_APPLICATION_VERSION_USE_LATEST_FALLBACK_SKIP = True + # Pipeline configuration for staging environment + # Using varied settings for testing: L4 GPUs with SPOT provisioning, higher GPU count + PIPELINE_GPU_TYPE = "L4" + PIPELINE_GPU_PROVISIONING_MODE = "SPOT" + PIPELINE_MAX_GPUS_PER_SLIDE = 2 + PIPELINE_CPU_PROVISIONING_MODE = "SPOT" + SPOT_0_EXPECTED_RESULT_FILES = [ ("tissue_qc_segmentation_map_image.tiff", 1540764, 10), ("tissue_qc_geojson_polygons.json", 160668, 10), From 35b5f5672a7f2eca3fe662047b5f0dce8c9e07a8 Mon Sep 17 00:00:00 2001 From: Helmut Hoffer von Ankershoffen Date: Wed, 19 Nov 2025 21:43:50 +0100 Subject: [PATCH 2/4] test(application): reactivate test_cli_run_submit_and_describe_and_cancel_and_download_and_delete against production --- tests/aignostics/application/cli_test.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/aignostics/application/cli_test.py b/tests/aignostics/application/cli_test.py index 18191c6f..68e605cb 100644 --- a/tests/aignostics/application/cli_test.py +++ b/tests/aignostics/application/cli_test.py @@ -1,6 +1,5 @@ """Tests to verify the CLI functionality of the application module.""" -import os import platform import re from datetime import UTC, datetime, timedelta @@ -254,10 +253,6 @@ def test_cli_run_submit_fails_on_missing_url(runner: CliRunner, tmp_path: Path, assert "Invalid platform bucket URL: ''" in normalize_output(result.stdout) -@pytest.mark.skipif( - os.getenv("AIGNOSTICS_PLATFORM_ENVIRONMENT", "staging") == "production", - reason="Broken when targeting production", -) @pytest.mark.e2e @pytest.mark.long_running @pytest.mark.flaky(retries=3, delay=5) From c55a75d0c8224f80f34db0089ea8e6469b4471c4 Mon Sep 17 00:00:00 2001 From: Helmut Hoffer von Ankershoffen Date: Wed, 19 Nov 2025 21:52:03 +0100 Subject: [PATCH 3/4] chore(deps): some --- pyproject.toml | 14 ++-- uv.lock | 182 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 139 insertions(+), 57 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f0136ca5..c41bc016 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ requires-python = ">=3.11, <3.14" dependencies = [ # From Template - "fastapi[standard,all]>=0.121.1,<1", + "fastapi[standard,all]>=0.121.3,<1", "humanize>=4.14.0,<5", "nicegui[native]>=3.1.0,<3.2.0", # Regression in 3.2.0 "packaging>=25.0,<26", @@ -83,24 +83,24 @@ dependencies = [ "pydantic-settings>=2.12.0,<3", "pywin32>=310,<311 ; sys_platform == 'win32'", "pyyaml>=6.0.3,<7", - "sentry-sdk>=2.44.0,<3", + "sentry-sdk>=2.45.0,<3", "typer>=0.20.0,<1", "uptime>=3.0.1,<4", # Custom "aiopath>=0.6.11,<1", - "boto3>=1.40.61,<2", + "boto3>=1.41.0,<2", "certifi>=2025.11.12,<2026", "defusedxml>=0.7.1", "dicom-validator>=0.7.3,<1", "dicomweb-client[gcp]>=0.59.3,<1", "duckdb>=0.10.0,<=1.4.1", "fastparquet>=2024.11.0,<2025", - "google-cloud-storage>=3.5.0,<4", + "google-cloud-storage>=3.6.0,<4", "google-crc32c>=1.7.1,<2", "highdicom>=0.26.1,<1", "html-sanitizer>=2.6.0,<3", "httpx>=0.28.1,<1", - "idc-index-data==22.1.2", + "idc-index-data==22.1.5", "ijson>=3.4.0.post0,<4", "jsf>=0.11.2,<1", "jsonschema[format-nongpl]>=4.25.1,<5", @@ -131,7 +131,7 @@ jupyter = ["jupyter>=1.1.1,<2"] marimo = [ "cloudpathlib>=0.23.0,<1", "ipython>=9.7.0,<10", - "marimo>=0.17.7,<1", + "marimo>=0.17.8,<1", "matplotlib>=3.10.7,<4", "shapely>=2.1.0,<3", ] @@ -165,7 +165,7 @@ dev = [ "pytest-timeout>=2.4.0,<3", "pytest-watcher>=0.4.3,<1", "pytest-xdist[psutil]>=3.8.0,<4", - "ruff>=0.14.4,<1", + "ruff>=0.14.5,<1", "scalene>=1.5.55,<2", "sphinx>=8.2.3,<9", "sphinx-autobuild>=2025.8.25,<2026", diff --git a/uv.lock b/uv.lock index 23f1d602..440b1f48 100644 --- a/uv.lock +++ b/uv.lock @@ -155,29 +155,29 @@ dev = [ [package.metadata] requires-dist = [ { name = "aiopath", specifier = ">=0.6.11,<1" }, - { name = "boto3", specifier = ">=1.40.61,<2" }, + { name = "boto3", specifier = ">=1.41.0,<2" }, { name = "certifi", specifier = ">=2025.11.12,<2026" }, { name = "cloudpathlib", marker = "extra == 'marimo'", specifier = ">=0.23.0,<1" }, { name = "defusedxml", specifier = ">=0.7.1" }, { name = "dicom-validator", specifier = ">=0.7.3,<1" }, { name = "dicomweb-client", extras = ["gcp"], specifier = ">=0.59.3,<1" }, { name = "duckdb", specifier = ">=0.10.0,<=1.4.1" }, - { name = "fastapi", extras = ["standard", "all"], specifier = ">=0.121.1,<1" }, + { name = "fastapi", extras = ["standard", "all"], specifier = ">=0.121.3,<1" }, { name = "fastparquet", specifier = ">=2024.11.0,<2025" }, - { name = "google-cloud-storage", specifier = ">=3.5.0,<4" }, + { name = "google-cloud-storage", specifier = ">=3.6.0,<4" }, { name = "google-crc32c", specifier = ">=1.7.1,<2" }, { name = "highdicom", specifier = ">=0.26.1,<1" }, { name = "html-sanitizer", specifier = ">=2.6.0,<3" }, { name = "httpx", specifier = ">=0.28.1,<1" }, { name = "humanize", specifier = ">=4.14.0,<5" }, - { name = "idc-index-data", specifier = "==22.1.2" }, + { name = "idc-index-data", specifier = "==22.1.5" }, { name = "ijson", specifier = ">=3.4.0.post0,<4" }, { name = "ipython", marker = "extra == 'marimo'", specifier = ">=9.7.0,<10" }, { name = "jsf", specifier = ">=0.11.2,<1" }, { name = "jsonschema", extras = ["format-nongpl"], specifier = ">=4.25.1,<5" }, { name = "jupyter", marker = "extra == 'jupyter'", specifier = ">=1.1.1,<2" }, { name = "loguru", specifier = ">=0.7.3" }, - { name = "marimo", marker = "extra == 'marimo'", specifier = ">=0.17.7,<1" }, + { name = "marimo", marker = "extra == 'marimo'", specifier = ">=0.17.8,<1" }, { name = "matplotlib", marker = "extra == 'marimo'", specifier = ">=3.10.7,<4" }, { name = "nicegui", extras = ["native"], specifier = ">=3.1.0,<3.2.0" }, { name = "openslide-bin", specifier = ">=4.0.0.8,<5" }, @@ -198,7 +198,7 @@ requires-dist = [ { name = "requests-oauthlib", specifier = ">=2.0.0,<3" }, { name = "s5cmd", specifier = ">=0.3.3,<1" }, { name = "semver", specifier = ">=3.0.4,<4" }, - { name = "sentry-sdk", specifier = ">=2.44.0,<3" }, + { name = "sentry-sdk", specifier = ">=2.45.0,<3" }, { name = "shapely", specifier = ">=2.1.2,<3" }, { name = "shapely", marker = "extra == 'marimo'", specifier = ">=2.1.0,<3" }, { name = "tenacity", specifier = ">=9.1.2,<10" }, @@ -240,7 +240,7 @@ dev = [ { name = "pytest-timeout", specifier = ">=2.4.0,<3" }, { name = "pytest-watcher", specifier = ">=0.4.3,<1" }, { name = "pytest-xdist", extras = ["psutil"], specifier = ">=3.8.0,<4" }, - { name = "ruff", specifier = ">=0.14.4,<1" }, + { name = "ruff", specifier = ">=0.14.5,<1" }, { name = "scalene", specifier = ">=1.5.55,<2" }, { name = "sphinx", specifier = ">=8.2.3,<9" }, { name = "sphinx-autobuild", specifier = ">=2025.8.25,<2026" }, @@ -685,30 +685,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.40.72" +version = "1.41.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/23/a2015ca755f11cbc3080aa1fe17af3c97225388aa4a10de1a22b1ae46152/boto3-1.40.72.tar.gz", hash = "sha256:58d30dd5e046789a760db7a49f817650b8ff08d8d169e127976a61f44b7c59ad", size = 111618, upload-time = "2025-11-12T20:34:29.03Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/4f/92744c97f42e214948b9c8eff86e7e72c7ca8be788867a8aea80dc192052/boto3-1.41.0.tar.gz", hash = "sha256:73bf7f63152406404c0359c013a692e884b98a3b297160058a38f00ef19e375b", size = 111589, upload-time = "2025-11-19T20:29:10.72Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/52/ec01e9814379a049852a1eec7d0bd9afd92a3176cbc6ec54e9c70c1afe7f/boto3-1.40.72-py3-none-any.whl", hash = "sha256:1063a295712f2605d3e463e4dc1fe32fce17cf77a0f4d3bb14249d68533ee856", size = 139360, upload-time = "2025-11-12T20:34:26.995Z" }, + { url = "https://files.pythonhosted.org/packages/32/35/5f4b70f20188614a485b26e80369b9fa260a06fb0ae328153d7fc647619f/boto3-1.41.0-py3-none-any.whl", hash = "sha256:d5c454bb23655b052073c8dc6703dda5360825b72b1691822ae7709050b96390", size = 139340, upload-time = "2025-11-19T20:29:09.03Z" }, ] [[package]] name = "botocore" -version = "1.40.72" +version = "1.41.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/f3/dad4057d13a6b2c72a62b4477d81b2273be2a565e07440e76c54d72acad5/botocore-1.40.72.tar.gz", hash = "sha256:f69199ff6570695556e733fa052f2739e01e0c592c9b60f843f84c77ba3bcdf3", size = 14448732, upload-time = "2025-11-12T20:34:17.231Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/8d/af94a3a0a5dc3ff255fdbd9a4bdf8e41beb33ea61ebab92e3d8e017f9ee4/botocore-1.41.0.tar.gz", hash = "sha256:555afbf86a644bfa4ebd7bd98d717b53b792e6bbb2c49f2b308fb06964cf1655", size = 14580059, upload-time = "2025-11-19T20:28:59.605Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/25/7332e9443d5eda0ccb06270e058aed385199be1035b1a8f58c24eb7378db/botocore-1.40.72-py3-none-any.whl", hash = "sha256:4f859e5aaf871fe59aac431d6bba59cc0c8ed8a38da2a6a5345700bdc5c74b32", size = 14112257, upload-time = "2025-11-12T20:34:13.932Z" }, + { url = "https://files.pythonhosted.org/packages/1a/5c/65591ff3d30e790921635602bf53f60b89dd1f39a2cc0dad980b70dd569c/botocore-1.41.0-py3-none-any.whl", hash = "sha256:a5018d6268eee358dfc5d86e596c3062b4e225690acaf946f54c00063b804bf8", size = 14243471, upload-time = "2025-11-19T20:28:56.965Z" }, ] [[package]] @@ -1561,7 +1561,7 @@ wheels = [ [[package]] name = "fastapi" -version = "0.121.1" +version = "0.121.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -1569,9 +1569,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/a4/29e1b861fc9017488ed02ff1052feffa40940cb355ed632a8845df84ce84/fastapi-0.121.1.tar.gz", hash = "sha256:b6dba0538fd15dab6fe4d3e5493c3957d8a9e1e9257f56446b5859af66f32441", size = 342523, upload-time = "2025-11-08T21:48:14.068Z" } +sdist = { url = "https://files.pythonhosted.org/packages/80/f0/086c442c6516195786131b8ca70488c6ef11d2f2e33c9a893576b2b0d3f7/fastapi-0.121.3.tar.gz", hash = "sha256:0055bc24fe53e56a40e9e0ad1ae2baa81622c406e548e501e717634e2dfbc40b", size = 344501, upload-time = "2025-11-19T16:53:39.243Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/fd/2e6f7d706899cc08690c5f6641e2ffbfffe019e8f16ce77104caa5730910/fastapi-0.121.1-py3-none-any.whl", hash = "sha256:2c5c7028bc3a58d8f5f09aecd3fd88a000ccc0c5ad627693264181a3c33aa1fc", size = 109192, upload-time = "2025-11-08T21:48:12.458Z" }, + { url = "https://files.pythonhosted.org/packages/98/b6/4f620d7720fc0a754c8c1b7501d73777f6ba43b57c8ab99671f4d7441eb8/fastapi-0.121.3-py3-none-any.whl", hash = "sha256:0c78fc87587fcd910ca1bbf5bc8ba37b80e119b388a7206b39f0ecc95ebf53e9", size = 109801, upload-time = "2025-11-19T16:53:37.918Z" }, ] [package.optional-dependencies] @@ -1866,6 +1866,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ed/d4/90197b416cb61cefd316964fd9e7bd8324bcbafabf40eef14a9f20b81974/google_api_core-2.28.1-py3-none-any.whl", hash = "sha256:4021b0f8ceb77a6fb4de6fde4502cecab45062e66ff4f2895169e0b35bc9466c", size = 173706, upload-time = "2025-10-28T21:34:50.151Z" }, ] +[package.optional-dependencies] +grpc = [ + { name = "grpcio" }, + { name = "grpcio-status" }, +] + [[package]] name = "google-auth" version = "2.43.0" @@ -1880,6 +1886,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6f/d1/385110a9ae86d91cc14c5282c61fe9f4dc41c0b9f7d423c6ad77038c4448/google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16", size = 223114, upload-time = "2025-11-06T00:13:35.209Z" }, ] +[[package]] +name = "google-cloud-bigquery" +version = "3.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-api-core", extra = ["grpc"] }, + { name = "google-auth" }, + { name = "google-cloud-core" }, + { name = "google-resumable-media" }, + { name = "packaging" }, + { name = "python-dateutil" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/b2/a17e40afcf9487e3d17db5e36728ffe75c8d5671c46f419d7b6528a5728a/google_cloud_bigquery-3.38.0.tar.gz", hash = "sha256:8afcb7116f5eac849097a344eb8bfda78b7cfaae128e60e019193dd483873520", size = 503666, upload-time = "2025-09-17T20:33:33.47Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/3c/c8cada9ec282b29232ed9aed5a0b5cca6cf5367cb2ffa8ad0d2583d743f1/google_cloud_bigquery-3.38.0-py3-none-any.whl", hash = "sha256:e06e93ff7b245b239945ef59cb59616057598d369edac457ebf292bd61984da6", size = 259257, upload-time = "2025-09-17T20:33:31.404Z" }, +] + [[package]] name = "google-cloud-core" version = "2.5.0" @@ -1895,7 +1919,7 @@ wheels = [ [[package]] name = "google-cloud-storage" -version = "3.5.0" +version = "3.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -1905,9 +1929,9 @@ dependencies = [ { name = "google-resumable-media" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/98/c0c6d10f893509585c755a6567689e914df3501ae269f46b0d67d7e7c70a/google_cloud_storage-3.5.0.tar.gz", hash = "sha256:10b89e1d1693114b3e0ca921bdd28c5418701fd092e39081bb77e5cee0851ab7", size = 17242207, upload-time = "2025-11-05T12:41:02.715Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/cd/7e112cf025b2b591067b599e4bfe965df0c12b0cc0afdb5556469bff126d/google_cloud_storage-3.6.0.tar.gz", hash = "sha256:29cc6b9a6c0fc9cdad071e375d540a5a50fbc9a7fad8300fa02fb904f6fe2ca2", size = 17251072, upload-time = "2025-11-17T10:18:29.81Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/81/a567236070e7fe79a17a11b118d7f5ce4adefe2edd18caf1824d7e29a30a/google_cloud_storage-3.5.0-py3-none-any.whl", hash = "sha256:e28fd6ad8764e60dbb9a398a7bc3296e7920c494bc329057d828127e5f9630d3", size = 289998, upload-time = "2025-11-05T12:41:01.212Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ef/3b57bf617ee0c79450c1ff211d1eb888db8fc1050ac74b3e52cc6ed86e63/google_cloud_storage-3.6.0-py3-none-any.whl", hash = "sha256:5decbdddd63b7d1fc3e266a393ad6453d2e27d172bd982b1e2f15481668db097", size = 299039, upload-time = "2025-11-17T10:18:27.66Z" }, ] [[package]] @@ -1961,6 +1985,61 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038", size = 297515, upload-time = "2025-11-06T18:29:13.14Z" }, ] +[[package]] +name = "grpcio" +version = "1.76.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/e0/318c1ce3ae5a17894d5791e87aea147587c9e702f24122cc7a5c8bbaeeb1/grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73", size = 12785182, upload-time = "2025-10-21T16:23:12.106Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/00/8163a1beeb6971f66b4bbe6ac9457b97948beba8dd2fc8e1281dce7f79ec/grpcio-1.76.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2e1743fbd7f5fa713a1b0a8ac8ebabf0ec980b5d8809ec358d488e273b9cf02a", size = 5843567, upload-time = "2025-10-21T16:20:52.829Z" }, + { url = "https://files.pythonhosted.org/packages/10/c1/934202f5cf335e6d852530ce14ddb0fef21be612ba9ecbbcbd4d748ca32d/grpcio-1.76.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:a8c2cf1209497cf659a667d7dea88985e834c24b7c3b605e6254cbb5076d985c", size = 11848017, upload-time = "2025-10-21T16:20:56.705Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/8dec16b1863d74af6eb3543928600ec2195af49ca58b16334972f6775663/grpcio-1.76.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:08caea849a9d3c71a542827d6df9d5a69067b0a1efbea8a855633ff5d9571465", size = 6412027, upload-time = "2025-10-21T16:20:59.3Z" }, + { url = "https://files.pythonhosted.org/packages/d7/64/7b9e6e7ab910bea9d46f2c090380bab274a0b91fb0a2fe9b0cd399fffa12/grpcio-1.76.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f0e34c2079d47ae9f6188211db9e777c619a21d4faba6977774e8fa43b085e48", size = 7075913, upload-time = "2025-10-21T16:21:01.645Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/093c46e9546073cefa789bd76d44c5cb2abc824ca62af0c18be590ff13ba/grpcio-1.76.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8843114c0cfce61b40ad48df65abcfc00d4dba82eae8718fab5352390848c5da", size = 6615417, upload-time = "2025-10-21T16:21:03.844Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b6/5709a3a68500a9c03da6fb71740dcdd5ef245e39266461a03f31a57036d8/grpcio-1.76.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8eddfb4d203a237da6f3cc8a540dad0517d274b5a1e9e636fd8d2c79b5c1d397", size = 7199683, upload-time = "2025-10-21T16:21:06.195Z" }, + { url = "https://files.pythonhosted.org/packages/91/d3/4b1f2bf16ed52ce0b508161df3a2d186e4935379a159a834cb4a7d687429/grpcio-1.76.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:32483fe2aab2c3794101c2a159070584e5db11d0aa091b2c0ea9c4fc43d0d749", size = 8163109, upload-time = "2025-10-21T16:21:08.498Z" }, + { url = "https://files.pythonhosted.org/packages/5c/61/d9043f95f5f4cf085ac5dd6137b469d41befb04bd80280952ffa2a4c3f12/grpcio-1.76.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dcfe41187da8992c5f40aa8c5ec086fa3672834d2be57a32384c08d5a05b4c00", size = 7626676, upload-time = "2025-10-21T16:21:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/36/95/fd9a5152ca02d8881e4dd419cdd790e11805979f499a2e5b96488b85cf27/grpcio-1.76.0-cp311-cp311-win32.whl", hash = "sha256:2107b0c024d1b35f4083f11245c0e23846ae64d02f40b2b226684840260ed054", size = 3997688, upload-time = "2025-10-21T16:21:12.746Z" }, + { url = "https://files.pythonhosted.org/packages/60/9c/5c359c8d4c9176cfa3c61ecd4efe5affe1f38d9bae81e81ac7186b4c9cc8/grpcio-1.76.0-cp311-cp311-win_amd64.whl", hash = "sha256:522175aba7af9113c48ec10cc471b9b9bd4f6ceb36aeb4544a8e2c80ed9d252d", size = 4709315, upload-time = "2025-10-21T16:21:15.26Z" }, + { url = "https://files.pythonhosted.org/packages/bf/05/8e29121994b8d959ffa0afd28996d452f291b48cfc0875619de0bde2c50c/grpcio-1.76.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:81fd9652b37b36f16138611c7e884eb82e0cec137c40d3ef7c3f9b3ed00f6ed8", size = 5799718, upload-time = "2025-10-21T16:21:17.939Z" }, + { url = "https://files.pythonhosted.org/packages/d9/75/11d0e66b3cdf998c996489581bdad8900db79ebd83513e45c19548f1cba4/grpcio-1.76.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:04bbe1bfe3a68bbfd4e52402ab7d4eb59d72d02647ae2042204326cf4bbad280", size = 11825627, upload-time = "2025-10-21T16:21:20.466Z" }, + { url = "https://files.pythonhosted.org/packages/28/50/2f0aa0498bc188048f5d9504dcc5c2c24f2eb1a9337cd0fa09a61a2e75f0/grpcio-1.76.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d388087771c837cdb6515539f43b9d4bf0b0f23593a24054ac16f7a960be16f4", size = 6359167, upload-time = "2025-10-21T16:21:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/66/e5/bbf0bb97d29ede1d59d6588af40018cfc345b17ce979b7b45424628dc8bb/grpcio-1.76.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9f8f757bebaaea112c00dba718fc0d3260052ce714e25804a03f93f5d1c6cc11", size = 7044267, upload-time = "2025-10-21T16:21:25.995Z" }, + { url = "https://files.pythonhosted.org/packages/f5/86/f6ec2164f743d9609691115ae8ece098c76b894ebe4f7c94a655c6b03e98/grpcio-1.76.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:980a846182ce88c4f2f7e2c22c56aefd515daeb36149d1c897f83cf57999e0b6", size = 6573963, upload-time = "2025-10-21T16:21:28.631Z" }, + { url = "https://files.pythonhosted.org/packages/60/bc/8d9d0d8505feccfdf38a766d262c71e73639c165b311c9457208b56d92ae/grpcio-1.76.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f92f88e6c033db65a5ae3d97905c8fea9c725b63e28d5a75cb73b49bda5024d8", size = 7164484, upload-time = "2025-10-21T16:21:30.837Z" }, + { url = "https://files.pythonhosted.org/packages/67/e6/5d6c2fc10b95edf6df9b8f19cf10a34263b7fd48493936fffd5085521292/grpcio-1.76.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4baf3cbe2f0be3289eb68ac8ae771156971848bb8aaff60bad42005539431980", size = 8127777, upload-time = "2025-10-21T16:21:33.577Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c8/dce8ff21c86abe025efe304d9e31fdb0deaaa3b502b6a78141080f206da0/grpcio-1.76.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:615ba64c208aaceb5ec83bfdce7728b80bfeb8be97562944836a7a0a9647d882", size = 7594014, upload-time = "2025-10-21T16:21:41.882Z" }, + { url = "https://files.pythonhosted.org/packages/e0/42/ad28191ebf983a5d0ecef90bab66baa5a6b18f2bfdef9d0a63b1973d9f75/grpcio-1.76.0-cp312-cp312-win32.whl", hash = "sha256:45d59a649a82df5718fd9527ce775fd66d1af35e6d31abdcdc906a49c6822958", size = 3984750, upload-time = "2025-10-21T16:21:44.006Z" }, + { url = "https://files.pythonhosted.org/packages/9e/00/7bd478cbb851c04a48baccaa49b75abaa8e4122f7d86da797500cccdd771/grpcio-1.76.0-cp312-cp312-win_amd64.whl", hash = "sha256:c088e7a90b6017307f423efbb9d1ba97a22aa2170876223f9709e9d1de0b5347", size = 4704003, upload-time = "2025-10-21T16:21:46.244Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ed/71467ab770effc9e8cef5f2e7388beb2be26ed642d567697bb103a790c72/grpcio-1.76.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:26ef06c73eb53267c2b319f43e6634c7556ea37672029241a056629af27c10e2", size = 5807716, upload-time = "2025-10-21T16:21:48.475Z" }, + { url = "https://files.pythonhosted.org/packages/2c/85/c6ed56f9817fab03fa8a111ca91469941fb514e3e3ce6d793cb8f1e1347b/grpcio-1.76.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:45e0111e73f43f735d70786557dc38141185072d7ff8dc1829d6a77ac1471468", size = 11821522, upload-time = "2025-10-21T16:21:51.142Z" }, + { url = "https://files.pythonhosted.org/packages/ac/31/2b8a235ab40c39cbc141ef647f8a6eb7b0028f023015a4842933bc0d6831/grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:83d57312a58dcfe2a3a0f9d1389b299438909a02db60e2f2ea2ae2d8034909d3", size = 6362558, upload-time = "2025-10-21T16:21:54.213Z" }, + { url = "https://files.pythonhosted.org/packages/bd/64/9784eab483358e08847498ee56faf8ff6ea8e0a4592568d9f68edc97e9e9/grpcio-1.76.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:3e2a27c89eb9ac3d81ec8835e12414d73536c6e620355d65102503064a4ed6eb", size = 7049990, upload-time = "2025-10-21T16:21:56.476Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/8c12319a6369434e7a184b987e8e9f3b49a114c489b8315f029e24de4837/grpcio-1.76.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61f69297cba3950a524f61c7c8ee12e55c486cb5f7db47ff9dcee33da6f0d3ae", size = 6575387, upload-time = "2025-10-21T16:21:59.051Z" }, + { url = "https://files.pythonhosted.org/packages/15/0f/f12c32b03f731f4a6242f771f63039df182c8b8e2cf8075b245b409259d4/grpcio-1.76.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a15c17af8839b6801d554263c546c69c4d7718ad4321e3166175b37eaacca77", size = 7166668, upload-time = "2025-10-21T16:22:02.049Z" }, + { url = "https://files.pythonhosted.org/packages/ff/2d/3ec9ce0c2b1d92dd59d1c3264aaec9f0f7c817d6e8ac683b97198a36ed5a/grpcio-1.76.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:25a18e9810fbc7e7f03ec2516addc116a957f8cbb8cbc95ccc80faa072743d03", size = 8124928, upload-time = "2025-10-21T16:22:04.984Z" }, + { url = "https://files.pythonhosted.org/packages/1a/74/fd3317be5672f4856bcdd1a9e7b5e17554692d3db9a3b273879dc02d657d/grpcio-1.76.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:931091142fd8cc14edccc0845a79248bc155425eee9a98b2db2ea4f00a235a42", size = 7589983, upload-time = "2025-10-21T16:22:07.881Z" }, + { url = "https://files.pythonhosted.org/packages/45/bb/ca038cf420f405971f19821c8c15bcbc875505f6ffadafe9ffd77871dc4c/grpcio-1.76.0-cp313-cp313-win32.whl", hash = "sha256:5e8571632780e08526f118f74170ad8d50fb0a48c23a746bef2a6ebade3abd6f", size = 3984727, upload-time = "2025-10-21T16:22:10.032Z" }, + { url = "https://files.pythonhosted.org/packages/41/80/84087dc56437ced7cdd4b13d7875e7439a52a261e3ab4e06488ba6173b0a/grpcio-1.76.0-cp313-cp313-win_amd64.whl", hash = "sha256:f9f7bd5faab55f47231ad8dba7787866b69f5e93bc306e3915606779bbfb4ba8", size = 4702799, upload-time = "2025-10-21T16:22:12.709Z" }, +] + +[[package]] +name = "grpcio-status" +version = "1.76.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/46/e9f19d5be65e8423f886813a2a9d0056ba94757b0c5007aa59aed1a961fa/grpcio_status-1.76.0.tar.gz", hash = "sha256:25fcbfec74c15d1a1cb5da3fab8ee9672852dc16a5a9eeb5baf7d7a9952943cd", size = 13679, upload-time = "2025-10-21T16:28:52.545Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/cc/27ba60ad5a5f2067963e6a858743500df408eb5855e98be778eaef8c9b02/grpcio_status-1.76.0-py3-none-any.whl", hash = "sha256:380568794055a8efbbd8871162df92012e0228a5f6dffaf57f2a00c534103b18", size = 14425, upload-time = "2025-10-21T16:28:40.853Z" }, +] + [[package]] name = "h11" version = "0.16.0" @@ -2082,11 +2161,14 @@ wheels = [ [[package]] name = "idc-index-data" -version = "22.1.2" +version = "22.1.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/f5/ebeba9f80f3c60dd828c3cf9819fa7af7fafa2cd5f668dd3660e540a5d3d/idc_index_data-22.1.2.tar.gz", hash = "sha256:6166a82826019f5a4c68f163c3dc9bdde743b118b17c70980123eef0e5c2fb79", size = 24336, upload-time = "2025-11-12T18:21:11.393Z" } +dependencies = [ + { name = "google-cloud-bigquery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/b0/fd9b42ef1257e8d9d53ea258e8e76ed7b0aa5759f347310a888e247dd33b/idc_index_data-22.1.5.tar.gz", hash = "sha256:e742e81776380d1678cdb9ad5b1b52a2454ee36c738cf223108cca38f94d2235", size = 28952, upload-time = "2025-11-17T22:33:17.515Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/83/a0f0f620259c2d1af2680aeb5d0f6013c2830b8ea57da38497c6e66a55be/idc_index_data-22.1.2-py3-none-any.whl", hash = "sha256:79c5a557213506f7b4631cc498c50d81cc0994d537a598eb73d833e6eb2f24f6", size = 82666508, upload-time = "2025-11-12T18:21:08.382Z" }, + { url = "https://files.pythonhosted.org/packages/09/11/2c24673c50eda540f2de4eb5f377bd5a7b4fae98d9668869c7d3c812f6f6/idc_index_data-22.1.5-py3-none-any.whl", hash = "sha256:e04da51e815e29ce907760d176e48593c7fb673252c1a59e2e867f45ab493612", size = 82660446, upload-time = "2025-11-17T22:33:14.75Z" }, ] [[package]] @@ -2856,7 +2938,7 @@ wheels = [ [[package]] name = "marimo" -version = "0.17.7" +version = "0.17.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2877,9 +2959,9 @@ dependencies = [ { name = "uvicorn" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d0/46/9c1985a5f5e299bf51e787003218e02c755326549557a2c3700c7238aff3/marimo-0.17.7.tar.gz", hash = "sha256:d35d2ae4b1221e8174bab3f3bd7ec6791f0957efeedc62e824effce687644333", size = 33462833, upload-time = "2025-11-04T23:40:22.15Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/55/91ae9083e99eba09437187f1b2cc1aa0bf01aece63d7a9687ea3d548eac0/marimo-0.17.8.tar.gz", hash = "sha256:bf68aaf733007e1aa61cfc8fb6739543df11d8e64148a14c9975f1a41439b25b", size = 33498557, upload-time = "2025-11-13T23:40:34.266Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/db/7f857b13e83ac0ea7827e5580d9199e186dea275e466890ac185f16e81f2/marimo-0.17.7-py3-none-any.whl", hash = "sha256:1254c5bd7597e3977ad74f4f261acaccaafcfff09c154efffc8cdcb1c8be10ed", size = 33978023, upload-time = "2025-11-04T23:40:26.702Z" }, + { url = "https://files.pythonhosted.org/packages/97/90/62462e51a66273db33a20ec07ba7e8188151593435da7efb71d2923bbea8/marimo-0.17.8-py3-none-any.whl", hash = "sha256:8ed8ac12843eb677b1e573d670d4ebbcd52d5fb077391e003c0104075c9a3978", size = 34011576, upload-time = "2025-11-13T23:40:30.078Z" }, ] [[package]] @@ -5372,28 +5454,28 @@ wheels = [ [[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/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" }, +version = "0.14.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/fa/fbb67a5780ae0f704876cb8ac92d6d76da41da4dc72b7ed3565ab18f2f52/ruff-0.14.5.tar.gz", hash = "sha256:8d3b48d7d8aad423d3137af7ab6c8b1e38e4de104800f0d596990f6ada1a9fc1", size = 5615944, upload-time = "2025-11-13T19:58:51.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/31/c07e9c535248d10836a94e4f4e8c5a31a1beed6f169b31405b227872d4f4/ruff-0.14.5-py3-none-linux_armv6l.whl", hash = "sha256:f3b8248123b586de44a8018bcc9fefe31d23dda57a34e6f0e1e53bd51fd63594", size = 13171630, upload-time = "2025-11-13T19:57:54.894Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/283c62516dca697cd604c2796d1487396b7a436b2f0ecc3fd412aca470e0/ruff-0.14.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f7a75236570318c7a30edd7f5491945f0169de738d945ca8784500b517163a72", size = 13413925, upload-time = "2025-11-13T19:57:59.181Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f3/aa319f4afc22cb6fcba2b9cdfc0f03bbf747e59ab7a8c5e90173857a1361/ruff-0.14.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d146132d1ee115f8802356a2dc9a634dbf58184c51bff21f313e8cd1c74899a", size = 12574040, upload-time = "2025-11-13T19:58:02.056Z" }, + { url = "https://files.pythonhosted.org/packages/f9/7f/cb5845fcc7c7e88ed57f58670189fc2ff517fe2134c3821e77e29fd3b0c8/ruff-0.14.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2380596653dcd20b057794d55681571a257a42327da8894b93bbd6111aa801f", size = 13009755, upload-time = "2025-11-13T19:58:05.172Z" }, + { url = "https://files.pythonhosted.org/packages/21/d2/bcbedbb6bcb9253085981730687ddc0cc7b2e18e8dc13cf4453de905d7a0/ruff-0.14.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d1fa985a42b1f075a098fa1ab9d472b712bdb17ad87a8ec86e45e7fa6273e68", size = 12937641, upload-time = "2025-11-13T19:58:08.345Z" }, + { url = "https://files.pythonhosted.org/packages/a4/58/e25de28a572bdd60ffc6bb71fc7fd25a94ec6a076942e372437649cbb02a/ruff-0.14.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88f0770d42b7fa02bbefddde15d235ca3aa24e2f0137388cc15b2dcbb1f7c7a7", size = 13610854, upload-time = "2025-11-13T19:58:11.419Z" }, + { url = "https://files.pythonhosted.org/packages/7d/24/43bb3fd23ecee9861970978ea1a7a63e12a204d319248a7e8af539984280/ruff-0.14.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3676cb02b9061fee7294661071c4709fa21419ea9176087cb77e64410926eb78", size = 15061088, upload-time = "2025-11-13T19:58:14.551Z" }, + { url = "https://files.pythonhosted.org/packages/23/44/a022f288d61c2f8c8645b24c364b719aee293ffc7d633a2ca4d116b9c716/ruff-0.14.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b595bedf6bc9cab647c4a173a61acf4f1ac5f2b545203ba82f30fcb10b0318fb", size = 14734717, upload-time = "2025-11-13T19:58:17.518Z" }, + { url = "https://files.pythonhosted.org/packages/58/81/5c6ba44de7e44c91f68073e0658109d8373b0590940efe5bd7753a2585a3/ruff-0.14.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f55382725ad0bdb2e8ee2babcbbfb16f124f5a59496a2f6a46f1d9d99d93e6e2", size = 14028812, upload-time = "2025-11-13T19:58:20.533Z" }, + { url = "https://files.pythonhosted.org/packages/ad/ef/41a8b60f8462cb320f68615b00299ebb12660097c952c600c762078420f8/ruff-0.14.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7497d19dce23976bdaca24345ae131a1d38dcfe1b0850ad8e9e6e4fa321a6e19", size = 13825656, upload-time = "2025-11-13T19:58:23.345Z" }, + { url = "https://files.pythonhosted.org/packages/7c/00/207e5de737fdb59b39eb1fac806904fe05681981b46d6a6db9468501062e/ruff-0.14.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:410e781f1122d6be4f446981dd479470af86537fb0b8857f27a6e872f65a38e4", size = 13959922, upload-time = "2025-11-13T19:58:26.537Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7e/fa1f5c2776db4be405040293618846a2dece5c70b050874c2d1f10f24776/ruff-0.14.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01be527ef4c91a6d55e53b337bfe2c0f82af024cc1a33c44792d6844e2331e1", size = 12932501, upload-time = "2025-11-13T19:58:29.822Z" }, + { url = "https://files.pythonhosted.org/packages/67/d8/d86bf784d693a764b59479a6bbdc9515ae42c340a5dc5ab1dabef847bfaa/ruff-0.14.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f66e9bb762e68d66e48550b59c74314168ebb46199886c5c5aa0b0fbcc81b151", size = 12927319, upload-time = "2025-11-13T19:58:32.923Z" }, + { url = "https://files.pythonhosted.org/packages/ac/de/ee0b304d450ae007ce0cb3e455fe24fbcaaedae4ebaad6c23831c6663651/ruff-0.14.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d93be8f1fa01022337f1f8f3bcaa7ffee2d0b03f00922c45c2207954f351f465", size = 13206209, upload-time = "2025-11-13T19:58:35.952Z" }, + { url = "https://files.pythonhosted.org/packages/33/aa/193ca7e3a92d74f17d9d5771a765965d2cf42c86e6f0fd95b13969115723/ruff-0.14.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c135d4b681f7401fe0e7312017e41aba9b3160861105726b76cfa14bc25aa367", size = 13953709, upload-time = "2025-11-13T19:58:39.002Z" }, + { url = "https://files.pythonhosted.org/packages/cc/f1/7119e42aa1d3bf036ffc9478885c2e248812b7de9abea4eae89163d2929d/ruff-0.14.5-py3-none-win32.whl", hash = "sha256:c83642e6fccfb6dea8b785eb9f456800dcd6a63f362238af5fc0c83d027dd08b", size = 12925808, upload-time = "2025-11-13T19:58:42.779Z" }, + { url = "https://files.pythonhosted.org/packages/3b/9d/7c0a255d21e0912114784e4a96bf62af0618e2190cae468cd82b13625ad2/ruff-0.14.5-py3-none-win_amd64.whl", hash = "sha256:9d55d7af7166f143c94eae1db3312f9ea8f95a4defef1979ed516dbb38c27621", size = 14331546, upload-time = "2025-11-13T19:58:45.691Z" }, + { url = "https://files.pythonhosted.org/packages/e5/80/69756670caedcf3b9be597a6e12276a6cf6197076eb62aad0c608f8efce0/ruff-0.14.5-py3-none-win_arm64.whl", hash = "sha256:4b700459d4649e2594b31f20a9de33bc7c19976d4746d8d0798ad959621d64a4", size = 13433331, upload-time = "2025-11-13T19:58:48.434Z" }, ] [[package]] @@ -5491,15 +5573,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.44.0" +version = "2.45.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/26/ff7d93a14a0ec309021dca2fb7c62669d4f6f5654aa1baf60797a16681e0/sentry_sdk-2.44.0.tar.gz", hash = "sha256:5b1fe54dfafa332e900b07dd8f4dfe35753b64e78e7d9b1655a28fd3065e2493", size = 371464, upload-time = "2025-11-11T09:35:56.075Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/89/1561b3dc8e28bf7978d031893297e89be266f53650c87bb14a29406a9791/sentry_sdk-2.45.0.tar.gz", hash = "sha256:e9bbfe69d5f6742f48bad22452beffb525bbc5b797d817c7f1b1f7d210cdd271", size = 373631, upload-time = "2025-11-18T13:23:22.475Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/56/c16bda4d53012c71fa1b588edde603c6b455bc8206bf6de7b83388fcce75/sentry_sdk-2.44.0-py2.py3-none-any.whl", hash = "sha256:9e36a0372b881e8f92fdbff4564764ce6cec4b7f25424d0a3a8d609c9e4651a7", size = 402352, upload-time = "2025-11-11T09:35:54.1Z" }, + { url = "https://files.pythonhosted.org/packages/94/c6/039121a0355bc1b5bcceef0dabf211b021fd435d0ee5c46393717bb1c09f/sentry_sdk-2.45.0-py2.py3-none-any.whl", hash = "sha256:86c8ab05dc3e8666aece77a5c747b45b25aa1d5f35f06cde250608f495d50f23", size = 404791, upload-time = "2025-11-18T13:23:20.533Z" }, ] [[package]] From 8eed64bbda61c05194c0d2b1c9e3278fb800adb5 Mon Sep 17 00:00:00 2001 From: Helmut Hoffer von Ankershoffen Date: Wed, 19 Nov 2025 21:54:05 +0100 Subject: [PATCH 4/4] chore(deps): bump nicegui to 3.3.1 --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c41bc016..8f26d17d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,7 @@ dependencies = [ # From Template "fastapi[standard,all]>=0.121.3,<1", "humanize>=4.14.0,<5", - "nicegui[native]>=3.1.0,<3.2.0", # Regression in 3.2.0 + "nicegui[native]>=3.3.1,<4", # Regression in 3.2.0 "packaging>=25.0,<26", "platformdirs>=4.5.0,<5", "psutil>=7.1.3,<8", diff --git a/uv.lock b/uv.lock index 440b1f48..d413b517 100644 --- a/uv.lock +++ b/uv.lock @@ -179,7 +179,7 @@ requires-dist = [ { name = "loguru", specifier = ">=0.7.3" }, { name = "marimo", marker = "extra == 'marimo'", specifier = ">=0.17.8,<1" }, { name = "matplotlib", marker = "extra == 'marimo'", specifier = ">=3.10.7,<4" }, - { name = "nicegui", extras = ["native"], specifier = ">=3.1.0,<3.2.0" }, + { name = "nicegui", extras = ["native"], specifier = ">=3.3.1,<4" }, { name = "openslide-bin", specifier = ">=4.0.0.8,<5" }, { name = "openslide-python", specifier = ">=1.4.2,<2" }, { name = "packaging", specifier = ">=25.0,<26" }, @@ -3429,7 +3429,7 @@ wheels = [ [[package]] name = "nicegui" -version = "3.1.0" +version = "3.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiofiles" }, @@ -3453,9 +3453,9 @@ dependencies = [ { name = "uvicorn", extra = ["standard"] }, { name = "watchfiles" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/23/1a709ac5ae3b91674b7fb75b7eb2db851cf09b55a809936c106efa46c52f/nicegui-3.1.0.tar.gz", hash = "sha256:1496b9719292cdd64fb89a9e560a197f517347e8808c829fae9ba28a294d78ae", size = 20342929, upload-time = "2025-10-22T08:33:07.869Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/ee/43ecb61be17b3487d9bc17bf493970714dfb85bda32bff2f268cd9304262/nicegui-3.3.1.tar.gz", hash = "sha256:0de625b836acf1c36875dc290ae769ef114aba9535e33d302566b19381b206fa", size = 20353012, upload-time = "2025-11-17T10:24:16.452Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/4e/ce491f04b07d2530a441f01fa028c936c353ee92e0ad153bf6b7cf2c3e9d/nicegui-3.1.0-py3-none-any.whl", hash = "sha256:c5ad4ac120eaec138bee71514e9cba2f9d27384b7e9201c11f309a90a128a96f", size = 20996176, upload-time = "2025-10-22T08:33:05.178Z" }, + { url = "https://files.pythonhosted.org/packages/d7/5c/fccb05fd8e9e9bdb5dd1531af1d40bcfbb3d7e850b2d43902ca117becde9/nicegui-3.3.1-py3-none-any.whl", hash = "sha256:7eb4e35936958c1df4b0fa6f5f4ed51d6e060c2938aca09b229abfec6b25e35e", size = 21007617, upload-time = "2025-11-17T10:24:13.13Z" }, ] [package.optional-dependencies]