arraylake 1.1.0__tar.gz → 1.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. {arraylake-1.1.0 → arraylake-1.1.1}/PKG-INFO +2 -2
  2. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/_version.py +2 -2
  3. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/client.py +11 -2
  4. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/types.py +20 -2
  5. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/storage.py +39 -4
  6. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/types.py +1 -0
  7. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/types.py +24 -0
  8. {arraylake-1.1.0 → arraylake-1.1.1}/pyproject.toml +2 -2
  9. {arraylake-1.1.0 → arraylake-1.1.1}/tests/conftest.py +26 -0
  10. {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/conftest.py +13 -0
  11. {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/test_storage.py +16 -0
  12. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_client.py +16 -0
  13. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_types.py +12 -0
  14. {arraylake-1.1.0 → arraylake-1.1.1}/uv.lock +48 -48
  15. {arraylake-1.1.0 → arraylake-1.1.1}/.gitignore +0 -0
  16. {arraylake-1.1.0 → arraylake-1.1.1}/README.md +0 -0
  17. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/__init__.py +0 -0
  18. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/__main__.py +0 -0
  19. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/_credential_cache.py +0 -0
  20. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/api_utils.py +0 -0
  21. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/asyn.py +0 -0
  22. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/__init__.py +0 -0
  23. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/auth.py +0 -0
  24. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/compute.py +0 -0
  25. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/config.py +0 -0
  26. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/main.py +0 -0
  27. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/repo.py +0 -0
  28. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/skills.py +0 -0
  29. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/utils.py +0 -0
  30. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/doctor.py +0 -0
  31. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/http_client.py +0 -0
  32. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/services.py +0 -0
  33. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/config.py +0 -0
  34. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/config.yaml +0 -0
  35. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/credentials.py +0 -0
  36. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/diagnostics.py +0 -0
  37. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/display/__init__.py +0 -0
  38. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/display/repo.py +0 -0
  39. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/display/repolist.py +0 -0
  40. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/exceptions.py +0 -0
  41. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/log_util.py +0 -0
  42. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/metastore/__init__.py +0 -0
  43. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/metastore/abc.py +0 -0
  44. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/metastore/http_metastore.py +0 -0
  45. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/py.typed +0 -0
  46. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/__init__.py +0 -0
  47. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/__init__.py +0 -0
  48. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/virtual.py +0 -0
  49. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/token.py +0 -0
  50. {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/tuning.py +0 -0
  51. {arraylake-1.1.0 → arraylake-1.1.1}/tests/__init__.py +0 -0
  52. {arraylake-1.1.0 → arraylake-1.1.1}/tests/compute/test_client.py +0 -0
  53. {arraylake-1.1.0 → arraylake-1.1.1}/tests/compute/test_doctor.py +0 -0
  54. {arraylake-1.1.0 → arraylake-1.1.1}/tests/config.yaml +0 -0
  55. {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/__init__.py +0 -0
  56. {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/test_virtual.py +0 -0
  57. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_api_utils.py +0 -0
  58. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_asyn.py +0 -0
  59. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_cli.py +0 -0
  60. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_config.py +0 -0
  61. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_credential_cache.py +0 -0
  62. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_credentials.py +0 -0
  63. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_diagnostics.py +0 -0
  64. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_performance.py +0 -0
  65. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_skills.py +0 -0
  66. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_subscriptions.py +0 -0
  67. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_token_handler.py +0 -0
  68. {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_virtual_chunks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arraylake
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: Python client for ArrayLake
5
5
  Project-URL: Documentation, https://docs.earthmover.io/
6
6
  Project-URL: Changelog, https://docs.earthmover.io/changelog
@@ -14,7 +14,7 @@ Requires-Python: <3.15,>=3.12
14
14
  Requires-Dist: click<9.0,>=8.1.3
15
15
  Requires-Dist: donfig<1.0,>=0.7
16
16
  Requires-Dist: httpx<0.29,>=0.23
17
- Requires-Dist: icechunk<3.0.0,>=2.0.1
17
+ Requires-Dist: icechunk<3.0.0,>=2.0.6
18
18
  Requires-Dist: numpy<3.0,>=1.23
19
19
  Requires-Dist: packaging<27.0,>=23.0
20
20
  Requires-Dist: pydantic[email]<3.0,>=2.9
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.1.0'
22
- __version_tuple__ = version_tuple = (1, 1, 0)
21
+ __version__ = version = '1.1.1'
22
+ __version_tuple__ = version_tuple = (1, 1, 1)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -45,6 +45,7 @@ from arraylake.metastore import HttpMetastore, HttpMetastoreConfig
45
45
  from arraylake.repos.icechunk.storage import (
46
46
  _get_credential_type,
47
47
  _get_icechunk_storage_obj,
48
+ apply_bucket_repo_config,
48
49
  )
49
50
  from arraylake.repos.icechunk.virtual import (
50
51
  create_virtual_chunk_container,
@@ -1027,6 +1028,9 @@ class AsyncClient:
1027
1028
  repo_model, user_id=user.id, storage_options=storage_options
1028
1029
  )
1029
1030
 
1031
+ if repo_model.bucket is not None:
1032
+ config = apply_bucket_repo_config(repo_model.bucket, config)
1033
+
1030
1034
  if authorize_virtual_chunk_access is not None:
1031
1035
  config = await self._add_virtual_chunk_containers(
1032
1036
  org=org, user=user, config=config, authorize_virtual_chunk_access=authorize_virtual_chunk_access
@@ -1141,6 +1145,9 @@ class AsyncClient:
1141
1145
  config = None
1142
1146
  prefixes_credential_mapping = None
1143
1147
 
1148
+ if repo_model.bucket is not None:
1149
+ config = apply_bucket_repo_config(repo_model.bucket, config)
1150
+
1144
1151
  ic_repo = IcechunkRepository.open(
1145
1152
  icechunk_storage,
1146
1153
  config=config,
@@ -1614,7 +1621,8 @@ class AsyncClient:
1614
1621
  explicit parameters above when possible. Keys set here are overridden
1615
1622
  by any explicit parameters that are also provided.
1616
1623
  auth_config: Dictionary of auth parameters. Must include a ``"method"`` key.
1617
- Defaults to ``{"method": "anonymous"}``.
1624
+ Defaults to ``{"method": "anonymous"}``. Anonymous (public) Azure
1625
+ containers must also set ``storage_account`` in this dict.
1618
1626
  """
1619
1627
  validated = NewBucket(
1620
1628
  **self._make_bucket_config(
@@ -2278,7 +2286,8 @@ class Client:
2278
2286
  explicit parameters above when possible. Keys set here are overridden
2279
2287
  by any explicit parameters that are also provided.
2280
2288
  auth_config: Dictionary of auth parameters. Must include a ``"method"`` key.
2281
- Defaults to ``{"method": "anonymous"}``.
2289
+ Defaults to ``{"method": "anonymous"}``. Anonymous (public) Azure
2290
+ containers must also set ``storage_account`` in this dict.
2282
2291
  """
2283
2292
  return sync(
2284
2293
  self.aclient.create_bucket_config,
@@ -56,14 +56,21 @@ class ServiceConfig(BaseModel):
56
56
  # If not set, the default is 0, which means functionally no caching, but requests are revalidated.
57
57
  cache_max_age: int | None = 0
58
58
 
59
- # Optional control over icechunk chunk cache size in bytes
59
+ # Optional control over icechunk chunk cache size in bytes. Override for services whose
60
+ # single-request working set (e.g. all shards touched by an EDR query) exceeds the default,
61
+ # otherwise chunks are evicted and re-fetched from object storage on every request.
60
62
  icechunk_cache_chunk_bytes: int | None = 1024 * 1024 * 1024
61
63
 
62
64
  # Optional control over the number of chunk refs icechunk cache
63
65
  icechunk_cache_chunk_ref_count: int | None = 10_000_000
64
66
 
65
67
  # Optional zarr concurrency configuration, the number of concurrent reads zarr will use fulfilling requests
66
- zarr_concurrency: int | None = 128
68
+ zarr_concurrency: int | None = 1000
69
+
70
+ # Optional zarr codec pipeline batch size, the number of chunks zarr encodes/decodes per
71
+ # asyncio task. Zarr's own default of 1 spawns a task per inner chunk when decoding
72
+ # sharded arrays, which is significantly slower.
73
+ zarr_codec_pipeline_batch_size: int | None = 256
67
74
 
68
75
  # Optional zarr threading configuration, the max number of worker threads zarr uses for codec
69
76
  # encode/decode. If unset, zarr uses its default of min(32, os.cpu_count() + 4).
@@ -76,6 +83,17 @@ class ServiceConfig(BaseModel):
76
83
  # other than DAP2. DAP2 always uses Dask regardless of this setting.
77
84
  use_dask: bool = False
78
85
 
86
+ # Optional container resource overrides. When unset, the per-service-type
87
+ # defaults from the server's ImageConfig are used. Setting any of these
88
+ # requires the caller to have the CAN_MANAGE_ALL_ORGS service permission;
89
+ # non-admin callers will be rejected. Values are Kubernetes resource
90
+ # quantities (e.g. "500m", "4", "8Gi"). Requests drive node selection and
91
+ # packing; limits cap burst. Set request == limit for Guaranteed QoS.
92
+ cpu_request: str | None = None
93
+ cpu_limit: str | None = None
94
+ memory_request: str | None = None
95
+ memory_limit: str | None = None
96
+
79
97
  @field_validator("deployment_name")
80
98
  @classmethod
81
99
  def validate_deployment_name(cls, v: str | None) -> str | None:
@@ -17,7 +17,6 @@ import icechunk
17
17
  from arraylake.log_util import get_logger
18
18
  from arraylake.types import (
19
19
  AzureCredentials,
20
- AzureDelegatedCredentialsAuth,
21
20
  BucketResponse,
22
21
  GSCredentials,
23
22
  S3Credentials,
@@ -232,14 +231,22 @@ def _get_icechunk_storage_obj(
232
231
 
233
232
  assert credentials is None or isinstance(credentials, AzureCredentials)
234
233
 
235
- if not isinstance(bucket_config.auth_config, AzureDelegatedCredentialsAuth):
236
- raise ValueError(f"Invalid auth config for Azure bucket: {bucket_config.auth_config}")
234
+ # The Azure storage account name lives on the auth config for both delegated and
235
+ # anonymous Azure buckets (it's needed to resolve the blob endpoint host). Fall
236
+ # back to the vended credentials if they carry it.
237
+ storage_account: str | None = getattr(bucket_config.auth_config, "storage_account", None)
238
+ if not storage_account and credentials is not None:
239
+ storage_account = credentials.storage_account
240
+
241
+ if not storage_account:
242
+ raise ValueError(f"Could not determine the Azure storage account for bucket {bucket_config.nickname}.")
237
243
 
238
244
  return icechunk.azure_storage(
239
- account=bucket_config.auth_config.storage_account,
245
+ account=storage_account,
240
246
  container=bucket_config.name,
241
247
  prefix=prefix or "",
242
248
  sas_token=credentials.sas_token if credentials else None,
249
+ anonymous=credential_type == CredentialType.ANONYMOUS,
243
250
  from_env=False,
244
251
  )
245
252
 
@@ -329,3 +336,31 @@ def create_icechunk_store_config(
329
336
 
330
337
  else:
331
338
  raise ValueError(f"Unsupported bucket platform: {bucket_config.platform}")
339
+
340
+
341
+ def apply_bucket_repo_config(
342
+ bucket_config: BucketResponse,
343
+ user_config: icechunk.RepositoryConfig | None,
344
+ ) -> icechunk.RepositoryConfig | None:
345
+ """Merge bucket-level icechunk RepositoryConfig flags into a user-supplied config.
346
+
347
+ Reads ``unsafe_use_conditional_update`` and ``unsafe_use_conditional_create`` from
348
+ ``bucket_config.extra_config`` and folds them into a ``RepositoryConfig``. Caller-provided
349
+ ``user_config`` wins on overlap (icechunk's ``RepositoryConfig.merge`` semantics: fields set on
350
+ the argument override fields set on the receiver).
351
+ """
352
+ extra = bucket_config.extra_config or {}
353
+ unsafe_update = extra.get("unsafe_use_conditional_update")
354
+ unsafe_create = extra.get("unsafe_use_conditional_create")
355
+
356
+ if unsafe_update is None and unsafe_create is None:
357
+ return user_config
358
+
359
+ bucket_storage = icechunk.StorageSettings(
360
+ unsafe_use_conditional_update=None if unsafe_update is None else bool(unsafe_update),
361
+ unsafe_use_conditional_create=None if unsafe_create is None else bool(unsafe_create),
362
+ )
363
+ bucket_derived = icechunk.RepositoryConfig(storage=bucket_storage)
364
+ if user_config is None:
365
+ return bucket_derived
366
+ return bucket_derived.merge(user_config)
@@ -178,6 +178,7 @@ class ClassifiedArray(BaseModel):
178
178
  dimension_names: list[str]
179
179
  attributes: dict[str, Any]
180
180
  chunk_shape: list[int]
181
+ shard_shape: list[int] | None = None # Outer shard shape; None for unsharded arrays
181
182
  fill_value: Any = None
182
183
  codecs: list[dict[str, Any]] = [] # List of codec configurations
183
184
  classification: ArrayClassification
@@ -448,6 +448,11 @@ class HmacAuth(BaseModel):
448
448
  # TODO: Rename to Self Managed
449
449
  class AnonymousAuth(BaseModel):
450
450
  method: Literal["anonymous"]
451
+ # Anonymous (public) Azure containers need the storage account name to resolve the
452
+ # blob endpoint host (<storage_account>.blob.core.windows.net). It's carried here so
453
+ # the account lives in auth_config for both anonymous and delegated Azure buckets, and
454
+ # is left None for s3/gcs anonymous buckets. Required for azure (see NewBucket).
455
+ storage_account: str | None = None
451
456
 
452
457
 
453
458
  AuthConfig: TypeAlias = CustomerManagedRoleAuth | BucketPolicyAuth | HmacAuth | AnonymousAuth
@@ -642,6 +647,12 @@ class BucketModel(BaseModel):
642
647
  elif self.platform == "azure":
643
648
  if credentials is None:
644
649
  azure_config: AzureConfig = {"skip_signature": True}
650
+ # Anonymous access still needs the storage account name to resolve the host.
651
+ # It lives on the (anonymous) auth_config, only present on Bucket subclasses
652
+ # that carry auth_config, e.g. BucketResponse.
653
+ account_name = getattr(getattr(self, "auth_config", None), "storage_account", None)
654
+ if account_name:
655
+ azure_config["account_name"] = account_name
645
656
  elif isinstance(credentials, AzureCredentials):
646
657
  azure_config = {
647
658
  "sas_key": credentials.sas_token,
@@ -710,6 +721,13 @@ class Bucket(BucketModel):
710
721
  return url + "/" if not url.endswith("/") else url
711
722
 
712
723
 
724
+ def _validate_role_auth_shared_secret(auth_config: AuthConfig | None) -> None:
725
+ if isinstance(auth_config, AWSCustomerManagedRoleAuth):
726
+ secret = auth_config.shared_secret
727
+ if secret is None or not secret.get_secret_value():
728
+ raise ValueError("AWS customer-managed-role buckets require a shared_secret (used as the STS AssumeRole ExternalId).")
729
+
730
+
713
731
  class NewBucket(BucketModel):
714
732
  """A request to create a new bucket."""
715
733
 
@@ -737,6 +755,10 @@ class NewBucket(BucketModel):
737
755
  if self.platform == "s3-compatible":
738
756
  if "endpoint_url" not in self.extra_config:
739
757
  raise ValueError("S3-compatible buckets require an endpoint_url.")
758
+ # Anonymous Azure buckets need the storage account name (the blob endpoint host),
759
+ # which the generic AnonymousAuth only carries optionally.
760
+ if self.platform == "azure" and isinstance(self.auth_config, AnonymousAuth) and not self.auth_config.storage_account:
761
+ raise ValueError("Anonymous Azure buckets require a storage_account (the Azure storage account name).")
740
762
  return self
741
763
 
742
764
  @field_validator("auth_config")
@@ -769,6 +791,7 @@ class NewBucket(BucketModel):
769
791
  raise ValueError("R2 customer managed role is only supported for R2 buckets.")
770
792
  if auth_config.method == "azure_credential_delegation" and not info.data["platform"] == "azure":
771
793
  raise ValueError("Azure credential delegation is only supported for azure buckets.")
794
+ _validate_role_auth_shared_secret(auth_config)
772
795
  return auth_config if auth_config else None
773
796
 
774
797
 
@@ -811,6 +834,7 @@ class BucketModifyRequest(BaseModel):
811
834
  ]:
812
835
  # Deprecating bucket policy method
813
836
  raise ValueError("Bucket auth config method must be Anonymous, Customer Managed Role, or HMAC")
837
+ _validate_role_auth_shared_secret(auth_config)
814
838
  return auth_config if auth_config else None
815
839
 
816
840
 
@@ -35,7 +35,7 @@ dependencies = [
35
35
  "click >= 8.1.3, < 9.0",
36
36
  "donfig >= 0.7, < 1.0",
37
37
  "httpx >= 0.23, < 0.29",
38
- "icechunk >= 2.0.1, < 3.0.0",
38
+ "icechunk >= 2.0.6, < 3.0.0",
39
39
  "numpy >= 1.23, < 3.0",
40
40
  "packaging>=23.0,<27.0",
41
41
  "pydantic[email] >= 2.9, < 3.0",
@@ -65,7 +65,7 @@ dev = [
65
65
  "cloudpickle>=3.0,<3.2",
66
66
  "hatch>=1.14.2",
67
67
  "hypothesis>=6.88.1",
68
- "icechunk >= 2.0.1, < 3.0.0",
68
+ "icechunk >= 2.0.6, < 3.0.0",
69
69
  "mypy>=1.11,<3.0",
70
70
  "pytest-asyncio>=0.21.1,<1.4.0",
71
71
  "pytest-click~=1.1.0",
@@ -291,6 +291,32 @@ def minio_anon_bucket(default_bucket):
291
291
  return minio_anon_bucket_request_constructor
292
292
 
293
293
 
294
+ @pytest.fixture
295
+ def azure_anon_bucket(default_bucket):
296
+ """Anonymous (public) Azure container.
297
+
298
+ Mirrors the public NOAA Sea Surface Temperature WHOI dataset that icechunk's
299
+ anonymous-Azure test reads from (earth-mover/icechunk#2173). Azure needs the
300
+ storage account name (the blob endpoint host) supplied via extra_config since
301
+ anonymous buckets carry no delegated-credentials auth config.
302
+ """
303
+
304
+ def azure_anon_bucket_request_constructor(
305
+ *,
306
+ prefix: BucketPrefix = None,
307
+ ):
308
+ return default_bucket(
309
+ auth_config={"method": "anonymous", "storage_account": "noaacdr"},
310
+ nickname="azure_anon_bucket",
311
+ name="sea-surface-temp-whoi",
312
+ prefix=prefix,
313
+ platform="azure",
314
+ extra_config={},
315
+ )
316
+
317
+ return azure_anon_bucket_request_constructor
318
+
319
+
294
320
  @pytest.fixture
295
321
  def delegated_creds_bucket(default_bucket):
296
322
  def delegated_creds_bucket_request_constructor(
@@ -91,3 +91,16 @@ def anon_minio_bucket_config() -> BucketResponse:
91
91
  "endpoint_url": "http://localhost:9000",
92
92
  },
93
93
  )
94
+
95
+
96
+ @pytest.fixture
97
+ def anon_azure_bucket_config() -> BucketResponse:
98
+ return BucketResponse(
99
+ id=uuid4(),
100
+ platform="azure",
101
+ nickname="test-azure-anon",
102
+ name="public-container",
103
+ auth_config={"method": "anonymous", "storage_account": "publicaccount"},
104
+ is_default=False,
105
+ extra_config={},
106
+ )
@@ -146,6 +146,22 @@ def test_get_icechunk_storage_obj_gcs_anonymous_credentials(gcs_bucket_config: B
146
146
  assert isinstance(storage, icechunk.Storage)
147
147
 
148
148
 
149
+ def test_get_icechunk_storage_obj_azure_anonymous_credentials(
150
+ anon_azure_bucket_config: BucketResponse,
151
+ ):
152
+ storage = _get_icechunk_storage_obj(
153
+ bucket_config=anon_azure_bucket_config,
154
+ prefix=None,
155
+ credentials=None,
156
+ credential_type=CredentialType.ANONYMOUS,
157
+ credential_refresh_func=None,
158
+ scatter_initial_credentials=False,
159
+ arraylake_version=arraylake_version,
160
+ user_id=uuid.uuid4(),
161
+ )
162
+ assert isinstance(storage, icechunk.Storage)
163
+
164
+
149
165
  def test_get_icechunk_storage_obj_invalid_credential_input(
150
166
  s3_bucket_config: BucketResponse,
151
167
  s3_credentials: S3Credentials,
@@ -1599,6 +1599,22 @@ class TestGetObstoreForBucket:
1599
1599
  assert store.config["skip_signature"] == "true" # type: ignore[comparison-overlap]
1600
1600
  assert store.client_options == {"allow_http": "true"}
1601
1601
 
1602
+ @pytest.mark.parametrize("access", ["read", "write", None])
1603
+ @pytest.mark.asyncio
1604
+ async def test_returns_unsigned_store_for_anonymous_azure_bucket(self, isolated_org, azure_anon_bucket, token, access):
1605
+ import obstore as obs
1606
+
1607
+ async with isolated_org(azure_anon_bucket()) as (org_name, buckets):
1608
+ aclient = AsyncClient(token=token)
1609
+ kwargs = {"org": org_name, "nickname": buckets[0].nickname}
1610
+ if access is not None:
1611
+ kwargs["access"] = access
1612
+ store = await aclient.get_obstore_for_bucket(**kwargs)
1613
+
1614
+ assert isinstance(store, obs.store.AzureStore)
1615
+ assert store.config["skip_signature"] == "true" # type: ignore[comparison-overlap]
1616
+ assert store.config["account_name"] == "noaacdr"
1617
+
1602
1618
  @pytest.mark.asyncio
1603
1619
  async def test_raises_when_bucket_nickname_does_not_exist(self, isolated_org, token):
1604
1620
  async with isolated_org() as (org_name, _):
@@ -111,6 +111,18 @@ def test_name_length_limits():
111
111
  assert RepoCreateBody(name="a" * MAX_REPO_NAME_LENGTH, bucket_nickname="my-bucket").name == "a" * MAX_REPO_NAME_LENGTH
112
112
 
113
113
 
114
+ def test_anonymous_azure_bucket_requires_storage_account():
115
+ # Anonymous Azure buckets must carry the storage account name (s3/gcs don't need it).
116
+ with pytest.raises(ValidationError, match="Anonymous Azure buckets require a storage_account"):
117
+ NewBucket(
118
+ nickname="public-azure",
119
+ platform="azure",
120
+ name="public-container",
121
+ extra_config={},
122
+ auth_config={"method": "anonymous"},
123
+ )
124
+
125
+
114
126
  def test_aws_auth_secret_serialization():
115
127
  """Test that AWS auth secrets are obfuscated by default but revealed with context."""
116
128
  auth = AWSCustomerManagedRoleAuth(
@@ -117,7 +117,7 @@ requires-dist = [
117
117
  { name = "click", specifier = ">=8.1.3,<9.0" },
118
118
  { name = "donfig", specifier = ">=0.7,<1.0" },
119
119
  { name = "httpx", specifier = ">=0.23,<0.29" },
120
- { name = "icechunk", specifier = ">=2.0.1,<3.0.0" },
120
+ { name = "icechunk", specifier = ">=2.0.6,<3.0.0" },
121
121
  { name = "numpy", specifier = ">=1.23,<3.0" },
122
122
  { name = "obstore", marker = "extra == 'obstore'", specifier = ">=0.9.2" },
123
123
  { name = "packaging", specifier = ">=23.0,<27.0" },
@@ -138,7 +138,7 @@ dev = [
138
138
  { name = "cloudpickle", specifier = ">=3.0,<3.2" },
139
139
  { name = "hatch", specifier = ">=1.14.2" },
140
140
  { name = "hypothesis", specifier = ">=6.88.1" },
141
- { name = "icechunk", specifier = ">=2.0.1,<3.0.0" },
141
+ { name = "icechunk", specifier = ">=2.0.6,<3.0.0" },
142
142
  { name = "mypy", specifier = ">=1.11,<3.0" },
143
143
  { name = "pytest", specifier = ">=7.3,<10.0" },
144
144
  { name = "pytest-asyncio", specifier = ">=0.21.1,<1.4.0" },
@@ -1045,43 +1045,43 @@ wheels = [
1045
1045
 
1046
1046
  [[package]]
1047
1047
  name = "icechunk"
1048
- version = "2.0.5"
1048
+ version = "2.0.6"
1049
1049
  source = { registry = "https://pypi.org/simple" }
1050
1050
  dependencies = [
1051
1051
  { name = "zarr" },
1052
1052
  ]
1053
- sdist = { url = "https://files.pythonhosted.org/packages/97/99/fabc9794c1f82e51b5c7c66301695b8fd920f72dee1726104dbdbd8df3e7/icechunk-2.0.5.tar.gz", hash = "sha256:50a2a44a1b561d3f2d3b5d19725c3759f300dc67225a2360fc793d894abfcab1", size = 3327412, upload-time = "2026-05-18T20:22:05.466Z" }
1054
- wheels = [
1055
- { url = "https://files.pythonhosted.org/packages/6a/35/ac0974a9c837b04848d853e49857a985dca9fae9ea3945a102c3f223609e/icechunk-2.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b6d30c170d034fa97293976fc193786274dff6246549c50081df16674bc457f1", size = 16836172, upload-time = "2026-05-18T20:22:39.65Z" },
1056
- { url = "https://files.pythonhosted.org/packages/ae/02/cd4806ce82aead41108c17a88135cdead8d7e6aa728a569e9ea2c2cddda1/icechunk-2.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:60a2189970efe43d57b1186d769c0c899d308294db4f123afb128372d1673f3d", size = 15538907, upload-time = "2026-05-18T20:22:30.114Z" },
1057
- { url = "https://files.pythonhosted.org/packages/a6/c1/f6c02c611d0e5cafe7046e0421f243a22e423d8de636cc843e3760db9196/icechunk-2.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ee9d3e6339f729d790d835ec8e3eac8d03052ee9366147358df34ec97075bba", size = 17230282, upload-time = "2026-05-18T20:22:20.355Z" },
1058
- { url = "https://files.pythonhosted.org/packages/af/40/15b3f18b12d5220283bfff740e1f58fad9bcebe97f98b845ef290758a9ba/icechunk-2.0.5-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b7a200db882e5eafa47b4824ed2d365eaa4f4588cf959e37f6610ff3728c41a5", size = 16870373, upload-time = "2026-05-18T20:21:56.376Z" },
1059
- { url = "https://files.pythonhosted.org/packages/19/85/e077b98c50fdb130beae28622d46838910b339ce20cf86d3e4cb14202676/icechunk-2.0.5-cp312-cp312-manylinux_2_28_armv7l.whl", hash = "sha256:2c52ec6c1e129745912b5eb6ed018616269da48e6d41e1905e9449a0537461c0", size = 16698967, upload-time = "2026-05-18T20:22:08.425Z" },
1060
- { url = "https://files.pythonhosted.org/packages/19/54/e9bd6e7d23e907149ac8a0a2bd9b916abf72ea1e7200ad9d5f8ab0cf6757/icechunk-2.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f3bbe19cc445b2b978c306d6525c46a585c7b820a25c63650b171f23ace12fc", size = 17087238, upload-time = "2026-05-18T20:22:49.263Z" },
1061
- { url = "https://files.pythonhosted.org/packages/61/86/234e389c2db60d81189cd0a8855a0243be0566cb7f25035f31020b2f8f73/icechunk-2.0.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5e92bc3ef9055e9fcd59254c0dee1c3eb5381c740e85fbe4ee8798ba750207ba", size = 16869874, upload-time = "2026-05-18T20:22:59.599Z" },
1062
- { url = "https://files.pythonhosted.org/packages/b1/6e/3fca3d27d4f938a889a6ffccebf72032f11448ee718391e56c6a6e0dd1b8/icechunk-2.0.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87ff89135fc267124f60cf816777e59ca1b6eb7b92d12ca8a5a809a915d3914e", size = 16946397, upload-time = "2026-05-18T20:23:10.222Z" },
1063
- { url = "https://files.pythonhosted.org/packages/4a/a4/c976769415ba8890e318291f3156df7c375e954d6d24d7ebf68bbb19cbe7/icechunk-2.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:28fca4b96eb6bb18ec19fbd53254841a405650785947415b4cf1deec5cdd2547", size = 17637541, upload-time = "2026-05-18T20:23:19.834Z" },
1064
- { url = "https://files.pythonhosted.org/packages/ca/23/db3b502f79546e438fa4284518626c3b9170e168b6bf6dd18ce8abcff9af/icechunk-2.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:d6465b3d26c651f76e9939e46c92450fd8e4adab64c7fdb83d71351c38a06153", size = 15936117, upload-time = "2026-05-18T20:23:33.835Z" },
1065
- { url = "https://files.pythonhosted.org/packages/a2/4e/73e0851289894ce7ba1d88e8ecc00f49dbf51220129ac3ab703a0a599eab/icechunk-2.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:9c7baeab6837a1e0aec8b5dd63f865b842d66d92314e02de40612190acdcaa2c", size = 16834379, upload-time = "2026-05-18T20:22:42.89Z" },
1066
- { url = "https://files.pythonhosted.org/packages/2b/54/84e504554e9a502a4bed4d2d1e72ff0cd256e103e0c632a40e31d6c7fc9d/icechunk-2.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd02bc6fb32c9c6477f45d6818e7e363d5365884d42c03d66d97801c9ed98726", size = 15538385, upload-time = "2026-05-18T20:22:33.645Z" },
1067
- { url = "https://files.pythonhosted.org/packages/49/a9/3241119145b05beec05b45e46581faebdc02c14f5f923ebbb56ac6d0bdb0/icechunk-2.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5105891c297c9a8c3ff96bef78125a576224eaf3b970e6f0aa6ec4d8cab876", size = 17229820, upload-time = "2026-05-18T20:22:23.591Z" },
1068
- { url = "https://files.pythonhosted.org/packages/4e/ac/8392e6b23841aa81324144b7893bf7685137658848a2d8cffbd4955d89b1/icechunk-2.0.5-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:b73c5ce8987a6975970c050751d47b43af7ecaaf94c1dfa130446e3972b7f8bd", size = 16867941, upload-time = "2026-05-18T20:21:59.35Z" },
1069
- { url = "https://files.pythonhosted.org/packages/ca/95/a323289e37ccdd6e4a7ddc8251681d921428c788c9b7f05e731d537015f0/icechunk-2.0.5-cp313-cp313-manylinux_2_28_armv7l.whl", hash = "sha256:53d7c7926251c8a45d1b526e1fe348619239c011920402f6466cfcfbcd96ba74", size = 16697076, upload-time = "2026-05-18T20:22:11.771Z" },
1070
- { url = "https://files.pythonhosted.org/packages/2d/82/ef006b6433127a7b6aa9fbd9183cb2f4ce69df61096220e16d0292b563c9/icechunk-2.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:47883961b0b570eb206b3218ee285ad9e36dd407c5988ee39032356c73a90f40", size = 17086219, upload-time = "2026-05-18T20:22:53.068Z" },
1071
- { url = "https://files.pythonhosted.org/packages/6e/42/0d1ede1a3cd383f2bf00cc8905816339885022efde31951015fb2e110885/icechunk-2.0.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4779422967dcf69b2c2606211ae48b313e865a0caf3414afab790422ef1b5d7e", size = 16868204, upload-time = "2026-05-18T20:23:03.334Z" },
1072
- { url = "https://files.pythonhosted.org/packages/ae/b3/baefe0939737277efbec5b97fe0f4286f53f81a423d7cab2e7d5128f1633/icechunk-2.0.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83bf18ac31aace8325ce9cc1ee73581f007c0bf3061ad10b4b3ffff8b734977b", size = 16945422, upload-time = "2026-05-18T20:23:13.69Z" },
1073
- { url = "https://files.pythonhosted.org/packages/be/1f/144799746b0b5269458c4a24049bae7f4d52da55735c10e173de5c76c134/icechunk-2.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ae7bb09eafeb714597d795e74506a9f258a798d7a26d840c37b3bfec44e988a4", size = 17637469, upload-time = "2026-05-18T20:23:23.199Z" },
1074
- { url = "https://files.pythonhosted.org/packages/02/bc/1dec19138d4ab82175a8b2cddd24320003476c8e9e4d2cafa70b096d5b76/icechunk-2.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:978ddc20fb1e6abfaacdb31810a37a83b94b488d7795e77931576f220930f72a", size = 15936134, upload-time = "2026-05-18T20:23:37.825Z" },
1075
- { url = "https://files.pythonhosted.org/packages/e3/47/0e29dd5248dbaddef6351e9807d61c4eacae325f3b1415a2bb0ce5b2e92e/icechunk-2.0.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:2d2369db67502118150612ad481468cc0ae1333ba5cf6084179da04591e566b2", size = 16841657, upload-time = "2026-05-18T20:22:45.594Z" },
1076
- { url = "https://files.pythonhosted.org/packages/2f/c5/9652585ee78a0f242d2c92983a550990b6a39779d6d0a7c24ab82f293d39/icechunk-2.0.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0554ef924b14f7d6369919c22f042a817f8dbc85d0b9efd793398e2d44786fa4", size = 15544742, upload-time = "2026-05-18T20:22:36.879Z" },
1077
- { url = "https://files.pythonhosted.org/packages/59/2c/076e478b9b45616ef268bdb0473d6d0c8bfc4ad62224477c0c066b74ebe0/icechunk-2.0.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43289b68bc3ca93804a8ffd96e356f509c87bfd35c3d8202382dd97febd9957d", size = 17240728, upload-time = "2026-05-18T20:22:26.306Z" },
1078
- { url = "https://files.pythonhosted.org/packages/fa/06/8c0f3fb0df245f42d05d4b423a92766a466ad9e36711972da84196263d14/icechunk-2.0.5-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:35812c0c3087688c422470610fa9f77f6edb2d5d7c3345e0610beb32c8028f96", size = 16883484, upload-time = "2026-05-18T20:22:02.374Z" },
1079
- { url = "https://files.pythonhosted.org/packages/0f/6a/74440741ac30bb09c9d3fb74acb1332f218ae87faba24f6a81c8c575b9d2/icechunk-2.0.5-cp314-cp314-manylinux_2_28_armv7l.whl", hash = "sha256:ba30ea180b056c34fcf094b36fd7fb7cbd2521f778e5d1080ce9ab9b2f28204d", size = 16706325, upload-time = "2026-05-18T20:22:15.083Z" },
1080
- { url = "https://files.pythonhosted.org/packages/4b/09/fe20275108f44a7ad8bbb904165feaf65f31796a8dad7baa764d86181fa9/icechunk-2.0.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:65075bce7674d2292344a661129fa987a579e5ab46c35862ef366b0c167e1066", size = 17099016, upload-time = "2026-05-18T20:22:56.368Z" },
1081
- { url = "https://files.pythonhosted.org/packages/fb/f6/bd9b9d79b1a10a8382116ac018f3580f6e8021674fe53167829fba70bd7e/icechunk-2.0.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:231f8a46de0949da8ffd0e59446342a1051e374276385ca9a529ab593e73c7ce", size = 16878446, upload-time = "2026-05-18T20:23:06.761Z" },
1082
- { url = "https://files.pythonhosted.org/packages/c6/af/025f9c303dca742c709a8c01f809479c3d22bdf630954f08eadb6eaace5b/icechunk-2.0.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:65e514a6394b1ed5f3726d7da1cc3cafae8e23c7a6b243dc793b1eb876078813", size = 16955472, upload-time = "2026-05-18T20:23:16.865Z" },
1083
- { url = "https://files.pythonhosted.org/packages/52/b3/7429c90e9a0512f6e11443ccbc9d4ee392757b53c8604db05578457ffac9/icechunk-2.0.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e1a488e9162d64e05e995aa4015cc8118c68fc54d0ed5af4616627a66a4d1d01", size = 17646740, upload-time = "2026-05-18T20:23:30.02Z" },
1084
- { url = "https://files.pythonhosted.org/packages/25/3c/8e086299cc1a779837e65e4152d03d02b457f8974bb388082fef20894b5e/icechunk-2.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:95b1beb874ad287fcb99dfea29cd5218c795b5d9bca47b8f43ef78b8e6c5b572", size = 15945027, upload-time = "2026-05-18T20:23:40.81Z" },
1053
+ sdist = { url = "https://files.pythonhosted.org/packages/dd/c3/c43ce00558a545c93b7891697656c4dabc276414fc45466c26bb359847be/icechunk-2.0.6.tar.gz", hash = "sha256:7bf5660188ea1ee7e5487fa4733f36fb3de779ebbb160aa9b1117cbc0df2157d", size = 3344079, upload-time = "2026-06-04T21:35:52.726Z" }
1054
+ wheels = [
1055
+ { url = "https://files.pythonhosted.org/packages/0c/bc/0439099c547e19cc51a1f08f1c2261ece866b4738144227aec46db639400/icechunk-2.0.6-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c158f4d503451e62fe6f80d213dc99689fa49787258028e58562905cfe8f8db7", size = 16862055, upload-time = "2026-06-04T21:36:18.034Z" },
1056
+ { url = "https://files.pythonhosted.org/packages/c3/f9/647283b2b272d3aa20f264f9db4a9f58ba76d8b3623ffc6e1c24ecd8326a/icechunk-2.0.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed652239f3f6b0a293e5b746babf420942b1307f802f7d5a8ad5f31a3ccb40a9", size = 15553982, upload-time = "2026-06-04T21:36:11.197Z" },
1057
+ { url = "https://files.pythonhosted.org/packages/20/7c/0f24607e6c1d08ed93df7a67b86f94e0e971222cbad39786761d355e0c11/icechunk-2.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cd1722da41443c811d113fbeee972cee0e7db67771bf6a58beaa0f0a5f50493", size = 17241116, upload-time = "2026-06-04T21:36:03.665Z" },
1058
+ { url = "https://files.pythonhosted.org/packages/0a/05/b13109cefad82394139d15b08b64249bbdb78026028a92cb234f4d84385d/icechunk-2.0.6-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:4276c3712a2a92be2fce3cabbbba0563af12b2a90ef579a1d5cc6f0740ce732d", size = 16887134, upload-time = "2026-06-04T21:35:45.441Z" },
1059
+ { url = "https://files.pythonhosted.org/packages/b3/0e/89dc65adf8d5c7fe9628b47c5feb32b7033f3c5755278d492d3e1953a28b/icechunk-2.0.6-cp312-cp312-manylinux_2_28_armv7l.whl", hash = "sha256:337094452f5c07264b37477ab0f63ac164b77d0f79e218053c7ab86cbfa9e3d8", size = 16719325, upload-time = "2026-06-04T21:35:54.319Z" },
1060
+ { url = "https://files.pythonhosted.org/packages/ab/4e/0687099b5e616e409d403290269d5eaad0835ad39c0c4a8d14330cf6398d/icechunk-2.0.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4b60b75c4e511a2296cbe3c5b476bedb9101e074c05de737a9d1c6b99fa77c", size = 17120218, upload-time = "2026-06-04T21:36:24.578Z" },
1061
+ { url = "https://files.pythonhosted.org/packages/4d/dd/dba49824fb1ce42f2ec7812d9ee401b640d4de492686f7b7037f5a9c12db/icechunk-2.0.6-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fb05ffeb89e7ca2fc905154b53ab31225dab13556bb1b8eff674700cf747e065", size = 16886145, upload-time = "2026-06-04T21:36:31.113Z" },
1062
+ { url = "https://files.pythonhosted.org/packages/3d/82/2ebd411fd09d6611beb2e944a27eba1efe27e8e47879229a21979714ca02/icechunk-2.0.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:728c15e3c6f834c08adc0f689e51916fe671243b57dc8f99140df1486e7dfa6b", size = 16972190, upload-time = "2026-06-04T21:36:37.849Z" },
1063
+ { url = "https://files.pythonhosted.org/packages/e9/13/ff8344875f968dde3d3c09c1e83203a2d7d5582d2833ae96eb2a8d660352/icechunk-2.0.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d6fe11179e98157a8ccc549d5cf59ee80737c208f62faf9cf1cd77d99be7e54e", size = 17644992, upload-time = "2026-06-04T21:36:44.556Z" },
1064
+ { url = "https://files.pythonhosted.org/packages/56/1a/dce9c269198fc6672c553389387a20663c3f83886e127d83ddda230d2a48/icechunk-2.0.6-cp312-cp312-win_amd64.whl", hash = "sha256:d307def9ec3d0c684a98b31e9ca730de96860436bc587fb45b1e302028f8fe97", size = 15972997, upload-time = "2026-06-04T21:36:52.335Z" },
1065
+ { url = "https://files.pythonhosted.org/packages/6b/ec/90870bd2539081ce8a8a4a3b25c9a98001d14cc81c0b311a2bbbbb93b6ba/icechunk-2.0.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f1c7035dc809b3d6403ddfbfa5bc6a43daed69c2c02f7ac7cafd3651d0ba6670", size = 16861433, upload-time = "2026-06-04T21:36:20.156Z" },
1066
+ { url = "https://files.pythonhosted.org/packages/90/16/31bf3edf9823dca06ac8a80576f559f0a9479b81cd3e1cd2100a22636e07/icechunk-2.0.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdf031111aa20f51558cac45e80751bffd7cd85825ed66457129987bcfe3d56a", size = 15551895, upload-time = "2026-06-04T21:36:13.431Z" },
1067
+ { url = "https://files.pythonhosted.org/packages/31/b7/55368605465f7085c24ce53b173994e112bfee55b268d51597f09a6be3c7/icechunk-2.0.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c78906ade1fc80d6b320705cd3d509020b5093d074f1f78fe2a27503f1cff6a2", size = 17240911, upload-time = "2026-06-04T21:36:05.739Z" },
1068
+ { url = "https://files.pythonhosted.org/packages/d2/76/a80702999fafedb4c2fa08dbbb535a5bbcf65e875fe64f77d74e4ec6eadb/icechunk-2.0.6-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:811eb4b6bf068a1124c04b3a9b25d3d8793d4d936c004c4dd70c2aafdc7cef67", size = 16885273, upload-time = "2026-06-04T21:35:47.738Z" },
1069
+ { url = "https://files.pythonhosted.org/packages/65/01/7a6c7134fe8a2adb9824bf2f7f6dd7b4aab1509b32d8d7034e6a72af2791/icechunk-2.0.6-cp313-cp313-manylinux_2_28_armv7l.whl", hash = "sha256:ce1f02575510b64762ec1feccaba96f0b63877808dcaa1675273a2d05845c858", size = 16718100, upload-time = "2026-06-04T21:35:56.538Z" },
1070
+ { url = "https://files.pythonhosted.org/packages/23/d8/091507fe3ae3384c1751cc3ac466f024e8577f7f23fad6e46438714f8a19/icechunk-2.0.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3c5a77448b69ee8e111dc68a2b5e903088ce5243bfc786bd76e7c06e63ee3cc", size = 17119603, upload-time = "2026-06-04T21:36:26.697Z" },
1071
+ { url = "https://files.pythonhosted.org/packages/d3/8b/2acdfa9090ef95a04a605de6d85f9833ebf781333d149cb75a106cc03e25/icechunk-2.0.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4ba2a5ccac290d483d164884bf6f1a33079bd8eed1429d4ac99f158fbe7682be", size = 16885831, upload-time = "2026-06-04T21:36:33.188Z" },
1072
+ { url = "https://files.pythonhosted.org/packages/33/a8/65cf48ce67c523cbc7aac96b62984a9e1972da12f49a5ea2f4cdef630865/icechunk-2.0.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:14f72c739dc7fc3fc3b0bd8e88b0f416a8ae4455320e26804c8e12d5a71e035c", size = 16971822, upload-time = "2026-06-04T21:36:39.993Z" },
1073
+ { url = "https://files.pythonhosted.org/packages/ae/e2/cbc71a03e6baf7954ead5257b1162e4896705c4f7624e8b26da194807355/icechunk-2.0.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8670a76b8508effc0eb82667696c9642c122f2485c0038de8b6ce56421c7cd7", size = 17644161, upload-time = "2026-06-04T21:36:46.83Z" },
1074
+ { url = "https://files.pythonhosted.org/packages/53/bf/d7ebab6c2765c5b7cb33380190dbff489532893e0ef912d9113ab416c0ac/icechunk-2.0.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b68c523ee8367c9467e6818f9858cfea5da89defe4696d59ebefba850e6992a", size = 15971208, upload-time = "2026-06-04T21:36:54.679Z" },
1075
+ { url = "https://files.pythonhosted.org/packages/2e/00/8d2e2386827fd92def82d805ba1e4d013fb44c00d92dff78dbfd5e951f80/icechunk-2.0.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:a74012da2d83cf309521766c73f91a1a2a373b2774b6269384971e285da40a13", size = 16867623, upload-time = "2026-06-04T21:36:22.508Z" },
1076
+ { url = "https://files.pythonhosted.org/packages/5b/05/6d4eaa5afe2952dd4c4a1a073da9244f3d2911fd098b0342a54f824301e9/icechunk-2.0.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3d417af54f44995f4411c1bfa100355f1cc9b082880ec4411669e28e9a42656", size = 15560697, upload-time = "2026-06-04T21:36:15.661Z" },
1077
+ { url = "https://files.pythonhosted.org/packages/00/03/17e1d02f4c7cf2958724992382d7d99fa1aaddb8f13404bf6c84c19f341b/icechunk-2.0.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d68ffe631e2c12dfb09f8bfac055c3ab3dd897e4ef7b6ec1b067b8efdf9d5ed", size = 17249891, upload-time = "2026-06-04T21:36:08.22Z" },
1078
+ { url = "https://files.pythonhosted.org/packages/ff/74/49ef76b6ec4389a0cdd6caeff47a2375ef5d1828dae6e25d02df9095e9c5/icechunk-2.0.6-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:67e7748888c50c8c62c5b5a7e832b26f66af497f5f278478a45bd7f98cfbec76", size = 16893554, upload-time = "2026-06-04T21:35:50.619Z" },
1079
+ { url = "https://files.pythonhosted.org/packages/9b/b5/8a17f210d536bc877ba95c8e85501ce889613a57915934f4101316318b06/icechunk-2.0.6-cp314-cp314-manylinux_2_28_armv7l.whl", hash = "sha256:e56a07e6daa4299b9c30c4cbfcc68f82063286e3a0ade8aabcdf64bd452dce6e", size = 16725746, upload-time = "2026-06-04T21:36:01.049Z" },
1080
+ { url = "https://files.pythonhosted.org/packages/f6/6e/87e48f05c2bf0e6fd3c1c900405a20c739ef05b29fde2e92fdd11cf9d431/icechunk-2.0.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:36bf455e7c079c03d1c41135ac0b6f07450f97b1cb9031b603c59d8cc47e35ad", size = 17129051, upload-time = "2026-06-04T21:36:29.061Z" },
1081
+ { url = "https://files.pythonhosted.org/packages/8a/42/eddeb4a6186e5c9a889869292fc26309ae9306a1aa96c7d99566bae75ad9/icechunk-2.0.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:e7c0ecff0c4a25f826cd2e6f576c7e882c1398c1c0cd7271b0fef8bea75588b8", size = 16892132, upload-time = "2026-06-04T21:36:35.784Z" },
1082
+ { url = "https://files.pythonhosted.org/packages/16/be/d9c581d1b351b89a440e20475c643f58ac669a487ece98841b9e28741f19/icechunk-2.0.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c3a7bbaccfe8b5cd563e36bc40483b83c83b74fb380a03fd809159e4bc936da9", size = 16976002, upload-time = "2026-06-04T21:36:42.18Z" },
1083
+ { url = "https://files.pythonhosted.org/packages/f9/ce/f431e35efbc7c228f4bdc1fd2aebf54e50667aa9aad8183920cda9927255/icechunk-2.0.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a17d59a35225fa5dd84b3680fe0d0f6a5beecd591d65d2ca047f09884f6a810f", size = 17650995, upload-time = "2026-06-04T21:36:49.779Z" },
1084
+ { url = "https://files.pythonhosted.org/packages/54/f7/cfa90a242336f693d64b610c140011c6e456c47cbbb18caf8f6c4dbaeb95/icechunk-2.0.6-cp314-cp314-win_amd64.whl", hash = "sha256:7b4a22821e05a636f9060377dc58060c272e131cce2c4756213aba4c3c93a4c4", size = 15984769, upload-time = "2026-06-04T21:36:56.887Z" },
1085
1085
  ]
1086
1086
 
1087
1087
  [[package]]
@@ -2559,19 +2559,19 @@ wheels = [
2559
2559
 
2560
2560
  [[package]]
2561
2561
  name = "tornado"
2562
- version = "6.5.5"
2563
- source = { registry = "https://pypi.org/simple" }
2564
- sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" }
2565
- wheels = [
2566
- { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" },
2567
- { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" },
2568
- { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" },
2569
- { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" },
2570
- { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" },
2571
- { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" },
2572
- { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" },
2573
- { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" },
2574
- { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" },
2562
+ version = "6.5.6"
2563
+ source = { registry = "https://pypi.org/simple" }
2564
+ sdist = { url = "https://files.pythonhosted.org/packages/50/57/6d7303a77ae439d9189108f76c0c4fd89ee5e2cc8387bffb55232565c4ed/tornado-6.5.6.tar.gz", hash = "sha256:9a365179fe8ff6b8766f602c0f67c185d778193e9bdd828b19f0b6ed7764177d", size = 518139, upload-time = "2026-05-27T15:35:54.646Z" }
2565
+ wheels = [
2566
+ { url = "https://files.pythonhosted.org/packages/1b/0d/b4f481e18c5a51864e6d12b9a05ecf72919696680b747c958c3fc1f4fbae/tornado-6.5.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:65fcfaafb079435c2c19dc9e07c0f1cf0fa9051759ed0a7d0a3ba7ea7f64919c", size = 447737, upload-time = "2026-05-27T15:35:38.122Z" },
2567
+ { url = "https://files.pythonhosted.org/packages/9e/9c/5430c39fcab1144d35860f457b15e9c08b4bc7ac86764354204e983d6183/tornado-6.5.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:38bc01b4acacded2de63ae78023548e41ebe6fbed3ec05a796d7ae3ad893887e", size = 445899, upload-time = "2026-05-27T15:35:40.519Z" },
2568
+ { url = "https://files.pythonhosted.org/packages/8b/79/fa7e14a2f939c807a8d30619b4eb604eab219601b78792516ebe22d40cf9/tornado-6.5.6-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b942e6a137fda31ff54bf8e6e2c8d1c37f1f50583f3ed53fb840b53b9601d104", size = 448964, upload-time = "2026-05-27T15:35:42.106Z" },
2569
+ { url = "https://files.pythonhosted.org/packages/a7/71/bd67d5f5199f937dafe03a49a37989f60f600ff6fef34c79412a829d97bd/tornado-6.5.6-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8666946e70171b8c3f1fc9b7876fac492e84822c4c7f3746f4e8f8bc9ac92a79", size = 449935, upload-time = "2026-05-27T15:35:43.906Z" },
2570
+ { url = "https://files.pythonhosted.org/packages/cc/a4/c24388c9cf5b3c3a513b56a158af9f23092c9a2810d789e294310797df21/tornado-6.5.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1c34cfab7ad6d104f052f55de06d39bbafc5885cfeb4da688803308dbcfa90b7", size = 449767, upload-time = "2026-05-27T15:35:45.793Z" },
2571
+ { url = "https://files.pythonhosted.org/packages/a5/eb/6a07ad550c3f7b37244bd0becdf293ec3d3e961783d8b720a97df50de1b2/tornado-6.5.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:385f35e4e22fb52551dfcda4cdc8c30c61c2c001aef5ddad99cdfe116952efd3", size = 449174, upload-time = "2026-05-27T15:35:47.485Z" },
2572
+ { url = "https://files.pythonhosted.org/packages/bb/84/3469e098dccdb6763130e06aacd786bb4363fca7b590a55c101ddf34ed30/tornado-6.5.6-cp39-abi3-win32.whl", hash = "sha256:db475f1b67b2809b10bb16264829087724ca8d24fe4ed47f7b8675cae453ef86", size = 450230, upload-time = "2026-05-27T15:35:49.322Z" },
2573
+ { url = "https://files.pythonhosted.org/packages/d2/3c/273a04e0b9dd9016f1685cca0c1c8795a71ac88a34a8c889a0b443483226/tornado-6.5.6-cp39-abi3-win_amd64.whl", hash = "sha256:6739bf1e8eb09230f1280ddbd3236f0309db70f2c551a8dbc40f62babdf82f79", size = 450667, upload-time = "2026-05-27T15:35:51.194Z" },
2574
+ { url = "https://files.pythonhosted.org/packages/02/98/0cffe22a224f60c5fb1e3aa0b76f9da2e1ca78b0e9545e3d077c68ce60a7/tornado-6.5.6-cp39-abi3-win_arm64.whl", hash = "sha256:2543597b24a695d72338a9a77818362d72387c03ae173f1f169eadc5c91466ac", size = 449690, upload-time = "2026-05-27T15:35:52.902Z" },
2575
2575
  ]
2576
2576
 
2577
2577
  [[package]]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes