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.
- {arraylake-1.1.0 → arraylake-1.1.1}/PKG-INFO +2 -2
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/_version.py +2 -2
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/client.py +11 -2
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/types.py +20 -2
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/storage.py +39 -4
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/types.py +1 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/types.py +24 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/pyproject.toml +2 -2
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/conftest.py +26 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/conftest.py +13 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/test_storage.py +16 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_client.py +16 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_types.py +12 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/uv.lock +48 -48
- {arraylake-1.1.0 → arraylake-1.1.1}/.gitignore +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/README.md +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/__main__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/_credential_cache.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/api_utils.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/asyn.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/auth.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/compute.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/config.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/main.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/repo.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/skills.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/cli/utils.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/doctor.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/http_client.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/compute/services.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/config.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/config.yaml +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/credentials.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/diagnostics.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/display/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/display/repo.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/display/repolist.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/exceptions.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/log_util.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/metastore/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/metastore/abc.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/metastore/http_metastore.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/py.typed +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/repos/icechunk/virtual.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/token.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/arraylake/tuning.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/compute/test_client.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/compute/test_doctor.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/config.yaml +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/__init__.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/icechunk/test_virtual.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_api_utils.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_asyn.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_cli.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_config.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_credential_cache.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_credentials.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_diagnostics.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_performance.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_skills.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_subscriptions.py +0 -0
- {arraylake-1.1.0 → arraylake-1.1.1}/tests/test_token_handler.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 1,
|
|
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 =
|
|
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
|
-
|
|
236
|
-
|
|
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=
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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/
|
|
1054
|
-
wheels = [
|
|
1055
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1056
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1057
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1058
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1059
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1060
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1061
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1062
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1063
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1064
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1065
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1066
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1067
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1068
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1069
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1070
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1071
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1072
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1073
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1074
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1075
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1076
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1077
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1078
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1079
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1080
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1081
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1082
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1083
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1084
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
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.
|
|
2563
|
-
source = { registry = "https://pypi.org/simple" }
|
|
2564
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
2565
|
-
wheels = [
|
|
2566
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2567
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2568
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2569
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2570
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2571
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2572
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2573
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
2574
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|