diff --git a/pkgs/development/python-modules/async-geotiff/default.nix b/pkgs/development/python-modules/async-geotiff/default.nix new file mode 100644 index 000000000000..eb9bd93ef26c --- /dev/null +++ b/pkgs/development/python-modules/async-geotiff/default.nix @@ -0,0 +1,76 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + fetchpatch2, + pytestCheckHook, + uv-build, + + affine, + async-tiff, + defusedxml, + numpy, + pyproj, + + # tests + pydantic, + rasterio, + morecantile, + jsonschema, + pytest-asyncio, +}: +buildPythonPackage (finalAttrs: { + pname = "async-geotiff"; + version = "0.4.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "developmentseed"; + repo = "async-geotiff"; + tag = "v${finalAttrs.version}"; + hash = "sha256-J72/VRDAgqGOm7rYmlkURKgWSIa11L260LX447MQWbc="; + fetchSubmodules = true; + }; + + patches = [ + # see https://github.com/developmentseed/async-geotiff/pull/136 + ./uv-build-relax-deps.patch + # see https://github.com/developmentseed/async-tiff/pull/292 + (fetchpatch2 { + url = "https://github.com/developmentseed/async-geotiff/commit/f8325c0decb2a7e61faf3db5e51ec5a104d3cbdb.patch?full_index=1"; + hash = "sha256-RLqMWKtjDSmxQkUXz9dXKIIqRXM7BWkuJIbbeHxCPyQ="; + }) + ]; + + build-system = [ uv-build ]; + + # see https://github.com/developmentseed/async-geotiff/pull/133 + pythonRemoveDeps = [ "types-defusedxml" ]; + + dependencies = [ + affine + async-tiff + defusedxml + numpy + pyproj + ]; + + pythonImportsCheck = [ "async_geotiff" ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + checkInputs = [ + jsonschema + morecantile + rasterio + pydantic + pytest-asyncio + ]; + + meta = { + description = "Fast, async GeoTIFF and COG reader for Python"; + homepage = "https://developmentseed.org/async-geotiff/latest/"; + license = lib.licenses.mit; + teams = [ lib.teams.geospatial ]; + }; +}) diff --git a/pkgs/development/python-modules/async-geotiff/uv-build-relax-deps.patch b/pkgs/development/python-modules/async-geotiff/uv-build-relax-deps.patch new file mode 100644 index 000000000000..68597869ca15 --- /dev/null +++ b/pkgs/development/python-modules/async-geotiff/uv-build-relax-deps.patch @@ -0,0 +1,49 @@ +diff --git i/pyproject.toml w/pyproject.toml +index 601e2e5..cd26339 100644 +--- i/pyproject.toml ++++ w/pyproject.toml +@@ -69,7 +69,7 @@ docs = [ + + + [build-system] +-requires = ["uv_build>=0.8.8,<0.9.0"] ++requires = ["uv_build>=0.8.8,<0.12.0"] + build-backend = "uv_build" + + [tool.ruff] +diff --git i/uv.lock w/uv.lock +index e7cd10f..2a74412 100644 +--- i/uv.lock ++++ w/uv.lock +@@ -55,7 +55,6 @@ dependencies = [ + { name = "defusedxml" }, + { name = "numpy" }, + { name = "pyproj" }, +- { name = "types-defusedxml" }, + ] + + [package.optional-dependencies] +@@ -77,6 +76,7 @@ dev = [ + { name = "pytest-asyncio" }, + { name = "rasterio", version = "1.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "rasterio", version = "1.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ++ { name = "types-defusedxml" }, + { name = "types-jsonschema" }, + ] + docs = [ +@@ -97,7 +97,6 @@ requires-dist = [ + { name = "morecantile", marker = "extra == 'morecantile'", specifier = ">=7.0,<8.0" }, + { name = "numpy", specifier = ">=2.0" }, + { name = "pyproj", specifier = ">=3.3.0" }, +- { name = "types-defusedxml", specifier = ">=0.7.0.20250822" }, + ] + provides-extras = ["morecantile"] + +@@ -114,6 +113,7 @@ dev = [ + { name = "pytest", specifier = ">=9.0.2" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "rasterio", specifier = ">=1.4.4" }, ++ { name = "types-defusedxml", specifier = ">=0.7.0.20250822" }, + { name = "types-jsonschema", specifier = ">=4.26.0.20260109" }, + ] + docs = [ diff --git a/pkgs/development/python-modules/async-tiff/default.nix b/pkgs/development/python-modules/async-tiff/default.nix new file mode 100644 index 000000000000..b1291723dfdf --- /dev/null +++ b/pkgs/development/python-modules/async-tiff/default.nix @@ -0,0 +1,93 @@ +{ + # utils + buildPythonPackage, + fetchFromGitHub, + fetchpatch2, + lib, + rustPlatform, + + # build and dependencies + llvmPackages, + maturin, + obspec, + + # tests dependencies + pytestCheckHook, + numpy, + obstore, + pytest-asyncio, + rasterio, +}: +buildPythonPackage (finalAttrs: { + pname = "async-tiff"; + version = "0.7.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "developmentseed"; + repo = "async-tiff"; + tag = "py-v${finalAttrs.version}"; + hash = "sha256-o77iYqzBCloE5xgn0Sa6SWbrCMgnNuZwQ2MZ0wgtNew="; + fetchSubmodules = true; + }; + + patches = [ + (fetchpatch2 { + url = "https://github.com/developmentseed/async-tiff/commit/c7db2fc693089f3326328cc59863f8a9a6dd1cb9.patch?full_index=1"; + hash = "sha256-FsOZk8KZ3guqIoECYRsBQMEq8TrAQn9Z01NqUJAQOu8="; + }) + ]; + + postPatch = '' + cd python + ''; + + buildSystem = [ maturin ]; + + buildInputs = [ llvmPackages.libclang ]; + + cargoDeps = rustPlatform.fetchCargoVendor { + pname = finalAttrs.pname; + version = finalAttrs.version; + src = finalAttrs.src; + hash = "sha256-AKa4SsBYBCabMlYJqTcbHv9Z7ouqtiIEK0el/i/fo6I="; + + preBuild = '' + cd python + ''; + }; + + nativeBuildInputs = with rustPlatform; [ + cargoSetupHook + maturinBuildHook + rustPlatform.bindgenHook + ]; + + dependencies = [ + obspec + ]; + + pythonImportsCheck = [ "async_tiff" ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + checkInputs = [ + numpy + obstore + pytest-asyncio + rasterio + ]; + + disabledTests = [ + # network access + "test_cog_s3" + "test_raise_typeerror_fetch_tile_striped_tiff" + ]; + + meta = { + description = "Async TIFF reader for Python"; + homepage = "http://developmentseed.org/async-tiff/"; + license = lib.licenses.mit; + teams = [ lib.teams.geospatial ]; + }; +}) diff --git a/pkgs/development/python-modules/obspec/default.nix b/pkgs/development/python-modules/obspec/default.nix new file mode 100644 index 000000000000..a684b0e34537 --- /dev/null +++ b/pkgs/development/python-modules/obspec/default.nix @@ -0,0 +1,53 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + pytestCheckHook, + + # build system + hatchling, + + # dependencies + typing-extensions, + + # test dependencies + pytest, + pytest-mypy-plugins, + mypy, +}: +buildPythonPackage (finalAttrs: { + pname = "obspec"; + version = "0.1.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "developmentseed"; + repo = "obspec"; + tag = "v${finalAttrs.version}"; + hash = "sha256-zO2T189WUl1HJkBLrGpArS5NoFNpEchWfjJQJEME5W8="; + }; + + build-system = [ hatchling ]; + + dependencies = [ + typing-extensions + ]; + + pythonImportsCheck = [ "obspec" ]; + + nativeCheckInputs = [ + pytestCheckHook + mypy + ]; + + checkInputs = [ + pytest-mypy-plugins + ]; + + meta = { + description = "Object storage interface definitions for Python"; + homepage = "http://developmentseed.org/obspec/"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ autra ]; + }; +}) diff --git a/pkgs/development/python-modules/rio-tiler/default.nix b/pkgs/development/python-modules/rio-tiler/default.nix index 91dc919876ca..eb6672f51bbe 100644 --- a/pkgs/development/python-modules/rio-tiler/default.nix +++ b/pkgs/development/python-modules/rio-tiler/default.nix @@ -4,6 +4,7 @@ fetchFromGitHub, pytestCheckHook, + async-geotiff, attrs, boto3, cachetools, @@ -17,21 +18,23 @@ obstore, pydantic, pystac, + pytest-asyncio, rasterio, rioxarray, + typing-extensions, zarr, }: buildPythonPackage (finalAttrs: { pname = "rio-tiler"; - version = "8.0.5"; + version = "9.0.4"; pyproject = true; src = fetchFromGitHub { owner = "cogeotiff"; repo = "rio-tiler"; tag = finalAttrs.version; - hash = "sha256-FOTwP4iTLfWl81KKarLOQQyp4gpi6Q+pjUXfZrXXsfo="; + hash = "sha256-R8vmb33ZfKGqRLkJ55npL031Gnc7HTUDeWiCvtaLsiM="; }; build-system = [ hatchling ]; @@ -47,6 +50,7 @@ buildPythonPackage (finalAttrs: { pydantic pystac rasterio + typing-extensions ]; optional-dependencies = { @@ -64,11 +68,18 @@ buildPythonPackage (finalAttrs: { ] ++ lib.flatten (builtins.attrValues finalAttrs.passthru.optional-dependencies); + checkInputs = [ + async-geotiff + pytest-asyncio + ]; + pythonImportsCheck = [ "rio_tiler" ]; disabledTests = [ # Requires network access "test_dataset_reader" + # for some reason, str date representation are not the same + "test_xarray_reader" ]; meta = { diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 465620070443..edda4a85e58f 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -1116,6 +1116,8 @@ self: super: with self; { async-generator = callPackage ../development/python-modules/async-generator { }; + async-geotiff = callPackage ../development/python-modules/async-geotiff { }; + async-interrupt = callPackage ../development/python-modules/async-interrupt { }; async-lru = callPackage ../development/python-modules/async-lru { }; @@ -1124,6 +1126,8 @@ self: super: with self; { async-stagger = callPackage ../development/python-modules/async-stagger { }; + async-tiff = callPackage ../development/python-modules/async-tiff { }; + async-timeout = callPackage ../development/python-modules/async-timeout { }; async-tkinter-loop = callPackage ../development/python-modules/async-tkinter-loop { }; @@ -11321,6 +11325,8 @@ self: super: with self; { obsidian-media = callPackage ../development/python-modules/obsidian-media { }; + obspec = callPackage ../development/python-modules/obspec { }; + obspy = callPackage ../development/python-modules/obspy { }; obstore = callPackage ../development/python-modules/obstore { };