Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Require Python 3.11 or newer across all packages, removing Python 3.10 compatibility code and typing backfills.
- `tilebox-grpc`: Use `nest-asyncio2` for nested event-loop support on Python 3.14. Restart notebook kernels already
patched by `nest-asyncio` and apply `nest-asyncio2` before the old library to use the updated patch.
- `tilebox-storage`: Replace legacy synchronous client patching with explicit wrappers using `asyncio.run()`.
When called inside a running event loop (including notebooks), run the operation in a worker thread instead.
Remove the internal `syncify` helper and the `nest-asyncio2` dependency from `tilebox-grpc`.
- Raise dependency minimums to remove obsolete compatibility workarounds: boto3 1.40.2, OpenTelemetry 1.43.0
(logging instrumentation 0.64b0), grpcio 1.84.0, and pyqwest 0.7.0.
- `tilebox-datasets`: Require NumPy 1.25, pandas 2.2.2, xarray 2024.6, and Shapely 2.0.6 or newer.
Expand Down
117 changes: 0 additions & 117 deletions tilebox-grpc/_tilebox/grpc/aio/syncify.py

This file was deleted.

1 change: 0 additions & 1 deletion tilebox-grpc/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ dependencies = [
# for the libraries below we specify a minimum, tested to be working version
"lz4>=4",
"anyio>=4",
"nest-asyncio2>=1.7.2",
]

[dependency-groups]
Expand Down
77 changes: 0 additions & 77 deletions tilebox-grpc/tests/aio/test_syncify.py

This file was deleted.

63 changes: 63 additions & 0 deletions tilebox-storage/tests/test_sync_storage_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import asyncio
from contextvars import ContextVar
from pathlib import Path
from threading import get_ident
from unittest.mock import patch

import pytest

from tilebox import storage
from tilebox.storage._sync import _run
from tilebox.storage.granule import LocationStorageGranule


def test_local_sync_client(tmp_path: Path) -> None:
folder = tmp_path / "scene"
folder.mkdir()
(folder / "data.tif").write_bytes(b"raster")
(tmp_path / "preview.jpg").write_bytes(b"preview")
granule = LocationStorageGranule("scene", "preview.jpg")
client = storage.LocalFileSystemStorageClient(tmp_path)

# Reuse the same client across separate asyncio.run() event loops.
assert client.list_objects(granule) == ["data.tif"]
assert client.download(granule) == folder
assert client.download_quicklook(granule) == tmp_path / "preview.jpg"
with patch("tilebox.storage.aio._display_quicklook") as display:
client.quicklook(granule, width=321, height=123)
display.assert_called_once_with(tmp_path / "preview.jpg", 321, 123, None)

with pytest.raises(ValueError, match="Data not found"):
client.download(LocationStorageGranule("missing"))


@pytest.mark.asyncio
async def test_local_sync_client_in_running_loop(tmp_path: Path) -> None:
loop = asyncio.get_running_loop()
task = asyncio.current_task()
test_local_sync_client(tmp_path)
assert asyncio.get_running_loop() is loop
assert asyncio.current_task() is task
await asyncio.sleep(0)


@pytest.mark.asyncio
async def test_run_preserves_context_in_worker_thread() -> None:
context = ContextVar("storage_test_context", default="unset")
token = context.set("caller")
caller_thread = get_ident()
caller_loop = asyncio.get_running_loop()

async def operation() -> str:
assert get_ident() != caller_thread
assert asyncio.get_running_loop() is not caller_loop
await asyncio.sleep(0)
value = context.get()
context.set("worker")
return value

try:
assert _run(operation()) == "caller"
assert context.get() == "caller"
finally:
context.reset(token)
Loading
Loading